All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 1/4] fs: move sgid strip operation from inode_init_owner into inode_sgid_strip
@ 2022-04-25  3:09 Yang Xu
  2022-04-25  2:45 ` Matthew Wilcox
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Yang Xu @ 2022-04-25  3:09 UTC (permalink / raw)
  To: linux-fsdevel, ceph-devel
  Cc: viro, david, djwong, brauner, willy, jlayton, Yang Xu

This has no functional change. Just create and export inode_sgid_strip
api for the subsequent patch. This function is used to strip inode's
S_ISGID mode when init a new inode.

Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 fs/inode.c         | 37 +++++++++++++++++++++++++++++++++----
 include/linux/fs.h |  2 ++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/fs/inode.c b/fs/inode.c
index 9d9b422504d1..78e7ef567e04 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -2246,10 +2246,8 @@ void inode_init_owner(struct user_namespace *mnt_userns, struct inode *inode,
 		/* 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(i_gid_into_mnt(mnt_userns, dir)) &&
-			 !capable_wrt_inode_uidgid(mnt_userns, dir, CAP_FSETID))
-			mode &= ~S_ISGID;
+		else
+			mode = inode_sgid_strip(mnt_userns, dir, mode);
 	} else
 		inode_fsgid_set(inode, mnt_userns);
 	inode->i_mode = mode;
@@ -2405,3 +2403,34 @@ struct timespec64 current_time(struct inode *inode)
 	return timestamp_truncate(now, inode);
 }
 EXPORT_SYMBOL(current_time);
+
+/**
+ * inode_sgid_strip - handle the sgid bit for non-directories
+ * @mnt_userns: User namespace of the mount the inode was created from
+ * @dir: parent directory inode
+ * @mode: mode of the file to be created in @dir
+ *
+ * If the @mode of the new file has both the S_ISGID and S_IXGRP bit
+ * raised and @dir has the S_ISGID bit raised ensure that the caller is
+ * either in the group of the parent directory or they have CAP_FSETID
+ * in their user namespace and are privileged over the parent directory.
+ * In all other cases, strip the S_ISGID bit from @mode.
+ *
+ * Return: the new mode to use for the file
+ */
+umode_t inode_sgid_strip(struct user_namespace *mnt_userns,
+			 const struct inode *dir, umode_t mode)
+{
+	if (S_ISDIR(mode) || !dir || !(dir->i_mode & S_ISGID))
+		return mode;
+	if ((mode & (S_ISGID | S_IXGRP)) != (S_ISGID | S_IXGRP))
+		return mode;
+	if (in_group_p(i_gid_into_mnt(mnt_userns, dir)))
+		return mode;
+	if (capable_wrt_inode_uidgid(mnt_userns, dir, CAP_FSETID))
+		return mode;
+
+	mode &= ~S_ISGID;
+	return mode;
+}
+EXPORT_SYMBOL(inode_sgid_strip);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bbde95387a23..532de76c9b91 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1897,6 +1897,8 @@ extern long compat_ptr_ioctl(struct file *file, unsigned int cmd,
 void inode_init_owner(struct user_namespace *mnt_userns, struct inode *inode,
 		      const struct inode *dir, umode_t mode);
 extern bool may_open_dev(const struct path *path);
+umode_t inode_sgid_strip(struct user_namespace *mnt_userns,
+			 const struct inode *dir, umode_t mode);
 
 /*
  * This is the "filldir" function type, used by readdir() to let
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2022-04-26  1:25 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-25  3:09 [PATCH v6 1/4] fs: move sgid strip operation from inode_init_owner into inode_sgid_strip Yang Xu
2022-04-25  2:45 ` Matthew Wilcox
2022-04-25  3:08   ` xuyang2018.jy
2022-04-25 11:29     ` Christian Brauner
2022-04-25 17:33       ` Matthew Wilcox
2022-04-26  1:22         ` xuyang2018.jy
2022-04-25  3:09 ` [PATCH v6 2/4] fs: Add missing umask strip in vfs_tmpfile Yang Xu
2022-04-25 16:54   ` Darrick J. Wong
2022-04-25  3:09 ` [PATCH v6 3/4] fs: strip file's S_ISGID mode on vfs instead of on underlying filesystem Yang Xu
2022-04-25 16:51   ` Darrick J. Wong
2022-04-26  1:25     ` xuyang2018.jy
2022-04-25  3:09 ` [PATCH v6 4/4] ceph: Remove S_ISGID stripping code in ceph_finish_async_create Yang Xu
2022-04-25 16:53 ` [PATCH v6 1/4] fs: move sgid strip operation from inode_init_owner into inode_sgid_strip Darrick J. Wong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.