All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: Christian Brauner <brauner@kernel.org>,
	Seth Forshee <sforshee@kernel.org>,
	Christoph Hellwig <hch@lst.de>, Al Viro <viro@zeniv.linux.org.uk>,
	linux-security-module@vger.kernel.org
Subject: [PATCH v5 24/30] xattr: use posix acl api
Date: Tue, 18 Oct 2022 13:56:54 +0200	[thread overview]
Message-ID: <20221018115700.166010-25-brauner@kernel.org> (raw)
In-Reply-To: <20221018115700.166010-1-brauner@kernel.org>

In previous patches we built a new posix api solely around get and set
inode operations. Now that we have all the pieces in place we can switch
the system calls and the vfs over to only rely on this api when
interacting with posix acls. This finally removes all type unsafety and
type conversion issues explained in detail in [1] that we aim to get rid
of.

With the new posix acl api we immediately translate into an appropriate
kernel internal struct posix_acl format both when getting and setting
posix acls. This is a stark contrast to before were we hacked unsafe raw
values into the uapi struct that was stored in a void pointer relying
and having filesystems and security modules hack around in the uapi
struct as well.

Link: https://lore.kernel.org/all/20220801145520.1532837-1-brauner@kernel.org [1]
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
---

Notes:
    /* v2 */
    unchanged
    
    /* v3 */
    unchanged
    
    /* v4 */
    Christoph Hellwig <hch@lst.de>:
    - Add do_set_acl() and do_get_acl() to fs/posix_acl.c and fs/internal.h that
      wrap all the conversion and call them from fs/xattr.c. This allows to
      simplify the whole patch and remove unneeded helpers.
    
    /* v5 */
    unchanged

 fs/internal.h                   |  4 ++++
 fs/posix_acl.c                  | 37 +++++++++++++++++++++++++++++++++
 fs/xattr.c                      | 31 +++++++++++++++++----------
 include/linux/posix_acl_xattr.h | 10 +++++++--
 4 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/fs/internal.h b/fs/internal.h
index de43795ab7cd..14fac61ee071 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -235,3 +235,7 @@ int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 
 ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos);
 int may_write_xattr(struct user_namespace *mnt_userns, struct inode *inode);
+int do_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+	       const char *acl_name, const void *kvalue, size_t size);
+ssize_t do_get_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+		   const char *acl_name, void *kvalue, size_t size);
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index a84be3fdb6c5..35e4caaedfd8 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -1544,3 +1544,40 @@ int vfs_remove_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
 	return error;
 }
 EXPORT_SYMBOL_GPL(vfs_remove_acl);
