9652a1e
From acff81ec2c79492b180fade3c2894425cd35a545 Mon Sep 17 00:00:00 2001
9652a1e
From: Miklos Szeredi <miklos@szeredi.hu>
9652a1e
Date: Fri, 4 Dec 2015 19:18:48 +0100
9652a1e
Subject: [PATCH] ovl: fix permission checking for setattr
9652a1e
9652a1e
[Al Viro] The bug is in being too enthusiastic about optimizing ->setattr()
9652a1e
away - instead of "copy verbatim with metadata" + "chmod/chown/utimes"
9652a1e
(with the former being always safe and the latter failing in case of
9652a1e
insufficient permissions) it tries to combine these two.  Note that copyup
9652a1e
itself will have to do ->setattr() anyway; _that_ is where the elevated
9652a1e
capabilities are right.  Having these two ->setattr() (one to set verbatim
9652a1e
copy of metadata, another to do what overlayfs ->setattr() had been asked
9652a1e
to do in the first place) combined is where it breaks.
9652a1e
9652a1e
Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
9652a1e
Cc: <stable@vger.kernel.org>
9652a1e
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9652a1e
---
9652a1e
 fs/overlayfs/inode.c | 8 ++++----
9652a1e
 1 file changed, 4 insertions(+), 4 deletions(-)
9652a1e
9652a1e
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
9652a1e
index ec0c2a050043..961284936917 100644
9652a1e
--- a/fs/overlayfs/inode.c
9652a1e
+++ b/fs/overlayfs/inode.c
9652a1e
@@ -49,13 +49,13 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
9652a1e
 	if (err)
9652a1e
 		goto out;
9652a1e
 
9652a1e
-	upperdentry = ovl_dentry_upper(dentry);
9652a1e
-	if (upperdentry) {
9652a1e
+	err = ovl_copy_up(dentry);
9652a1e
+	if (!err) {
9652a1e
+		upperdentry = ovl_dentry_upper(dentry);
9652a1e
+
9652a1e
 		mutex_lock(&upperdentry->d_inode->i_mutex);
9652a1e
 		err = notify_change(upperdentry, attr, NULL);
9652a1e
 		mutex_unlock(&upperdentry->d_inode->i_mutex);
9652a1e
-	} else {
9652a1e
-		err = ovl_copy_up_last(dentry, attr, false);
9652a1e
 	}
9652a1e
 	ovl_drop_write(dentry);
9652a1e
 out:
9652a1e
-- 
9652a1e
2.5.0
9652a1e