public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH, RFC] Add public function syscall_no_errno
@ 2024-01-28 16:39 Askar Safin
  2024-02-01 17:53 ` Adhemerval Zanella Netto
  2024-02-07  1:57 ` Mike Frysinger
  0 siblings, 2 replies; 23+ messages in thread
From: Askar Safin @ 2024-01-28 16:39 UTC (permalink / raw)
  To: libc-alpha; +Cc: carlos

Hi! I want glibc to have function "syscall_no_errno" on Linux.
It should do the same "syscall" does, but it should not interpret
return value and set errno. This is useful for calling syscalls
such as getuid. I. e. now the user can call directly all syscalls
including getuid and similar.

I add example patch. It is quick-and-dirty. I was unable to figure out
how to add function to headers. So, please, don't apply it as-is.

I just want to know do you agree with my proposal. If yes, I will try
to write better patch.

I will repeat: currently glibc is simply incomplete, because it
does not provide a way to call directly syscalls, such as getuid.
So the user have to craft assembly, which is very difficult.

The patch is against current master, i. e. ae49a7b29acc184b03c2a6bd6ac01b5e08efd54f

--

diff --git a/misc/Versions b/misc/Versions
index d5b348e8..ad37a4c2 100644
--- a/misc/Versions
+++ b/misc/Versions
@@ -71,7 +71,7 @@ libc {
     # s*
     sbrk; select; setdomainname; setfsent; sethostent; sethostid; sethostname;
     setlogmask; setmntent; setregid; setreuid; setttyent; setusershell; sstk;
-    stty; sync; syscall; syslog;
+    stty; sync; syscall; syslog; syscall_no_errno;
 
     # t*
     tdelete; tfind; truncate; tsearch; ttyslot; twalk;
diff --git a/posix/unistd.h b/posix/unistd.h
index 54d7d752..2f0f6e79 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -1089,6 +1089,7 @@ extern void *sbrk (intptr_t __delta) __THROW;
    In Mach, all system calls take normal arguments and always return an
    error code (zero for success).  */
 extern long int syscall (long int __sysno, ...) __THROW;
+extern long int syscall_no_errno (long int __sysno, ...) __THROW;
 
 #endif	/* Use misc.  */
 
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index aac065e7..dac4d78e 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -612,6 +612,7 @@ sys_epoll_create
 sys_epoll_ctl
 sys_epoll_wait
 syscall
+syscall_no_errno
 sysfs
 sysinfo
 syslog
diff --git a/sysdeps/unix/sysv/linux/syscall.c b/sysdeps/unix/sysv/linux/syscall.c
index 3cff1d97..481b18a4 100644
--- a/sysdeps/unix/sysv/linux/syscall.c
+++ b/sysdeps/unix/sysv/linux/syscall.c
@@ -41,3 +41,20 @@ syscall (long int number, ...)
     }
   return r;
 }
+long int
+syscall_no_errno (long int number, ...)
+{
+  va_list args;
+
+  va_start (args, number);
+  long int a0 = va_arg (args, long int);
+  long int a1 = va_arg (args, long int);
+  long int a2 = va_arg (args, long int);
+  long int a3 = va_arg (args, long int);
+  long int a4 = va_arg (args, long int);
+  long int a5 = va_arg (args, long int);
+  va_end (args);
+
+  long int r = INTERNAL_SYSCALL_NCS_CALL (number, a0, a1, a2, a3, a4, a5);
+  return r;
+}
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index aea7848e..55d9dadd 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1761,6 +1761,7 @@ GLIBC_2.2.5 sys_nerr D 0x4
 GLIBC_2.2.5 sys_sigabbrev D 0x200
 GLIBC_2.2.5 sys_siglist D 0x200
 GLIBC_2.2.5 syscall F
+GLIBC_2.2.5 syscall_no_errno F
 GLIBC_2.2.5 sysconf F
 GLIBC_2.2.5 sysctl F
 GLIBC_2.2.5 sysinfo F
diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S
index 43af8087..04483251 100644
--- a/sysdeps/unix/sysv/linux/x86_64/syscall.S
+++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S
@@ -26,6 +26,18 @@
 
 
 	.text
+ENTRY (syscall_no_errno)
+	movq %rdi, %rax		/* Syscall number -> rax.  */
+	movq %rsi, %rdi		/* shift arg1 - arg5.  */
+	movq %rdx, %rsi
+	movq %rcx, %rdx
+	movq %r8, %r10
+	movq %r9, %r8
+	movq 8(%rsp),%r9	/* arg6 is on the stack.  */
+	syscall			/* Do the system call.  */
+	ret			/* Return to caller.  */
+
+PSEUDO_END_NOERRNO (syscall_no_errno)
 ENTRY (syscall)
 	movq %rdi, %rax		/* Syscall number -> rax.  */
 	movq %rsi, %rdi		/* shift arg1 - arg5.  */

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-01-28 16:39 [PATCH, RFC] Add public function syscall_no_errno Askar Safin
@ 2024-02-01 17:53 ` Adhemerval Zanella Netto
  2024-02-01 18:18   ` Rich Felker
  2024-02-01 19:32   ` Askar Safin
  2024-02-07  1:57 ` Mike Frysinger
  1 sibling, 2 replies; 23+ messages in thread
From: Adhemerval Zanella Netto @ 2024-02-01 17:53 UTC (permalink / raw)
  To: Askar Safin, libc-alpha, Rich Felker; +Cc: carlos



On 28/01/24 13:39, Askar Safin wrote:
> Hi! I want glibc to have function "syscall_no_errno" on Linux.
> It should do the same "syscall" does, but it should not interpret
> return value and set errno. This is useful for calling syscalls
> such as getuid. I. e. now the user can call directly all syscalls
> including getuid and similar.
> 
> I add example patch. It is quick-and-dirty. I was unable to figure out
> how to add function to headers. So, please, don't apply it as-is.
> 
> I just want to know do you agree with my proposal. If yes, I will try
> to write better patch.
> 
> I will repeat: currently glibc is simply incomplete, because it
> does not provide a way to call directly syscalls, such as getuid.
> So the user have to craft assembly, which is very difficult.

Indeed there some old syscalls where trying to issue them directly with
syscall is problematic (like 'time' and 'brk' for some ABIs), but getuid
is not one of them.  Also, recent Linux kABI is trying to avoid such 
problematic interfaces to return the value as the return code and make
the invalid value similar to all cases.  So these are not very compeling
reason to add a non-standard symbol to issue syscalls.

CCing Rich, maybe he has a different view about this.

> 
> The patch is against current master, i. e. ae49a7b29acc184b03c2a6bd6ac01b5e08efd54f
> 
> --
> 
> diff --git a/misc/Versions b/misc/Versions
> index d5b348e8..ad37a4c2 100644
> --- a/misc/Versions
> +++ b/misc/Versions
> @@ -71,7 +71,7 @@ libc {
>      # s*
>      sbrk; select; setdomainname; setfsent; sethostent; sethostid; sethostname;
>      setlogmask; setmntent; setregid; setreuid; setttyent; setusershell; sstk;
> -    stty; sync; syscall; syslog;
> +    stty; sync; syscall; syslog; syscall_no_errno;
>  
>      # t*
>      tdelete; tfind; truncate; tsearch; ttyslot; twalk;
> diff --git a/posix/unistd.h b/posix/unistd.h
> index 54d7d752..2f0f6e79 100644
> --- a/posix/unistd.h
> +++ b/posix/unistd.h
> @@ -1089,6 +1089,7 @@ extern void *sbrk (intptr_t __delta) __THROW;
>     In Mach, all system calls take normal arguments and always return an
>     error code (zero for success).  */
>  extern long int syscall (long int __sysno, ...) __THROW;
> +extern long int syscall_no_errno (long int __sysno, ...) __THROW;
>  
>  #endif	/* Use misc.  */
>  
> diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
> index aac065e7..dac4d78e 100644
> --- a/sysdeps/unix/sysv/linux/syscall-names.list
> +++ b/sysdeps/unix/sysv/linux/syscall-names.list
> @@ -612,6 +612,7 @@ sys_epoll_create
>  sys_epoll_ctl
>  sys_epoll_wait
>  syscall
> +syscall_no_errno
>  sysfs
>  sysinfo
>  syslog
> diff --git a/sysdeps/unix/sysv/linux/syscall.c b/sysdeps/unix/sysv/linux/syscall.c
> index 3cff1d97..481b18a4 100644
> --- a/sysdeps/unix/sysv/linux/syscall.c
> +++ b/sysdeps/unix/sysv/linux/syscall.c
> @@ -41,3 +41,20 @@ syscall (long int number, ...)
>      }
>    return r;
>  }
> +long int
> +syscall_no_errno (long int number, ...)
> +{
> +  va_list args;
> +
> +  va_start (args, number);
> +  long int a0 = va_arg (args, long int);
> +  long int a1 = va_arg (args, long int);
> +  long int a2 = va_arg (args, long int);
> +  long int a3 = va_arg (args, long int);
> +  long int a4 = va_arg (args, long int);
> +  long int a5 = va_arg (args, long int);
> +  va_end (args);
> +
> +  long int r = INTERNAL_SYSCALL_NCS_CALL (number, a0, a1, a2, a3, a4, a5);
> +  return r;
> +}
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index aea7848e..55d9dadd 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -1761,6 +1761,7 @@ GLIBC_2.2.5 sys_nerr D 0x4
>  GLIBC_2.2.5 sys_sigabbrev D 0x200
>  GLIBC_2.2.5 sys_siglist D 0x200
>  GLIBC_2.2.5 syscall F
> +GLIBC_2.2.5 syscall_no_errno F
>  GLIBC_2.2.5 sysconf F
>  GLIBC_2.2.5 sysctl F
>  GLIBC_2.2.5 sysinfo F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S
> index 43af8087..04483251 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/syscall.S
> +++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S
> @@ -26,6 +26,18 @@
>  
>  
>  	.text
> +ENTRY (syscall_no_errno)
> +	movq %rdi, %rax		/* Syscall number -> rax.  */
> +	movq %rsi, %rdi		/* shift arg1 - arg5.  */
> +	movq %rdx, %rsi
> +	movq %rcx, %rdx
> +	movq %r8, %r10
> +	movq %r9, %r8
> +	movq 8(%rsp),%r9	/* arg6 is on the stack.  */
> +	syscall			/* Do the system call.  */
> +	ret			/* Return to caller.  */
> +
> +PSEUDO_END_NOERRNO (syscall_no_errno)
>  ENTRY (syscall)
>  	movq %rdi, %rax		/* Syscall number -> rax.  */
>  	movq %rsi, %rdi		/* shift arg1 - arg5.  */

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-01 17:53 ` Adhemerval Zanella Netto
@ 2024-02-01 18:18   ` Rich Felker
  2024-02-01 19:32   ` Askar Safin
  1 sibling, 0 replies; 23+ messages in thread
From: Rich Felker @ 2024-02-01 18:18 UTC (permalink / raw)
  To: Adhemerval Zanella Netto; +Cc: Askar Safin, libc-alpha, carlos

On Thu, Feb 01, 2024 at 02:53:44PM -0300, Adhemerval Zanella Netto wrote:
> 
> 
> On 28/01/24 13:39, Askar Safin wrote:
> > Hi! I want glibc to have function "syscall_no_errno" on Linux.
> > It should do the same "syscall" does, but it should not interpret
> > return value and set errno. This is useful for calling syscalls
> > such as getuid. I. e. now the user can call directly all syscalls
> > including getuid and similar.
> > 
> > I add example patch. It is quick-and-dirty. I was unable to figure out
> > how to add function to headers. So, please, don't apply it as-is.
> > 
> > I just want to know do you agree with my proposal. If yes, I will try
> > to write better patch.
> > 
> > I will repeat: currently glibc is simply incomplete, because it
> > does not provide a way to call directly syscalls, such as getuid.
> > So the user have to craft assembly, which is very difficult.
> 
> Indeed there some old syscalls where trying to issue them directly with
> syscall is problematic (like 'time' and 'brk' for some ABIs), but getuid
> is not one of them.  Also, recent Linux kABI is trying to avoid such 
> problematic interfaces to return the value as the return code and make
> the invalid value similar to all cases.  So these are not very compeling
> reason to add a non-standard symbol to issue syscalls.
> 
> CCing Rich, maybe he has a different view about this.

That would be my view too. In general, it's rarely useful to make a
raw syscall() to begin with. For the majority of syscalls that are
ingredients in implementing standard or almost-standard functions
provided by libc, going around libc to call it directly risks creating
inconsistent state (brk), having inconsistent types (stat, etc.),
missing fallback cases (direct use of time64 syscalls), etc. and
really should not be encouraged by making unneeded new ways to do it.
Indeed the only syscalls I'm aware of for which there's ambiguity
about the result are of this sort.

I don't even think brk is an affected one; values >=4095UL are not
valid brk boundaries. Similarly, I don't think Linux supports setting
system clock to before the epoch (and doing so would not be accurate
anyway), so time is arguably not affected either. Even if it were,
it's superseded by clock_gettime or gettimeofday, which don't have the
problem, and might not even be available on future archs.

There is also fcntl with F_GETOWN, which was not mentioned above, but
it is superseded by F_GETOWN_EX, which the libc fcntl function
automatically uses when available instead of using F_GETOWN directly.
So I don't think it has modern relevance either.

In any case, back to my original point, the use case for syscall()
should be seen as calling newly-added extensions that don't yet have,
or that aren't suitable to have, libc functions for them. Use of it as
a means to "poke behind libc" should not be encouraged, as that tends
to break things. If someone really wants to write code that's
independent of libc -- like to run in a vforked child or CLONE_VM
context or something without a valid thread pointer/TLS state/etc. --
it can't be using libc at all, and that includes the libc syscall()
function (which not only may write errno, but might inspect TLS to
determine how to make the syscall). For this level of "raw" syscall
access, you need to write your own asm.

Rich

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-01 17:53 ` Adhemerval Zanella Netto
  2024-02-01 18:18   ` Rich Felker
@ 2024-02-01 19:32   ` Askar Safin
  2024-02-01 20:16     ` dalias
  1 sibling, 1 reply; 23+ messages in thread
From: Askar Safin @ 2024-02-01 19:32 UTC (permalink / raw)
  To: Adhemerval Zanella Netto, dalias; +Cc: libc-alpha, carlos

Hi, Rich and Adhemerval!

 ---- On Thu, 01 Feb 2024 21:53:44 +0400  Adhemerval Zanella Netto  wrote --- 
 > Indeed there some old syscalls where trying to issue them directly with
 > syscall is problematic (like 'time' and 'brk' for some ABIs), but getuid
 > is not one of them.
It *is* one of them!

Keep in mind that Linux supports 32-bit uids.

Run this code as root as 32-bit i386 binary (my letter continues after code). It is okay to run it on 64-bit amd64 kernel, you just have to make sure the binary itself is compiled as i386
=*=*=*=*=
#if !defined(__i386__)
#error
#endif

#include <stdint.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>

int
main (void)
{
  // 4294967286 is (2^32)-10
  uint32_t a = 4294967286U;
  if (syscall (SYS_setuid32, a) == -1)
    {
      perror("setuid");
      return 1;
    }

  uint32_t b = syscall (SYS_getuid32);

  // Now b is equal to (uint32_t)-1 instead of wanted 4294967286 (i. e. (uint32_t)-10)
  printf("%u (wanted)\n", a);
  printf("%u (got)\n", b);
  return 0;
}
=*=*=*=*=

(Also, when I said "getuid", I meant "SYS_getuid32".)

I see this output:
=*=*=*=*=
4294967286 (wanted)
4294967295 (got)
=*=*=*=*=

So, yes, function "syscall" is incompatible with SYS_getuid32.

I'm nearly sure the same is true about getpid.

Rich:
> If someone really wants to write code that's
> independent of libc -- like to run in a vforked child or CLONE_VM

This is another use case I want to support. I. e. I want to
have portable function (i. e. independent of arch) for issuing
syscall in such case. And I don't
want to write assembly.

> but might inspect TLS to
> determine how to make the syscall

Okay, so syscall_no_errno should not do this. I. e. it should
always do some way to make syscall, which always works,
even if it is slow. For i386 it is "int 0x80" as well as I understand.

Also, even if we read TLS to determine how to make syscall,
what will go wrong? Child shares TLS with its parent after CLONE_VM,
so we simply will read parent's TLS

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-01 19:32   ` Askar Safin
@ 2024-02-01 20:16     ` dalias
  2024-02-01 20:57       ` Adhemerval Zanella Netto
  2024-02-07  0:59       ` [PATCH, RFC] " Askar Safin
  0 siblings, 2 replies; 23+ messages in thread
From: dalias @ 2024-02-01 20:16 UTC (permalink / raw)
  To: Askar Safin; +Cc: Adhemerval Zanella Netto, libc-alpha, carlos

On Thu, Feb 01, 2024 at 11:32:41PM +0400, Askar Safin wrote:
> Hi, Rich and Adhemerval!
> 
>  ---- On Thu, 01 Feb 2024 21:53:44 +0400  Adhemerval Zanella Netto  wrote --- 
>  > Indeed there some old syscalls where trying to issue them directly with
>  > syscall is problematic (like 'time' and 'brk' for some ABIs), but getuid
>  > is not one of them.
> It *is* one of them!
> 
> Keep in mind that Linux supports 32-bit uids.
> 
> Run this code as root as 32-bit i386 binary (my letter continues
> after code). It is okay to run it on 64-bit amd64 kernel, you just
> have to make sure the binary itself is compiled as i386
> =*=*=*=*=
> #if !defined(__i386__)
> #error
> #endif
> 
> #include <stdint.h>
> #include <stdio.h>
> #include <sys/syscall.h>
> #include <unistd.h>
> 
> int
> main (void)
> {
>   // 4294967286 is (2^32)-10
>   uint32_t a = 4294967286U;
>   if (syscall (SYS_setuid32, a) == -1)
>     {
>       perror("setuid");
>       return 1;
>     }
> 
>   uint32_t b = syscall (SYS_getuid32);
> 
>   // Now b is equal to (uint32_t)-1 instead of wanted 4294967286 (i. e. (uint32_t)-10)
>   printf("%u (wanted)\n", a);
>   printf("%u (got)\n", b);
>   return 0;
> }
> =*=*=*=*=
> 
> (Also, when I said "getuid", I meant "SYS_getuid32".)
> 
> I see this output:
> =*=*=*=*=
> 4294967286 (wanted)
> 4294967295 (got)
> =*=*=*=*=
> 
> So, yes, function "syscall" is incompatible with SYS_getuid32.

OK, but this falls under "poking around behind libc's back". If you
call getuid() you'll find you get the right answer (at least on musl;
not sure about glibc).

> I'm nearly sure the same is true about getpid.

It's not. PIDs are a 29- or 30-bit space (which is a matter of a bug I
currently have open) on Linux. At least the high two bits are banned
from ever being usable as a consequence of the futex interface.

> Rich:
> > If someone really wants to write code that's
> > independent of libc -- like to run in a vforked child or CLONE_VM
> 
> This is another use case I want to support. I. e. I want to
> have portable function (i. e. independent of arch) for issuing
> syscall in such case. And I don't
> want to write assembly.

Well that's not something syscall() gives you and it's not something
syscall_no_errno() would reliably give you either unless it was
specifically documented to be callable from such a context. If that's
what you want, maybe that's what should be discussed.

> > but might inspect TLS to
> > determine how to make the syscall
> 
> Okay, so syscall_no_errno should not do this. I. e. it should
> always do some way to make syscall, which always works,
> even if it is slow. For i386 it is "int 0x80" as well as I understand.
> 
> Also, even if we read TLS to determine how to make syscall,
> what will go wrong? Child shares TLS with its parent after CLONE_VM,
> so we simply will read parent's TLS

At least on glibc, you can pass clone flags that setup a new thread
pointer in the child, which you may be intending to use for your own
purposes in 'bare, no libc' code in the child. On musl this is not
possible; the flags are rejected and you have to write your own asm to
call clone if you want that.

In any case, "what will go wrong?" is not the right question. The
question is whether there's a contract for the thing you want to do to
work, and there isn't.

Rich

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-01 20:16     ` dalias
@ 2024-02-01 20:57       ` Adhemerval Zanella Netto
  2024-02-08 15:02         ` [PATCH v2] " Askar Safin
  2024-02-07  0:59       ` [PATCH, RFC] " Askar Safin
  1 sibling, 1 reply; 23+ messages in thread
From: Adhemerval Zanella Netto @ 2024-02-01 20:57 UTC (permalink / raw)
  To: dalias, Askar Safin; +Cc: libc-alpha, carlos



On 01/02/24 17:16, dalias wrote:
> On Thu, Feb 01, 2024 at 11:32:41PM +0400, Askar Safin wrote:
>> Hi, Rich and Adhemerval!
>>
>>  ---- On Thu, 01 Feb 2024 21:53:44 +0400  Adhemerval Zanella Netto  wrote --- 
>>  > Indeed there some old syscalls where trying to issue them directly with
>>  > syscall is problematic (like 'time' and 'brk' for some ABIs), but getuid
>>  > is not one of them.
>> It *is* one of them!
>>
>> Keep in mind that Linux supports 32-bit uids.
>>
>> Run this code as root as 32-bit i386 binary (my letter continues
>> after code). It is okay to run it on 64-bit amd64 kernel, you just
>> have to make sure the binary itself is compiled as i386
>> =*=*=*=*=
>> #if !defined(__i386__)
>> #error
>> #endif
>>
>> #include <stdint.h>
>> #include <stdio.h>
>> #include <sys/syscall.h>
>> #include <unistd.h>
>>
>> int
>> main (void)
>> {
>>   // 4294967286 is (2^32)-10
>>   uint32_t a = 4294967286U;
>>   if (syscall (SYS_setuid32, a) == -1)
>>     {
>>       perror("setuid");
>>       return 1;
>>     }
>>
>>   uint32_t b = syscall (SYS_getuid32);
>>
>>   // Now b is equal to (uint32_t)-1 instead of wanted 4294967286 (i. e. (uint32_t)-10)
>>   printf("%u (wanted)\n", a);
>>   printf("%u (got)\n", b);
>>   return 0;
>> }
>> =*=*=*=*=
>>
>> (Also, when I said "getuid", I meant "SYS_getuid32".)
>>
>> I see this output:
>> =*=*=*=*=
>> 4294967286 (wanted)
>> 4294967295 (got)
>> =*=*=*=*=
>>
>> So, yes, function "syscall" is incompatible with SYS_getuid32.
> 
> OK, but this falls under "poking around behind libc's back". If you
> call getuid() you'll find you get the right answer (at least on musl;
> not sure about glibc).

It works as expected on glibc as well.

> 
>> I'm nearly sure the same is true about getpid.
> 
> It's not. PIDs are a 29- or 30-bit space (which is a matter of a bug I
> currently have open) on Linux. At least the high two bits are banned
> from ever being usable as a consequence of the futex interface.
> 
>> Rich:
>>> If someone really wants to write code that's
>>> independent of libc -- like to run in a vforked child or CLONE_VM
>>
>> This is another use case I want to support. I. e. I want to
>> have portable function (i. e. independent of arch) for issuing
>> syscall in such case. And I don't
>> want to write assembly.
> 
> Well that's not something syscall() gives you and it's not something
> syscall_no_errno() would reliably give you either unless it was
> specifically documented to be callable from such a context. If that's
> what you want, maybe that's what should be discussed.

There is another potential issue where you have multiple syscall
with slight different kABI (like the ones that have 64 bit arguments
on 32 bit architectures) and, at least for glibc, where the user
exported argument does not really match the kernel (stat/fstat/etc.).

> 
>>> but might inspect TLS to
>>> determine how to make the syscall
>>
>> Okay, so syscall_no_errno should not do this. I. e. it should
>> always do some way to make syscall, which always works,
>> even if it is slow. For i386 it is "int 0x80" as well as I understand.
>>
>> Also, even if we read TLS to determine how to make syscall,
>> what will go wrong? Child shares TLS with its parent after CLONE_VM,
>> so we simply will read parent's TLS
> 
> At least on glibc, you can pass clone flags that setup a new thread
> pointer in the child, which you may be intending to use for your own
> purposes in 'bare, no libc' code in the child. On musl this is not
> possible; the flags are rejected and you have to write your own asm to
> call clone if you want that.
> 
> In any case, "what will go wrong?" is not the right question. The
> question is whether there's a contract for the thing you want to do to
> work, and there isn't.

And I am not very found of this possible slight different contract for
a non-standard interface.  

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-01 20:16     ` dalias
  2024-02-01 20:57       ` Adhemerval Zanella Netto
@ 2024-02-07  0:59       ` Askar Safin
  2024-02-07 20:59         ` dalias
  1 sibling, 1 reply; 23+ messages in thread
From: Askar Safin @ 2024-02-07  0:59 UTC (permalink / raw)
  To: dalias, Adhemerval Zanella Netto; +Cc: libc-alpha, carlos

Hi, Rich and Adhemerval!

 ---- On Fri, 02 Feb 2024 00:16:26 +0400  dalias  wrote --- 
 > OK, but this falls under "poking around behind libc's back".

Function "syscall" exists in glibc. So it is assumed to be useful.
Thus it is okay to have "syscall_no_errno", too. "syscall" in
its current form has a problem: you cannot correctly call
SYS_getuid32. Thus there is need for "syscall_no_errno".

So I will write next version of my patch. I hope in several days,
when I have time.
"syscall_no_errno" will be simple wrapper for "INTERNAL_SYSCALL_NCS_CALL".

 > Well that's not something syscall() gives you and it's not something
 > syscall_no_errno() would reliably give you either unless it was
 > specifically documented to be callable from such a context. If that's
 > what you want, maybe that's what should be discussed.

I did some research. I have read all places where glibc calls "clone".
And I see that in all these places if CLONE_VM specified, then
CLONE_SETTLS or CLONE_VFORK is specified.

In fact, there is 2 places only, where glibc calls clone (in Linux x86_64).

One is implementation of pthread_create. We pass CLONE_VM and
CLONE_SETTLS. Thus (as well as I understand) TLS is set up
in child right from the beginning.
There is no time gap, when TLS is not initialized yet.

Second place is implementation of posix_spawn. We pass CLONE_VM
and CLONE_VFORK. CLONE_VFORK means that parent is suspended,
and thus it is okay to access its TLS.

Thus glibc absolutely always (even internally!) maintains invariant
"TLS is safe to access". I. e. glibc itself does not need a way to perform
syscalls when TLS is not set up.

Thus if I want syscall_no_errno to provide such guarantee, this will
be absolutely unique guarantee, which is not needed even by
glibc authors themselves. So I think this will be very hard to provide it,
and benefits will be small.

Yes, small time gap when TLS is not initialized, still exists. Before "main".
But in this case we have one thread only, so everything is simple.

For all these reasons I think that guarantee "you may call syscall_no_errno
even after clone(CLONE_VM) without CLONE_VFORK and
without CLONE_SETTLS" should not be provided.

(Correct me if I wrong.)

So I go back to my original proposal: add function, which will be able to
call directly syscalls, such as SYS_getuid32.

Adhemerval Zanella Netto:
> There is another potential issue where you have multiple syscall
> with slight different kABI

In fact my original use case is so: I want to parse true kernel ABI
from files /sys/kernel/debug/tracing/events/syscalls/sys_enter_*/format
and then generate a library based on the ABI.

Such library will provide syscall wrappers with correct types. These
wrappers will call functions "syscall" and "syscall_no_errno".

(In fact, this will be Rust library, not C one, but I don't think
this is important for our discussion. You may say: "Then why
you want to add syscall_no_errno to upstream glibc?"
Well, because I want it to be available to everyone. To Rust
programmers, to C programmers and to everyone else.
Without the need to write assembly.)

So, I will read proper kernel ABI from /sys/kernel/..., so
I will get ABI right.

> at least for glibc, where the user
> exported argument does not really match the kernel (stat/fstat/etc.).

I will use Linux headers, so all will be okay.
(Well, correction: I will use Rust's crate "linux-raw-sys",
which is based on Linux headers.)

You may say: "Well, I still think you should find Rust library,
which does what you want, and stop bothering upstream glibc".
I will answer: I don't trust Rust libs! Yes, there exist multiple
Rust crates, which provide something similar to syscall_no_errno.

They are implemented using hand-coded assembly.
Why should I trust that they got this assembly correct?

On the other hand, glibc already has high quality
INTERNAL_SYSCALL_NCS_CALL, which I trust. It is
more likely to be correct, than all these buggy Rust crates.

We just need to export it. So I propose to export simple
wrapper for INTERNAL_SYSCALL_NCS_CALL called
"syscall_no_errno". And everybody will use it. C devs,
Rust devs, etc. Big benefits for everybody. For low
cost on glibc side.

Also, I have a question. It seems that function "syscall"
uses TLS and nothing else. This means that it is okay to
call it in a child, created using "clone", assuming that one
of these holds:
- We didn't specify CLONE_VM
- We specified CLONE_VM and CLONE_VFORK (thus parent
is suspended and it is okay to use its TLS)

So may I also write a patch for documentation, which will
document this guarantee? It surely already holds, because
glibc uses it in implementation of posix_spawn. I just
want to document it, and this will mean that now it
will hold in the future.

Moreover, such guarantee holds if we call clone using this code
without specifiying new stack:

if (syscall(SYS_clone, ...) == 0){ /* we are in child */ }

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-01-28 16:39 [PATCH, RFC] Add public function syscall_no_errno Askar Safin
  2024-02-01 17:53 ` Adhemerval Zanella Netto
