summaryrefslogtreecommitdiffstats
path: root/fs/attr.c
diff options
context:
space:
mode:
authorakpm <akpm@linux-foundation.org>2022-06-27 10:31:34 -0700
committerakpm <akpm@linux-foundation.org>2022-06-27 10:31:34 -0700
commit46a3b1125308f8f90a065eeecfafd2a96b01a36c (patch)
tree6e080118fbad5aa217d160cedf02f10108ce3bf2 /fs/attr.c
parent6edda04ccc7cfb281d139e352dbd5dd933bd2751 (diff)
parent03c765b0e3b4cb5063276b086c76f7a612856a9a (diff)
downloadlinux-46a3b1125308f8f90a065eeecfafd2a96b01a36c.tar.gz
linux-46a3b1125308f8f90a065eeecfafd2a96b01a36c.tar.bz2
linux-46a3b1125308f8f90a065eeecfafd2a96b01a36c.zip
Merge branch 'master' into mm-stable
Diffstat (limited to 'fs/attr.c')
-rw-r--r--fs/attr.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/fs/attr.c b/fs/attr.c
index 66899b6e9bd8..dbe996b0dedf 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -61,9 +61,15 @@ static bool chgrp_ok(struct user_namespace *mnt_userns,
const struct inode *inode, kgid_t gid)
{
kgid_t kgid = i_gid_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)))
- return true;
+ if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode))) {
+ kgid_t mapped_gid;
+
+ 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))
return true;
if (gid_eq(kgid, INVALID_GID) &&
@@ -123,12 +129,20 @@ int setattr_prepare(struct user_namespace *mnt_userns, struct dentry *dentry,
/* Make sure a caller can chmod. */
if (ia_valid & ATTR_MODE) {
+ kgid_t mapped_gid;
+
if (!inode_owner_or_capable(mnt_userns, inode))
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! */
- if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
- i_gid_into_mnt(mnt_userns, inode)) &&
- !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
+ if (!in_group_p(mapped_gid) &&
+ !capable_wrt_inode_uidgid(mnt_userns, inode, CAP_FSETID))
attr->ia_mode &= ~S_ISGID;
}