diff options
author | akpm <akpm@linux-foundation.org> | 2022-06-27 10:31:34 -0700 |
---|---|---|
committer | akpm <akpm@linux-foundation.org> | 2022-06-27 10:31:34 -0700 |
commit | 46a3b1125308f8f90a065eeecfafd2a96b01a36c (patch) | |
tree | 6e080118fbad5aa217d160cedf02f10108ce3bf2 /fs/attr.c | |
parent | 6edda04ccc7cfb281d139e352dbd5dd933bd2751 (diff) | |
parent | 03c765b0e3b4cb5063276b086c76f7a612856a9a (diff) | |
download | linux-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.c | 26 |
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; } |