diff options
Diffstat (limited to 'fs/inode.c')
| -rw-r--r-- | fs/inode.c | 6 | 
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;  |