| 123456789101112131415161718192021222324252627282930313233343536373839404142434445 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Linus Torvalds <[email protected]>
- Date: Tue, 3 Jul 2018 17:10:19 -0700
- Subject: [PATCH] Fix up non-directory creation in SGID directories
- sgid directories have special semantics, making newly created files in
- the directory belong to the group of the directory, and newly created
- subdirectories will also become sgid. This is historically used for
- group-shared directories.
- But group directories writable by non-group members should not imply
- that such non-group members can magically join the group, so make sure
- to clear the sgid bit on non-directories for non-members (but remember
- that sgid without group execute means "mandatory locking", just to
- confuse things even more).
- Reported-by: Jann Horn <[email protected]>
- Cc: Andy Lutomirski <[email protected]>
- Cc: Al Viro <[email protected]>
- Signed-off-by: Linus Torvalds <[email protected]>
- (cherry picked from commit 0fa3ecd87848c9c93c2c828ef4c3a8ca36ce46c7)
- Signed-off-by: Stoiko Ivanov <[email protected]>
- ---
- fs/inode.c | 6 ++++++
- 1 file changed, 6 insertions(+)
- diff --git a/fs/inode.c b/fs/inode.c
- index 5c1138e9cac0..797b4cb3d20b 100644
- --- a/fs/inode.c
- +++ b/fs/inode.c
- @@ -2008,8 +2008,14 @@ void inode_init_owner(struct inode *inode, const struct inode *dir,
- inode->i_uid = current_fsuid();
- if (dir && dir->i_mode & S_ISGID) {
- inode->i_gid = dir->i_gid;
- +
- + /* Directories are special, and always inherit S_ISGID */
- if (S_ISDIR(mode))
- mode |= S_ISGID;
- + else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) &&
- + !in_group_p(inode->i_gid) &&
- + !capable_wrt_inode_uidgid(dir, CAP_FSETID))
- + mode &= ~S_ISGID;
- } else
- inode->i_gid = current_fsgid();
- inode->i_mode = mode;
|