From: Greg Kroah-Hartman Date: Sun, 26 Apr 2015 11:47:44 +0000 (+0200) Subject: 4.0-stable patches X-Git-Tag: v4.0.1~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b56e170415b29c4de3f270c291ede02c759a5915;p=thirdparty%2Fkernel%2Fstable-queue.git 4.0-stable patches added patches: fs-take-i_mutex-during-prepare_binprm-for-setid-executables.patch --- diff --git a/queue-4.0/fs-take-i_mutex-during-prepare_binprm-for-setid-executables.patch b/queue-4.0/fs-take-i_mutex-during-prepare_binprm-for-setid-executables.patch new file mode 100644 index 00000000000..99b54b4bd0e --- /dev/null +++ b/queue-4.0/fs-take-i_mutex-during-prepare_binprm-for-setid-executables.patch @@ -0,0 +1,117 @@ +From 8b01fc86b9f425899f8a3a8fc1c47d73c2c20543 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Sun, 19 Apr 2015 02:48:39 +0200 +Subject: fs: take i_mutex during prepare_binprm for set[ug]id executables + +From: Jann Horn + +commit 8b01fc86b9f425899f8a3a8fc1c47d73c2c20543 upstream. + +This prevents a race between chown() and execve(), where chowning a +setuid-user binary to root would momentarily make the binary setuid +root. + +This patch was mostly written by Linus Torvalds. + +Signed-off-by: Jann Horn +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exec.c | 76 +++++++++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 48 insertions(+), 28 deletions(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1265,6 +1265,53 @@ static void check_unsafe_exec(struct lin + spin_unlock(&p->fs->lock); + } + ++static void bprm_fill_uid(struct linux_binprm *bprm) ++{ ++ struct inode *inode; ++ unsigned int mode; ++ kuid_t uid; ++ kgid_t gid; ++ ++ /* clear any previous set[ug]id data from a previous binary */ ++ bprm->cred->euid = current_euid(); ++ bprm->cred->egid = current_egid(); ++ ++ if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) ++ return; ++ ++ if (task_no_new_privs(current)) ++ return; ++ ++ inode = file_inode(bprm->file); ++ mode = READ_ONCE(inode->i_mode); ++ if (!(mode & (S_ISUID|S_ISGID))) ++ return; ++ ++ /* Be careful if suid/sgid is set */ ++ mutex_lock(&inode->i_mutex); ++ ++ /* reload atomically mode/uid/gid now that lock held */ ++ mode = inode->i_mode; ++ uid = inode->i_uid; ++ gid = inode->i_gid; ++ mutex_unlock(&inode->i_mutex); ++ ++ /* We ignore suid/sgid if there are no mappings for them in the ns */ ++ if (!kuid_has_mapping(bprm->cred->user_ns, uid) || ++ !kgid_has_mapping(bprm->cred->user_ns, gid)) ++ return; ++ ++ if (mode & S_ISUID) { ++ bprm->per_clear |= PER_CLEAR_ON_SETID; ++ bprm->cred->euid = uid; ++ } ++ ++ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { ++ bprm->per_clear |= PER_CLEAR_ON_SETID; ++ bprm->cred->egid = gid; ++ } ++} ++ + /* + * Fill the binprm structure from the inode. + * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes +@@ -1273,36 +1320,9 @@ static void check_unsafe_exec(struct lin + */ + int prepare_binprm(struct linux_binprm *bprm) + { +- struct inode *inode = file_inode(bprm->file); +- umode_t mode = inode->i_mode; + int retval; + +- +- /* clear any previous set[ug]id data from a previous binary */ +- bprm->cred->euid = current_euid(); +- bprm->cred->egid = current_egid(); +- +- if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && +- !task_no_new_privs(current) && +- kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) && +- kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) { +- /* Set-uid? */ +- if (mode & S_ISUID) { +- bprm->per_clear |= PER_CLEAR_ON_SETID; +- bprm->cred->euid = inode->i_uid; +- } +- +- /* Set-gid? */ +- /* +- * If setgid is set but no group execute bit then this +- * is a candidate for mandatory locking, not a setgid +- * executable. +- */ +- if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { +- bprm->per_clear |= PER_CLEAR_ON_SETID; +- bprm->cred->egid = inode->i_gid; +- } +- } ++ bprm_fill_uid(bprm); + + /* fill in binprm security blob */ + retval = security_bprm_set_creds(bprm); diff --git a/queue-4.0/series b/queue-4.0/series index f63af7def87..baf81b212d9 100644 --- a/queue-4.0/series +++ b/queue-4.0/series @@ -4,3 +4,4 @@ bnx2x-fix-busy_poll-vs-netpoll.patch bpf-fix-verifier-memory-corruption.patch revert-net-reset-secmark-when-scrubbing-packet.patch skbuff-do-not-scrub-skb-mark-within-the-same-name-space.patch +fs-take-i_mutex-during-prepare_binprm-for-setid-executables.patch