All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: Jens Axboe <axboe@kernel.dk>
Cc: linux-fsdevel@vger.kernel.org, brauner@kernel.org,
	io-uring@vger.kernel.org, cgzones@googlemail.com
Subject: Re: [PATCH 5/9] replace do_setxattr() with saner helpers.
Date: Sun, 6 Oct 2024 06:28:59 +0100	[thread overview]
Message-ID: <20241006052859.GD4017910@ZenIV> (raw)
In-Reply-To: <d69b33f9-31a0-4c70-baf2-a72dc28139e0@kernel.dk>

On Wed, Oct 02, 2024 at 04:55:22PM -0600, Jens Axboe wrote:

> The reason I liked the putname() is that it's unconditional - the caller
> can rely on it being put, regardless of the return value. So I'd say the
> same should be true for ctx.kvalue, and if not, the caller should still
> free it. That's the path of least surprise - no leak for the least
> tested error path, and no UAF in the success case.

The problem with ctx.kvalue is that on the syscall side there's a case when
we do not call either file_setxattr() or filename_setxattr() - -EBADF.
And it's a lot more convenient to do setxattr_copy() first, so we end
up with a lovely landmine:
        filename = getname_xattr(pathname, at_flags);
	if (!filename) {
		CLASS(fd, f)(dfd);
		if (fd_empty(f)) {
			kfree(ctx.kvalue); // lest we leak
			return -EBADF;
		}
		return file_setxattr(fd_file(f), &ctx);
	}
	return filename_setxattr(dfd, filename, lookup_flags, &ctx);

That's asking for trouble, obviously.  So I think we ought to consume
filename (in filename_...()) case, leave struct file reference alone
(we have to - it might have been borrowed rather than cloned) and leave
->kvalue unchanged.  Yes, it ends up being more clumsy, but at least
it's consistent between the cases...

As for consuming filename...  On the syscall side it allows things like
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
{
        return do_mkdirat(dfd, getname(pathname), mode);
}  
which is better than the alternatives - I mean, that's
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
{
	struct filename *filename = getname(pathname);
	int res = do_mkdirat(dfd, filename, mode);
	putname(filename);
	return ret;
}  
or 
SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
{
	struct filename *filename __free(putname) = getname(pathname);
	return do_mkdirat(dfd, filename, mode);
}
and both stink, if for different reasons ;-/  Having those things consume
(unconditionally) is better, IMO.

Hell knows; let's go with what I described above for now and see where it leads
when more such helpers are regularized.

> That's a bit different than your putname() case, but I think as long as
> it's consistent regardless of return value, then either approach is
> fine. Maybe just add a comment about that? At least for the consistent
> case, if it blows up, it'll blow up instantly rather than be a surprise
> down the line for "case x,y,z doesn't put it" or "case x,y,z always puts
> in, normal one does not".

Obviously.

> > Questions on the io_uring side:
> > 	* you usually reject REQ_F_FIXED_FILE for ...at() at ->prep() time.
> > Fine, but... what's the point of doing that in IORING_OP_FGETXATTR case?
> > Or IORING_OP_GETXATTR, for that matter, since you pass AT_FDCWD anyway...
> > Am I missing something subtle here?
> 
> Right, it could be allowed for fgetxattr on the io_uring side. Anything
> that passes in a struct file would be fair game to enable it on.
> Anything that passes in a path (eg a non-fd value), it obviously
> wouldn't make sense anyway.

OK, done and force-pushed into #work.xattr.

  reply	other threads:[~2024-10-06  5:29 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-02  1:10 [RFC][PATCHES] xattr stuff and interactions with io_uring Al Viro
2024-10-02  1:22 ` [PATCH 1/9] xattr: switch to CLASS(fd) Al Viro
2024-10-02  1:22   ` [PATCH 2/9] fs: rename struct xattr_ctx to kernel_xattr_ctx Al Viro
2024-10-02  5:56     ` Christian Brauner
2024-10-02  1:22   ` [PATCH 3/9] io_[gs]etxattr_prep(): just use getname() Al Viro
2024-10-02  5:57     ` Christian Brauner
2024-10-02  1:22   ` [PATCH 4/9] new helper: import_xattr_name() Al Viro
2024-10-02  5:57     ` Christian Brauner
2024-10-02  1:22   ` [PATCH 5/9] replace do_setxattr() with saner helpers Al Viro
2024-10-02  1:34     ` Jens Axboe
2024-10-02  2:08       ` Al Viro
2024-10-02 18:00         ` Jens Axboe
2024-10-02 21:19           ` Al Viro
2024-10-02 22:55             ` Jens Axboe
2024-10-06  5:28               ` Al Viro [this message]
2024-10-07 18:09                 ` Jens Axboe
2024-10-07 18:20                   ` Jens Axboe
2024-10-07 21:20                     ` Al Viro
2024-10-07 22:29                       ` Jens Axboe
2024-10-07 23:58                         ` Al Viro
2024-10-08  1:58                           ` Jens Axboe
2024-10-08  4:08                             ` Al Viro
2024-10-02  1:22   ` [PATCH 6/9] replace do_getxattr() " Al Viro
2024-10-02  5:59     ` Christian Brauner
2024-10-02  1:22   ` [PATCH 7/9] new helpers: file_listxattr(), filename_listxattr() Al Viro
2024-10-02  6:00     ` Christian Brauner
2024-10-02  1:22   ` [PATCH 8/9] new helpers: file_removexattr(), filename_removexattr() Al Viro
2024-10-02  6:01     ` Christian Brauner
2024-10-02  1:22   ` [PATCH 9/9] fs/xattr: add *at family syscalls Al Viro
2024-10-02  6:03     ` Christian Brauner
2024-10-02  5:56   ` [PATCH 1/9] xattr: switch to CLASS(fd) Christian Brauner
2024-11-02  7:28 ` [RFC][PATCHES v2] xattr stuff and interactions with io_uring Al Viro
2024-11-02  7:31   ` [PATCH v2 01/13] teach filename_lookup() to treat NULL filename as "" Al Viro
2024-11-02  7:31     ` [PATCH v2 02/13] getname_maybe_null() - the third variant of pathname copy-in Al Viro
2024-11-02  7:31     ` [PATCH v2 03/13] io_uring: IORING_OP_F[GS]ETXATTR is fine with REQ_F_FIXED_FILE Al Viro
2024-11-02  7:31     ` [PATCH v2 04/13] io_[gs]etxattr_prep(): just use getname() Al Viro
2024-11-02 14:44       ` Jens Axboe
2024-11-02  7:31     ` [PATCH v2 05/13] xattr: switch to CLASS(fd) Al Viro
2024-11-02  7:31     ` [PATCH v2 06/13] fs: rename struct xattr_ctx to kernel_xattr_ctx Al Viro
2024-11-02  7:31     ` [PATCH v2 07/13] new helper: import_xattr_name() Al Viro
2024-11-02  7:31     ` [PATCH v2 08/13] replace do_setxattr() with saner helpers Al Viro
2024-11-02  7:31     ` [PATCH v2 09/13] replace do_getxattr() " Al Viro
2024-11-02  7:31     ` [PATCH v2 10/13] new helpers: file_listxattr(), filename_listxattr() Al Viro
2024-11-02  7:31     ` [PATCH v2 11/13] new helpers: file_removexattr(), filename_removexattr() Al Viro
2024-11-02  7:31     ` [PATCH v2 12/13] fs/xattr: add *at family syscalls Al Viro
2024-11-02  7:31     ` [PATCH v2 13/13] xattr: remove redundant check on variable err Al Viro
2024-11-02 14:43   ` [RFC][PATCHES v2] xattr stuff and interactions with io_uring Jens Axboe
2024-11-03  6:51     ` Al Viro
2024-11-03 13:57       ` Arnd Bergmann
2024-11-03 18:32         ` Al Viro

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=20241006052859.GD4017910@ZenIV \
    --to=viro@zeniv.linux.org.uk \
    --cc=axboe@kernel.dk \
    --cc=brauner@kernel.org \
    --cc=cgzones@googlemail.com \
    --cc=io-uring@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.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.