diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-06-15 15:19:53 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-06-29 10:32:31 +0200 |
| commit | 22b27d403dd034148c8499c37dc1127e713f1b11 (patch) | |
| tree | 70d71fee014b3ee4f9409eb26c5555b54bb075a1 /fs/overlayfs | |
| parent | 10a16f5b9111da6e553f8533605f7216e13a37b8 (diff) | |
ovl: handle idmapped mounts in ovl_getattr()
ovl_getattr() fetches attributes from the real (upper or lower) path
via vfs_getattr(), so the returned stat->uid/stat->gid are already
mapped through the real layer idmap but not through the overlay mount
idmap. Unlike the generic path, the VFS does not re-apply the
accessing mount's idmap after ->getattr returns - generic_fillattr()
does it, but overlayfs bypasses it - so overlayfs has to do it itself.
Map stat->uid/stat->gid through the overlay mount idmap before
returning, mirroring generic_fillattr(). The owner reported through an
idmapped overlay mount is thus the overlay-final id translated by the
mount idmap.
No functional change until FS_ALLOW_IDMAP is set on ovl_fs_type; until
then make_vfsuid()/make_vfsgid() are the identity for &nop_mnt_idmap.
Link: https://patch.msgid.link/20260615-work-idmapped-overlayfs-v1-4-7381632aa402@kernel.org
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'fs/overlayfs')
| -rw-r--r-- | fs/overlayfs/inode.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 33734ca971e1..45b2a5c3d978 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -180,6 +180,8 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, int fsid = 0; int err; bool metacopy_blocks = false; + vfsuid_t vfsuid; + vfsgid_t vfsgid; metacopy_blocks = ovl_is_metacopy_dentry(dentry); @@ -292,6 +294,12 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, if (!is_dir && ovl_test_flag(OVL_INDEX, d_inode(dentry))) stat->nlink = dentry->d_inode->i_nlink; + /* Map ownership of the real inode through the overlay mount idmap. */ + vfsuid = make_vfsuid(idmap, i_user_ns(inode), stat->uid); + vfsgid = make_vfsgid(idmap, i_user_ns(inode), stat->gid); + stat->uid = vfsuid_into_kuid(vfsuid); + stat->gid = vfsgid_into_kgid(vfsgid); + return err; } |
