ovl: fix permission checking for setattr
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 4 Dec 2015 18:18:48 +0000 (19:18 +0100)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 6 Dec 2015 17:28:23 +0000 (12:28 -0500)
[Al Viro] The bug is in being too enthusiastic about optimizing ->setattr()
away - instead of "copy verbatim with metadata" + "chmod/chown/utimes"
(with the former being always safe and the latter failing in case of
insufficient permissions) it tries to combine these two.  Note that copyup
itself will have to do ->setattr() anyway; _that_ is where the elevated
capabilities are right.  Having these two ->setattr() (one to set verbatim
copy of metadata, another to do what overlayfs ->setattr() had been asked
to do in the first place) combined is where it breaks.

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Cc: <stable@vger.kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/overlayfs/inode.c

index ec0c2a050043afbb3eff4c7451930dc6d86006ec..961284936917e69742f837463999c27e90defb43 100644 (file)
@@ -49,13 +49,13 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
        if (err)
                goto out;
 
-       upperdentry = ovl_dentry_upper(dentry);
-       if (upperdentry) {
+       err = ovl_copy_up(dentry);
+       if (!err) {
+               upperdentry = ovl_dentry_upper(dentry);
+
                mutex_lock(&upperdentry->d_inode->i_mutex);
                err = notify_change(upperdentry, attr, NULL);
                mutex_unlock(&upperdentry->d_inode->i_mutex);
-       } else {
-               err = ovl_copy_up_last(dentry, attr, false);
        }
        ovl_drop_write(dentry);
 out: