ovl: handle idmappings in ovl_xattr_{g,s}et()
authorChristian Brauner <brauner@kernel.org>
Mon, 4 Apr 2022 10:51:57 +0000 (12:51 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 28 Apr 2022 14:31:12 +0000 (16:31 +0200)
When retrieving xattrs from the upper or lower layers take the relevant
mount's idmapping into account. We rely on the previously introduced
ovl_i_path_real() helper to retrieve the relevant path. This is needed
to support idmapped base layers with overlay.

Cc: <linux-unionfs@vger.kernel.org>
Tested-by: Giuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/inode.c

index 123ce07..492edde 100644 (file)
@@ -349,6 +349,7 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
        struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
        struct dentry *upperdentry = ovl_i_dentry_upper(inode);
        struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry);
+       struct path realpath;
        const struct cred *old_cred;
 
        err = ovl_want_write(dentry);
@@ -356,8 +357,9 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
                goto out;
 
        if (!value && !upperdentry) {
+               ovl_path_lower(dentry, &realpath);
                old_cred = ovl_override_creds(dentry->d_sb);
-               err = vfs_getxattr(&init_user_ns, realdentry, name, NULL, 0);
+               err = vfs_getxattr(mnt_user_ns(realpath.mnt), realdentry, name, NULL, 0);
                revert_creds(old_cred);
                if (err < 0)
                        goto out_drop_write;
@@ -395,11 +397,11 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
 {
        ssize_t res;
        const struct cred *old_cred;
-       struct dentry *realdentry =
-               ovl_i_dentry_upper(inode) ?: ovl_dentry_lower(dentry);
+       struct path realpath;
 
+       ovl_i_path_real(inode, &realpath);
        old_cred = ovl_override_creds(dentry->d_sb);
-       res = vfs_getxattr(&init_user_ns, realdentry, name, value, size);
+       res = vfs_getxattr(mnt_user_ns(realpath.mnt), realpath.dentry, name, value, size);
        revert_creds(old_cred);
        return res;
 }