From 08b46ce9e33c472ae04a8f1ec6ad1601594797f7 Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Wed, 9 Dec 2015 08:46:50 +0100 Subject: linux-hierofalcon: CVE-2015-3339 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes race condition between chown() and execve() system calls in the linux-hierofalcon 3.19 (backported from stable v3.18.24 kernel.org). References: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-3339 http://seclists.org/oss-sec/2015/q2/216 Upstream fix: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/ patch/?id=7f1a6ae73b5c2d24b21d9a27928ceacef3a9a939 Signed-off-by: Sona Sarmadi Signed-off-by: Nora Björklund --- .../linux-hierofalcon-3.19/fs-CVE-2015-3339.patch | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch (limited to 'recipes-kernel/linux/linux-hierofalcon-3.19') diff --git a/recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch b/recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch new file mode 100644 index 0000000..ec86cb8 --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch @@ -0,0 +1,121 @@ +Date: Sun, 19 Apr 2015 02:48:39 +0200 +Subject: fs: take i_mutex during prepare_binprm for set[ug]id executables + +[ Upstream commit 8b01fc86b9f425899f8a3a8fc1c47d73c2c20543 ] + +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. + +Fixes CVE-2015-3339. +Upstream-Status: Backport + +Signed-off-by: Jann Horn +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Sona Sarmadi +--- + fs/exec.c | 76 ++++++++++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 48 insertions(+), 28 deletions(-) + +diff --git a/fs/exec.c b/fs/exec.c +index 7302b75..2e83209 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1250,6 +1250,53 @@ static void check_unsafe_exec(struct linux_binprm *bprm) + 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 +@@ -1258,36 +1305,9 @@ static void check_unsafe_exec(struct linux_binprm *bprm) + */ + 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); +-- +cgit v0.11.2 + -- cgit v1.2.3-54-g00ecf