diff options
author | Jan Kara <jack@suse.cz> | 2016-09-19 17:39:09 +0200 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2016-11-20 01:01:44 +0000 |
commit | a06d3be52bce98746341cfb290203603fd028290 (patch) | |
tree | 9f7ae7df501bdc79b7efb6cddeb067ae7fb419c8 /include | |
parent | cef37d3ae1c1847b553e22160fe33f2892bd39d4 (diff) |
posix_acl: Clear SGID bit when setting file permissions
commit 073931017b49d9458aa351605b43a7e34598caef upstream.
When file permissions are modified via chmod(2) and the user is not in
the owning group or capable of CAP_FSETID, the setgid bit is cleared in
inode_change_ok(). Setting a POSIX ACL via setxattr(2) sets the file
permissions as well as the new ACL, but doesn't clear the setgid bit in
a similar way; this allows to bypass the check in chmod(2). Fix that.
References: CVE-2016-7097
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
[bwh: Backported to 3.2:
- Drop changes to ceph, f2fs, hfsplus, orangefs
- Use capable() instead of capable_wrt_inode_uidgid()
- Update ext3 and generic_acl.c as well
- In gfs2, jfs, and xfs, take care to avoid leaking the allocated ACL if
posix_acl_update_mode() determines it's not needed
- Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/posix_acl.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index b7681102a4b9..da432868954f 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -83,6 +83,7 @@ extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t); extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *); extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *); extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); +extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **); extern struct posix_acl *get_posix_acl(struct inode *, int); extern int set_posix_acl(struct inode *, int, struct posix_acl *); |