@ 2024-02-07  1:57 ` Mike Frysinger
  2024-02-07 12:55   ` Askar Safin
  1 sibling, 1 reply; 23+ messages in thread
From: Mike Frysinger @ 2024-02-07  1:57 UTC (permalink / raw)
  To: Askar Safin; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 98 bytes --]

sounds like you want this project:
https://chromium.googlesource.com/linux-syscall-support/
-mike

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-07  1:57 ` Mike Frysinger
@ 2024-02-07 12:55   ` Askar Safin
  0 siblings, 0 replies; 23+ messages in thread
From: Askar Safin @ 2024-02-07 12:55 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: libc-alpha, dalias, adhemervalzanella, Carlos

 ---- On Wed, 07 Feb 2024 05:57:49 +0400  Mike Frysinger  wrote --- 
 > sounds like you want this project:
 > https://chromium.googlesource.com/linux-syscall-support/

This project has exactly the problem I'm talking abort! Exactly problem
I'm trying to fix using syscall_no_errno!

linux-syscall-support always unconditionally checks syscall result and sets
errno based on it:

https://chromium.googlesource.com/linux-syscall-support/+/ed31caa60f20a4f6569883b2d752ef7522de51e0/linux_syscall_support.h#2175

You can verify that this happens in all code paths by carefully reading the
source. Fortunately, the project doesn't provide "getuid" at all. I think
this is because authors aware of the problem.

