diff options
author | Christian Brauner <brauner@kernel.org> | 2022-04-04 12:51:57 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2022-04-28 16:31:12 +0200 |
commit | 8bc0095df6618371768ed43fb1c569707d2a1fb4 (patch) | |
tree | c2f66bcf0c579506499f2d6eb31d3dec63bacc25 /fs/overlayfs | |
parent | 8423b3bd7d970f26a4cbd92f4b9a95b5c246660d (diff) |
ovl: handle idmappings in ovl_xattr_{g,s}et()
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>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r-- | fs/overlayfs/inode.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 123ce07cdc77..492eddeb481f 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -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; } |