diff mbox series

[v2] Add public function syscall_no_errno

Message ID 20240208152224.11031-2-safinaskar@zohomail.com
State New
Headers show
Series [v2] Add public function syscall_no_errno | expand

Commit Message

Askar Safin Feb. 8, 2024, 3:02 p.m. UTC
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

Comments

Szabolcs Nagy Feb. 8, 2024, 5:48 p.m. UTC | #1
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.
Florian Weimer Feb. 12, 2024, 2:24 p.m. UTC | #2
* 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
Rich Felker Feb. 12, 2024, 2:44 p.m. UTC | #3
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
Askar Safin Feb. 12, 2024, 4:16 p.m. UTC | #4
---- 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
Zack Weinberg Feb. 12, 2024, 5:25 p.m. UTC | #5
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
Andreas Schwab Feb. 12, 2024, 5:43 p.m. UTC | #6
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.
Adhemerval Zanella Netto Feb. 12, 2024, 5:55 p.m. UTC | #7
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
Zack Weinberg Feb. 12, 2024, 6:22 p.m. UTC | #8
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
Askar Safin Feb. 12, 2024, 6:34 p.m. UTC | #9
---- 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
Andreas Schwab Feb. 13, 2024, 9:10 a.m. UTC | #10
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.
Adhemerval Zanella Netto Feb. 13, 2024, 11:57 a.m. UTC | #11
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.
diff mbox series

Patch

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