Also, the project is simply buggy. Look at this (my!) commit:

https://chromium.googlesource.com/linux-syscall-support/+/e1e7b0ad8ee99a875b272c8e33e308472e897660

If I didn't notice this bug and didn't fix it, the bug would stay forever!

So, after my expirence with this project I conclude: I don't trust such projects. I. e. small
project claiming to support performing direct syscalls. I don't trust C libraries
for this purpose and I don't trust Rust libraries for this purpose.
The only libraries I trust are glibc and musl. But both don't export
anything like syscall_no_errno. And this is what I'm trying
to change.

I'm aware of existance of "nolibc" project inside Linux source tree.
But (based on my expirence with linux-syscall-support) I don't trust it,
either.

But... well, I *will* trust some of these projects if I carefully read sources.

So, yes, I can fix problem for me personally: just carefully read sources of
linux-syscall-support and use it! Or some similar C or Rust library.

Moreover: my task is even simpler! The only architectures I want to support
in my project are x86_64 and i386. So I can simply copy needed assembly
from glibc sources and all will be done!

But I'm not trying to fix the problem for me personally. I want to fix it
for everyone! I want anyone to be able just to use universally available
trusted function from glibc. Without the need for assembly or
third party projects such as linux-syscall-support.

glibc already provides "syscall", thus it should provide "syscall_no_errno", too!


Askar Safin
https://types.pl/@safinaskar


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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-07  0:59       ` [PATCH, RFC] " Askar Safin
@ 2024-02-07 20:59         ` dalias
  2024-02-08 17:08           ` Askar Safin
  0 siblings, 1 reply; 23+ messages in thread
From: dalias @ 2024-02-07 20:59 UTC (permalink / raw)
  To: Askar Safin; +Cc: Adhemerval Zanella Netto, libc-alpha, carlos

On Wed, Feb 07, 2024 at 04:59:54AM +0400, Askar Safin wrote:
> Hi, Rich and Adhemerval!
> 
>  ---- On Fri, 02 Feb 2024 00:16:26 +0400  dalias  wrote --- 
>  > OK, but this falls under "poking around behind libc's back".
> 
> Function "syscall" exists in glibc. So it is assumed to be useful.
> Thus it is okay to have "syscall_no_errno", too. "syscall" in
> its current form has a problem: you cannot correctly call
> SYS_getuid32. Thus there is need for "syscall_no_errno".
> 
> So I will write next version of my patch. I hope in several days,
> when I have time.
> "syscall_no_errno" will be simple wrapper for "INTERNAL_SYSCALL_NCS_CALL".
> 
>  > Well that's not something syscall() gives you and it's not something
>  > syscall_no_errno() would reliably give you either unless it was
>  > specifically documented to be callable from such a context. If that's
>  > what you want, maybe that's what should be discussed.
> 
> I did some research. I have read all places where glibc calls "clone".
> And I see that in all these places if CLONE_VM specified, then
> CLONE_SETTLS or CLONE_VFORK is specified.
> 
> In fact, there is 2 places only, where glibc calls clone (in Linux x86_64).
> 
> One is implementation of pthread_create. We pass CLONE_VM and
> CLONE_SETTLS. Thus (as well as I understand) TLS is set up
> in child right from the beginning.
> There is no time gap, when TLS is not initialized yet.
> 
> Second place is implementation of posix_spawn. We pass CLONE_VM
> and CLONE_VFORK. CLONE_VFORK means that parent is suspended,
> and thus it is okay to access its TLS.
> 
> Thus glibc absolutely always (even internally!) maintains invariant
> "TLS is safe to access". I. e. glibc itself does not need a way to perform
> syscalls when TLS is not set up.

You're missing the point. Of course glibc maintains that invariant
because it's providing a consistent platform to applications. If you
have application code that uses clone() itself, it may not be meeting
those invariants necessary to be able to call into libc.

> In fact my original use case is so: I want to parse true kernel ABI
> from files /sys/kernel/debug/tracing/events/syscalls/sys_enter_*/format
> and then generate a library based on the ABI.
> 
> Such library will provide syscall wrappers with correct types. These
> wrappers will call functions "syscall" and "syscall_no_errno".
> 
> (In fact, this will be Rust library, not C one, but I don't think
> this is important for our discussion. You may say: "Then why
> you want to add syscall_no_errno to upstream glibc?"
> Well, because I want it to be available to everyone. To Rust
> programmers, to C programmers and to everyone else.
> Without the need to write assembly.)
> 
> So, I will read proper kernel ABI from /sys/kernel/..., so
> I will get ABI right.

Can you clarify *why* you want to do that? Making raw syscalls like
this is ill-advised and *will* run into mismatched ABI for certain
types (where the kernel and user types differ), poor compatibility
with kernel versions that aren't the same you expected, time64 issues
on 32-bit archs, etc.

Based on our conversations in this thread, I do not think you're
prepared to handle all that right. It most certainly cannot be handled
in an automated way by parsing the data you have in mind; doing it
right requires knowing semantic relationships between syscalls.

It sounds like you plan to hand Rust programmers a big footgun.

Rich

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

* [PATCH v2] Add public function syscall_no_errno
  2024-02-01 20:57       ` Adhemerval Zanella Netto
