Re: [PATCH 1/2] uaccess: Simplify code pattern for masked user copies

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 9 Feb 2025 09:40:05 -0800
Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:

> On Sun, 9 Feb 2025 at 02:56, David Laight <david.laight.linux@xxxxxxxxx> wrote:
> >
> > Code can then be changed:
> > -               if (!user_read_access_begin(from, sizeof(*from)))
> > +               if (!masked_user_read_access_begin(&from, sizeof(*from)))
> >                         return -EFAULT;  
> 
> I really dislike the use of "pass pointer to simple variable you are
> going to change" interfaces which is why I didn't do it this way.

For real functions they do generate horrid code.
But since this is a define the *&from is optimised away.
Definitely better than just passing 'from' and having it unexpectedly
changed (why did C++ allow that one?).

> It's actually one of my least favorite parts of C - and one of the
> things that Rust got right - because the whole "error separate from
> return value" is such an important thing for graceful error handling.

Especially since the ABI almost always let a register pair be returned.
Shame it can't be used for anything other than double-length integers.

> And it's also why we use error pointers in the kernel: because I
> really *hated* all the cases where people were returning separate
> errors and results. The kernel error pointer thing may seem obvious
> and natural to people now, but it was a fairly big change at the time.

I've a lurking plan to change getsockopt() to return error/length and
move all the user copies into the syscall wrapper.
Made more complicated by code that wants to return an error and a length.
(They'll probably need packing into a single value that is negative - so
that the decode is in the slow path.)

> I'd actually much prefer the "goto efault" model that
> "unsafe_get/put_user()" uses than passing in the other return value
> with a pointer.
> 
> I wish we had a good error handling model.
> 
> Not the async crap that is exceptions with try/catch (or
> setjmp/longjmp - the horror). Just nice synchronous error handling
> that doesn't require the whole "hide return value as a in-out
> argument".
> 
> I know people think 'goto' and labels are bad. But I seriously think
> they are better and more legible constructs than the 'return value in
> arguments'.

I've had to fix some 'day-job' code which had repeated 'if (!error)'
clauses to avoid early return (never mind goto).
Typically at least one path got the error handling wrong.
At least explicit 'return error' or 'goto return_error' are easy
to validate.

> 
> Yes, you can make spaghetti code with goto and labels. But 'return
> value in arguments' is worse, because it makes the *data flow* harder
> to see.

Hidden returns are a real nightmare - you can't even guess whether any
locking (etc) is done.
At least hidden goto are visible.

Let me see if I can to a 'hidden goto' version.

	David

> 
>           Linus





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux