[kernel] r22522 - in dists/sid/linux/debian: . patches patches/bugfix/all

Ben Hutchings benh at moszumanska.debian.org
Wed Apr 22 18:17:09 UTC 2015


Author: benh
Date: Wed Apr 22 18:17:09 2015
New Revision: 22522

Log:
fs: take i_mutex during prepare_binprm for set[ug]id executables (CVE-2015-3339)

Added:
   dists/sid/linux/debian/patches/bugfix/all/fs-take-i_mutex-during-prepare_binprm-for-set-ug-id-.patch
Modified:
   dists/sid/linux/debian/changelog
   dists/sid/linux/debian/patches/series

Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog	Wed Apr 22 18:13:57 2015	(r22521)
+++ dists/sid/linux/debian/changelog	Wed Apr 22 18:17:09 2015	(r22522)
@@ -4,6 +4,8 @@
   * [x86] crypto: aesni - fix memory usage in GCM decryption (Closes: #782561)
     (CVE-2015-3331)
   * tcp: Fix crash in TCP Fast Open (Closes: #782515) (CVE-2015-3332)
+  * fs: take i_mutex during prepare_binprm for set[ug]id executables
+    (CVE-2015-3339)
 
   [ Ian Campbell ]
   * [xen] release per-queue Tx and Rx resource when disconnecting, fixing

Added: dists/sid/linux/debian/patches/bugfix/all/fs-take-i_mutex-during-prepare_binprm-for-set-ug-id-.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/bugfix/all/fs-take-i_mutex-during-prepare_binprm-for-set-ug-id-.patch	Wed Apr 22 18:17:09 2015	(r22522)
@@ -0,0 +1,112 @@
+From: Jann Horn <jann at thejh.net>
+Date: Sun, 19 Apr 2015 02:48:39 +0200
+Subject: fs: take i_mutex during prepare_binprm for set[ug]id executables
+Origin: https://git.kernel.org/linus/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.
+
+Signed-off-by: Jann Horn <jann at thejh.net>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+[bwh: Backported to 3.16: s/task_no_new_privs(current)/current->no_new_privs/]
+---
+ fs/exec.c | 76 ++++++++++++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 48 insertions(+), 28 deletions(-)
+
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1254,6 +1254,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 (current->no_new_privs)
++		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
+@@ -1262,36 +1309,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) &&
+-	    !current->no_new_privs &&
+-	    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);

Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series	Wed Apr 22 18:13:57 2015	(r22521)
+++ dists/sid/linux/debian/patches/series	Wed Apr 22 18:17:09 2015	(r22522)
@@ -582,3 +582,4 @@
 
 bugfix/x86/crypto-aesni-fix-memory-usage-in-GCM-decryption.patch
 bugfix/all/tcp-fix-crash-in-tcp-fast-open.patch
+bugfix/all/fs-take-i_mutex-during-prepare_binprm-for-set-ug-id-.patch



More information about the Kernel-svn-changes mailing list