]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ovl: lookup: do getxattr with mounter's permission
authorMiklos Szeredi <mszeredi@redhat.com>
Fri, 16 Sep 2016 12:12:11 +0000 (14:12 +0200)
committerAnand Jain <anand.jain@oracle.com>
Thu, 26 Oct 2017 08:15:29 +0000 (16:15 +0800)
The getxattr() in ovl_is_opaquedir() was missed when converting all
operations on underlying fs to be done under mounter's permission.

This patch fixes this by moving the ovl_override_creds()/revert_creds() out
from ovl_lookup_real() to ovl_lookup().

Also convert to using vfs_getxattr() instead of directly calling
i_op->getxattr().

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Orabug: 25684456

(backport upstream commit 2b6bc7f48d34a6043915beddbf53b981603737c8)

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Acked-by: James Morris <james.l.morris@oracle.com>
Reviewed-by: James Morris <james.l.morris@oracle.com>
conflict fix
fs/overlay/super.c

fs/overlayfs/super.c

index a12878234a8135b26f06f5731dfceb5c03a7ce7d..1a18b97dcf0b02cb80fc589b17a3e509e6e2567a 100644 (file)
@@ -273,12 +273,11 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
 {
        int res;
        char val;
-       struct inode *inode = dentry->d_inode;
 
-       if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr)
+       if (!d_is_dir(dentry))
                return false;
 
-       res = inode->i_op->getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
+       res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
        if (res == 1 && val == 'y')
                return true;
 
@@ -315,16 +314,12 @@ static struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
        return oe;
 }
 
-static inline struct dentry *ovl_lookup_real(struct super_block *ovl_sb,
-                                            struct dentry *dir,
+static inline struct dentry *ovl_lookup_real(struct dentry *dir,
                                             struct qstr *name)
 {
-       const struct cred *old_cred;
        struct dentry *dentry;
 
-       old_cred = ovl_override_creds(ovl_sb);
        dentry = lookup_one_len_unlocked(name->name, dir, name->len);
-       revert_creds(old_cred);
 
        if (IS_ERR(dentry)) {
                if (PTR_ERR(dentry) == -ENOENT)
@@ -361,6 +356,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                          unsigned int flags)
 {
        struct ovl_entry *oe;
+       const struct cred *old_cred;
        struct ovl_entry *poe = dentry->d_parent->d_fsdata;
        struct path *stack = NULL;
        struct dentry *upperdir, *upperdentry = NULL;
@@ -371,9 +367,10 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
        unsigned int i;
        int err;
 
+       old_cred = ovl_override_creds(dentry->d_sb);
        upperdir = ovl_upperdentry_dereference(poe);
        if (upperdir) {
-               this = ovl_lookup_real(dentry->d_sb, upperdir, &dentry->d_name);
+               this = ovl_lookup_real(upperdir, &dentry->d_name);
                err = PTR_ERR(this);
                if (IS_ERR(this))
                        goto out;
@@ -401,8 +398,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                bool opaque = false;
                struct path lowerpath = poe->lowerstack[i];
 
-               this = ovl_lookup_real(dentry->d_sb,
-                                      lowerpath.dentry, &dentry->d_name);
+               this = ovl_lookup_real(lowerpath.dentry, &dentry->d_name);
                err = PTR_ERR(this);
                if (IS_ERR(this)) {
                        /*
@@ -475,6 +471,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                ovl_copyattr(realdentry->d_inode, inode);
        }
 
+       revert_creds(old_cred);
        oe->opaque = upperopaque;
        oe->__upperdentry = upperdentry;
        memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
@@ -493,6 +490,7 @@ out_put:
 out_put_upper:
        dput(upperdentry);
 out:
+       revert_creds(old_cred);
        return ERR_PTR(err);
 }