Commit 979086f5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fs.fixes.v5.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux

Pull vfs idmapping fix from Christian Brauner:
 "This fixes an issue where we fail to change the group of a file when
  the caller owns the file and is a member of the group to change to.

  This is only relevant on idmapped mounts.

  There's a detailed description in the commit message and regression
  tests have been added to xfstests"

* tag 'fs.fixes.v5.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
  fs: account for group membership
parents 018ab4fa 168f9128
...@@ -61,9 +61,15 @@ static bool chgrp_ok(struct user_namespace *mnt_userns, ...@@ -61,9 +61,15 @@ static bool chgrp_ok(struct user_namespace *mnt_userns,
const struct inode *inode, kgid_t gid) const struct inode *inode, kgid_t gid)
{ {
kgid_t kgid = i_gid_into_mnt(mnt_userns, inode); kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)) && if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode))) {
(in_group_p(gid) || gid_eq(gid, inode->i_gid))) kgid_t mapped_gid;
return true;
if (gid_eq(gid, inode->i_gid))
return true;
mapped_gid = mapped_kgid_fs(mnt_userns, i_user_ns(inode), gid);
if (in_group_p(mapped_gid))
return true;
}
if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
return true; return true;
if (gid_eq(kgid, INVALID_GID) && if (gid_eq(kgid, INVALID_GID) &&
...@@ -123,12 +129,20 @@ int setattr_prepare(struct user_namespace *mnt_userns, struct dentry *dentry, ...@@ -123,12 +129,20 @@ int setattr_prepare(struct user_namespace *mnt_userns, struct dentry *dentry,
/* Make sure a caller can chmod. */ /* Make sure a caller can chmod. */
if (ia_valid & ATTR_MODE) { if (ia_valid & ATTR_MODE) {
kgid_t mapped_gid;
if (!inode_owner_or_capable(mnt_userns, inode)) if (!inode_owner_or_capable(mnt_userns, inode))
return -EPERM; return -EPERM;
if (ia_valid & ATTR_GID)
mapped_gid = mapped_kgid_fs(mnt_userns,
i_user_ns(inode), attr->ia_gid);
else
mapped_gid = i_gid_into_mnt(mnt_userns, inode);
/* Also check the setgid bit! */ /* Also check the setgid bit! */
if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : if (!in_group_p(mapped_gid) &&
i_gid_into_mnt(mnt_userns, inode)) && !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
!capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
attr->ia_mode &= ~S_ISGID; attr->ia_mode &= ~S_ISGID;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment