From: Al Viro <viro@zeniv.linux.org.uk>
To: Christian Brauner <christian.brauner@ubuntu.com>
Cc: Stefan Roesch <shr@fb.com>,
io-uring@vger.kernel.org, linux-fsdevel@vger.kernel.org,
kernel-team@fb.com, torvalds@linux-foundation.org
Subject: Re: [PATCH v10 4/5] io_uring: add fsetxattr and setxattr support
Date: Thu, 30 Dec 2021 16:16:34 +0000 [thread overview]
Message-ID: <Yc3bYj33YPwpAg8q@zeniv-ca.linux.org.uk> (raw)
In-Reply-To: <20211230101242.j6jzxc4ahmx2plqx@wittgenstein>
On Thu, Dec 30, 2021 at 11:12:42AM +0100, Christian Brauner wrote:
> @@ -545,6 +545,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
> int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
> {
> int error;
> + struct xattr_ctx *new_ctx;
>
> if (ctx->flags & ~(XATTR_CREATE|XATTR_REPLACE))
> return -EINVAL;
> @@ -606,12 +607,9 @@ setxattr(struct user_namespace *mnt_userns, struct dentry *d,
> int error;
>
> error = setxattr_copy(name, &ctx);
> - if (error)
> - return error;
> -
> - error = do_setxattr(mnt_userns, d, &ctx);
> -
> - kvfree(ctx.kvalue);
> + if (!error)
> + error = do_setxattr(mnt_userns, d, &ctx);
> + setxattr_finish(&ctx);
> return error;
> }
Huh? Have you lost a chunk or two in there? The only modification of
setxattr_copy() in your delta is the introduction of an unused local
variable. Confused...
What I had in mind is something like this:
// same for getxattr and setxattr
static int xattr_name_from_user(const char __user *name, struct xattr_ctx *ctx)
{
int copied;
if (!ctx->xattr_name) {
ctx->xattr_name = kmalloc(XATTR_NAME_MAX + 1, GFP_KERNEL);
if (!ctx->xattr_name)
return -ENOMEM;
}
copied = strncpy_from_user(ctx->xattr_name, name, XATTR_NAME_MAX + 1);
if (copied < 0)
return copied; // copyin failure; almost always -EFAULT
if (copied == 0 || copied == XATTR_NAME_MAX + 1)
return -ERANGE;
return 0;
}
// freeing is up to the caller, whether we succeed or not
int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
{
int error;
if (ctx->flags & ~(XATTR_CREATE|XATTR_REPLACE))
return -EINVAL;
error = xattr_name_from_user(name, ctx);
if (error)
return error;
if (ctx->size) {
void *p;
if (ctx->size > XATTR_SIZE_MAX)
return -E2BIG;
p = vmemdup_user(ctx->value, ctx->size);
if (IS_ERR(p))
return PTR_ERR(p);
ctx->kvalue = p;
}
return 0;
}
with syscall side concluded with freeing ->kvalue (unconditionally), while
io_uring one - ->kvalue and ->xattr_name (also unconditionally). And to
hell with struct xattr_name - a string is a string.
However, what I really want to see is the answer to my question re control
flow and the place where we do copy the arguments from userland. Including
the pathname.
*IF* there's a subtle reason that has to be done from prep phase (and there
might very well be - figuring out the control flow in io_uring is bloody
painful), I would really like to see it spelled out, along with the explanation
of the reasons why statx() doesn't need anything of that sort.
If there's no such reasons, I would bloody well leave marshalling to the
payload, allowing to share a lot more with the syscall path. In that
case xattr_ctx only needs to carry the userland pointers/size/flags.
And all that "do we allocate the kernel copy of the name dynamically,
or does it live on stack" simply goes away.
Details, please.
next prev parent reply other threads:[~2021-12-30 16:16 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-29 20:29 [PATCH v10 0/5] io_uring: add xattr support Stefan Roesch
2021-12-29 20:29 ` [PATCH v10 1/5] fs: split off do_user_path_at_empty from user_path_at_empty() Stefan Roesch
2021-12-30 0:49 ` Al Viro
2021-12-30 19:57 ` Stefan Roesch
2021-12-29 20:29 ` [PATCH v10 2/5] fs: split off setxattr_copy and do_setxattr function from setxattr Stefan Roesch
2021-12-30 1:15 ` Al Viro
2021-12-30 9:41 ` Christian Brauner
2021-12-30 19:57 ` Stefan Roesch
2021-12-29 20:30 ` [PATCH v10 3/5] fs: split off do_getxattr from getxattr Stefan Roesch
2021-12-29 20:30 ` [PATCH v10 4/5] io_uring: add fsetxattr and setxattr support Stefan Roesch
2021-12-30 1:58 ` Al Viro
2021-12-30 2:17 ` Al Viro
2021-12-30 2:19 ` Al Viro
2021-12-30 3:04 ` Al Viro
2021-12-30 10:12 ` Christian Brauner
2021-12-30 16:16 ` Al Viro [this message]
2021-12-30 18:01 ` Christian Brauner
2021-12-30 19:09 ` Jens Axboe
2021-12-30 22:24 ` Al Viro
2021-12-30 22:46 ` Jens Axboe
2021-12-30 23:02 ` Al Viro
2021-12-30 20:18 ` Stefan Roesch
2021-12-29 20:30 ` [PATCH v10 5/5] io_uring: add fgetxattr and getxattr support Stefan Roesch
2021-12-30 1:41 ` Al Viro
2021-12-30 1:46 ` Al Viro
2021-12-30 20:01 ` Stefan Roesch
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=Yc3bYj33YPwpAg8q@zeniv-ca.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=christian.brauner@ubuntu.com \
--cc=io-uring@vger.kernel.org \
--cc=kernel-team@fb.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=shr@fb.com \
--cc=torvalds@linux-foundation.org \
/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.