@ 2024-02-08 15:02         ` Askar Safin
  2024-02-08 17:48           ` Szabolcs Nagy
  2024-02-12 14:24           ` Florian Weimer
  0 siblings, 2 replies; 23+ messages in thread
From: Askar Safin @ 2024-02-08 15:02 UTC (permalink / raw)
  To: libc-alpha, adhemerval.zanella, carlos; +Cc: dalias

Add public function syscall_no_errno. Linux-specific. It is the same as syscall,
but it doesn't interpret value, returned by Linux. So it is
okay for issuing syscalls, such as SYS_getuid. Example:

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>

int
main ()
{
  long int rc;
  rc = syscall_no_errno(SYS_getuid);
  printf("uid = %ld\n", rc);
}

---

This is second version of my patch. This time I did everything right.
I. e. this is not quick-and-dirty patch, this is patch ready
for inclusion in glibc.

My code works for all Linux archs. The patch includes docs.

You can see motivation in my previous letters in this thread.

Let me quickly repeat my main argument: glibc in its current
form is incomplete. It contains "syscall", but it will not
work with SYS_getuid32 on i386. Thus we need "syscall_no_errno"

 NEWS                                          |  2 +
 manual/startup.texi                           | 39 ++++++++++++++++++-
 sysdeps/unix/sysv/linux/Makefile              |  1 +
 sysdeps/unix/sysv/linux/Versions              |  3 ++
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |  1 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist    |  1 +
 sysdeps/unix/sysv/linux/arc/libc.abilist      |  1 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist   |  1 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist   |  1 +
 sysdeps/unix/sysv/linux/bits/unistd_ext.h     |  4 ++
 sysdeps/unix/sysv/linux/csky/libc.abilist     |  1 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |  1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |  1 +
 .../sysv/linux/loongarch/lp64/libc.abilist    |  1 +
 .../sysv/linux/m68k/coldfire/libc.abilist     |  1 +
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |  1 +
 .../sysv/linux/microblaze/be/libc.abilist     |  1 +
 .../sysv/linux/microblaze/le/libc.abilist     |  1 +
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |  1 +
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |  1 +
 .../sysv/linux/mips/mips64/n32/libc.abilist   |  1 +
 .../sysv/linux/mips/mips64/n64/libc.abilist   |  1 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist    |  1 +
 sysdeps/unix/sysv/linux/or1k/libc.abilist     |  1 +
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |  1 +
 .../powerpc/powerpc32/nofpu/libc.abilist      |  1 +
 .../linux/powerpc/powerpc64/be/libc.abilist   |  1 +
 .../linux/powerpc/powerpc64/le/libc.abilist   |  1 +
 .../unix/sysv/linux/riscv/rv32/libc.abilist   |  1 +
 .../unix/sysv/linux/riscv/rv64/libc.abilist   |  1 +
 .../unix/sysv/linux/s390/s390-32/libc.abilist |  1 +
 .../unix/sysv/linux/s390/s390-64/libc.abilist |  1 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist    |  1 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist    |  1 +
 .../sysv/linux/sparc/sparc32/libc.abilist     |  1 +
 .../sysv/linux/sparc/sparc64/libc.abilist     |  1 +
 sysdeps/unix/sysv/linux/syscall_no_errno.c    | 38 ++++++++++++++++++
 .../unix/sysv/linux/x86_64/64/libc.abilist    |  1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |  1 +
 39 files changed, 118 insertions(+), 2 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/syscall_no_errno.c

diff --git a/NEWS b/NEWS
index 2d8eaffc58..98b8064cc5 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,8 @@ Major new features:
   by _GNU_SOURCE, or by compiling with the GCC options -std=c23,
   -std=gnu23, -std=c2x or -std=gnu2x.
 
+* On Linux, the function syscall_no_errno have been added.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/manual/startup.texi b/manual/startup.texi
index 9bf24123f5..59893232a9 100644
--- a/manual/startup.texi
+++ b/manual/startup.texi
@@ -713,7 +713,7 @@ library source code as a specification of the interface between them
 anyway.
 
 
-@code{syscall} is declared in @file{unistd.h}.
+@code{syscall} and @code{syscall_no_errno} are declared in @file{unistd.h}.
 
 @deftypefun {long int} syscall (long int @var{sysno}, @dots{})
 @standards{???, unistd.h}
@@ -735,7 +735,11 @@ the right are ignored.
 The return value is the return value from the system call, unless the
 system call failed.  In that case, @code{syscall} returns @code{-1} and
 sets @code{errno} to an error code that the system call returned.  Note
-that system calls do not return @code{-1} when they succeed.
+that system calls do not return @code{-1} when they succeed (there is
+an exception here: few Linux syscalls, such as @code{SYS_getuid32} on i386
+may return @code{-1}, when no error happened; so do not pass @code{SYS_getuid32}
+to @code{syscall} on Linux; you should use @code{syscall_no_errno} instead,
+which is described below).
 @cindex errno
 
 If you specify an invalid @var{sysno}, @code{syscall} returns @code{-1}
@@ -781,6 +785,37 @@ if (rc == -1)
 
 @end deftypefun
 
+@deftypefun {long int} syscall_no_errno (long int @var{sysno}, @dots{})
+@standards{GNU, unistd.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+@code{syscall_no_errno} is Linux-specific GNU extension. It does the same
+as @code{syscall}, but does not interpret return value, returned by Linux
+kernel, and doesn't set @code{errno}. This makes @code{syscall_no_errno}
+suitable for performing Linux syscalls, which never fail, such as
+@code{SYS_getuid}.
+
+Example:
+
+@smallexample
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+@dots{}
+
+long int rc;
+
+rc = syscall_no_errno(SYS_getuid);
+
+printf("uid = %ld\n", rc);
+
+@end smallexample
+
+@end deftypefun
+
 
 @node Program Termination
 @section Program Termination
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 415aa1f14d..3be40dd0fc 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -100,6 +100,7 @@ sysdep_routines += \
   setvmaname \
   signalfd \
   splice \
+  syscall_no_errno \
   sysctl \
   tee \
   timerfd_gettime \
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 268ba1b6ac..398b2d31be 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -328,6 +328,9 @@ libc {
     posix_spawnattr_getcgroup_np;
     posix_spawnattr_setcgroup_np;
   }
+  GLIBC_2.40 {
+    syscall_no_errno;
+  }
   GLIBC_PRIVATE {
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 68eeca1c08..b2760fb686 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2748,3 +2748,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 34c187b721..7592e1f71f 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -3095,6 +3095,7 @@ GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 916c18ea94..63d39ebc3b 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2509,3 +2509,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index ea95de282a..c5081bdec9 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -2801,6 +2801,7 @@ GLIBC_2.4 xdrstdio_create F
 GLIBC_2.4 xencrypt F
 GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 1cdbc983e1..90d3181cbb 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -2798,6 +2798,7 @@ GLIBC_2.4 xdrstdio_create F
 GLIBC_2.4 xencrypt F
 GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
index 2ce1d45138..a5149b0c4c 100644
--- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h
+++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
@@ -47,4 +47,8 @@ extern __pid_t gettid (void) __THROW;
 # define CLOSE_RANGE_CLOEXEC (1U << 2)
 #endif
 
+/* Same as syscall, but doesn't try to interpret raw return value.
+   Never sets errno.  */
+extern long int syscall_no_errno (long int __sysno, ...) __THROW;
+
 #endif /* __USE_GNU  */
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 96d45961e2..76d8df8616 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2785,3 +2785,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index fbcd60c2b3..1abdb4ccf9 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2821,6 +2821,7 @@ GLIBC_2.4 sys_errlist D 0x400
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index c989b433c0..9cafcd4ca8 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -3005,6 +3005,7 @@ GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
index 0023ec1fa1..b5151baeaf 100644
--- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
@@ -2269,3 +2269,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index d9bd6a9b56..0d6972747c 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -2781,6 +2781,7 @@ GLIBC_2.4 xdrstdio_create F
 GLIBC_2.4 xencrypt F
 GLIBC_2.4 xprt_register F
 GLIBC_2.4 xprt_unregister F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 439796d693..5d55addb44 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2948,6 +2948,7 @@ GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 1069d3252c..fb460f8223 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2834,3 +2834,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 17abe08c8b..d5e271ad23 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2831,3 +2831,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 799e508950..bdd852481a 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2909,6 +2909,7 @@ GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 1c10996cbc..8d4ed14ad5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2907,6 +2907,7 @@ GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 03d9655f26..b15d38bcde 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2915,6 +2915,7 @@ GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 05e402ed30..0c2ddd1fa0 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2817,6 +2817,7 @@ GLIBC_2.4 renameat F
 GLIBC_2.4 symlinkat F
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 3aa81766aa..91d9e86823 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2873,3 +2873,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
index c40c843aaf..ff93694aa0 100644
--- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
+++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
@@ -2255,3 +2255,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 9714305608..0f6685a9e4 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -3138,6 +3138,7 @@ GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 0beb52c542..53450512e0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -3183,6 +3183,7 @@ GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index cfc2ebd3ec..121f8dd555 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2892,6 +2892,7 @@ GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 8c9efc5a16..8654cdf60c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2968,3 +2968,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index f90c94bc35..2f21912ce7 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2511,3 +2511,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index e04ff93bd2..f8f5952878 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2711,3 +2711,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a7467e2850..6c76ea2f04 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -3136,6 +3136,7 @@ GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index fd1cb2972d..8c16869b3f 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2929,6 +2929,7 @@ GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index ff6e6b1a13..1a6af130de 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2828,6 +2828,7 @@ GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 449d92bbc5..f2ce488fb2 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2825,6 +2825,7 @@ GLIBC_2.4 sys_errlist D 0x210
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index e615be759a..55d6df917a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -3157,6 +3157,7 @@ GLIBC_2.4 wcstold F
 GLIBC_2.4 wcstold_l F
 GLIBC_2.4 wprintf F
 GLIBC_2.4 wscanf F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index bd36431dd7..620efd5adf 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2793,6 +2793,7 @@ GLIBC_2.4 sys_errlist D 0x430
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/syscall_no_errno.c b/sysdeps/unix/sysv/linux/syscall_no_errno.c
new file mode 100644
index 0000000000..15aeb1c4c0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/syscall_no_errno.c
@@ -0,0 +1,38 @@
+/* syscall_no_errno - Same as syscall, but doesn't try to interpret
+   raw return value. Never sets errno.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdarg.h>
+#include <sysdep.h>
+
+long int
+syscall_no_errno (long int number, ...)
+{
+  va_list args;
+
+  va_start (args, number);
+  long int a0 = va_arg (args, long int);
+  long int a1 = va_arg (args, long int);
+  long int a2 = va_arg (args, long int);
+  long int a3 = va_arg (args, long int);
+  long int a4 = va_arg (args, long int);
+  long int a5 = va_arg (args, long int);
+  va_end (args);
+
+  return INTERNAL_SYSCALL_NCS_CALL (number, a0, a1, a2, a3, a4, a5);
+}
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index aea7848ed6..093348529a 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2744,6 +2744,7 @@ GLIBC_2.4 sys_errlist D 0x420
 GLIBC_2.4 sys_nerr D 0x4
 GLIBC_2.4 unlinkat F
 GLIBC_2.4 unshare F
+GLIBC_2.40 syscall_no_errno F
 GLIBC_2.5 __readlinkat_chk F
 GLIBC_2.5 inet6_opt_append F
 GLIBC_2.5 inet6_opt_find F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 4ab3681914..77ef1b678f 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2763,3 +2763,4 @@ GLIBC_2.39 stdc_trailing_zeros_ui F
 GLIBC_2.39 stdc_trailing_zeros_ul F
 GLIBC_2.39 stdc_trailing_zeros_ull F
 GLIBC_2.39 stdc_trailing_zeros_us F
+GLIBC_2.40 syscall_no_errno F
-- 
2.43.0


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

* Re: [PATCH, RFC] Add public function syscall_no_errno
  2024-02-07 20:59         ` dalias
