Fwd: EINTR for fsync(2)

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

 



Forgot to send this to the mailing list.

---------- Forwarded message ---------
From: Mathnerd314 <mathnerd314.gph@xxxxxxxxx>
Date: Thu, Feb 3, 2022 at 10:27 AM
Subject: Re: EINTR for fsync(2)
To: Matthew Wilcox <willy@xxxxxxxxxxxxx>


On Tue, Feb 1, 2022 at 1:32 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
>
> On Tue, Feb 01, 2022 at 12:56:51PM -0700, Mathnerd314 wrote:
> > On Mon, Jan 31, 2022 at 5:30 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
> > > So while it's worth adding EINTR to the man page, I don't think it's
> > > worth going through an exercise of trying to add every possible
> > > errno to every syscall.
> >
> > It's true that POSIX's error list is purely a guideline. But that
> > doesn't mean Linux can't specify the precise set of possible error
> > codes. There are currently 133 error codes defined, across an equally
> > large number of syscalls - coding defensively and handling every
> > combination is impossible. Not to mention that the meaning of the
> > error codes differs from syscall to syscall. But with precise
> > information there are likely only 5-10 codes per syscall, so handling
> > every error appropriately is feasible. So the information can be quite
> > useful.
>
> Ahahahaha.  For one, every filesystem gets to return its own errors.
> So basically any syscall that takes an fd gets to return all the errors
> that any of our 50+ filesystems decides to use.

Right. This is where static analysis would help, allowing an audit of
all the error codes returned by filesystems.
The simple approximation `git grep -ho '\-E[A-Z]*' fs | sort -u | wc
-l` = 142 suggests all error codes are in use by filesystem APIs.

>
> Then there are the interposers.  Things like seccomp, Linux Security
> Modules, and other such hooks which might return their own errors.

Here the situation is much better, replacing fs with security in the
command above gives only 56 error codes.

I guess the static analysis might need some help tracing through the
syscall -> function pointer call -> security call indirection, and
similarly for the vfs indirection.

>
> On top of that there's error injection, which might allow eBPF to
> return any error that userspace has deemed appropriate from basically
> any function.

You're right, it is possible: https://github.com/trailofbits/ebpfault.
But the point of error injection is to increase reliability against
real errors, so injecting an error that a syscall couldn't possibly
return would be really dumb.
I think a note in the syscall(2) man pages that "eBPF overrides allow
any syscall to return any error code" is sufficient.

>
> Further, you generally don't execute syscalls.  You call glibc, which
> might decide to return its own errors, not even bothering to call
> the kernel.

I don't think glibc modifies the error codes it gets from the kernel.
And Go and Zig don't use glibc for syscalls, so they definitely use
unmodified error codes.

If glibc doesn't call the kernel, then it's a glibc thing, not
relevant at all to this discussion.

>
> But the real problem is that the kernel might decide to return new
> errors at any time.  Just because you exhaustively handled every error
> that could have occurred in 5.15 doesn't mean that there might not be
> an error returned by 5.20.

The ABI stability guarantee for syscalls
(https://www.kernel.org/doc/Documentation/ABI/stable/syscalls) says
that interface will be added to and not have things removed from it.
This is kind of vague but the way I interpret it is that if a syscall
returns a certain error code in a specific situation, then it's always
going to return that error code. So for example open() could only
return a new error code if it was a new filesystem or a new flag - the
ext4 open() codes are frozen at this point.
So assuming that, new errors have very few places to show up
unexpectedly in the ABI.

>
> This isn't even an Herculean task.  This is Sisyphean, and you'll
> probably feel like Prometheus by the end of it.  I mean, you'd learn a
> lot by attempting it, but you'd be better off picking a task that would
> actually help people.

Zig inspired me because it converts all unrecognized error codes to
"unexpected error":
https://github.com/ziglang/zig/blob/5210b9074ca68c23da474b0afcaa4ce11f7cc57c/lib/std/os.zig#L4979
I like the approach, but it does seem Zig is missing a few 100 possible errors.

I've opened a Zig bug with your line of reasoning:
https://github.com/ziglang/zig/issues/10776

-- Mathnerd314



[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux