Re: [PATCH v3] fs: Replace user_access_{begin/end} by scoped user access
From: Linus Torvalds
Date: Mon Mar 16 2026 - 13:17:43 EST
On Mon, 16 Mar 2026 at 01:53, Christophe Leroy (CS GROUP)
<chleroy@xxxxxxxxxx> wrote:
>
> - if (!user_write_access_begin(dirent,
> - (unsigned long)(dirent->d_name + namlen + 1) -
> - (unsigned long)dirent))
> - goto efault;
This was already pretty unreadable (my bad), but..
> + scoped_user_write_access_size(dirent, (unsigned long)(dirent->d_name + namlen + 1) -
> + (unsigned long)dirent, efault) {
.. in my opinion, this is even worse. It's a 90+ character long line
(or something), *and* it continues on the next line.
Yes, yes, the old code was disgusting too, but when changing it for
something that is supposed to be easier to read, please let's make it
*really* easier to read.
(And yes, there's another case of this same pattern a bit later).
Adding a helper inline function like dirent_size() might do it. And I
think it might as well be cleaned up while at it, and make it be
something like
static inline size_t dirent_size(int namelen)
{
return offsetof(struct linux_dirent, d_name) + namelen + 1;
}
[ Making things doubly sad, the size shouldn't even be *used* in sane
situations, because the user access validity is often checked by only
checking the beginning,
The x86-64 __access_ok() does actually do that optimization, but
only if we can statically see that the thing is smaller than one page,
which in this case it can't, because while namelen is range checked,
it is allowed to be up to PATH_MAX in size, so even if the compiler
does do the full value range analysis, we'd need to relax that
__access_ok() check a bit more ]
Hmm? Can you do at least that dirent_size() kind of cleanup?
Linus