@ 2024-02-08 17:08           ` Askar Safin
  0 siblings, 0 replies; 23+ messages in thread
From: Askar Safin @ 2024-02-08 17:08 UTC (permalink / raw)
  To: dalias; +Cc: Adhemerval Zanella Netto, libc-alpha, carlos

 ---- On Thu, 08 Feb 2024 00:59:02 +0400  dalias  wrote --- 
 > You're missing the point. Of course glibc maintains that invariant
 > because it's providing a consistent platform to applications. If you
 > have application code that uses clone() itself, it may not be meeting
 > those invariants necessary to be able to call into libc.

Let me try to explain in other way. I tried to understand what guarantees
of "syscall" and "syscall_no_errno" functions will be easy for glibc
maintainers to provide, and what will be hard. Let's begin with
guarantee "it is okay to call 'syscall_no_errno', when TLS is possibly not initialized
properly, for example in child created by clone(CLONE_VM)".
Such guarantee will be hard to provide, because it seems that it is not
provided currently. I. e. additional work will be needed to provide it.
It seems to be not provided, because glibc nearly never uses it.
glibc seems to never use it, because in glibc TLS is nearly always initialized.

Now let's consider another possible guarantee "it is okay to call
'syscall' and 'syscall_no_errno' in child created by clone(CLONE_VM | CLONE_VFORK)".
It will be easy to provide, because (as of current master) it is already provided,
but not documented. I see that it is provided, because I see that glibc internally
uses this guarantee. glibc uses it in spawn implementation. glibc creates
child in posix_spawn using CLONE_VM | CLONE_VFORK.
And then issues syscalls using something very close to "syscall".
So it is very easy to provide such guarantee. We just need to
document it. If it is broken, glibc developers will notice this,
because they depend on this guarantee in spawn implementation.

So I don't propose to add that guarantee about TLS. But I do propose to
add (i. e. to document) guarantee about CLONE_VM | CLONE_VFORK.

 > Can you clarify *why* you want to do that?

As I already told I want to write that Rust library.
I don't want to publish it. Just for personal use.
I need it to expirement with Linux. I. e. no any serious use.
Just a playground.

I want to have full control over what syscalls I issue.

And I want to send syscall_no_errno to upstream glibc (and
ideally to upstream musl, too), because other developers
may have similar needs. I. e. because they sometimes
want to have full control over syscalls they issue.

Currently, if someone wants to issue syscall, such as SYS_getuid32
on i386, they must either use assembly (which is hard to do right),
either use some third-party library.

But I don't trust third-party libraries, as I already told in this thread.
So I suggest other people not to use them. For example, there exists
https://chromium.googlesource.com/linux-syscall-support/ , which
is intended to be way to make raw syscalls. But as I said previously,
it doesn't provide way to call getuid, and also it had a bug, which was
not fixed until *I* noticed it.

So I propose to export battle-tested trusted glibc implementation
as a public symbol. And everyone will be able to use it.

 > Making raw syscalls like
 > this is ill-advised and *will* run into mismatched ABI for certain
 > types (where the kernel and user types differ)

It will not, because I will use Rust crate "linux-raw-sys", which is
based on Linux uapi headers, i. e. headers from dir "include/uapi"
from Linux source tree.

 > poor compatibility
 > with kernel versions that aren't the same you expected

What you mean? Newer kernel versions are ABI compatible
with older ones. And yes, if you write program for newer
kernel and try to run it on older, you may get some issues.
But the same applies to usual programs written with glibc
and musl. Yes, glibc and musl know how to fail back to
older syscalls. So, what? I can manually write such fail back
code if needed. Again: I'm aware of all these issues. Of course,
I know that issuing syscalls directly is harder than using libc
wrappers.

 > time64 issues
 > on 32-bit archs, etc.

As I said, I will use prototypes parsed from /sys/... with types
got from Linux uapi headers. This will remove all time64 and
similar problems. Yes, this will mean that I will have to manually
write fail back code, i. e. "try time64, if it fails, then do time32".
But I'm aware about this.

 > It most certainly cannot be handled
 > in an automated way by parsing the data you have in mind

As I said, it *can* be done it automated way. Just use prototypes
from /sys/... and type definitions from uapi headers.

Feel free to steal this idea and use it in musl. :)

Also you may consider this project https://syscalls.mebeim.net/ instead
of parsing /sys/... . They get prototypes from kernel ELF binary.

And, yes, I know that when I see, say, "pid_t" in /sys/... , this
really means __kernel_pid_t from uapi headers.

(Also I plan to parse files from strace project, such as this:
https://github.com/strace/strace/blob/eb6014c510d663938db331fef5ac4ef78fdcf583/src/linux/i386/syscallent.h .
Because they mark functions, which cannot fail, as "NF". So I will know
when I should check errors, and when not.)

Of course, this process will produce not-so-usable functions.
So I then will manually write for them wrappers. For example,
this process may automatically produce this Rust prototype for "write":

fn write(fd: c_int, buf: *const c_void, len: usize) -> Result<isize, Errno>

And then I will futher manually wrap it and will make something like this:

fn write(fd: c_int, buf: &[u8]) -> Result<usize, Errno>

And of course, all these functions will be marked as "unsafe". I have no plans
for creating safe (in Rust sense) interface for Linux syscalls.

I do not plan to publish code, but if you want, I can show it to you,
when it is ready.

 > doing it
 > right requires knowing semantic relationships between syscalls.

Knowing semantic relationship may be required if I want to
add extra type data not present in /sys/... . For example if I want
to have separated type for "int", which means file descriptor, and
for other "int"s. Yes, I know that this cannot be done in automated
way. Yes, I know that generated code will simply have "int"s everywhere
and I will have to write manual wrapper if I want something more type-safe.

Also semantic relationship may be needed if I want to present
safe interface (in Rust sense). I have no such plans.

--
Askar Safin
https://types.pl/@safinaskar

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-08 15:02         ` [PATCH v2] " Askar Safin
@ 2024-02-08 17:48           ` Szabolcs Nagy
  2024-02-12 14:24           ` Florian Weimer
  1 sibling, 0 replies; 23+ messages in thread
