summaryrefslogtreecommitdiff
path: root/fs/inode.c
diff options
context:
space:
mode:
authorStefan Schmidt <stefan@datenfreihafen.org>2018-08-06 09:04:48 +0200
committerStefan Schmidt <stefan@datenfreihafen.org>2018-08-06 09:04:48 +0200
commita30461080366214b690a367225a48c95d7a6a189 (patch)
tree02cd7cfb8cea14cebe1ab2a1638edd8c9b9e0d3f /fs/inode.c
parent811e299f4645588cc7a1b78d97b6847c155324b9 (diff)
parent981467033a37d916649647fa3afe1fe99bba1817 (diff)
Merge remote-tracking branch 'net-next/master'
Diffstat (limited to 'fs/inode.c')
-rw-r--r--fs/inode.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 2c300e981796..8c86c809ca17 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -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;