The two checks ovl_set_acl() performs on the overlay inode itself - inode_owner_or_capable() and the setgid-stripping test - were done with &nop_mnt_idmap. On an idmapped overlay mount this compares the overlay inode's id space directly against the caller's: it denies the rightful owner (as seen through the mount idmap) the right to set an ACL, and evaluates the setgid-drop decision in the wrong id space, which can mis-set the mode on the upper inode. Use the struct mnt_idmap passed in by the VFS for both. Fold the open-coded "caller not in group and not CAP_FSETID privileged" test into in_group_or_capable() with i_gid_into_vfsgid(), the same idmap-aware helpers used by setattr_should_drop_sgid(). The subsequent internal forced setgid-kill via ovl_setattr() stays on &nop_mnt_idmap: it carries only ATTR_KILL_SGID with no uid/gid to translate and is overlayfs' own mode change, not a user-driven operation through the mount. No functional change until FS_ALLOW_IDMAP is set on ovl_fs_type. Signed-off-by: Christian Brauner (Amutable) --- fs/overlayfs/inode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 45b2a5c3d978..57aa74de5bc4 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -550,7 +550,7 @@ int ovl_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, return -EOPNOTSUPP; if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) return acl ? -EACCES : 0; - if (!inode_owner_or_capable(&nop_mnt_idmap, inode)) + if (!inode_owner_or_capable(idmap, inode)) return -EPERM; /* @@ -558,8 +558,8 @@ int ovl_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, * be done with mounter's capabilities and so that won't do it for us). */ if (unlikely(inode->i_mode & S_ISGID) && type == ACL_TYPE_ACCESS && - !in_group_p(inode->i_gid) && - !capable_wrt_inode_uidgid(&nop_mnt_idmap, inode, CAP_FSETID)) { + !in_group_or_capable(idmap, inode, + i_gid_into_vfsgid(idmap, inode))) { struct iattr iattr = { .ia_valid = ATTR_KILL_SGID }; err = ovl_setattr(&nop_mnt_idmap, dentry, &iattr); -- 2.47.3