linux-toolchains.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: Is adding an argument to an existing syscall okay?
       [not found] <CALCETrXU2KcH0nsH_vd-fmvpZt_yW2+=VnYtN_BQJ6xsSvm+6A@mail.gmail.com>
@ 2020-11-17 17:16 ` Florian Weimer
  2020-11-17 18:36   ` Segher Boessenkool
  0 siblings, 1 reply; 7+ messages in thread
From: Florian Weimer @ 2020-11-17 17:16 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Linux API, Peter Oskolkov, Mathieu Desnoyers, Peter Zijlstra,
	linux-toolchains

* Andy Lutomirski:

> Linux 5.10 contains this patch:
>
> commit 2a36ab717e8fe678d98f81c14a0b124712719840
> Author: Peter Oskolkov <posk@google.com>
> Date:   Wed Sep 23 16:36:16 2020 -0700
>
>     rseq/membarrier: Add MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ
>
> This adds an argument to an existing syscall.  Before the patch,
> membarrier had 2 parameters; now it has 3.  Is this really okay?  At
> least the patch is careful and ignores the third parameter unless a
> previously unused flag bit is set.

It's really iffy.  It's hard to break this in system call wrappers on
x86-64, where we just load %eax and call into the kernel.  But on
architectures which require argument shuffling, it will break.

If there were a system call wrapper in glibc (my patch was rejected
due to lack of documentation fo the semantics, so we got lucky there),
we'd have to add a new symbol version for this.  It happened before in
the dark ages, repeatedly, but it's a bit disappointing to be in this
situation again.

In general the main problem I see is the poor source code
compatibility.  We really, really don't want variadic system call
wrappers, and we specifically do not want to introduce them
retroactively.  (Changing an implementation from non-variadic to
variadic is not an ABI-safe change on POWER and probably other
targets.)  So we'd require that from now on, the programmer has to
pass the zero argument explicitly.  Porting is simpler than the recent
futex_time64 breakage, but the downside is that immediately impacts
all targets.

Cc: linux-toolchains for ABI impact.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is adding an argument to an existing syscall okay?
  2020-11-17 17:16 ` Is adding an argument to an existing syscall okay? Florian Weimer
@ 2020-11-17 18:36   ` Segher Boessenkool
  2020-11-17 18:44     ` Florian Weimer
  0 siblings, 1 reply; 7+ messages in thread
From: Segher Boessenkool @ 2020-11-17 18:36 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Andy Lutomirski, Linux API, Peter Oskolkov, Mathieu Desnoyers,
	Peter Zijlstra, linux-toolchains

On Tue, Nov 17, 2020 at 06:16:28PM +0100, Florian Weimer wrote:
> * Andy Lutomirski:
> 
> > Linux 5.10 contains this patch:
> >
> > commit 2a36ab717e8fe678d98f81c14a0b124712719840
> > Author: Peter Oskolkov <posk@google.com>
> > Date:   Wed Sep 23 16:36:16 2020 -0700
> >
> >     rseq/membarrier: Add MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ
> >
> > This adds an argument to an existing syscall.  Before the patch,
> > membarrier had 2 parameters; now it has 3.  Is this really okay?  At
> > least the patch is careful and ignores the third parameter unless a
> > previously unused flag bit is set.
> 
> It's really iffy.  It's hard to break this in system call wrappers on
> x86-64, where we just load %eax and call into the kernel.  But on
> architectures which require argument shuffling, it will break.
> 
> If there were a system call wrapper in glibc (my patch was rejected
> due to lack of documentation fo the semantics, so we got lucky there),
> we'd have to add a new symbol version for this.  It happened before in
> the dark ages, repeatedly, but it's a bit disappointing to be in this
> situation again.
> 
> In general the main problem I see is the poor source code
> compatibility.  We really, really don't want variadic system call
> wrappers, and we specifically do not want to introduce them
> retroactively.  (Changing an implementation from non-variadic to
> variadic is not an ABI-safe change on POWER and probably other
> targets.)

But this isn't variadic in the sense of "..." -- on Power that always
passes the unspecified arguments in memory, while in this case it just
passes in either two or three registers.  I don't know any arg where
that would not work, given the Linux system call restrictions.

This is similar to the "open" system call.

> So we'd require that from now on, the programmer has to
> pass the zero argument explicitly.  Porting is simpler than the recent
> futex_time64 breakage, but the downside is that immediately impacts
> all targets.
> 
> Cc: linux-toolchains for ABI impact.

It certainly would simplify matters if this was simply not done ;-)


Segher

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is adding an argument to an existing syscall okay?
  2020-11-17 18:36   ` Segher Boessenkool
@ 2020-11-17 18:44     ` Florian Weimer
  2020-11-17 18:58       ` Peter Oskolkov
  0 siblings, 1 reply; 7+ messages in thread
From: Florian Weimer @ 2020-11-17 18:44 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Andy Lutomirski, Linux API, Peter Oskolkov, Mathieu Desnoyers,
	Peter Zijlstra, linux-toolchains

* Segher Boessenkool:

> But this isn't variadic in the sense of "..." -- on Power that always
> passes the unspecified arguments in memory, while in this case it just
> passes in either two or three registers.  I don't know any arg where
> that would not work, given the Linux system call restrictions.
>
> This is similar to the "open" system call.

Exactly.  You cannot call the open function through a non-variadic
function pointer.  I've seen it cause stack corruption in practice:

commit c7774174beffe9a8d29dd4fb38bbed43ece1cecd
Author: Andreas Schneider <asn@samba.org>
Date:   Wed Aug 2 13:21:59 2017 +0200

    swrap: Fix prototype of open[64] to prevent segfault on ppc64le
    
    The calling conventions for vaarg are different on ppc64le. The patch
    fixes segfaults on that platform.
    
    Thanks to Florian Weimer who helped debugging it!
    
    Signed-off-by: Andreas Schneider <asn@samba.org>
    Reviewed-by: Stefan Metzmacher <metze@samba.org>

<https://git.samba.org/?p=socket_wrapper.git;a=commitdiff;h=c7774174beffe>

It is possible to implement the open function in such a way that it
does not have this problem (simply do not use the parameter save area,
using assembler if necessary), but it's another obscure step that libc
implementers would have to take.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is adding an argument to an existing syscall okay?
  2020-11-17 18:44     ` Florian Weimer
@ 2020-11-17 18:58       ` Peter Oskolkov
  2020-11-17 19:21         ` Mathieu Desnoyers
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Oskolkov @ 2020-11-17 18:58 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Segher Boessenkool, Andy Lutomirski, Linux API,
	Mathieu Desnoyers, Peter Zijlstra, linux-toolchains

My assumption here was that applications that are aware of the new API
will always provide three parameters, while older applications will
continue calling the syscall with two.

I can't think of a situation/architecture where this will break anything.

Thanks,
Peter


On Tue, Nov 17, 2020 at 10:44 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>
> * Segher Boessenkool:
>
> > But this isn't variadic in the sense of "..." -- on Power that always
> > passes the unspecified arguments in memory, while in this case it just
> > passes in either two or three registers.  I don't know any arg where
> > that would not work, given the Linux system call restrictions.
> >
> > This is similar to the "open" system call.
>
> Exactly.  You cannot call the open function through a non-variadic
> function pointer.  I've seen it cause stack corruption in practice:
>
> commit c7774174beffe9a8d29dd4fb38bbed43ece1cecd
> Author: Andreas Schneider <asn@samba.org>
> Date:   Wed Aug 2 13:21:59 2017 +0200
>
>     swrap: Fix prototype of open[64] to prevent segfault on ppc64le
>
>     The calling conventions for vaarg are different on ppc64le. The patch
>     fixes segfaults on that platform.
>
>     Thanks to Florian Weimer who helped debugging it!
>
>     Signed-off-by: Andreas Schneider <asn@samba.org>
>     Reviewed-by: Stefan Metzmacher <metze@samba.org>
>
> <https://git.samba.org/?p=socket_wrapper.git;a=commitdiff;h=c7774174beffe>
>
> It is possible to implement the open function in such a way that it
> does not have this problem (simply do not use the parameter save area,
> using assembler if necessary), but it's another obscure step that libc
> implementers would have to take.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is adding an argument to an existing syscall okay?
  2020-11-17 18:58       ` Peter Oskolkov
@ 2020-11-17 19:21         ` Mathieu Desnoyers
  2020-11-17 19:32           ` Peter Oskolkov
  2020-11-17 19:45           ` Florian Weimer
  0 siblings, 2 replies; 7+ messages in thread
From: Mathieu Desnoyers @ 2020-11-17 19:21 UTC (permalink / raw)
  To: Peter Oskolkov
  Cc: Florian Weimer, Segher Boessenkool, Andy Lutomirski, linux-api,
	Peter Zijlstra, linux-toolchains

----- On Nov 17, 2020, at 1:58 PM, Peter Oskolkov posk@google.com wrote:

> My assumption here was that applications that are aware of the new API
> will always provide three parameters, while older applications will
> continue calling the syscall with two.
> 
> I can't think of a situation/architecture where this will break anything.

I think what Florian refers to here is if there would be a glibc library
wrapper exposing the system call to applications. There, the number of
arguments would matter. But it does not exist today.

In some sense, it's a good thing that there isn't such wrapper exposed
yet. It also makes me wonder whether exposing system calls directly as a
library ABI is a good thing. It appears that library ABIs have stronger
restrictions with respect to number and types of parameters than system
calls.

Thanks,

Mathieu

> 
> Thanks,
> Peter
> 
> 
> On Tue, Nov 17, 2020 at 10:44 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>>
>> * Segher Boessenkool:
>>
>> > But this isn't variadic in the sense of "..." -- on Power that always
>> > passes the unspecified arguments in memory, while in this case it just
>> > passes in either two or three registers.  I don't know any arg where
>> > that would not work, given the Linux system call restrictions.
>> >
>> > This is similar to the "open" system call.
>>
>> Exactly.  You cannot call the open function through a non-variadic
>> function pointer.  I've seen it cause stack corruption in practice:
>>
>> commit c7774174beffe9a8d29dd4fb38bbed43ece1cecd
>> Author: Andreas Schneider <asn@samba.org>
>> Date:   Wed Aug 2 13:21:59 2017 +0200
>>
>>     swrap: Fix prototype of open[64] to prevent segfault on ppc64le
>>
>>     The calling conventions for vaarg are different on ppc64le. The patch
>>     fixes segfaults on that platform.
>>
>>     Thanks to Florian Weimer who helped debugging it!
>>
>>     Signed-off-by: Andreas Schneider <asn@samba.org>
>>     Reviewed-by: Stefan Metzmacher <metze@samba.org>
>>
>> <https://git.samba.org/?p=socket_wrapper.git;a=commitdiff;h=c7774174beffe>
>>
>> It is possible to implement the open function in such a way that it
>> does not have this problem (simply do not use the parameter save area,
>> using assembler if necessary), but it's another obscure step that libc
> > implementers would have to take.

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is adding an argument to an existing syscall okay?
  2020-11-17 19:21         ` Mathieu Desnoyers