From: Szabolcs Nagy @ 2024-02-08 17:48 UTC (permalink / raw)
  To: Askar Safin, libc-alpha, adhemerval.zanella, carlos; +Cc: dalias

The 02/08/2024 18:02, Askar Safin wrote:
> Add public function syscall_no_errno. Linux-specific. It is the same as syscall,
> but it doesn't interpret value, returned by Linux. So it is
> okay for issuing syscalls, such as SYS_getuid. Example:
> 
> #define _GNU_SOURCE
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/syscall.h>
> 
> int
> main ()
> {
>   long int rc;
>   rc = syscall_no_errno(SYS_getuid);
>   printf("uid = %ld\n", rc);
> }
> 

the commit message has to explain why this is added
and how do we expect users to use this api.

it has to address why do we care about this use-case
more than the long list of other cases on linux that
don't work with the existing syscall api.

the patch needs tests for the new api.

i think the variadic nature of syscall and the libc vs
linux type differences are problematic enough that we
should discourage its use with or without errno.

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-08 15:02         ` [PATCH v2] " Askar Safin
  2024-02-08 17:48           ` Szabolcs Nagy
@ 2024-02-12 14:24           ` Florian Weimer
  2024-02-12 14:44             ` Rich Felker
  1 sibling, 1 reply; 23+ messages in thread
From: Florian Weimer @ 2024-02-12 14:24 UTC (permalink / raw)
  To: Askar Safin; +Cc: libc-alpha, adhemerval.zanella, carlos, dalias

* Askar Safin:

> +@code{syscall_no_errno} is Linux-specific GNU extension. It does the same
> +as @code{syscall}, but does not interpret return value, returned by Linux
> +kernel, and doesn't set @code{errno}. This makes @code{syscall_no_errno}
> +suitable for performing Linux syscalls, which never fail, such as
> +@code{SYS_getuid}.

Are there really any system calls which return a value in the range
-4095 to -1, and it's still considered a success?

Thanks,
Florian


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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 14:24           ` Florian Weimer
@ 2024-02-12 14:44             ` Rich Felker
  2024-02-12 16:16               ` Askar Safin
  0 siblings, 1 reply; 23+ messages in thread
From: Rich Felker @ 2024-02-12 14:44 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Askar Safin, libc-alpha, adhemerval.zanella, carlos

On Mon, Feb 12, 2024 at 03:24:52PM +0100, Florian Weimer wrote:
> * Askar Safin:
> 
> > +@code{syscall_no_errno} is Linux-specific GNU extension. It does the same
> > +as @code{syscall}, but does not interpret return value, returned by Linux
> > +kernel, and doesn't set @code{errno}. This makes @code{syscall_no_errno}
> > +suitable for performing Linux syscalls, which never fail, such as
> > +@code{SYS_getuid}.
> 
> Are there really any system calls which return a value in the range
> -4095 to -1, and it's still considered a success?

Yes, there are a very small number of such syscalls -- getuid and
getgid are the only relevant ones AFAICT -- but the author of this
proposal is missing the point. They want to avoid using libc, but then
have a libc function to make their raw syscalls for them, rather than
just doing that themselves. And apparently this function is supposed
to have an undocumented contract that you can call it from contexts
where calling other libc functions might not be valid..? Or not? It
was never really clarified.

They also seem to be under the mistaken impression that you can just
add arbitrary pet functions to libc as long as you follow some
procedures for doing it the right way, rather than understanding that
the maintainer's job is to say no, and that functions don't go in libc
unless there's some sort of consensus that they belong there.

Rich

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 14:44             ` Rich Felker
@ 2024-02-12 16:16               ` Askar Safin
  2024-02-12 17:25                 ` Zack Weinberg
  0 siblings, 1 reply; 23+ messages in thread
From: Askar Safin @ 2024-02-12 16:16 UTC (permalink / raw)
  To: Rich Felker; +Cc: Florian Weimer, libc-alpha, adhemerval.zanella, carlos

 ---- On Mon, 12 Feb 2024 18:44:31 +0400  Rich Felker  wrote --- 
 > Yes, there are a very small number of such syscalls -- getuid and
 > getgid are the only relevant ones AFAICT -- but the author of this
 > proposal is missing the point

Okay, I declare defeat
--
Askar Safin
https://types.pl/@safinaskar


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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 16:16               ` Askar Safin
@ 2024-02-12 17:25                 ` Zack Weinberg
  2024-02-12 17:43                   ` Andreas Schwab
                                     ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Zack Weinberg @ 2024-02-12 17:25 UTC (permalink / raw)
  To: Askar Safin; +Cc: GNU libc development

On Mon, Feb 12, 2024, at 11:16 AM, Askar Safin wrote:
> ---- On Mon, 12 Feb 2024 18:44:31 +0400  Rich Felker  wrote ---
>  > Yes, there are a very small number of such syscalls -- getuid and
>  > getgid are the only relevant ones AFAICT -- but the author of this
>  > proposal is missing the point
>
> Okay, I declare defeat

I have a question for you: Do glibc's existing getuid() and getgid()
functions correctly handle IDs in the [-4095, -1] range (perhaps better
described as the [4294963201, 4294967295] range) ?  It appears to me
from binary code inspection that they do -- here's the assembly dump of
getuid() on x86-64:

(gdb) disas getuid
Dump of assembler code for function __GI_getuid:
   0x00000000000cf940 <+0>:	mov    $0x66,%eax
   0x00000000000cf945 <+5>:	syscall
   0x00000000000cf947 <+7>:	ret
End of assembler dump.

But I am not having any luck figuring out what bit of glibc's *source*
code tells the syscall stub generator not to emit the code to check for
error returns for these syscalls, so it's plausible to me that there is
a bug in here somewhere, possibly only on lesser-used architectures.  If
you know of a case where we get this wrong, please tell us about it so
we can fix it.

zw

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 17:25                 ` Zack Weinberg
@ 2024-02-12 17:43                   ` Andreas Schwab
  2024-02-12 18:22                     ` Zack Weinberg
  2024-02-12 17:55                   ` Adhemerval Zanella Netto
  2024-02-12 18:34                   ` Askar Safin
  2 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2024-02-12 17:43 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: Askar Safin, GNU libc development

On Feb 12 2024, Zack Weinberg wrote:

> But I am not having any luck figuring out what bit of glibc's *source*
> code tells the syscall stub generator not to emit the code to check for
> error returns for these syscalls,

It's the E flag in the syscalls.list which sets SYSCALL_NOERRNO to
nonzero.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 17:25                 ` Zack Weinberg
  2024-02-12 17:43                   ` Andreas Schwab
