]> git.proxmox.com Git - pve-kernel.git/blame - patches/kernel/0011-Fix-up-non-directory-creation-in-SGID-directories.patch
rebase patches on top of Ubuntu-4.15.0-32.35
[pve-kernel.git] / patches / kernel / 0011-Fix-up-non-directory-creation-in-SGID-directories.patch
CommitLineData
72f9fd46
SI
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Linus Torvalds <torvalds@linux-foundation.org>
3Date: Tue, 3 Jul 2018 17:10:19 -0700
4Subject: [PATCH] Fix up non-directory creation in SGID directories
5
6sgid directories have special semantics, making newly created files in
7the directory belong to the group of the directory, and newly created
8subdirectories will also become sgid. This is historically used for
9group-shared directories.
10
11But group directories writable by non-group members should not imply
12that such non-group members can magically join the group, so make sure
13to clear the sgid bit on non-directories for non-members (but remember
14that sgid without group execute means "mandatory locking", just to
15confuse things even more).
16
17Reported-by: Jann Horn <jannh@google.com>
18Cc: Andy Lutomirski <luto@kernel.org>
19Cc: Al Viro <viro@zeniv.linux.org.uk>
20Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
21(cherry picked from commit 0fa3ecd87848c9c93c2c828ef4c3a8ca36ce46c7)
22Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
72f9fd46
SI
23---
24 fs/inode.c | 6 ++++++
25 1 file changed, 6 insertions(+)
26
27diff --git a/fs/inode.c b/fs/inode.c
28index 5c1138e9cac0..797b4cb3d20b 100644
29--- a/fs/inode.c
30+++ b/fs/inode.c
31@@ -2008,8 +2008,14 @@ void inode_init_owner(struct inode *inode, const struct inode *dir,
32 inode->i_uid = current_fsuid();
33 if (dir && dir->i_mode & S_ISGID) {
34 inode->i_gid = dir->i_gid;
35+
36+ /* Directories are special, and always inherit S_ISGID */
37 if (S_ISDIR(mode))
38 mode |= S_ISGID;
39+ else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) &&
40+ !in_group_p(inode->i_gid) &&
41+ !capable_wrt_inode_uidgid(dir, CAP_FSETID))
42+ mode &= ~S_ISGID;
43 } else
44 inode->i_gid = current_fsgid();
45 inode->i_mode = mode;