[linux] 03/03: Fix regressions caused by fix for CVE-2016-7097 (Closes: #873026)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Sun Sep 24 21:41:56 UTC 2017


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch stretch
in repository linux.

commit b660f8c0219dbcad0ce09b64df7bbfad5cc4c9e1
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Sun Sep 24 22:03:53 2017 +0100

    Fix regressions caused by fix for CVE-2016-7097 (Closes: #873026)
    
    - ext4: preserve i_mode if __ext4_set_acl() fails
    - ext4: Don't clear SGID when inheriting ACLs
---
 debian/changelog                                   |  5 ++
 ...xt4-don-t-clear-sgid-when-inheriting-acls.patch | 93 ++++++++++++++++++++++
 ...4-preserve-i_mode-if-__ext4_set_acl-fails.patch | 68 ++++++++++++++++
 debian/patches/series                              |  2 +
 4 files changed, 168 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 0989d45..c88e123 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -113,6 +113,11 @@ linux (4.9.51-1) UNRELEASED; urgency=medium
     - md/raid5: release/flush io in raid5_do_work()
     - ipv6: Fix may be used uninitialized warning in rt6_check
 
+  [ Ben Hutchings ]
+  * Fix regressions caused by fix for CVE-2016-7097 (Closes: #873026):
+    - ext4: preserve i_mode if __ext4_set_acl() fails
+    - ext4: Don't clear SGID when inheriting ACLs
+
  -- Ben Hutchings <ben at decadent.org.uk>  Tue, 19 Sep 2017 00:38:28 +0100
 
 linux (4.9.47-1) stretch; urgency=medium
diff --git a/debian/patches/bugfix/all/ext4-don-t-clear-sgid-when-inheriting-acls.patch b/debian/patches/bugfix/all/ext4-don-t-clear-sgid-when-inheriting-acls.patch
new file mode 100644
index 0000000..8fbdba3
--- /dev/null
+++ b/debian/patches/bugfix/all/ext4-don-t-clear-sgid-when-inheriting-acls.patch
@@ -0,0 +1,93 @@
+From: Jan Kara <jack at suse.cz>
+Date: Sun, 30 Jul 2017 23:33:01 -0400
+Subject: ext4: Don't clear SGID when inheriting ACLs
+Origin: https://git.kernel.org/linus/a3bb2d5587521eea6dab2d05326abb0afb460abd
+Bug-Debian: https://bugs.debian.org/873026
+
+When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
+set, DIR1 is expected to have SGID bit set (and owning group equal to
+the owning group of 'DIR0'). However when 'DIR0' also has some default
+ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
+'DIR1' to get cleared if user is not member of the owning group.
+
+Fix the problem by moving posix_acl_update_mode() out of
+__ext4_set_acl() into ext4_set_acl(). That way the function will not be
+called when inheriting ACLs which is what we want as it prevents SGID
+bit clearing and the mode has been properly set by posix_acl_create()
+anyway.
+
+Fixes: 073931017b49d9458aa351605b43a7e34598caef
+CC: stable at vger.kernel.org
+Signed-off-by: Theodore Ts'o <tytso at mit.edu>
+Signed-off-by: Jan Kara <jack at suse.cz>
+Reviewed-by: Andreas Gruenbacher <agruenba at redhat.com>
+[bwh: Backported to 4.9:
+ - Keep using ext4_current_time()
+ - Adjust context]
+---
+ fs/ext4/acl.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+--- a/fs/ext4/acl.c
++++ b/fs/ext4/acl.c
+@@ -188,18 +188,10 @@ __ext4_set_acl(handle_t *handle, struct
+ 	void *value = NULL;
+ 	size_t size = 0;
+ 	int error;
+-	int update_mode = 0;
+-	umode_t mode = inode->i_mode;
+ 
+ 	switch (type) {
+ 	case ACL_TYPE_ACCESS:
+ 		name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
+-		if (acl) {
+-			error = posix_acl_update_mode(inode, &mode, &acl);
+-			if (error)
+-				return error;
+-			update_mode = 1;
+-		}
+ 		break;
+ 
+ 	case ACL_TYPE_DEFAULT:
+@@ -223,11 +215,6 @@ __ext4_set_acl(handle_t *handle, struct
+ 	kfree(value);
+ 	if (!error) {
+ 		set_cached_acl(inode, type, acl);
+-		if (update_mode) {
+-			inode->i_mode = mode;
+-			inode->i_ctime = ext4_current_time(inode);
+-			ext4_mark_inode_dirty(handle, inode);
+-		}
+ 	}
+ 
+ 	return error;
+@@ -238,6 +225,8 @@ ext4_set_acl(struct inode *inode, struct
+ {
+ 	handle_t *handle;
+ 	int error, retries = 0;
++	umode_t mode = inode->i_mode;
++	int update_mode = 0;
+ 
+ retry:
+ 	handle = ext4_journal_start(inode, EXT4_HT_XATTR,
+@@ -245,7 +234,20 @@ retry:
+ 	if (IS_ERR(handle))
+ 		return PTR_ERR(handle);
+ 
++	if ((type == ACL_TYPE_ACCESS) && acl) {
++		error = posix_acl_update_mode(inode, &mode, &acl);
++		if (error)
++			goto out_stop;
++		update_mode = 1;
++	}
++
+ 	error = __ext4_set_acl(handle, inode, type, acl);
++	if (!error && update_mode) {
++		inode->i_mode = mode;
++		inode->i_ctime = ext4_current_time(inode);
++		ext4_mark_inode_dirty(handle, inode);
++	}
++out_stop:
+ 	ext4_journal_stop(handle);
+ 	if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+ 		goto retry;
diff --git a/debian/patches/bugfix/all/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch b/debian/patches/bugfix/all/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch
new file mode 100644
index 0000000..838d67c
--- /dev/null
+++ b/debian/patches/bugfix/all/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch
@@ -0,0 +1,68 @@
+From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?=
+ <ernesto.mnd.fernandez at gmail.com>
+Date: Sun, 30 Jul 2017 22:43:41 -0400
+Subject: ext4: preserve i_mode if __ext4_set_acl() fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/397e434176bb62bc6068d2210af1d876c6212a7e
+Bug-Debian: https://bugs.debian.org/873026
+
+When changing a file's acl mask, __ext4_set_acl() will first set the group
+bits of i_mode to the value of the mask, and only then set the actual
+extended attribute representing the new acl.
+
+If the second part fails (due to lack of space, for example) and the file
+had no acl attribute to begin with, the system will from now on assume
+that the mask permission bits are actual group permission bits, potentially
+granting access to the wrong users.
+
+Prevent this by only changing the inode mode after the acl has been set.
+
+Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez at gmail.com>
+Signed-off-by: Theodore Ts'o <tytso at mit.edu>
+Reviewed-by: Jan Kara <jack at suse.cz>
+[bwh: Backported to 4.9: keep using ext4_current_time()]
+---
+ fs/ext4/acl.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/acl.c
++++ b/fs/ext4/acl.c
+@@ -188,16 +188,17 @@ __ext4_set_acl(handle_t *handle, struct
+ 	void *value = NULL;
+ 	size_t size = 0;
+ 	int error;
++	int update_mode = 0;
++	umode_t mode = inode->i_mode;
+ 
+ 	switch (type) {
+ 	case ACL_TYPE_ACCESS:
+ 		name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++			error = posix_acl_update_mode(inode, &mode, &acl);
+ 			if (error)
+ 				return error;
+-			inode->i_ctime = ext4_current_time(inode);
+-			ext4_mark_inode_dirty(handle, inode);
++			update_mode = 1;
+ 		}
+ 		break;
+ 
+@@ -220,8 +221,14 @@ __ext4_set_acl(handle_t *handle, struct
+ 				      value, size, 0);
+ 
+ 	kfree(value);
+-	if (!error)
++	if (!error) {
+ 		set_cached_acl(inode, type, acl);
++		if (update_mode) {
++			inode->i_mode = mode;
++			inode->i_ctime = ext4_current_time(inode);
++			ext4_mark_inode_dirty(handle, inode);
++		}
++	}
+ 
+ 	return error;
+ }
diff --git a/debian/patches/series b/debian/patches/series
index 3969d56..a848e89 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -89,6 +89,8 @@ bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch
 bugfix/all/kbuild-do-not-use-hyphen-in-exported-variable-name.patch
 bugfix/all/partially-revert-usb-kconfig-using-select-for-usb_co.patch
 bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch
+bugfix/all/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch
+bugfix/all/ext4-don-t-clear-sgid-when-inheriting-acls.patch
 
 # Miscellaneous features
 features/all/netfilter-nft_ct-add-notrack-support.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list