@ 2024-02-12 17:55                   ` Adhemerval Zanella Netto
  2024-02-12 18:34                   ` Askar Safin
  2 siblings, 0 replies; 23+ messages in thread
From: Adhemerval Zanella Netto @ 2024-02-12 17:55 UTC (permalink / raw)
  To: libc-alpha



On 12/02/24 14:25, Zack Weinberg wrote:
> On Mon, Feb 12, 2024, at 11:16 AM, Askar Safin wrote:
>> ---- On Mon, 12 Feb 2024 18:44:31 +0400  Rich Felker  wrote ---
>>  > Yes, there are a very small number of such syscalls -- getuid and
>>  > getgid are the only relevant ones AFAICT -- but the author of this
>>  > proposal is missing the point
>>
>> Okay, I declare defeat
> 
> I have a question for you: Do glibc's existing getuid() and getgid()
> functions correctly handle IDs in the [-4095, -1] range (perhaps better
> described as the [4294963201, 4294967295] range) ?  It appears to me
> from binary code inspection that they do -- here's the assembly dump of
> getuid() on x86-64:
> 
> (gdb) disas getuid
> Dump of assembler code for function __GI_getuid:
>    0x00000000000cf940 <+0>:	mov    $0x66,%eax
>    0x00000000000cf945 <+5>:	syscall
>    0x00000000000cf947 <+7>:	ret
> End of assembler dump.

Afaiu this is not an issue for x86_64, or any other 64-bit architecture,
because uid_t/gid_t are exported as an uint32_t (__UID_T_TYPE/__U32_TYPE),
and the invalid return valid are in the range of [-4096UL,-1UL].

> 
> But I am not having any luck figuring out what bit of glibc's *source*
> code tells the syscall stub generator not to emit the code to check for
> error returns for these syscalls, so it's plausible to me that there is
> a bug in here somewhere, possibly only on lesser-used architectures.  If
> you know of a case where we get this wrong, please tell us about it so
> we can fix it.
> 
> zw

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 17:43                   ` Andreas Schwab
@ 2024-02-12 18:22                     ` Zack Weinberg
  2024-02-13  9:10                       ` Andreas Schwab
  0 siblings, 1 reply; 23+ messages in thread
From: Zack Weinberg @ 2024-02-12 18:22 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GNU libc development

On Mon, Feb 12, 2024, at 12:43 PM, Andreas Schwab wrote:
> On Feb 12 2024, Zack Weinberg wrote:
>
>> But I am not having any luck figuring out what bit of glibc's *source*
>> code tells the syscall stub generator not to emit the code to check for
>> error returns for these syscalls,
>
> It's the E flag in the syscalls.list which sets SYSCALL_NOERRNO to
> nonzero.

Ah, thank you. I didn't think to look above sysdeps/unix/sysv/linux for
the stub generator.

These system calls are consistently tagged with 'E' in all syscalls.list
files where they appear, and all of the non-syscalls.list implementations
also don't look for an error code or set errno (except for Hurd, which is
noted as a bug in the relevant files).  I believe this is correct for all
of them.

getegid
geteuid
getgid
getpgrp
getpid
getppid
gettid
getuid
umask

These system calls are *inconsistently* tagged with 'E'.

clock_gettime
personality
setfsgid
setfsuid

Based on the manpages, I believe clock_gettime and personality
should _not_ have the E tag, but setfsgid and setfsuid should.
I am not presently able to develop patches.

zw

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 17:25                 ` Zack Weinberg
  2024-02-12 17:43                   ` Andreas Schwab
  2024-02-12 17:55                   ` Adhemerval Zanella Netto
@ 2024-02-12 18:34                   ` Askar Safin
  2 siblings, 0 replies; 23+ messages in thread
From: Askar Safin @ 2024-02-12 18:34 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: GNU libc development

 ---- On Mon, 12 Feb 2024 21:25:27 +0400  Zack Weinberg  wrote --- 
 > I have a question for you: Do glibc's existing getuid() and getgid()
 > functions correctly handle IDs in the [-4095, -1] range (perhaps better
 > described as the [4294963201, 4294967295] range) ?

Yes.

 > here's the assembly dump of
 > getuid() on x86-64:

Even "incorrect" getuid implementation will work correctly on x86_64,
because uids are 32 bit on Linux. Whole this problem matters for 32-bit
architectures, not 64-bit ones.

 > But I am not having any luck figuring out what bit of glibc's *source*
 > code tells the syscall stub generator not to emit the code to check for
 > error returns for these syscalls, so it's plausible to me that there is
 > a bug in here somewhere, possibly only on lesser-used architectures.  If
 > you know of a case where we get this wrong, please tell us about it so
 > we can fix it.

getuid is defined in ./sysdeps/unix/sysv/linux/i386/syscalls.list (and similar
files). In 4th column we see "E". This means that getuid never fails and we
should pass raw syscall result to userspace.

"E" gets processed here:
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/make-syscalls.sh;h=4f6c3490a20bc3eb34f11f1e7aab0ddec7e82e5d;hb=155bb9d036646138348fee0ac045de601811e0c5#l169

Then here:
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/make-syscalls.sh;h=4f6c3490a20bc3eb34f11f1e7aab0ddec7e82e5d;hb=155bb9d036646138348fee0ac045de601811e0c5#l273

--
Askar Safin
https://types.pl/@safinaskar


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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-12 18:22                     ` Zack Weinberg
@ 2024-02-13  9:10                       ` Andreas Schwab
  2024-02-13 11:57                         ` Adhemerval Zanella Netto
  0 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2024-02-13  9:10 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: GNU libc development

On Feb 12 2024, Zack Weinberg wrote:

> These system calls are *inconsistently* tagged with 'E'.
>
> clock_gettime
> personality
> setfsgid
> setfsuid
>
> Based on the manpages, I believe clock_gettime and personality
> should _not_ have the E tag, but setfsgid and setfsuid should.

See commit e0043e17df for the history of the personality syscall.  The
clock_gettime entry is only for the internal __syscall_clock_gettime
call which deliberately does not want errno checking.  For setfs[gu]id
only archs using the setfs[gu]id32 syscall need the E flag.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: [PATCH v2] Add public function syscall_no_errno
  2024-02-13  9:10                       ` Andreas Schwab
@ 2024-02-13 11:57                         ` Adhemerval Zanella Netto
  0 siblings, 0 replies; 23+ messages in thread
From: Adhemerval Zanella Netto @ 2024-02-13 11:57 UTC (permalink / raw)
  To: Andreas Schwab, Zack Weinberg; +Cc: GNU libc development



On 13/02/24 06:10, Andreas Schwab wrote:
> On Feb 12 2024, Zack Weinberg wrote:
> 
>> These system calls are *inconsistently* tagged with 'E'.
>>
>> clock_gettime
>> personality
>> setfsgid
>> setfsuid
>>
>> Based on the manpages, I believe clock_gettime and personality
>> should _not_ have the E tag, but setfsgid and setfsuid should.
> 
> See commit e0043e17df for the history of the personality syscall.  The
> clock_gettime entry is only for the internal __syscall_clock_gettime
> call which deliberately does not want errno checking.  For setfs[gu]id
> only archs using the setfs[gu]id32 syscall need the E flag.
> 

And the __syscall_clock_gettime is not really used anywhere.

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

end of thread, other threads:[~2024-02-13 11:57 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-28 16:39 [PATCH, RFC] Add public function syscall_no_errno Askar Safin
2024-02-01 17:53 ` Adhemerval Zanella Netto
2024-02-01 18:18   ` Rich Felker
2024-02-01 19:32   ` Askar Safin
2024-02-01 20:16     ` dalias
2024-02-01 20:57       ` Adhemerval Zanella Netto
2024-02-08 15:02         ` [PATCH v2] " Askar Safin
2024-02-08 17:48           ` Szabolcs Nagy
2024-02-12 14:24           ` Florian Weimer
2024-02-12 14:44             ` Rich Felker
2024-02-12 16:16               ` Askar Safin
2024-02-12 17:25                 ` Zack Weinberg
2024-02-12 17:43                   ` Andreas Schwab
2024-02-12 18:22                     ` Zack Weinberg
2024-02-13  9:10                       ` Andreas Schwab
2024-02-13 11:57                         ` Adhemerval Zanella Netto
2024-02-12 17:55                   ` Adhemerval Zanella Netto
2024-02-12 18:34                   ` Askar Safin
2024-02-07  0:59       ` [PATCH, RFC] " Askar Safin
2024-02-07 20:59         ` dalias
2024-02-08 17:08           ` Askar Safin
2024-02-07  1:57 ` Mike Frysinger
2024-02-07 12:55   ` Askar Safin

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 read-only IMAP folder(s) and NNTP newsgroup(s).