From a89823be4837856515ec6ba70311138c142030dadbf4b5994a283278e59e0417 Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Wed, 4 Jul 2012 09:14:28 +0000 Subject: [PATCH] refreshed with more fixes from sebastian OBS-URL: https://build.opensuse.org/package/show/security/ecryptfs-utils?expand=0&rev=36 --- ecryptfs-utils.security.patch | 87 +++++++++++++++++++---------------- ecryptfs-utils.spec | 1 - 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/ecryptfs-utils.security.patch b/ecryptfs-utils.security.patch index e4c7983..69f1cb5 100644 --- a/ecryptfs-utils.security.patch +++ b/ecryptfs-utils.security.patch @@ -14,19 +14,20 @@ Index: ecryptfs-utils-96/src/pam_ecryptfs/pam_ecryptfs.c #include "../include/ecryptfs.h" #define PRIVATE_DIR "Private" -@@ -119,9 +122,9 @@ static int wrap_passphrase_if_necessary( +@@ -119,9 +122,10 @@ static int wrap_passphrase_if_necessary( PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { - uid_t uid = 0; + uid_t uid = 0, oeuid = 0; -+ gid_t gid = 0, oegid = 0; ++ gid_t gid = 0, oegid = 0, groups[64]; ++ int ngids = 0; char *homedir = NULL; - uid_t saved_uid = 0; const char *username; char *passphrase = NULL; char salt[ECRYPTFS_SALT_SIZE]; -@@ -139,12 +142,24 @@ PAM_EXTERN int pam_sm_authenticate(pam_h +@@ -139,12 +143,25 @@ PAM_EXTERN int pam_sm_authenticate(pam_h pwd = getpwnam(username); if (pwd) { uid = pwd->pw_uid; @@ -38,20 +39,21 @@ Index: ecryptfs-utils-96/src/pam_ecryptfs/pam_ecryptfs.c goto out; } + -+ if ((oeuid = geteuid()) < 0 || (oegid = getegid()) < 0) { ++ if ((oeuid = geteuid()) < 0 || (oegid = getegid()) < 0 || ++ (ngids = getgroups(sizeof(groups)/sizeof(gid_t), groups)) < 0) { + syslog(LOG_ERR, "pam_ecryptfs: geteuid error"); + goto outnouid; + } + -+ if (setfsgid(gid) != gid || setfsuid(uid) != uid) { -+ syslog(LOG_ERR, "pam_ecryptfs: setfsuid error"); -+ goto outnouid; ++ if (setegid(gid) < 0 || setgroups(1, &gid) < 0 || seteuid(uid) < 0) { ++ syslog(LOG_ERR, "pam_ecryptfs: seteuid error"); ++ goto out; + } + if (!file_exists_dotecryptfs(homedir, "auto-mount")) goto out; private_mnt = ecryptfs_fetch_private_mnt(homedir); -@@ -158,13 +173,10 @@ PAM_EXTERN int pam_sm_authenticate(pam_h +@@ -158,13 +175,10 @@ PAM_EXTERN int pam_sm_authenticate(pam_h load ecryptfs module if not loaded already */ if (ecryptfs_get_version(&version) != 0) syslog(LOG_WARNING, "pam_ecryptfs: Can't check if kernel supports ecryptfs\n"); @@ -65,72 +67,75 @@ Index: ecryptfs-utils-96/src/pam_ecryptfs/pam_ecryptfs.c if (rc != PAM_SUCCESS) { syslog(LOG_ERR, "pam_ecryptfs: Error retrieving passphrase; rc = [%ld]\n", rc); -@@ -182,7 +194,11 @@ PAM_EXTERN int pam_sm_authenticate(pam_h +@@ -182,7 +196,12 @@ PAM_EXTERN int pam_sm_authenticate(pam_h } else from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE); if ((child_pid = fork()) == 0) { - setuid(uid); -+ if (setgroups(1, &gid) < 0 || setgid(gid) < 0 || setuid(uid) < 0) { -+ syslog(LOG_ERR, "pam_ecryptfs: setting uid/gid failed"); -+ rc = -errno; ++ /* temp regain uid 0 to drop privs */ ++ seteuid(oeuid); ++ /* setgroups() already called */ ++ if (setgid(gid) < 0 || setuid(uid) < 0) + goto out_child; -+ } ++ if (passphrase == NULL) { syslog(LOG_ERR, "pam_ecryptfs: NULL passphrase; aborting\n"); rc = -EINVAL; -@@ -240,6 +256,11 @@ out_child: +@@ -240,6 +259,12 @@ out_child: if (tmp_pid == -1) syslog(LOG_WARNING, "pam_ecryptfs: waitpid() returned with error condition\n"); out: + -+ setfsuid(oeuid); -+ setfsgid(oegid); ++ seteuid(oeuid); ++ setegid(oegid); ++ setgroups(ngids, groups); + +outnouid: if (private_mnt != NULL) free(private_mnt); return PAM_SUCCESS; -@@ -338,8 +359,12 @@ static int private_dir(pam_handle_t *pam +@@ -338,8 +363,12 @@ static int private_dir(pam_handle_t *pam syslog(LOG_DEBUG, "pam_ecryptfs: Skipping automatic eCryptfs mount"); return 0; } + clearenv(); ++ if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0) ++ return -1; /* run mount.ecryptfs_private as the user */ - setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid); + if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) < 0) -+ return -1; -+ if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0) + return -1; execl("/sbin/mount.ecryptfs_private", "mount.ecryptfs_private", NULL); } else { -@@ -348,8 +373,12 @@ static int private_dir(pam_handle_t *pam +@@ -348,8 +377,12 @@ static int private_dir(pam_handle_t *pam syslog(LOG_DEBUG, "pam_ecryptfs: Skipping automatic eCryptfs unmount"); return 0; } + clearenv(); ++ if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0) ++ return -1; /* run umount.ecryptfs_private as the user */ - setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid); + if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) < 0) -+ return -1; -+ if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0) + return -1; execl("/sbin/umount.ecryptfs_private", "umount.ecryptfs_private", NULL); } -@@ -391,9 +420,9 @@ pam_sm_close_session(pam_handle_t *pamh, +@@ -391,9 +424,10 @@ pam_sm_close_session(pam_handle_t *pamh, PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags, int argc, const char **argv) { - uid_t uid = 0; + uid_t uid = 0, oeuid = 0; -+ gid_t gid = 0, oegid = 0; ++ gid_t gid = 0, oegid = 0, groups[64]; ++ int ngids = 0; char *homedir = NULL; - uid_t saved_uid = 0; const char *username; char *old_passphrase = NULL; char *new_passphrase = NULL; -@@ -411,6 +440,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand +@@ -411,6 +445,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand pwd = getpwnam(username); if (pwd) { uid = pwd->pw_uid; @@ -138,21 +143,22 @@ Index: ecryptfs-utils-96/src/pam_ecryptfs/pam_ecryptfs.c homedir = pwd->pw_dir; name = pwd->pw_name; } -@@ -418,13 +448,21 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand +@@ -418,13 +453,22 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand syslog(LOG_ERR, "pam_ecryptfs: Error getting passwd info for user [%s]; rc = [%ld]\n", username, rc); goto out; } - saved_uid = geteuid(); - seteuid(uid); + -+ if ((oeuid = geteuid()) < 0 || (oegid = getegid()) < 0) { ++ if ((oeuid = geteuid()) < 0 || (oegid = getegid()) < 0 || ++ (ngids = getgroups(sizeof(groups)/sizeof(gid_t), groups)) < 0) { + syslog(LOG_ERR, "pam_ecryptfs: geteuid error"); + goto outnouid; + } + -+ if (setfsgid(gid) != gid || setfsuid(uid) != uid) { -+ syslog(LOG_ERR, "pam_ecryptfs: setfsuid error"); -+ goto outnouid; ++ if (setegid(gid) < 0 || setgroups(1, &gid) < 0 || seteuid(uid) < 0) { ++ syslog(LOG_ERR, "pam_ecryptfs: seteuid error"); ++ goto out; + } + if ((rc = pam_get_item(pamh, PAM_OLDAUTHTOK, @@ -163,7 +169,7 @@ Index: ecryptfs-utils-96/src/pam_ecryptfs/pam_ecryptfs.c goto out; } /* On the first pass, do nothing except check that we have a password */ -@@ -434,14 +472,12 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand +@@ -434,14 +478,12 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand syslog(LOG_WARNING, "pam_ecryptfs: PAM passphrase change module retrieved a NULL passphrase; nothing to do\n"); rc = PAM_AUTHTOK_RECOVER_ERR; } @@ -178,7 +184,7 @@ Index: ecryptfs-utils-96/src/pam_ecryptfs/pam_ecryptfs.c goto out; } if ((rc = asprintf(&wrapped_pw_filename, "%s/.ecryptfs/%s", homedir, -@@ -462,7 +498,6 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand +@@ -462,7 +504,6 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand goto out; } @@ -186,25 +192,28 @@ Index: ecryptfs-utils-96/src/pam_ecryptfs/pam_ecryptfs.c if (!old_passphrase || !new_passphrase || *new_passphrase == '\0') { syslog(LOG_WARNING, "pam_ecryptfs: PAM passphrase change module retrieved at least one NULL passphrase; nothing to do\n"); rc = PAM_AUTHTOK_RECOVER_ERR; -@@ -472,7 +507,10 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand +@@ -472,7 +513,12 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand if ((child_pid = fork()) == 0) { char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH + 1]; - setuid(uid); -+ if (setuid(uid) < 0 || setgid(gid) < 0 || setgroups(1, &gid) < 0) { -+ syslog(LOG_ERR, "pam_ecryptfs: Error setting uid/gid"); ++ /* temp regain uid 0 to drop privs */ ++ seteuid(oeuid); ++ /* setgroups() already called */ ++ if (setgid(gid) < 0 || setuid(uid) < 0) + goto out_child; -+ } ++ if ((rc = ecryptfs_unwrap_passphrase(passphrase, wrapped_pw_filename, old_passphrase, salt))) { -@@ -492,5 +530,10 @@ out_child: +@@ -492,5 +538,11 @@ out_child: syslog(LOG_WARNING, "pam_ecryptfs: waitpid() returned with error condition\n"); free(wrapped_pw_filename); out: + -+ setfsuid(oeuid); -+ setfsgid(oegid); ++ seteuid(oeuid); ++ setegid(oegid); ++ setgroups(ngids, groups); + +outnouid: return rc; diff --git a/ecryptfs-utils.spec b/ecryptfs-utils.spec index 5333495..648eca0 100644 --- a/ecryptfs-utils.spec +++ b/ecryptfs-utils.spec @@ -16,7 +16,6 @@ # - Name: ecryptfs-utils Url: https://launchpad.net/ecryptfs Summary: Userspace Utilities for ecryptfs