[kernel] r22536 - in dists/squeeze-security/linux-2.6/debian: . patches/bugfix/all patches/series

Ben Hutchings benh at moszumanska.debian.org
Mon Apr 27 00:44:22 UTC 2015


Author: benh
Date: Mon Apr 27 00:44:21 2015
New Revision: 22536

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

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

Modified: dists/squeeze-security/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/changelog	Sat Apr 25 00:48:58 2015	(r22535)
+++ dists/squeeze-security/linux-2.6/debian/changelog	Mon Apr 27 00:44:21 2015	(r22536)
@@ -13,6 +13,8 @@
   * net: llc: use correct size for sysctl timeout entries (CVE-2015-2041)
   * net: rds: use correct size for max unacked packets and bytes
     (CVE-2015-2042)
+  * fs: take i_mutex during prepare_binprm for set[ug]id executables
+    (CVE-2015-3339)
 
  -- Ben Hutchings <ben at decadent.org.uk>  Sun, 12 Apr 2015 17:12:31 +0100
 

Added: dists/squeeze-security/linux-2.6/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/squeeze-security/linux-2.6/debian/patches/bugfix/all/fs-take-i_mutex-during-prepare_binprm-for-set-ug-id-.patch	Mon Apr 27 00:44:21 2015	(r22536)
@@ -0,0 +1,105 @@
+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.2:
+ - Drop the task_no_new_privs() and user namespace checks
+ - Open-code file_inode()
+ - s/READ_ONCE/ACCESS_ONCE/
+ - Adjust context]
+---
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1183,6 +1183,45 @@ int check_unsafe_exec(struct linux_binpr
+ 	return res;
+ }
+ 
++static void bprm_fill_uid(struct linux_binprm *bprm)
++{
++	struct inode *inode;
++	unsigned int mode;
++	uid_t uid;
++	gid_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;
++
++	inode = bprm->file->f_path.dentry->d_inode;
++	mode = ACCESS_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);
++
++	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
+@@ -1190,36 +1229,12 @@ int check_unsafe_exec(struct linux_binpr
+  */
+ int prepare_binprm(struct linux_binprm *bprm)
+ {
+-	umode_t mode;
+-	struct inode * inode = bprm->file->f_path.dentry->d_inode;
+ 	int retval;
+ 
+-	mode = inode->i_mode;
+ 	if (bprm->file->f_op == NULL)
+ 		return -EACCES;
+ 
+-	/* 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)) {
+-		/* 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/squeeze-security/linux-2.6/debian/patches/series/48squeeze12
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/patches/series/48squeeze12	Sat Apr 25 00:48:58 2015	(r22535)
+++ dists/squeeze-security/linux-2.6/debian/patches/series/48squeeze12	Mon Apr 27 00:44:21 2015	(r22536)
@@ -7,3 +7,4 @@
 + bugfix/x86/x86-asm-entry-64-remove-a-bogus-ret_from_fork-optimi.patch
 + bugfix/all/net-llc-use-correct-size-for-sysctl-timeout-entries.patch
 + bugfix/all/net-rds-use-correct-size-for-max-unacked-packets-and.patch
++ bugfix/all/fs-take-i_mutex-during-prepare_binprm-for-set-ug-id-.patch



More information about the Kernel-svn-changes mailing list