Skip to content

Commit

Permalink
Fix up non-directory creation in SGID directories
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
torvalds committed Jul 5, 2018
1 parent d02d21e commit 0fa3ecd
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1999,8 +1999,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;
Expand Down

0 comments on commit 0fa3ecd

Please sign in to comment.