]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Aug 2017 16:16:14 +0000 (09:16 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Aug 2017 16:16:14 +0000 (09:16 -0700)
added patches:
ext4-don-t-clear-sgid-when-inheriting-acls.patch
ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch

queue-4.12/ext4-don-t-clear-sgid-when-inheriting-acls.patch [new file with mode: 0644]
queue-4.12/ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch [new file with mode: 0644]
queue-4.12/series

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 (file)
index 0000000..28e4f07
--- /dev/null
@@ -0,0 +1,94 @@
+From a3bb2d5587521eea6dab2d05326abb0afb460abd Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Sun, 30 Jul 2017 23:33:01 -0400
+Subject: ext4: Don't clear SGID when inheriting ACLs
+
+From: Jan Kara <jack@suse.cz>
+
+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 <tytso@mit.edu>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..c022d0d
--- /dev/null
@@ -0,0 +1,71 @@
+From 397e434176bb62bc6068d2210af1d876c6212a7e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?= <ernesto.mnd.fernandez@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
+
+From: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com>
+
+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 <ernesto.mnd.fernandez@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
index cb4bd70945c88bc7cb12ceeaf84c5ab0a4438495..5aa1bb17ed02585068828030cff6a6990be19080 100644 (file)
@@ -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