[2/2] fs/kernfs/dir: obey S_ISGID

Message ID 20231201125638.1699026-2-max.kellermann@ionos.com
State New
Headers
Series [1/2] kernel/cgroup: use kernfs_create_dir_ns() |

Commit Message

Max Kellermann Dec. 1, 2023, 12:56 p.m. UTC
  Handling of S_ISGID is usually done by inode_init_owner() in all other
filesystems, but kernfs doesn't use that function.  In kernfs, struct
kernfs_node is the primary data structure, and struct inode is only
created from it on demand.  Therefore, inode_init_owner() can't be
used and we need to imitate its behavior.

S_ISGID support is useful for the cgroup filesystem; it allows
subtrees managed by an unprivileged process to retain a certain owner
gid, which then enables sharing access to the subtree with another
unprivileged process.

Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
---
 fs/kernfs/dir.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
  

Comments

Tejun Heo Dec. 1, 2023, 4:59 p.m. UTC | #1
On Fri, Dec 01, 2023 at 01:56:38PM +0100, Max Kellermann wrote:
> Handling of S_ISGID is usually done by inode_init_owner() in all other
> filesystems, but kernfs doesn't use that function.  In kernfs, struct
> kernfs_node is the primary data structure, and struct inode is only
> created from it on demand.  Therefore, inode_init_owner() can't be
> used and we need to imitate its behavior.
> 
> S_ISGID support is useful for the cgroup filesystem; it allows
> subtrees managed by an unprivileged process to retain a certain owner
> gid, which then enables sharing access to the subtree with another
> unprivileged process.
> 
> Signed-off-by: Max Kellermann <max.kellermann@ionos.com>

Acked-by: Tejun Heo <tj@kernel.org>

Thanks.
  
Greg KH Dec. 4, 2023, 7:20 a.m. UTC | #2
On Fri, Dec 01, 2023 at 01:56:38PM +0100, Max Kellermann wrote:
> Handling of S_ISGID is usually done by inode_init_owner() in all other
> filesystems, but kernfs doesn't use that function.  In kernfs, struct
> kernfs_node is the primary data structure, and struct inode is only
> created from it on demand.  Therefore, inode_init_owner() can't be
> used and we need to imitate its behavior.
> 
> S_ISGID support is useful for the cgroup filesystem; it allows
> subtrees managed by an unprivileged process to retain a certain owner
> gid, which then enables sharing access to the subtree with another
> unprivileged process.
> 
> Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
> ---
>  fs/kernfs/dir.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)

I only see patch 2/2 here, what happened to patch 1/2?

Please send them as a full series, otherwise I don't know what to do
with just this one.

thanks,

greg k-h
  
Max Kellermann Dec. 4, 2023, 12:43 p.m. UTC | #3
On Mon, Dec 4, 2023 at 1:22 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
> I only see patch 2/2 here, what happened to patch 1/2?

I used "get_maintainer.pl" as "tocmd/cccmd", and apparently, only the
second patch touches code that you maintain, and "git send-email"
determines the destinations for each individual patch, not for the
series, so the first patch wasn't sent to you directly. Not sure how
to configure "git send-email" to merge the destinations of the whole
series for all patches, but I'll figure it out for v2 (fixing two
minor checkpatch warnings). Meanwhile, you can see the first patch
here: https://lore.kernel.org/lkml/20231201125638.1699026-1-max.kellermann@ionos.com/
  

Patch

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 8b2bd65d70e7..7580cc340d28 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -676,6 +676,17 @@  struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
 {
 	struct kernfs_node *kn;
 
+	if (parent->mode & S_ISGID) {
+		/* this code block imitates inode_init_owner() for
+		 * kernfs */
+
+		if (parent->iattr)
+			gid = parent->iattr->ia_gid;
+
+		if (flags & KERNFS_DIR)
+			mode |= S_ISGID;
+	}
+
 	kn = __kernfs_new_node(kernfs_root(parent), parent,
 			       name, mode, uid, gid, flags);
 	if (kn) {