+
+int do_set_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+	       const char *acl_name, const void *kvalue, size_t size)
+{
+	int error;
+	struct posix_acl *acl = NULL;
+
+	if (size) {
+		/*
+		 * Note that posix_acl_from_xattr() uses GFP_NOFS when it
+		 * probably doesn't need to here.
+		 */
+		acl = posix_acl_from_xattr(current_user_ns(), kvalue, size);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+	}
+
+	error = vfs_set_acl(mnt_userns, dentry, acl_name, acl);
+	posix_acl_release(acl);
+	return error;
+}
+
+ssize_t do_get_acl(struct user_namespace *mnt_userns, struct dentry *dentry,
+		   const char *acl_name, void *kvalue, size_t size)
+{
+	ssize_t error;
+	struct posix_acl *acl;
+
+	acl = vfs_get_acl(mnt_userns, dentry, acl_name);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+
+	error = vfs_posix_acl_to_xattr(mnt_userns, d_inode(dentry),
+				       acl, kvalue, size);
+	posix_acl_release(acl);
+	return error;
+}
diff --git a/fs/xattr.c b/fs/xattr.c
index 9ed9eea4d1b9..77db5aa26d13 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -189,6 +189,9 @@ __vfs_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 {
 	const struct xattr_handler *handler;
 
+	if (is_posix_acl_xattr(name))
+		return -EOPNOTSUPP;
+
 	handler = xattr_resolve_name(inode, &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
@@ -410,6 +413,9 @@ __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
 {
 	const struct xattr_handler *handler;
 
+	if (is_posix_acl_xattr(name))
+		return -EOPNOTSUPP;
+
 	handler = xattr_resolve_name(inode, &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
@@ -482,6 +488,9 @@ __vfs_removexattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 	struct inode *inode = d_inode(dentry);
 	const struct xattr_handler *handler;
 
+	if (is_posix_acl_xattr(name))
+		return -EOPNOTSUPP;
+
 	handler = xattr_resolve_name(inode, &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
@@ -591,17 +600,13 @@ int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
 	return error;
 }
 
-static void setxattr_convert(struct user_namespace *mnt_userns,
-			     struct dentry *d, struct xattr_ctx *ctx)
-{
-	if (ctx->size && is_posix_acl_xattr(ctx->kname->name))
-		posix_acl_fix_xattr_from_user(ctx->kvalue, ctx->size);
-}
-
 int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 		struct xattr_ctx *ctx)
 {
-	setxattr_convert(mnt_userns, dentry, ctx);
+	if (is_posix_acl_xattr(ctx->kname->name))
+		return do_set_acl(mnt_userns, dentry, ctx->kname->name,
+				  ctx->kvalue, ctx->size);
+
 	return vfs_setxattr(mnt_userns, dentry, ctx->kname->name,
 			ctx->kvalue, ctx->size, ctx->flags);
 }
@@ -708,10 +713,11 @@ do_getxattr(struct user_namespace *mnt_userns, struct dentry *d,
 			return -ENOMEM;
 	}
 
-	error = vfs_getxattr(mnt_userns, d, kname, ctx->kvalue, ctx->size);
+	if (is_posix_acl_xattr(ctx->kname->name))
+		error = do_get_acl(mnt_userns, d, kname, ctx->kvalue, ctx->size);
+	else
+		error = vfs_getxattr(mnt_userns, d, kname, ctx->kvalue, ctx->size);
 	if (error > 0) {
-		if (is_posix_acl_xattr(kname))
-			posix_acl_fix_xattr_to_user(ctx->kvalue, error);
 		if (ctx->size && copy_to_user(ctx->value, ctx->kvalue, error))
 			error = -EFAULT;
 	} else if (error == -ERANGE && ctx->size >= XATTR_SIZE_MAX) {
@@ -886,6 +892,9 @@ removexattr(struct user_namespace *mnt_userns, struct dentry *d,
 	if (error < 0)
 		return error;
 
+	if (is_posix_acl_xattr(kname))
+		return vfs_remove_acl(mnt_userns, d, kname);
+
 	return vfs_removexattr(mnt_userns, d, kname);
 }
 
diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h
index bf30296389d7..c5d5fbc348dc 100644
--- a/include/linux/posix_acl_xattr.h
+++ b/include/linux/posix_acl_xattr.h
@@ -33,6 +33,8 @@ posix_acl_xattr_count(size_t size)
 }
 
 #ifdef CONFIG_FS_POSIX_ACL
+struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns,
+				       const void *value, size_t size);
 void posix_acl_fix_xattr_from_user(void *value, size_t size);
 void posix_acl_fix_xattr_to_user(void *value, size_t size);
 void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
@@ -42,6 +44,12 @@ ssize_t vfs_posix_acl_to_xattr(struct user_namespace *mnt_userns,
 			       struct inode *inode, const struct posix_acl *acl,
 			       void *buffer, size_t size);
 #else
+static inline struct posix_acl *
+posix_acl_from_xattr(struct user_namespace *user_ns, const void *value,
+		     size_t size)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
 static inline void posix_acl_fix_xattr_from_user(void *value, size_t size)
 {
 }
@@ -63,8 +71,6 @@ static inline ssize_t vfs_posix_acl_to_xattr(struct user_namespace *mnt_userns,
 }
 #endif
 
-struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns, 
-				       const void *value, size_t size);
 int posix_acl_to_xattr(struct user_namespace *user_ns,
 		       const struct posix_acl *acl, void *buffer, size_t size);
 struct posix_acl *vfs_set_acl_prepare(struct user_namespace *mnt_userns,
-- 
2.34.1


  parent reply	other threads:[~2022-10-18 12:00 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-18 11:56 [PATCH v5 00/30] acl: add vfs posix acl api Christian Brauner
2022-10-18 11:56 ` [PATCH v5 01/30] orangefs: rework posix acl handling when creating new filesystem objects Christian Brauner
2022-11-11 21:38   ` Mike Marshall
2022-11-12 10:09     ` Christian Brauner
2022-11-13 11:50       ` [PATCH] orangefs: fix mode handling Christian Brauner
2022-10-18 11:56 ` [PATCH v5 02/30] fs: pass dentry to set acl method Christian Brauner
2022-11-18 10:09   ` Mickaël Salaün
2022-11-18 10:33     ` Christian Brauner
2022-11-18 12:32       ` Mickaël Salaün
2022-10-18 11:56 ` [PATCH v5 03/30] fs: rename current get " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 04/30] fs: add new " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 05/30] cifs: implement " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 06/30] cifs: implement set " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 07/30] 9p: implement get " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 08/30] 9p: implement set " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 09/30] security: add get, remove and set acl hook Christian Brauner
2022-10-18 11:56 ` [PATCH v5 10/30] selinux: implement get, set and remove " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 11/30] smack: " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 12/30] integrity: implement get and set " Christian Brauner
2022-10-18 19:17   ` Paul Moore
2022-10-18 11:56 ` [PATCH v5 13/30] evm: add post " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 14/30] internal: add may_write_xattr() Christian Brauner
2022-10-18 11:56 ` [PATCH v5 15/30] acl: add vfs_set_acl() Christian Brauner
2022-10-18 11:56 ` [PATCH v5 16/30] acl: add vfs_get_acl() Christian Brauner
2022-10-18 11:56 ` [PATCH v5 17/30] acl: add vfs_remove_acl() Christian Brauner
2022-10-18 11:56 ` [PATCH v5 18/30] ksmbd: use vfs_remove_acl() Christian Brauner
2022-10-18 11:56 ` [PATCH v5 19/30] ecryptfs: implement get acl method Christian Brauner
2022-10-18 11:56 ` [PATCH v5 20/30] ecryptfs: implement set " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 21/30] ovl: implement get " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 22/30] ovl: implement set " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 23/30] ovl: use posix acl api Christian Brauner
2022-10-18 11:56 ` Christian Brauner [this message]
2022-10-18 11:56 ` [PATCH v5 25/30] evm: remove evm_xattr_acl_change() Christian Brauner
2022-10-18 11:56 ` [PATCH v5 26/30] ecryptfs: use stub posix acl handlers Christian Brauner
2022-10-18 11:56 ` [PATCH v5 27/30] ovl: " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 28/30] cifs: " Christian Brauner
2022-10-18 11:56 ` [PATCH v5 29/30] 9p: " Christian Brauner
2022-10-18 11:57 ` [PATCH v5 30/30] acl: remove a slew of now unused helpers Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221018115700.166010-25-brauner@kernel.org \
    --to=brauner@kernel.org \
    --cc=hch@lst.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=sforshee@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.