@ 2020-11-17 19:32           ` Peter Oskolkov
  2020-11-17 19:45           ` Florian Weimer
  1 sibling, 0 replies; 7+ messages in thread
From: Peter Oskolkov @ 2020-11-17 19:32 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Florian Weimer, Segher Boessenkool, Andy Lutomirski, linux-api,
	Peter Zijlstra, linux-toolchains

On Tue, Nov 17, 2020 at 11:21 AM Mathieu Desnoyers
<mathieu.desnoyers@efficios.com> wrote:
>
> ----- On Nov 17, 2020, at 1:58 PM, Peter Oskolkov posk@google.com wrote:
>
> > My assumption here was that applications that are aware of the new API
> > will always provide three parameters, while older applications will
> > continue calling the syscall with two.
> >
> > I can't think of a situation/architecture where this will break anything.
>
> I think what Florian refers to here is if there would be a glibc library
> wrapper exposing the system call to applications. There, the number of
> arguments would matter. But it does not exist today.
>
> In some sense, it's a good thing that there isn't such wrapper exposed
> yet. It also makes me wonder whether exposing system calls directly as a
> library ABI is a good thing. It appears that library ABIs have stronger
> restrictions with respect to number and types of parameters than system
> calls.

Technically, a library that exposes membarrier() with two parameters
can just add membarrier_ex() or whatever with three parameters, not
breaking anything. From the final user perspective, this would look exactly
as if we added a new syscall membarrier_ex.

So the question becomes whether it is better to add a new syscall and a new
library function, or just add another parameter to the existing
syscall, and a new
library function, and the answer to this question is more about policy
than about
technical merits of the two approaches.

I have no comments on policy matters here - this is up to maintainers. :)

Thanks,
Peter

[...]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Is adding an argument to an existing syscall okay?
  2020-11-17 19:21         ` Mathieu Desnoyers
  2020-11-17 19:32           ` Peter Oskolkov
@ 2020-11-17 19:45           ` Florian Weimer
  1 sibling, 0 replies; 7+ messages in thread
From: Florian Weimer @ 2020-11-17 19:45 UTC (permalink / raw)
  To: Mathieu Desnoyers
  Cc: Peter Oskolkov, Segher Boessenkool, Andy Lutomirski, linux-api,
	Peter Zijlstra, linux-toolchains

* Mathieu Desnoyers:

> In some sense, it's a good thing that there isn't such wrapper exposed
> yet. It also makes me wonder whether exposing system calls directly as a
> library ABI is a good thing. It appears that library ABIs have stronger
> restrictions with respect to number and types of parameters than system
> calls.

The generic syscall wrapper function cannot be used to call all system
calls on several architectures (e.g., if the kernel ABI has long as 64
bits, userspace has 32 bits, and the syscall function is *required* to
return a long value, not long long).  It may also be difficult to get
the argument promotion correctly.  _time64-only architectures have
source code impact even if time is not actually used in the call.  And
so on.

A wrapper-less approach is possible, I think, even with C.  But I do
not think that userspace source code portability without wrappers has
been a concern for system call design so far.  It's a very constrained
space already, so I'm not sure if it's a good idea to add further
rules.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-11-17 19:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CALCETrXU2KcH0nsH_vd-fmvpZt_yW2+=VnYtN_BQJ6xsSvm+6A@mail.gmail.com>
2020-11-17 17:16 ` Is adding an argument to an existing syscall okay? Florian Weimer
2020-11-17 18:36   ` Segher Boessenkool
2020-11-17 18:44     ` Florian Weimer
2020-11-17 18:58       ` Peter Oskolkov
2020-11-17 19:21         ` Mathieu Desnoyers
2020-11-17 19:32           ` Peter Oskolkov
2020-11-17 19:45           ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).