[PATCH 04/10] ovl: handle idmapped mounts in ovl_getattr()

Christian Brauner <[email protected]> Mon, 15 Jun 2026 15:19:53 +0200
Newsgroups org.kernel.vger.linux-unionfs,org.kernel.vger.linux-fsdevel
Message-ID <[email protected]>
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.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 fs/overlayfs/inode.c | 8 ++++++++
 1 file changed, 8 insertions(+)

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;
 }
 

-- 
2.47.3