From 036bd8073c6a28d7fe802eee11f76066c1705dc0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 8 Aug 2017 09:16:14 -0700 Subject: [PATCH] 4.12-stable patches added patches: ext4-don-t-clear-sgid-when-inheriting-acls.patch ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch --- ...on-t-clear-sgid-when-inheriting-acls.patch | 94 +++++++++++++++++++ ...serve-i_mode-if-__ext4_set_acl-fails.patch | 71 ++++++++++++++ queue-4.12/series | 2 + 3 files changed, 167 insertions(+) create mode 100644 queue-4.12/ext4-don-t-clear-sgid-when-inheriting-acls.patch create mode 100644 queue-4.12/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch diff --git a/queue-4.12/ext4-don-t-clear-sgid-when-inheriting-acls.patch b/queue-4.12/ext4-don-t-clear-sgid-when-inheriting-acls.patch new file mode 100644 index 00000000000..28e4f072a09 --- /dev/null +++ b/queue-4.12/ext4-don-t-clear-sgid-when-inheriting-acls.patch @@ -0,0 +1,94 @@ +From a3bb2d5587521eea6dab2d05326abb0afb460abd Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Sun, 30 Jul 2017 23:33:01 -0400 +Subject: ext4: Don't clear SGID when inheriting ACLs + +From: Jan Kara + +commit a3bb2d5587521eea6dab2d05326abb0afb460abd upstream. + +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 +Signed-off-by: Theodore Ts'o +Signed-off-by: Jan Kara +Reviewed-by: Andreas Gruenbacher +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/acl.c | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +--- a/fs/ext4/acl.c ++++ b/fs/ext4/acl.c +@@ -189,18 +189,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: +@@ -224,11 +216,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 = current_time(inode); +- ext4_mark_inode_dirty(handle, inode); +- } + } + + return error; +@@ -239,6 +226,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; + + error = dquot_initialize(inode); + if (error) +@@ -249,7 +238,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 = 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/queue-4.12/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch b/queue-4.12/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch new file mode 100644 index 00000000000..c022d0da635 --- /dev/null +++ b/queue-4.12/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch @@ -0,0 +1,71 @@ +From 397e434176bb62bc6068d2210af1d876c6212a7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?= +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 + +From: Ernesto A. Fernández + +commit 397e434176bb62bc6068d2210af1d876c6212a7e upstream. + +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 +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/acl.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/fs/ext4/acl.c ++++ b/fs/ext4/acl.c +@@ -189,16 +189,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 = current_time(inode); +- ext4_mark_inode_dirty(handle, inode); ++ update_mode = 1; + } + break; + +@@ -221,8 +222,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 = current_time(inode); ++ ext4_mark_inode_dirty(handle, inode); ++ } ++ } + + return error; + } diff --git a/queue-4.12/series b/queue-4.12/series index cb4bd70945c..5aa1bb17ed0 100644 --- a/queue-4.12/series +++ b/queue-4.12/series @@ -48,3 +48,5 @@ media-platform-davinci-return-einval-for-vpfe_cmd_s_ccdc_raw_params-ioctl.patch ir-spi-fix-issues-with-lirc-api.patch tcmu-fix-flushing-cmd-entry-dcache-page.patch tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch +ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch +ext4-don-t-clear-sgid-when-inheriting-acls.patch -- 2.47.3