--- /dev/null
+From d7d824966530acfe32b94d1ed672e6fe1638cd68 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?=
+ <ernesto.mnd.fernandez@gmail.com>
+Date: Wed, 2 Aug 2017 03:18:27 -0300
+Subject: btrfs: preserve i_mode if __btrfs_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 d7d824966530acfe32b94d1ed672e6fe1638cd68 upstream.
+
+When changing a file's acl mask, btrfs_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 restoring the original mode bits if __btrfs_set_acl
+fails.
+
+Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/acl.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/acl.c
++++ b/fs/btrfs/acl.c
+@@ -114,13 +114,17 @@ out:
+ int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ {
+ int ret;
++ umode_t old_mode = inode->i_mode;
+
+ if (type == ACL_TYPE_ACCESS && acl) {
+ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (ret)
+ return ret;
+ }
+- return __btrfs_set_acl(NULL, inode, acl, type);
++ ret = __btrfs_set_acl(NULL, inode, acl, type);
++ if (ret)
++ inode->i_mode = old_mode;
++ return ret;
+ }
+
+ /*