public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH]  Linux: Add execveat system call wrapper
@ 2020-04-28 12:20 Alexandra Hájková
  2020-04-28 14:17 ` Florian Weimer
                   ` (13 more replies)
  0 siblings, 14 replies; 46+ messages in thread
From: Alexandra Hájková @ 2020-04-28 12:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

---
 sysdeps/mach/hurd/i386/libc.abilist           |  1 +
 sysdeps/unix/sysv/linux/Makefile              |  4 +-
 sysdeps/unix/sysv/linux/Versions              |  1 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |  1 +
 sysdeps/unix/sysv/linux/alpha/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     |  7 +-
 sysdeps/unix/sysv/linux/csky/libc.abilist     |  1 +
 sysdeps/unix/sysv/linux/execveat.c            | 67 ++++++++++++++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |  1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |  1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/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/tst-execveat.c        | 68 +++++++++++++++++++
 .../unix/sysv/linux/x86_64/64/libc.abilist    |  1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |  1 +
 36 files changed, 175 insertions(+), 3 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/tst-execveat.c

diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 60696d827f..571c281b06 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2182,6 +2182,7 @@ GLIBC_2.3.4 xdr_quad_t F
 GLIBC_2.3.4 xdr_u_quad_t F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 mach_print F
+GLIBC_2.32 execveat F
 GLIBC_2.32 thrd_current F
 GLIBC_2.32 thrd_equal F
 GLIBC_2.32 thrd_sleep F
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 089a4899d5..785bc15b06 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -96,7 +96,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
 	 test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
 	 tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
-	 tst-tgkill
+	 tst-tgkill tst-execveat
 tests-internal += tst-ofdlocks-compat tst-sigcontext-get_pc
 
 CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
@@ -228,7 +228,7 @@ endif
 ifeq ($(subdir),posix)
 sysdep_headers += bits/initspin.h
 
-sysdep_routines += sched_getcpu oldglob getcpu
+sysdep_routines += sched_getcpu oldglob getcpu execveat
 
 tests += tst-affinity tst-affinity-pid
 
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 9a58dda9f2..30120bb3fd 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -178,6 +178,7 @@ libc {
     getdents64; gettid; tgkill;
   }
   GLIBC_2.32 {
+    execveat;
   }
   GLIBC_PRIVATE {
     # functions used in other libraries
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 41bb214bb9..80aae4fcbd 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2147,3 +2147,4 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 6430af207f..f944c248d3 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2227,6 +2227,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index f4ea1756d5..116e99de0f 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -134,6 +134,7 @@ GLIBC_2.31 msgctl F
 GLIBC_2.31 semctl F
 GLIBC_2.31 shmctl F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index f1456b26b2..85140201a0 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -131,6 +131,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
index c315cc5cb8..55225b5447 100644
--- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h
+++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
@@ -17,7 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #ifndef _UNISTD_H
-# error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
+#error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
 #endif
 
 #ifdef __USE_GNU
@@ -33,4 +33,9 @@
    not detached and has not been joined.  */
 extern __pid_t gettid (void) __THROW;
 
+/* Execute program relative to a directory file descriptor.  */
+     extern int execveat (int __fd, const char *__path, char *const __argv[],
+                          char *const __envp[], int __flags)
+     __THROW __nonnull ((2, 3));
+
 #endif
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index c54aed2f8e..c4b4c75299 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2091,3 +2091,4 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..7ebf397091
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 1994-2020 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return -1;
+
+  int fd = openat (dirfd, path, flags | O_CLOEXEC);
+  if (fd < 0)
+    return -1;
+
+  struct fd_to_filename fdfilename;
+  const char *gfilename
+    = path != NULL ? path : __fd_to_filename (fd, &fdfilename);
+
+  /* We do not need the return value.  */
+  __execve (gfilename, argv, envp);
+
+  int save = errno;
+
+  /* We come here only if the 'execve' call fails.  Determine whether
+     /proc is mounted.  If not we return ENOSYS.  */
+  struct stat st;
+  if (stat ("/proc/self/fd", &st) != 0 && errno == ENOENT)
+    save = ENOSYS;
+
+  close (fd);
+  __set_errno (save);
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 87373f755b..ec757fbba8 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2048,6 +2048,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 1bd2e02f79..4739b6d123 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2214,6 +2214,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 07e51d46bf..df43f9ab47 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2080,6 +2080,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 42ea4c24bf..9eea47c8f8 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -135,6 +135,7 @@ GLIBC_2.31 msgctl F
 GLIBC_2.31 semctl F
 GLIBC_2.31 shmctl F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index e9358fb092..b4bfc2e64e 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2160,6 +2160,7 @@ GLIBC_2.31 msgctl F
 GLIBC_2.31 semctl F
 GLIBC_2.31 shmctl F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 2cefe739c0..862bbb0268 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2142,3 +2142,4 @@ GLIBC_2.31 msgctl F
 GLIBC_2.31 semctl F
 GLIBC_2.31 shmctl F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 3474ef1490..7198087cb8 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2139,3 +2139,4 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index a6f99a7369..b6d846f1f9 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2131,6 +2131,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 48222af11c..2664abb8d2 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2129,6 +2129,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 99965cfb0f..1412370ff2 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2137,6 +2137,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 2c8bafc669..7a7940e03f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2131,6 +2131,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 52cf72052c..15854e21ec 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2180,3 +2180,4 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 2ca5bbccf3..b8799013c9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2187,6 +2187,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e6c4d002d5..d13d38ebc8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2220,6 +2220,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 82d77b7e48..9d33471163 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2050,6 +2050,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 2b6a76d9c2..55affc7bd6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2249,3 +2249,4 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 234d34929a..b4e89ff01e 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2109,3 +2109,4 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 1f06cce028..9bd38c92c1 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2185,6 +2185,7 @@ GLIBC_2.31 msgctl F
 GLIBC_2.31 semctl F
 GLIBC_2.31 shmctl F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 26c2ce32e5..169f5f47b6 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2086,6 +2086,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 7ad2e920c3..71fa8cf0f6 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2055,6 +2055,7 @@ GLIBC_2.31 msgctl F
 GLIBC_2.31 semctl F
 GLIBC_2.31 shmctl F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index d2611bf0a5..3013575ed3 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2052,6 +2052,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 18a528f0e9..213e1fb126 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2176,6 +2176,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index a1d48b0f3c..24c76b528f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2103,6 +2103,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/tst-execveat.c b/sysdeps/unix/sysv/linux/tst-execveat.c
new file mode 100644
index 0000000000..06c4e9fc4b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-execveat.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 2017-2020 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 <errno.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+
+static int
+do_test (void)
+{
+  char *argv[] = { (char *) "-c", (char *) "exit 3", NULL };
+  char *envp[] = { (char *) "FOO=BAR", NULL };
+  DIR *dirp;
+  int fd;
+  pid_t pid;
+  int status;
+
+  dirp = opendir ("/bin");
+  if (!dirp)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  errno = 0;
+  pid = xfork ();
+  if (pid == 0)
+    {
+      execveat (fd, "sh", argv, envp, 0);
+
+      if (errno)
+        {
+          closedir (dirp);
+          FAIL_EXIT1 ("execveat failed, errno %d", errno);
+        }
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (WIFEXITED (status))
+    TEST_COMPARE (WEXITSTATUS (status), 3);
+  else
+    {
+      closedir (dirp);
+      FAIL_EXIT1 ("execveat failed");
+    }
+
+  closedir (dirp);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 6418ace78a..8f4388bf44 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2061,6 +2061,7 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index edb9f2f004..33825b4cd4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2160,3 +2160,4 @@ GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 pthread_sigmask F
+GLIBC_2.32 execveat F
-- 
2.21.1


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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
@ 2020-04-28 14:17 ` Florian Weimer
  2020-04-28 15:03   ` Joseph Myers
  2020-04-28 15:03 ` Joseph Myers
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-04-28 14:17 UTC (permalink / raw)
  To: Alexandra Hájková via Libc-alpha
  Cc: Alexandra Hájková, Alexandra Hájková

* Alexandra Hájková via Libc-alpha:

> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 60696d827f..571c281b06 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2182,6 +2182,7 @@ GLIBC_2.3.4 xdr_quad_t F
>  GLIBC_2.3.4 xdr_u_quad_t F
>  GLIBC_2.30 twalk_r F
>  GLIBC_2.32 mach_print F
> +GLIBC_2.32 execveat F
>  GLIBC_2.32 thrd_current F
>  GLIBC_2.32 thrd_equal F
>  GLIBC_2.32 thrd_sleep F
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile

This is not correct because you are not adding execveat for Hurd.  You
can just remove that change.

> diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> index c315cc5cb8..55225b5447 100644
> --- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> +++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> @@ -17,7 +17,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #ifndef _UNISTD_H
> -# error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
> +#error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
>  #endif

Spurious change, please remove it.

> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
> new file mode 100644
> index 0000000000..7ebf397091
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat.c
> @@ -0,0 +1,67 @@
> +/* Copyright (C) 1994-2020 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +
> +
> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;
> +
> +  int fd = openat (dirfd, path, flags | O_CLOEXEC);
> +  if (fd < 0)
> +    return -1;
> +
> +  struct fd_to_filename fdfilename;
> +  const char *gfilename
> +    = path != NULL ? path : __fd_to_filename (fd, &fdfilename);
> +
> +  /* We do not need the return value.  */
> +  __execve (gfilename, argv, envp);
> +
> +  int save = errno;
> +
> +  /* We come here only if the 'execve' call fails.  Determine whether
> +     /proc is mounted.  If not we return ENOSYS.  */
> +  struct stat st;
> +  if (stat ("/proc/self/fd", &st) != 0 && errno == ENOENT)
> +    save = ENOSYS;
> +
> +  close (fd);
> +  __set_errno (save);
> +#endif
> +
> +  return -1;
> +}

I think you should use __openat_nocancel and __close_nocancel (from
<not-cancel.h>) to avoid introducing cancellation points.  It will
also fix the elf/check-localplt failures.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 6418ace78a..8f4388bf44 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2061,6 +2061,7 @@ GLIBC_2.30 gettid F
>  GLIBC_2.30 tgkill F
>  GLIBC_2.30 twalk_r F
>  GLIBC_2.32 pthread_sigmask F
> +GLIBC_2.32 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F

This is quite odd.  Did you update the ABI list manually?  The order
of pthread_sigmask and execveat is wrong.  This is what causes
elf/check-abi-libc failures.

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 14:17 ` Florian Weimer
@ 2020-04-28 15:03   ` Joseph Myers
  0 siblings, 0 replies; 46+ messages in thread
From: Joseph Myers @ 2020-04-28 15:03 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Alexandra Hájková via Libc-alpha, Alexandra Hájková

On Tue, 28 Apr 2020, Florian Weimer wrote:

> * Alexandra Hájková via Libc-alpha:
> 
> > diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> > index 60696d827f..571c281b06 100644
> > --- a/sysdeps/mach/hurd/i386/libc.abilist
> > +++ b/sysdeps/mach/hurd/i386/libc.abilist
> > @@ -2182,6 +2182,7 @@ GLIBC_2.3.4 xdr_quad_t F
> >  GLIBC_2.3.4 xdr_u_quad_t F
> >  GLIBC_2.30 twalk_r F
> >  GLIBC_2.32 mach_print F
> > +GLIBC_2.32 execveat F
> >  GLIBC_2.32 thrd_current F
> >  GLIBC_2.32 thrd_equal F
> >  GLIBC_2.32 thrd_sleep F
> > diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> 
> This is not correct because you are not adding execveat for Hurd.  You
> can just remove that change.

First, the commit message should discuss the rationale for this being a 
Linux-specific interface in glibc, as opposed to an OS-independent 
interface with an ENOSYS stub for OSes that don't implement it.  The 
interface looks quite generic like the POSIX *at interfaces, so there's a 
reasonable case for it being an OS-independent interface (which doesn't 
require adding an implementation for Hurd, an ENOSYS stub in a suitable 
OS-independent directory would suffice, along with the declaration, test 
etc. being OS-independent).

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
  2020-04-28 14:17 ` Florian Weimer
@ 2020-04-28 15:03 ` Joseph Myers
  2020-04-28 15:08   ` Florian Weimer
  2020-04-28 17:44 ` Adhemerval Zanella
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 46+ messages in thread
From: Joseph Myers @ 2020-04-28 15:03 UTC (permalink / raw)
  To: Alexandra Hájková; +Cc: libc-alpha, Alexandra Hájková

This patch needs documentation for the new function in the glibc manual, 
as well as a NEWS entry for it (under "Major new features" for 2.32).

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 15:03 ` Joseph Myers
@ 2020-04-28 15:08   ` Florian Weimer
  2020-04-28 15:29     ` Joseph Myers
  0 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-04-28 15:08 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Alexandra Hájková, libc-alpha, Alexandra Hájková

* Joseph Myers:

> This patch needs documentation for the new function in the glibc manual, 
> as well as a NEWS entry for it (under "Major new features" for 2.32).

The documentation will conflict with the manual update for the
existing fexecve function, so that should be reviewed first:

  <https://sourceware.org/pipermail/libc-alpha/2020-April/113176.html>

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 15:08   ` Florian Weimer
@ 2020-04-28 15:29     ` Joseph Myers
  2020-04-28 17:15       ` Florian Weimer
  0 siblings, 1 reply; 46+ messages in thread
From: Joseph Myers @ 2020-04-28 15:29 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha, Alexandra Hájková

On Tue, 28 Apr 2020, Florian Weimer wrote:

> * Joseph Myers:
> 
> > This patch needs documentation for the new function in the glibc manual, 
> > as well as a NEWS entry for it (under "Major new features" for 2.32).
> 
> The documentation will conflict with the manual update for the
> existing fexecve function, so that should be reviewed first:
> 
>   <https://sourceware.org/pipermail/libc-alpha/2020-April/113176.html>

That documentation is fine with me, but I'm not sure where the O_RDONLY / 
O_PATH requirement comes from.  Is there some code in the Linux kernel 
(that I didn't find in a quick look at the execveat implementation) that 
imposes that requirement?

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 15:29     ` Joseph Myers
@ 2020-04-28 17:15       ` Florian Weimer
  2020-04-28 17:19         ` Joseph Myers
  0 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-04-28 17:15 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha, Alexandra Hájková

* Joseph Myers:

> On Tue, 28 Apr 2020, Florian Weimer wrote:
>
>> * Joseph Myers:
>> 
>> > This patch needs documentation for the new function in the glibc manual, 
>> > as well as a NEWS entry for it (under "Major new features" for 2.32).
>> 
>> The documentation will conflict with the manual update for the
>> existing fexecve function, so that should be reviewed first:
>> 
>>   <https://sourceware.org/pipermail/libc-alpha/2020-April/113176.html>
>
> That documentation is fine with me, but I'm not sure where the O_RDONLY / 
> O_PATH requirement comes from.  Is there some code in the Linux kernel 
> (that I didn't find in a quick look at the execveat implementation) that 
> imposes that requirement?

It's the deny_write_access call in do_open_execat in fs/exec.c.  It
returns an ETXTBSY error if the inode has been opened anywhere for
writing, which is the case if the open flag is not O_RDONLY or O_PATH.

(Admittedly, I relied on the manual page, but I've since verified this
with a test case.)

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 17:15       ` Florian Weimer
@ 2020-04-28 17:19         ` Joseph Myers
  0 siblings, 0 replies; 46+ messages in thread
From: Joseph Myers @ 2020-04-28 17:19 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha, Alexandra Hájková

On Tue, 28 Apr 2020, Florian Weimer wrote:

> >>   <https://sourceware.org/pipermail/libc-alpha/2020-April/113176.html>
> >
> > That documentation is fine with me, but I'm not sure where the O_RDONLY / 
> > O_PATH requirement comes from.  Is there some code in the Linux kernel 
> > (that I didn't find in a quick look at the execveat implementation) that 
> > imposes that requirement?
> 
> It's the deny_write_access call in do_open_execat in fs/exec.c.  It
> returns an ETXTBSY error if the inode has been opened anywhere for
> writing, which is the case if the open flag is not O_RDONLY or O_PATH.

Thanks.  The patch is OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
  2020-04-28 14:17 ` Florian Weimer
  2020-04-28 15:03 ` Joseph Myers
@ 2020-04-28 17:44 ` Adhemerval Zanella
  2020-04-28 17:50   ` Florian Weimer
  2020-04-30 11:15 ` Florian Weimer
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella @ 2020-04-28 17:44 UTC (permalink / raw)
  To: libc-alpha



On 28/04/2020 09:20, Alexandra Hájková via Libc-alpha wrote:

> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;
> +
> +  int fd = openat (dirfd, path, flags | O_CLOEXEC);
> +  if (fd < 0)
> +    return -1;
> +

Is this subject to a TOCTOU where a thread might close the fd by explicitly
reading /proc/self/fd/?


> +  struct fd_to_filename fdfilename;
> +  const char *gfilename
> +    = path != NULL ? path : __fd_to_filename (fd, &fdfilename);
> +> +  /* We do not need the return value.  */
> +  __	execve (gfilename, argv, envp);
> +
> +  int save = errno;
> +
> +  /* We come here only if the 'execve' call fails.  Determine whether
> +     /proc is mounted.  If not we return ENOSYS.  */
> +  struct stat st;
> +  if (stat ("/proc/self/fd", &st) != 0 && errno == ENOENT)
> +    save = ENOSYS;
> +
> +  close (fd);
> +  __set_errno (save);
> +#endif
> +
> +  return -1;
> +}



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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 17:44 ` Adhemerval Zanella
@ 2020-04-28 17:50   ` Florian Weimer
  2020-04-28 18:31     ` Adhemerval Zanella
  0 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-04-28 17:50 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

> On 28/04/2020 09:20, Alexandra Hájková via Libc-alpha wrote:
>
>> +/* Execute the file FD refers to, overlaying the running program image.
>> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
>> +int
>> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
>> +          int flags)
>> +{
>> +  /* Avoid implicit array coercion in syscall macros.  */
>> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
>> +#ifndef __ASSUME_EXECVEAT
>> +  if (errno != ENOSYS)
>> +    return -1;
>> +
>> +  int fd = openat (dirfd, path, flags | O_CLOEXEC);
>> +  if (fd < 0)
>> +    return -1;
>> +
>
> Is this subject to a TOCTOU where a thread might close the fd by explicitly
> reading /proc/self/fd/?

Sure, but that's as undefined as closing a file descriptor that the
code has not opened.  This impacts any code in glibc which opens file
descriptors.  I don't think it's a problem.

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 17:50   ` Florian Weimer
@ 2020-04-28 18:31     ` Adhemerval Zanella
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2020-04-28 18:31 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 28/04/2020 14:50, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>> On 28/04/2020 09:20, Alexandra Hájková via Libc-alpha wrote:
>>
>>> +/* Execute the file FD refers to, overlaying the running program image.
>>> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
>>> +int
>>> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
>>> +          int flags)
>>> +{
>>> +  /* Avoid implicit array coercion in syscall macros.  */
>>> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
>>> +#ifndef __ASSUME_EXECVEAT
>>> +  if (errno != ENOSYS)
>>> +    return -1;
>>> +
>>> +  int fd = openat (dirfd, path, flags | O_CLOEXEC);
>>> +  if (fd < 0)
>>> +    return -1;
>>> +
>>
>> Is this subject to a TOCTOU where a thread might close the fd by explicitly
>> reading /proc/self/fd/?
> 
> Sure, but that's as undefined as closing a file descriptor that the
> code has not opened.  This impacts any code in glibc which opens file
> descriptors.  I don't think it's a problem.
> 

Fair enough, I just want to avoid future issues with syscall fallback
machanisms.

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (2 preceding siblings ...)
  2020-04-28 17:44 ` Adhemerval Zanella
@ 2020-04-30 11:15 ` Florian Weimer
  2020-04-30 12:28   ` Adhemerval Zanella
  2020-04-30 12:32 ` Adhemerval Zanella
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-04-30 11:15 UTC (permalink / raw)
  To: Alexandra Hájková via Libc-alpha
  Cc: Alexandra Hájková, Alexandra Hájková

So it turns out that openat and execveat have totally different flags
arguments, and translation is needed.

The execveat manual page says this:

       AT_EMPTY_PATH
              If  pathname is an empty string, operate on the file referred to
              by dirfd (which may have been obtained using the open(2)  O_PATH
              flag).

       AT_SYMLINK_NOFOLLOW
              If  the  file  identified  by dirfd and a non-NULL pathname is a
              symbolic link, then the call fails with the error ELOOP.

fs/exec.c in the kernel sources handles flags in the do_open_execat
function:

	if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
		return ERR_PTR(-EINVAL);
	if (flags & AT_SYMLINK_NOFOLLOW)
		open_exec_flags.lookup_flags &= ~LOOKUP_FOLLOW;
	if (flags & AT_EMPTY_PATH)
		open_exec_flags.lookup_flags |= LOOKUP_EMPTY;

	file = do_filp_open(fd, name, &open_exec_flags);

So the manual page is correct and there are only two flags to support.

So I think we have to do this:

* If there are more flags than just the two, fail with EINVAL.

* To handle AT_EMPTY_PATH, do not open a new file descriptor (using
  openat) if AT_EMPTY_PATH is specified *and* the file name is "".

* To handle AT_SYMLINK_NOFOLLOW, openat needs to be called with
  O_NOFOLLOW in that case (in addition to O_CLOEXEC).

The behavior with AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW at the same
time is not immedately obvious from the kernel code, so I wrote a small
test program (/bin/sh is a symbolic link to /bin/bash on this system):

#include <err.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <unistd.h>

int
main (void)
{
  int fd = open ("/bin/sh", O_PATH | O_NOFOLLOW);
  if (fd < 0)
    err (1, "open");
  static char *const argv[] = { "sh", "-c", "exit 0", NULL };
  static char *const envp[] = { NULL };
  syscall (SYS_execveat, fd, "", argv, envp,
           AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
  err (1, "execveat");
}

This fails:

openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
execveat(3, "", ["sh", "-c", "exit 0"], 0x402040 /* 0 vars */, AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 ELOOP (Too many levels of symbolic links)
[…]
execveat-opath-symlink: execveat: Too many levels of symbolic links

So I think for the AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW case, we
need to call fstatat64 with AT_EMPTY_PATH and see if st_mode indicates
that the descriptor refers to a symbolic link.  If it does, the function
needs to fail with ELOOP.

AT_EMPTY_PATH without a "" file name does not need special treatment and
can use the regular openat path (with the conditional setting of
O_NOFOLLOW).

Thanks,
Florian


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-30 11:15 ` Florian Weimer
@ 2020-04-30 12:28   ` Adhemerval Zanella
  2020-04-30 12:55     ` Florian Weimer
  0 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella @ 2020-04-30 12:28 UTC (permalink / raw)
  To: libc-alpha



On 30/04/2020 08:15, Florian Weimer via Libc-alpha wrote:
> So it turns out that openat and execveat have totally different flags
> arguments, and translation is needed.
> 
> The execveat manual page says this:
> 
>        AT_EMPTY_PATH
>               If  pathname is an empty string, operate on the file referred to
>               by dirfd (which may have been obtained using the open(2)  O_PATH
>               flag).
> 
>        AT_SYMLINK_NOFOLLOW
>               If  the  file  identified  by dirfd and a non-NULL pathname is a
>               symbolic link, then the call fails with the error ELOOP.
> 
> fs/exec.c in the kernel sources handles flags in the do_open_execat
> function:
> 
> 	if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
> 		return ERR_PTR(-EINVAL);
> 	if (flags & AT_SYMLINK_NOFOLLOW)
> 		open_exec_flags.lookup_flags &= ~LOOKUP_FOLLOW;
> 	if (flags & AT_EMPTY_PATH)
> 		open_exec_flags.lookup_flags |= LOOKUP_EMPTY;
> 
> 	file = do_filp_open(fd, name, &open_exec_flags);
> 
> So the manual page is correct and there are only two flags to support.
> 
> So I think we have to do this:
> 
> * If there are more flags than just the two, fail with EINVAL.
> 
> * To handle AT_EMPTY_PATH, do not open a new file descriptor (using
>   openat) if AT_EMPTY_PATH is specified *and* the file name is "".
> 
> * To handle AT_SYMLINK_NOFOLLOW, openat needs to be called with
>   O_NOFOLLOW in that case (in addition to O_CLOEXEC).

These will surely need to be on the testcase.

> 
> The behavior with AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW at the same
> time is not immedately obvious from the kernel code, so I wrote a small
> test program (/bin/sh is a symbolic link to /bin/bash on this system):
> 
> #include <err.h>
> #include <fcntl.h>
> #include <sys/syscall.h>
> #include <unistd.h>
> 
> int
> main (void)
> {
>   int fd = open ("/bin/sh", O_PATH | O_NOFOLLOW);
>   if (fd < 0)
>     err (1, "open");
>   static char *const argv[] = { "sh", "-c", "exit 0", NULL };
>   static char *const envp[] = { NULL };
>   syscall (SYS_execveat, fd, "", argv, envp,
>            AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
>   err (1, "execveat");
> }
> 
> This fails:
> 
> openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
> execveat(3, "", ["sh", "-c", "exit 0"], 0x402040 /* 0 vars */, AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 ELOOP (Too many levels of symbolic links)
> […]
> execveat-opath-symlink: execveat: Too many levels of symbolic links
> 
> So I think for the AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW case, we
> need to call fstatat64 with AT_EMPTY_PATH and see if st_mode indicates
> that the descriptor refers to a symbolic link.  If it does, the function
> needs to fail with ELOOP.

I think execve would handle it:

openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
execve("/proc/self/fd/3", ["sh", "-c", "echo test"], 0x556815e580a8 /* 0 vars */) = -1 ELOOP (Too many levels of symbolic   links)

> 
> AT_EMPTY_PATH without a "" file name does not need special treatment and
> can use the regular openat path (with the conditional setting of
> O_NOFOLLOW).

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (3 preceding siblings ...)
  2020-04-30 11:15 ` Florian Weimer
@ 2020-04-30 12:32 ` Adhemerval Zanella
  2020-11-06 21:03 ` Alexandra Hájková
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2020-04-30 12:32 UTC (permalink / raw)
  To: Alexandra Hájková, libc-alpha; +Cc: Alexandra Hájková



On 28/04/2020 09:20, Alexandra Hájková via Libc-alpha wrote:
> diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> index c315cc5cb8..55225b5447 100644
> --- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> +++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> @@ -17,7 +17,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #ifndef _UNISTD_H
> -# error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
> +#error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
>  #endif
>  
>  #ifdef __USE_GNU
> @@ -33,4 +33,9 @@
>     not detached and has not been joined.  */
>  extern __pid_t gettid (void) __THROW;
>  
> +/* Execute program relative to a directory file descriptor.  */
> +     extern int execveat (int __fd, const char *__path, char *const __argv[],
> +                          char *const __envp[], int __flags)
> +     __THROW __nonnull ((2, 3));
> +
>  #endif

> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;
> +
> +  int fd = openat (dirfd, path, flags | O_CLOEXEC);
> +  if (fd < 0)
> +    return -1;
> +
> +  struct fd_to_filename fdfilename;
> +  const char *gfilename
> +    = path != NULL ? path : __fd_to_filename (fd, &fdfilename);

The path can't be NULL (it marked as nonnull) and you need to handle
empty path with AT_EMPTY_PATH.

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-30 12:28   ` Adhemerval Zanella
@ 2020-04-30 12:55     ` Florian Weimer
  2020-04-30 19:03       ` Adhemerval Zanella
  0 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-04-30 12:55 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha

* Adhemerval Zanella via Libc-alpha:

>> So I think we have to do this:
>> 
>> * If there are more flags than just the two, fail with EINVAL.
>> 
>> * To handle AT_EMPTY_PATH, do not open a new file descriptor (using
>>   openat) if AT_EMPTY_PATH is specified *and* the file name is "".
>> 
>> * To handle AT_SYMLINK_NOFOLLOW, openat needs to be called with
>>   O_NOFOLLOW in that case (in addition to O_CLOEXEC).
>
> These will surely need to be on the testcase.

Yes, these permutations need to be tested.

>> The behavior with AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW at the same
>> time is not immedately obvious from the kernel code, so I wrote a small
>> test program (/bin/sh is a symbolic link to /bin/bash on this system):
>> 
>> #include <err.h>
>> #include <fcntl.h>
>> #include <sys/syscall.h>
>> #include <unistd.h>
>> 
>> int
>> main (void)
>> {
>>   int fd = open ("/bin/sh", O_PATH | O_NOFOLLOW);
>>   if (fd < 0)
>>     err (1, "open");
>>   static char *const argv[] = { "sh", "-c", "exit 0", NULL };
>>   static char *const envp[] = { NULL };
>>   syscall (SYS_execveat, fd, "", argv, envp,
>>            AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
>>   err (1, "execveat");
>> }
>> 
>> This fails:
>> 
>> openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
>> execveat(3, "", ["sh", "-c", "exit 0"], 0x402040 /* 0 vars */, AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 ELOOP (Too many levels of symbolic links)
>> […]
>> execveat-opath-symlink: execveat: Too many levels of symbolic links
>> 
>> So I think for the AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW case, we
>> need to call fstatat64 with AT_EMPTY_PATH and see if st_mode indicates
>> that the descriptor refers to a symbolic link.  If it does, the function
>> needs to fail with ELOOP.
>
> I think execve would handle it:
>
> openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
> execve("/proc/self/fd/3", ["sh", "-c", "echo test"], 0x556815e580a8 /* 0 vars */) = -1 ELOOP (Too many levels of symbolic   links)

And execveat fails even without AT_SYMLINK_NOFOLLOW:

openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
execveat(3, "", ["sh", "-c", "exit 0"], 0x402040 /* 0 vars */, AT_EMPTY_PATH) = -1 ELOOP (Too many levels of symbolic links)

Does this mean we do not need a special case for an O_PATH|O_NOFOLLOW
open of a symbolic link?

Thanks,
Florian


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-30 12:55     ` Florian Weimer
@ 2020-04-30 19:03       ` Adhemerval Zanella
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2020-04-30 19:03 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha



On 30/04/2020 09:55, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>>> So I think we have to do this:
>>>
>>> * If there are more flags than just the two, fail with EINVAL.
>>>
>>> * To handle AT_EMPTY_PATH, do not open a new file descriptor (using
>>>   openat) if AT_EMPTY_PATH is specified *and* the file name is "".
>>>
>>> * To handle AT_SYMLINK_NOFOLLOW, openat needs to be called with
>>>   O_NOFOLLOW in that case (in addition to O_CLOEXEC).
>>
>> These will surely need to be on the testcase.
> 
> Yes, these permutations need to be tested.
> 
>>> The behavior with AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW at the same
>>> time is not immedately obvious from the kernel code, so I wrote a small
>>> test program (/bin/sh is a symbolic link to /bin/bash on this system):
>>>
>>> #include <err.h>
>>> #include <fcntl.h>
>>> #include <sys/syscall.h>
>>> #include <unistd.h>
>>>
>>> int
>>> main (void)
>>> {
>>>   int fd = open ("/bin/sh", O_PATH | O_NOFOLLOW);
>>>   if (fd < 0)
>>>     err (1, "open");
>>>   static char *const argv[] = { "sh", "-c", "exit 0", NULL };
>>>   static char *const envp[] = { NULL };
>>>   syscall (SYS_execveat, fd, "", argv, envp,
>>>            AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);
>>>   err (1, "execveat");
>>> }
>>>
>>> This fails:
>>>
>>> openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
>>> execveat(3, "", ["sh", "-c", "exit 0"], 0x402040 /* 0 vars */, AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 ELOOP (Too many levels of symbolic links)
>>> […]
>>> execveat-opath-symlink: execveat: Too many levels of symbolic links
>>>
>>> So I think for the AT_EMPTY_PATH/"" and AT_SYMLINK_NOFOLLOW case, we
>>> need to call fstatat64 with AT_EMPTY_PATH and see if st_mode indicates
>>> that the descriptor refers to a symbolic link.  If it does, the function
>>> needs to fail with ELOOP.
>>
>> I think execve would handle it:
>>
>> openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
>> execve("/proc/self/fd/3", ["sh", "-c", "echo test"], 0x556815e580a8 /* 0 vars */) = -1 ELOOP (Too many levels of symbolic   links)
> 
> And execveat fails even without AT_SYMLINK_NOFOLLOW:
> 
> openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
> execveat(3, "", ["sh", "-c", "exit 0"], 0x402040 /* 0 vars */, AT_EMPTY_PATH) = -1 ELOOP (Too many levels of symbolic links)
> 
> Does this mean we do not need a special case for an O_PATH|O_NOFOLLOW
> open of a symbolic link?

I think current proposal has some issues regarding handling the
path and flags, with the following code for fallback:

---
  int fd;
  if (path[0] == '\0' && flags & AT_EMPTY_PATH)
    fd = dirfd;
  else
    {
      int oflags = O_CLOEXEC;
      if (flags & AT_SYMLINK_NOFOLLOW)
        oflags |= O_NOFOLLOW;
      fd = openat (dirfd, path, oflags);
    }

  if (fd < 0)
    return -1;

  struct fd_to_filename fdfilename;
  const char *gfilename = __fd_to_filename (fd, &fdfilename);

  /* We do not need the return value.  */
  execve (gfilename, argv, envp);
---

It seems to follow execveat syscall semantic.  For instance:

  int fd = open ("/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH);
  [...]
  execveat (fd, "", argv, envp, AT_EMPTY_PATH);

produces:

openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
execve("/proc/self/fd/3", ["sh", "-c", "echo test"], 0x5624523db098 /* 0 vars */) = -1 ELOOP 

And:

  int fd = open ("/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH);
  [...]
  execveat (fd, "", argv, envp, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW);

also produces:

  openat(AT_FDCWD, "/bin/sh", O_RDONLY|O_NOFOLLOW|O_PATH) = 3
  execve("/proc/self/fd/3", ["sh", "-c", "echo test"], 0x563e8f1d0098 /* 0 vars */) = -1 ELOOP



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

* [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (4 preceding siblings ...)
  2020-04-30 12:32 ` Adhemerval Zanella
@ 2020-11-06 21:03 ` Alexandra Hájková
  2020-11-06 22:15   ` Joseph Myers
  2020-11-09 21:34   ` Yann Droneaud
  2020-11-09 20:39 ` Adhemerval Zanella
                   ` (7 subsequent siblings)
  13 siblings, 2 replies; 46+ messages in thread
From: Alexandra Hájková @ 2020-11-06 21:03 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

---
This iteration adds additional testing for the various corner cases.

 posix/Makefile                                |   5 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  40 ++++
 posix/tst-execveat.c                          | 174 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/Makefile              |   2 +-
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
 sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  79 ++++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/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 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 38 files changed, 336 insertions(+), 3 deletions(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c

diff --git a/posix/Makefile b/posix/Makefile
index 693082ed28..4a1f511acf 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -65,7 +65,8 @@ routines :=								      \
 	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
-	streams-compat
+	streams-compat                                            \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -102,7 +103,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
 		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
 		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
-		   tst-wordexp-nocmd
+		   tst-wordexp-nocmd tst-execveat
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
 		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
 		   tst-glob_lstat_compat tst-spawn4-compat
diff --git a/posix/Versions b/posix/Versions
index 7d06a6d0c0..9d07ce6c96 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.33 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..cab61952b3
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991-2020 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to DIFRD with
+ * arguments ARGV and environment ENVP.
+ * ARGV and ENVP are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (difrd < 0 || path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..e2c4164513
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,174 @@
+/* Copyright (C) 2017-2020 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit 3", NULL };
+  char *envp[] = { (char *) "FOO=BAR", NULL };
+  pid_t pid;
+  int status;
+
+  test_verbose = 1;
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed, errno %d", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations  */
+
+  /* fd: valid dir, pathname: relative, flags:: 0  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  /* fd: AT_FDCWD, pathname: relative, flags: 0
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process  */
+  chdir ("/bin");
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* fd: valid dir with O_PATH, pathname: relative, flags: 0  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* fd: AT_FDCWD, pathname: absolute in different dir, flags: 0  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  /* fd: valid dir with O_PATH, pathname: absolute, flags: 0  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* fd: valid dir, pathname: absolute in differen dir, flags: 0  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* fd: regular file, pathname: relative, flags: 0  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* fd: regular file, pathname: absolute, flags: 0  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* fd: O_PATH of regular file, pathname: empty, flags: 0  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* fd: O_PATH of regular file, pathname: empty, flags: AT_EMPTY_PATH  */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+  /* fd: O_PATH of regular file, pathname: empty,
+     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW  */
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  stat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  fchmod (fd_out, 0777);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+  /* fd: O_PATH of symbolic link, pathname: empty, flags: 0 */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+  /* fd: O_PATH of symbolic link, pathname: empty, flags: AT_EMPTY_PATH */
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+  /* fd: O_PATH of symbolic link, pathname: empty,
+     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW */
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 32b8161619..b1117f2eda 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index e2ff0e8b9e..7ee46e6077 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2181,6 +2181,7 @@ GLIBC_2.3.4 xdr_quad_t F
 GLIBC_2.3.4 xdr_u_quad_t F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 __libc_single_threaded D 0x1
+GLIBC_2.32 execveat F
 GLIBC_2.32 mach_print F
 GLIBC_2.32 mremap F
 GLIBC_2.32 sigabbrev_np F
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 09604e128b..bb916b7742 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -235,7 +235,7 @@ endif
 ifeq ($(subdir),posix)
 sysdep_headers += bits/initspin.h
 
-sysdep_routines += sched_getcpu oldglob getcpu
+sysdep_routines += sched_getcpu oldglob getcpu execveat
 
 tests += tst-affinity tst-affinity-pid
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4cc1c6a591..d281749621 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2155,6 +2155,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 26ad9845e4..9bbcda105e 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2237,6 +2237,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 3b0a47e967..25ce4024a8 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -139,6 +139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 9ab3924888..31675a4068 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -136,6 +136,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 14a84dac8f..b4b760fbc5 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2099,6 +2099,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..62f3f0514e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 1994-2020 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return -1;
+
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+    return EINVAL;
+
+  int fd;
+  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
+    fd = dirfd;
+  else
+    {
+      int oflags = O_CLOEXEC;
+      if (flags & AT_SYMLINK_NOFOLLOW)
+        oflags |= O_NOFOLLOW;
+      fd = openat (dirfd, path, oflags);
+    }
+  if (fd < 0)
+    return -1;
+
+  struct fd_to_filename fdfilename;
+  const char *gfilename = __fd_to_filename (fd, &fdfilename);
+
+  /* We do not need the return value.  */
+  __execve (gfilename, argv, envp);
+
+  int save = errno;
+
+  /* We come here only if the 'execve' call fails.  Determine whether
+     /proc is mounted.  If not we return ENOSYS.  */
+  struct stat st;
+  if (stat ("/proc/self/fd", &st) != 0 && errno == ENOENT)
+    save = ENOSYS;
+
+  if (fd != dirfd)
+    __close_nocancel (fd);
+  __set_errno (save);
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 5c8502f3d3..71ddaa2930 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2058,6 +2058,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 4f0d3c1eb5..350687bf6f 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2224,6 +2224,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index e3b345b803..8ac4337b70 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2090,6 +2090,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 25f2d1c08f..425a44bc5f 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -140,6 +140,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index c4891479d3..057c77119b 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2170,6 +2170,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 143b0163b4..a85ea5a0bd 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2150,6 +2150,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 13d374a031..5822ab2896 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index b2295f1937..30ead20668 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 4c786070d0..ac35f615aa 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2139,6 +2139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index aa9c6a4dca..76ae132755 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 5939588ad5..45ddc18ec1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 92556c4237..3887748b90 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2188,6 +2188,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 26c93dff05..a32a53e330 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2197,6 +2197,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index f04b167788..a787e224fc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2230,6 +2230,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index c2ca00709e..fc8a0a5e1c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2060,6 +2060,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 0ea50dc851..e1aaaedfbd 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2350,6 +2350,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 1626c5351f..35a6b7829b 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2117,6 +2117,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a66426eb4d..efa1bb3d9e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2195,6 +2195,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ab351873ae..27958ec30c 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2096,6 +2096,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 22ceaa3d87..40a904ac55 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2065,6 +2065,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index d36f228192..621c547e32 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2062,6 +2062,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 59b4313280..f01f085b5b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2186,6 +2186,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 266dcdfa08..c9225ae42e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2113,6 +2113,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 4fff61818b..5e1cb8b63c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2071,6 +2071,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 102ed47a9c..de1d452320 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2168,6 +2168,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
-- 
2.26.2


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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-11-06 21:03 ` Alexandra Hájková
@ 2020-11-06 22:15   ` Joseph Myers
  2020-11-09 18:43     ` Florian Weimer
  2020-11-09 21:34   ` Yann Droneaud
  1 sibling, 1 reply; 46+ messages in thread
From: Joseph Myers @ 2020-11-06 22:15 UTC (permalink / raw)
  To: Alexandra Hájková; +Cc: libc-alpha, Alexandra Hájková

Note the need for a NEWS update for the new feature, and for documentation 
of the new function in process.texi.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-11-06 22:15   ` Joseph Myers
@ 2020-11-09 18:43     ` Florian Weimer
  0 siblings, 0 replies; 46+ messages in thread
From: Florian Weimer @ 2020-11-09 18:43 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Alexandra Hájková, libc-alpha, Alexandra Hájková

* Joseph Myers:

> Note the need for a NEWS update for the new feature, and for documentation 
> of the new function in process.texi.

The manual parts are kind of my fault, I think they are blocked on a
generic section on *at functions and O_PATH.  I have posted a patch, but
the discussion was a bit involved, and got sidetracked afterwards.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (5 preceding siblings ...)
  2020-11-06 21:03 ` Alexandra Hájková
@ 2020-11-09 20:39 ` Adhemerval Zanella
  2020-12-03 13:55   ` Florian Weimer
  2020-11-26 21:28 ` Alexandra Hájková
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella @ 2020-11-09 20:39 UTC (permalink / raw)
  To: libc-alpha, Alexandra Hájková



On 28/04/2020 09:20, Alexandra Hájková via Libc-alpha wrote:
> From: Alexandra Hájková <ahajkova@redhat.com>

> diff --git a/sysdeps/unix/sysv/linux/bits/unistd_ext.h b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> index c315cc5cb8..55225b5447 100644
> --- a/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> +++ b/sysdeps/unix/sysv/linux/bits/unistd_ext.h
> @@ -17,7 +17,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #ifndef _UNISTD_H
> -# error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
> +#error "Never include <bits/unistd_ext.h> directly; use <unistd.h> instead."
>  #endif
>  

Spurious change.

>  #ifdef __USE_GNU
> @@ -33,4 +33,9 @@
>     not detached and has not been joined.  */
>  extern __pid_t gettid (void) __THROW;
>  
> +/* Execute program relative to a directory file descriptor.  */
> +     extern int execveat (int __fd, const char *__path, char *const __argv[],
> +                          char *const __envp[], int __flags)
> +     __THROW __nonnull ((2, 3));
> +

Indentation seems off here (extra space before extern).

>  #endif

> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
> new file mode 100644
> index 0000000000..7ebf397091
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat.c
> @@ -0,0 +1,67 @@
> +/* Copyright (C) 1994-2020 Free Software Foundation, Inc.

I think it should be solely 2020.

> +   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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +
> +
> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;
> +
> +  int fd = openat (dirfd, path, flags | O_CLOEXEC);

This will turn execevat in a cancellation entrypoint.

> +  if (fd < 0)
> +    return -1;
> +
> +  struct fd_to_filename fdfilename;
> +  const char *gfilename
> +    = path != NULL ? path : __fd_to_filename (fd, &fdfilename);
> +
> +  /* We do not need the return value.  */
> +  __execve (gfilename, argv, envp);
> +
> +  int save = errno;
> +
> +  /* We come here only if the 'execve' call fails.  Determine whether
> +     /proc is mounted.  If not we return ENOSYS.  */
> +  struct stat st;
> +  if (stat ("/proc/self/fd", &st) != 0 && errno == ENOENT)
> +    save = ENOSYS;

Not sure if it would make a difference here, but I think it would be
better to use the LFS interface here. 

> diff --git a/sysdeps/unix/sysv/linux/tst-execveat.c b/sysdeps/unix/sysv/linux/tst-execveat.c
> new file mode 100644
> index 0000000000..06c4e9fc4b
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-execveat.c
> @@ -0,0 +1,68 @@
> +/* Copyright (C) 2017-2020 Free Software Foundation, Inc.

Same as before, I think the Copyright year should be only 2020.

> +   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 <errno.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <support/check.h>
> +#include <support/xdlfcn.h>
> +#include <support/xstdio.h>
> +#include <support/xunistd.h>
> +#include <wait.h>
> +
> +static int
> +do_test (void)
> +{
> +  char *argv[] = { (char *) "-c", (char *) "exit 3", NULL };
> +  char *envp[] = { (char *) "FOO=BAR", NULL };

Maybe add a check if the environment variable is what you expect (to
check if envp passing is ok)?

> +  DIR *dirp;
> +  int fd;
> +  pid_t pid;
> +  int status;
> +
> +  dirp = opendir ("/bin");
> +  if (!dirp)
> +    FAIL_EXIT1 ("failed to open /bin");
> +  fd = dirfd (dirp);
> +
> +  errno = 0;
> +  pid = xfork ();
> +  if (pid == 0)
> +    {
> +      execveat (fd, "sh", argv, envp, 0);
> +
> +      if (errno)

Don't use implicit checks.

> +        {
> +          closedir (dirp);
> +          FAIL_EXIT1 ("execveat failed, errno %d", errno);
> +        }
> +    }
> +  xwaitpid (pid, &status, 0);
> +
> +  if (WIFEXITED (status))
> +    TEST_COMPARE (WEXITSTATUS (status), 3);
> +  else
> +    {
> +      closedir (dirp);
> +      FAIL_EXIT1 ("execveat failed");
> +    }
> +
> +  closedir (dirp);
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Besides the points raised by Joseph, the rest looks ok. I didn't check if it 
updates all the abilist files.

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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-11-06 21:03 ` Alexandra Hájková
  2020-11-06 22:15   ` Joseph Myers
@ 2020-11-09 21:34   ` Yann Droneaud
  2020-11-26 11:31     ` Alexandra Petlanova Hajkova
  1 sibling, 1 reply; 46+ messages in thread
From: Yann Droneaud @ 2020-11-09 21:34 UTC (permalink / raw)
  To: Alexandra Hájková, libc-alpha; +Cc: Alexandra Hájková

Hi,

Le vendredi 06 novembre 2020 à 22:03 +0100, Alexandra Hájková via Libc-
alpha a écrit :

> diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
> new file mode 100644
> index 0000000000..e2c4164513
> --- /dev/null
> +++ b/posix/tst-execveat.c
> @@ -0,0 +1,174 @@
> +/* Copyright (C) 2017-2020 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 <fcntl.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <support/xdlfcn.h>
> +#include <support/xstdio.h>
> +#include <support/xunistd.h>
> +#include <wait.h>
> +#include <support/test-driver.h>
> +
> +int
> +call_execveat (int fd, const char *pathname, int flags, int expected_fail,
> +               int num)
> +{
> +  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit 3", NULL };

May be there's no need to run a shell for the test. What about /bin/true or /bin/false ?

> +  char *envp[] = { (char *) "FOO=BAR", NULL };
> +  pid_t pid;
> +  int status;
> +
> +  test_verbose = 1;
> +  if (test_verbose > 0)
> +    printf ("call line number: %d\n", num);
> +
> +  pid = xfork ();
> +  if (pid == 0)
> +    {
> +
> +      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
> +      if (errno == ENOSYS)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (errno == expected_fail)
> +        {
> +          if (test_verbose > 0)
> +            printf ("expected fail: errno %d\n", errno);
> +          _exit (0);
> +        }
> +      else
> +        FAIL_EXIT1 ("execveat failed, errno %d", errno);
> +    }
> +  xwaitpid (pid, &status, 0);
> +
> +  if (WIFEXITED (status))
> +    {
> +      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (expected_fail)
> +        TEST_COMPARE (WEXITSTATUS (status), 0);
> +      else
> +        TEST_COMPARE (WEXITSTATUS (status), 3);
> +    }
> +  return 0;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  DIR *dirp;
> +  int fd, fd_out;
> +  char *tmp_dir, *symlink_name, *tmp_sh;
> +  struct stat st;
> +
> +  dirp = opendir ("/bin");
> +  if (dirp == NULL)
> +    FAIL_EXIT1 ("failed to open /bin");
> +  fd = dirfd (dirp);
> +
> +  /* Call execveat for various fd/pathname combinations  */
> +
> +  /* fd: valid dir, pathname: relative, flags:: 0  */
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  /* fd: AT_FDCWD, pathname: relative, flags: 0
> +     If pathname is relative and dirfd is the special value AT_FDCWD, then
> +     pathname is interpreted relative to the current working directory of
> +     the calling process  */
> +  chdir ("/bin");
> +  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +#ifdef O_PATH
> +  /* fd: valid dir with O_PATH, pathname: relative, flags: 0  */
> +  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
> +  /* fd: AT_FDCWD, pathname: absolute in different dir, flags: 0  */
> +  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
> +  /* fd: valid dir with O_PATH, pathname: absolute, flags: 0  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +#endif
> +
> +  fd = xopen ("/usr", O_RDONLY, 0);
> +  /* fd: valid dir, pathname: absolute in differen dir, flags: 0  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  /* fd: regular file, pathname: relative, flags: 0  */
> +  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
> +  /* fd: regular file, pathname: absolute, flags: 0  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +#ifdef O_PATH
> +  fd = xopen ("/bin/sh", O_PATH, 0);
> +  /* fd: O_PATH of regular file, pathname: empty, flags: 0  */
> +  call_execveat (fd, "", 0, ENOENT, __LINE__);
> +  /* fd: O_PATH of regular file, pathname: empty, flags: AT_EMPTY_PATH  */
> +  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
> +  /* fd: O_PATH of regular file, pathname: empty,
> +     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW  */
> +  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
> +  xclose (fd);
> +
> +  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
> +  symlink_name = xasprintf ("%s/symlink", tmp_dir);
> +  xsymlink ("tmp_sh", symlink_name);
> +  add_temp_file (symlink_name);
> +  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
> +  add_temp_file (tmp_sh);
> +  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
> +  stat ("/bin/sh", &st);
> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
> +  fchmod (fd_out, 0777);
> +  xclose (fd);
> +  xclose (fd_out);
> +  fd_out = xopen (symlink_name, O_PATH, 0);
> +
> +  /* fd: O_PATH of symbolic link, pathname: empty, flags: 0 */
> +  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
> +  /* fd: O_PATH of symbolic link, pathname: empty, flags: AT_EMPTY_PATH */
> +  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
> +  /* fd: O_PATH of symbolic link, pathname: empty,
> +     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW */
> +  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
> +                 __LINE__);
> +  xclose (fd_out);
> +  free (symlink_name);
> +  free (tmp_sh);
> +  free (tmp_dir);
> +#endif
> +
> +  /* Call execveat with closed fd, we expect this to fail with EBADF  */
> +  call_execveat (fd, "sh", 0, EBADF, __LINE__);
> +  /* Call execveat with closed fd, we expect this to pass because the pathname is
> +     absolute  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Regards

-- 
Yann Droneaud
OPTEYA



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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-11-09 21:34   ` Yann Droneaud
@ 2020-11-26 11:31     ` Alexandra Petlanova Hajkova
  0 siblings, 0 replies; 46+ messages in thread
From: Alexandra Petlanova Hajkova @ 2020-11-26 11:31 UTC (permalink / raw)
  To: Yann Droneaud; +Cc: Alexandra Hájková, libc-alpha

> +  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit 3", NULL
> };
>
> May be there's no need to run a shell for the test. What about /bin/true
> or /bin/false ?
>
>
>
Hello,

using sh was suggested by Florian Weimer because it produces exit status 3
which is far less common then 0 or 1 exit statuses produced by true/false.
Looking at the exit status 3 we can be relatively certain that the right
test script ran.

Regards,
Alexandra

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

* [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (6 preceding siblings ...)
  2020-11-09 20:39 ` Adhemerval Zanella
@ 2020-11-26 21:28 ` Alexandra Hájková
  2020-11-27 14:58   ` Adhemerval Zanella
  2020-12-03 14:20 ` Alexandra Hájková
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 46+ messages in thread
From: Alexandra Hájková @ 2020-11-26 21:28 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

 Also add the test for the new wrapper.
---
This iterations adds * NEWS update
                     * uses stat64 to use the LFS interface
                     * uses __openat_nocancel to open the fd without the cancelation point
                     * some cosmetic changs
                     * the docs are are blocked on a generic section on *at functions and O_PATH (the patch by Florian Weimer was already posted)

 NEWS                                          |   2 +
 posix/Makefile                                |   5 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  40 ++++
 posix/tst-execveat.c                          | 174 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/Makefile              |   2 +-
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
 sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  79 ++++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/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 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 39 files changed, 338 insertions(+), 3 deletions(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c

diff --git a/NEWS b/NEWS
index 685b93c8e9..962480f2e6 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,8 @@ Major new features:
   The 32-bit RISC-V port requires at least Linux 5.4, GCC 7.1 and binutils
   2.28.
 
+* Add execveat system call wrapper.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The mallinfo function is marked deprecated.  Callers should call
diff --git a/posix/Makefile b/posix/Makefile
index 4bfc8d942c..ca678ad781 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -65,7 +65,8 @@ routines :=								      \
 	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
-	streams-compat
+	streams-compat                                            \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -102,7 +103,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
 		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
 		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
-		   tst-wordexp-nocmd
+		   tst-wordexp-nocmd tst-execveat
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
 		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
 		   tst-glob_lstat_compat tst-spawn4-compat
diff --git a/posix/Versions b/posix/Versions
index 7d06a6d0c0..9d07ce6c96 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.33 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..cab61952b3
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1991-2020 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to DIFRD with
+ * arguments ARGV and environment ENVP.
+ * ARGV and ENVP are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (difrd < 0 || path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..c1dcd26183
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,174 @@
+/* Copyright (C) 2020 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit 3", NULL };
+  char *envp[] = { (char *) "FOO=BAR", NULL };
+  pid_t pid;
+  int status;
+
+  test_verbose = 1;
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed, errno %d", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations  */
+
+  /* fd: valid dir, pathname: relative, flags:: 0  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  /* fd: AT_FDCWD, pathname: relative, flags: 0
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process  */
+  chdir ("/bin");
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* fd: valid dir with O_PATH, pathname: relative, flags: 0  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* fd: AT_FDCWD, pathname: absolute in different dir, flags: 0  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  /* fd: valid dir with O_PATH, pathname: absolute, flags: 0  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* fd: valid dir, pathname: absolute in differen dir, flags: 0  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* fd: regular file, pathname: relative, flags: 0  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* fd: regular file, pathname: absolute, flags: 0  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* fd: O_PATH of regular file, pathname: empty, flags: 0  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* fd: O_PATH of regular file, pathname: empty, flags: AT_EMPTY_PATH  */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+  /* fd: O_PATH of regular file, pathname: empty,
+     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW  */
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  stat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  fchmod (fd_out, 0777);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+  /* fd: O_PATH of symbolic link, pathname: empty, flags: 0 */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+  /* fd: O_PATH of symbolic link, pathname: empty, flags: AT_EMPTY_PATH */
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+  /* fd: O_PATH of symbolic link, pathname: empty,
+     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW */
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 32b8161619..b1117f2eda 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 7a5eb66b85..5afcd48075 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2181,6 +2181,7 @@ GLIBC_2.3.4 xdr_quad_t F
 GLIBC_2.3.4 xdr_u_quad_t F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 __libc_single_threaded D 0x1
+GLIBC_2.32 execveat F
 GLIBC_2.32 mach_print F
 GLIBC_2.32 mremap F
 GLIBC_2.32 sigabbrev_np F
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 09604e128b..bb916b7742 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -235,7 +235,7 @@ endif
 ifeq ($(subdir),posix)
 sysdep_headers += bits/initspin.h
 
-sysdep_routines += sched_getcpu oldglob getcpu
+sysdep_routines += sched_getcpu oldglob getcpu execveat
 
 tests += tst-affinity tst-affinity-pid
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4cc1c6a591..d281749621 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2155,6 +2155,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 26ad9845e4..9bbcda105e 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2237,6 +2237,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 3b0a47e967..25ce4024a8 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -139,6 +139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 9ab3924888..31675a4068 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -136,6 +136,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 14a84dac8f..b4b760fbc5 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2099,6 +2099,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..8f93e9eb97
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 2020 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return -1;
+
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+    return EINVAL;
+
+  int fd;
+  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
+    fd = dirfd;
+  else
+    {
+      int oflags = O_CLOEXEC;
+      if (flags & AT_SYMLINK_NOFOLLOW)
+        oflags |= O_NOFOLLOW;
+      fd = __openat_nocancel (dirfd, path, oflags);
+    }
+  if (fd < 0)
+    return -1;
+
+  struct fd_to_filename fdfilename;
+  const char *gfilename = __fd_to_filename (fd, &fdfilename);
+
+  /* We do not need the return value.  */
+  __execve (gfilename, argv, envp);
+
+  int save = errno;
+
+  /* We come here only if the 'execve' call fails.  Determine whether
+     /proc is mounted.  If not we return ENOSYS.  */
+  struct stat64 st;
+  if (stat64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
+    save = ENOSYS;
+
+  if (fd != dirfd)
+    __close_nocancel_nostatus (fd);
+  __set_errno (save);
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 5c8502f3d3..71ddaa2930 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2058,6 +2058,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 4f0d3c1eb5..350687bf6f 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2224,6 +2224,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index e3b345b803..8ac4337b70 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2090,6 +2090,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 25f2d1c08f..425a44bc5f 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -140,6 +140,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index c4891479d3..057c77119b 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2170,6 +2170,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 143b0163b4..a85ea5a0bd 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2150,6 +2150,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 13d374a031..5822ab2896 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index b2295f1937..30ead20668 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 4c786070d0..ac35f615aa 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2139,6 +2139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index aa9c6a4dca..76ae132755 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 5939588ad5..45ddc18ec1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 92556c4237..3887748b90 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2188,6 +2188,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 26c93dff05..a32a53e330 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2197,6 +2197,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index f04b167788..a787e224fc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2230,6 +2230,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index c2ca00709e..fc8a0a5e1c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2060,6 +2060,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 0ea50dc851..e1aaaedfbd 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2350,6 +2350,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 1626c5351f..35a6b7829b 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2117,6 +2117,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a66426eb4d..efa1bb3d9e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2195,6 +2195,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ab351873ae..27958ec30c 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2096,6 +2096,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 22ceaa3d87..40a904ac55 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2065,6 +2065,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index d36f228192..621c547e32 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2062,6 +2062,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 59b4313280..f01f085b5b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2186,6 +2186,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 266dcdfa08..c9225ae42e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2113,6 +2113,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 4fff61818b..5e1cb8b63c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2071,6 +2071,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 102ed47a9c..de1d452320 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2168,6 +2168,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
-- 
2.26.2


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-11-26 21:28 ` Alexandra Hájková
@ 2020-11-27 14:58   ` Adhemerval Zanella
  2020-11-27 17:32     ` Florian Weimer
  0 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella @ 2020-11-27 14:58 UTC (permalink / raw)
  To: libc-alpha, Alexandra Hájková, Alexandra Hájková



On 26/11/2020 18:28, Alexandra Hájková via Libc-alpha wrote:
> From: Alexandra Hájková <ahajkova@redhat.com>
> 
>  Also add the test for the new wrapper.
> ---
> This iterations adds * NEWS update
>                      * uses stat64 to use the LFS interface
>                      * uses __openat_nocancel to open the fd without the cancelation point
>                      * some cosmetic changs
>                      * the docs are are blocked on a generic section on *at functions and O_PATH (the patch by Florian Weimer was already posted)

Some comments below.

> 
>  NEWS                                          |   2 +
>  posix/Makefile                                |   5 +-
>  posix/Versions                                |   3 +
>  posix/execveat.c                              |  40 ++++
>  posix/tst-execveat.c                          | 174 ++++++++++++++++++
>  posix/unistd.h                                |   5 +
>  sysdeps/mach/hurd/i386/libc.abilist           |   1 +
>  sysdeps/unix/sysv/linux/Makefile              |   2 +-
>  sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
>  sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/execveat.c            |  79 ++++++++
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/ia64/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 +
>  .../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/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 +
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
>  39 files changed, 338 insertions(+), 3 deletions(-)
>  create mode 100644 posix/execveat.c
>  create mode 100644 posix/tst-execveat.c
>  create mode 100644 sysdeps/unix/sysv/linux/execveat.c
> 
> diff --git a/NEWS b/NEWS
> index 685b93c8e9..962480f2e6 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -28,6 +28,8 @@ Major new features:
>    The 32-bit RISC-V port requires at least Linux 5.4, GCC 7.1 and binutils
>    2.28.
>  
> +* Add execveat system call wrapper.
> +

I think we could extend it a bit:

  * The function execveat have been added and it operates similar to execve.
    The syscall is already used to implement fexecve without require /proc to
    be mounted.  Similar to fexecve, if the syscall is not supported a fallback
    which access /proc is used.

>  Deprecated and removed features, and other changes affecting compatibility:
>  
>  * The mallinfo function is marked deprecated.  Callers should call
> diff --git a/posix/Makefile b/posix/Makefile
> index 4bfc8d942c..ca678ad781 100644
> --- a/posix/Makefile
> +++ b/posix/Makefile
> @@ -65,7 +65,8 @@ routines :=								      \
>  	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
>  	posix_madvise							      \
>  	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
> -	streams-compat
> +	streams-compat                                            \
> +	execveat
>  
>  aux		:= init-posix environ
>  tests		:= test-errno tstgetopt testfnm runtests runptests \
> @@ -102,7 +103,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
>  		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
>  		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
>  		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
> -		   tst-wordexp-nocmd
> +		   tst-wordexp-nocmd tst-execveat
>  tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
>  		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
>  		   tst-glob_lstat_compat tst-spawn4-compat
> diff --git a/posix/Versions b/posix/Versions
> index 7d06a6d0c0..9d07ce6c96 100644
> --- a/posix/Versions
> +++ b/posix/Versions
> @@ -147,6 +147,9 @@ libc {
>    }
>    GLIBC_2.30 {
>    }
> +  GLIBC_2.33 {
> +    execveat;
> +  }
>    GLIBC_PRIVATE {
>      __libc_fork; __libc_pread; __libc_pwrite;
>      __nanosleep_nocancel; __pause_nocancel;
> diff --git a/posix/execveat.c b/posix/execveat.c
> new file mode 100644
> index 0000000000..cab61952b3
> --- /dev/null
> +++ b/posix/execveat.c
> @@ -0,0 +1,40 @@
> +/* Copyright (C) 1991-2020 Free Software Foundation, Inc.

Missing one line comment and the Copyright should be only 2020.

> +   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 <errno.h>
> +#include <stddef.h>
> +#include <unistd.h>
> +
> +/* Replace the current process, executing PATH relative to DIFRD with
> + * arguments ARGV and environment ENVP.
> + * ARGV and ENVP are terminated by NULL pointers.  */
> +int
> +__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +            int flags)
> +{
> +  if (difrd < 0 || path == NULL || argv == NULL || envp == NULL)
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  __set_errno (ENOSYS);
> +  return -1;
> +}
> +stub_warning (execveat)
> +
> +weak_alias (__execveat, execveat)

Ok.

> diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
> new file mode 100644
> index 0000000000..c1dcd26183
> --- /dev/null
> +++ b/posix/tst-execveat.c
> @@ -0,0 +1,174 @@

Missing one line comment.

> +/* Copyright (C) 2020 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 <fcntl.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <support/xdlfcn.h>
> +#include <support/xstdio.h>
> +#include <support/xunistd.h>
> +#include <wait.h>
> +#include <support/test-driver.h>
> +
> +int
> +call_execveat (int fd, const char *pathname, int flags, int expected_fail,
> +               int num)
> +{
> +  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit 3", NULL };
> +  char *envp[] = { (char *) "FOO=BAR", NULL };

The shell environment is set, but this is no test that actually checks it
(if the resulting environment variable is set or if it containst the
expected value).

> +  pid_t pid;
> +  int status;
> +
> +  test_verbose = 1;

I think you should remove this line, --verbose will already set it. 

> +  if (test_verbose > 0)
> +    printf ("call line number: %d\n", num);
> +
> +  pid = xfork ();
> +  if (pid == 0)
> +    {
> +

Spurious new line.

> +      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
> +      if (errno == ENOSYS)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (errno == expected_fail)
> +        {
> +          if (test_verbose > 0)
> +            printf ("expected fail: errno %d\n", errno);
> +          _exit (0);
> +        }
> +      else
> +        FAIL_EXIT1 ("execveat failed, errno %d", errno);

Maybe 

  FAIL_EXIT1 ("execveat failed: %m (%d)", errno);

> +    }
> +  xwaitpid (pid, &status, 0);
> +
> +  if (WIFEXITED (status))
> +    {
> +      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (expected_fail)

No implicit checks. 

> +        TEST_COMPARE (WEXITSTATUS (status), 0);
> +      else
> +        TEST_COMPARE (WEXITSTATUS (status), 3);
> +    }
> +  return 0;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  DIR *dirp;
> +  int fd, fd_out;
> +  char *tmp_dir, *symlink_name, *tmp_sh;
> +  struct stat st;
> +
> +  dirp = opendir ("/bin");
> +  if (dirp == NULL)
> +    FAIL_EXIT1 ("failed to open /bin");
> +  fd = dirfd (dirp);
> +
> +  /* Call execveat for various fd/pathname combinations  */
> +
> +  /* fd: valid dir, pathname: relative, flags:: 0  */
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  /* fd: AT_FDCWD, pathname: relative, flags: 0
> +     If pathname is relative and dirfd is the special value AT_FDCWD, then
> +     pathname is interpreted relative to the current working directory of
> +     the calling process  */
> +  chdir ("/bin");
> +  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +#ifdef O_PATH
> +  /* fd: valid dir with O_PATH, pathname: relative, flags: 0  */
> +  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +

Not sure if we should rely on specific filesystem layout, but it should
be fine.

Another possibilty would move this test to a test-container, the minimal
shell implementation should be suffice for the checks.

> +  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);

This is not used on the test below, move to the test where it
actually uses it.

> +  /* fd: AT_FDCWD, pathname: absolute in different dir, flags: 0  */

Missing period and some other comments also misses double space before
comment closing.

Also this comment and the other below that does not really add much, 
different the one closed fd below.  I think it is too succinct, I 
would recomment to describes more thoroughly what the tests intends 
to do, the arguments, and the expected return. Something like:

  /* Check absolute pathname, dirfd should be ignored.  */

> +  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
> +  /* fd: valid dir with O_PATH, pathname: absolute, flags: 0  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +#endif
> +
> +  fd = xopen ("/usr", O_RDONLY, 0);
> +  /* fd: valid dir, pathname: absolute in differen dir, flags: 0  */

  /* Same check for absolute pathname, but with input file descriptor
     openend with different flags.  The dirfd should be ignored.  */
  
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  /* fd: regular file, pathname: relative, flags: 0  */

  /* Check relative pathname, where dirfd does not point to a directory.  */

> +  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
> +  /* fd: regular file, pathname: absolute, flags: 0  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);

  /* Check absolute pathname, but dirfd is a regular file.  The dirfd 
     should be ignored. */

> +  xclose (fd);
> +
> +#ifdef O_PATH
> +  fd = xopen ("/bin/sh", O_PATH, 0);
> +  /* fd: O_PATH of regular file, pathname: empty, flags: 0  */
> +  call_execveat (fd, "", 0, ENOENT, __LINE__);
> +  /* fd: O_PATH of regular file, pathname: empty, flags: AT_EMPTY_PATH  */
> +  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
> +  /* fd: O_PATH of regular file, pathname: empty,
> +     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW  */
> +  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
> +  xclose (fd);
> +
> +  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
> +  symlink_name = xasprintf ("%s/symlink", tmp_dir);
> +  xsymlink ("tmp_sh", symlink_name);
> +  add_temp_file (symlink_name);
> +  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
> +  add_temp_file (tmp_sh);
> +  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
> +  stat ("/bin/sh", &st);
> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
> +  fchmod (fd_out, 0777);
> +  xclose (fd);
> +  xclose (fd_out);
> +  fd_out = xopen (symlink_name, O_PATH, 0);
> +
> +  /* fd: O_PATH of symbolic link, pathname: empty, flags: 0 */
> +  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
> +  /* fd: O_PATH of symbolic link, pathname: empty, flags: AT_EMPTY_PATH */
> +  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
> +  /* fd: O_PATH of symbolic link, pathname: empty,
> +     flags: AT_EMPTY_PATH  AT_SYMLINK_NOFOLLOW */
> +  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
> +                 __LINE__);
> +  xclose (fd_out);
> +  free (symlink_name);
> +  free (tmp_sh);
> +  free (tmp_dir);
> +#endif
> +
> +  /* Call execveat with closed fd, we expect this to fail with EBADF  */
> +  call_execveat (fd, "sh", 0, EBADF, __LINE__);
> +  /* Call execveat with closed fd, we expect this to pass because the pathname is
> +     absolute  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Ok, I think this covers all the cases man-pages describes.

> diff --git a/posix/unistd.h b/posix/unistd.h
> index 32b8161619..b1117f2eda 100644
> --- a/posix/unistd.h
> +++ b/posix/unistd.h
> @@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
>  /* An alias for `euidaccess', used by some other systems.  */
>  extern int eaccess (const char *__name, int __type)
>       __THROW __nonnull ((1));
> +
> +/* Execute program relative to a directory file descriptor.  */
> +extern int execveat (int __fd, const char *__path, char *const __argv[],
> +                     char *const __envp[], int __flags)
> +    __THROW __nonnull ((2, 3));
>  #endif
>  
>  #ifdef __USE_ATFILE

Ok.

> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 7a5eb66b85..5afcd48075 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2181,6 +2181,7 @@ GLIBC_2.3.4 xdr_quad_t F
>  GLIBC_2.3.4 xdr_u_quad_t F
>  GLIBC_2.30 twalk_r F
>  GLIBC_2.32 __libc_single_threaded D 0x1
> +GLIBC_2.32 execveat F
>  GLIBC_2.32 mach_print F
>  GLIBC_2.32 mremap F
>  GLIBC_2.32 sigabbrev_np F
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 09604e128b..bb916b7742 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -235,7 +235,7 @@ endif
>  ifeq ($(subdir),posix)
>  sysdep_headers += bits/initspin.h
>  
> -sysdep_routines += sched_getcpu oldglob getcpu
> +sysdep_routines += sched_getcpu oldglob getcpu execveat
>  
>  tests += tst-affinity tst-affinity-pid
>  

This was already added on posix/Makefile.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 4cc1c6a591..d281749621 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2155,6 +2155,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 26ad9845e4..9bbcda105e 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2237,6 +2237,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index 3b0a47e967..25ce4024a8 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -139,6 +139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index 9ab3924888..31675a4068 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -136,6 +136,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index 14a84dac8f..b4b760fbc5 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2099,6 +2099,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
> new file mode 100644
> index 0000000000..8f93e9eb97
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat.c
> @@ -0,0 +1,79 @@

Missing one line comment.

> +/* Copyright (C) 2020 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;

You need get the INLINE_SYSCALL_CALL and check if it was sucessful as well,
instead of just check for the errno value. Also, this implementation always 
return '-1' (as below):

    int r = INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0],
                                 flags);
  #if __ASSUME_EXECVEAT
    return r;
  #else
    if (r == 0 || errno != ENOSYS)
      return r;
    [...]

  
> +
> +  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
> +    return EINVAL;
> +
> +  int fd;
> +  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
> +    fd = dirfd;
> +  else
> +    {
> +      int oflags = O_CLOEXEC;
> +      if (flags & AT_SYMLINK_NOFOLLOW)
> +        oflags |= O_NOFOLLOW;
> +      fd = __openat_nocancel (dirfd, path, oflags);
> +    }
> +  if (fd < 0)
> +    return -1;
> +
> +  struct fd_to_filename fdfilename;
> +  const char *gfilename = __fd_to_filename (fd, &fdfilename);
> +
> +  /* We do not need the return value.  */
> +  __execve (gfilename, argv, envp);
> +
> +  int save = errno;
> +
> +  /* We come here only if the 'execve' call fails.  Determine whether
> +     /proc is mounted.  If not we return ENOSYS.  */
> +  struct stat64 st;
> +  if (stat64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
> +    save = ENOSYS;
> +
> +  if (fd != dirfd)
> +    __close_nocancel_nostatus (fd);
> +  __set_errno (save);
> +#endif
> +
> +  return -1;
> +}

This will make the function always return -1.  Hasn't it shown in
testing?

> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 5c8502f3d3..71ddaa2930 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2058,6 +2058,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index 4f0d3c1eb5..350687bf6f 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2224,6 +2224,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index e3b345b803..8ac4337b70 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2090,6 +2090,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 25f2d1c08f..425a44bc5f 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -140,6 +140,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index c4891479d3..057c77119b 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2170,6 +2170,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 143b0163b4..a85ea5a0bd 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2150,6 +2150,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index 13d374a031..5822ab2896 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index b2295f1937..30ead20668 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 4c786070d0..ac35f615aa 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2139,6 +2139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index aa9c6a4dca..76ae132755 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 5939588ad5..45ddc18ec1 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 92556c4237..3887748b90 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2188,6 +2188,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 26c93dff05..a32a53e330 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2197,6 +2197,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index f04b167788..a787e224fc 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2230,6 +2230,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index c2ca00709e..fc8a0a5e1c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2060,6 +2060,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index 0ea50dc851..e1aaaedfbd 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2350,6 +2350,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 1626c5351f..35a6b7829b 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2117,6 +2117,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index a66426eb4d..efa1bb3d9e 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2195,6 +2195,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index ab351873ae..27958ec30c 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2096,6 +2096,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index 22ceaa3d87..40a904ac55 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2065,6 +2065,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index d36f228192..621c547e32 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2062,6 +2062,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 59b4313280..f01f085b5b 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2186,6 +2186,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 266dcdfa08..c9225ae42e 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2113,6 +2113,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 4fff61818b..5e1cb8b63c 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2071,6 +2071,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index 102ed47a9c..de1d452320 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2168,6 +2168,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> 

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-11-27 14:58   ` Adhemerval Zanella
@ 2020-11-27 17:32     ` Florian Weimer
  2020-11-27 17:38       ` Adhemerval Zanella
  0 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-11-27 17:32 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: Alexandra Hájková, Alexandra Hájková,
	Adhemerval Zanella

* Adhemerval Zanella via Libc-alpha:

>> +{
>> +  /* Avoid implicit array coercion in syscall macros.  */
>> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
>> +#ifndef __ASSUME_EXECVEAT
>> +  if (errno != ENOSYS)
>> +    return -1;
>
> You need get the INLINE_SYSCALL_CALL and check if it was sucessful as well,
> instead of just check for the errno value. Also, this implementation always 
> return '-1' (as below):
>
>     int r = INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0],
>                                  flags);
>   #if __ASSUME_EXECVEAT
>     return r;
>   #else
>     if (r == 0 || errno != ENOSYS)
>       return r;
>     [...]

>> +  return -1;
>> +}
>
> This will make the function always return -1.  Hasn't it shown in
> testing?

This is the expected behavior for execve and execveat.  It does not
return successfully, which is why it is not necessary to check the value
of the INLINE_SYSCALL_CALL macro, either.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-11-27 17:32     ` Florian Weimer
@ 2020-11-27 17:38       ` Adhemerval Zanella
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2020-11-27 17:38 UTC (permalink / raw)
  To: Florian Weimer, Adhemerval Zanella via Libc-alpha
  Cc: Alexandra Hájková, Alexandra Hájková



On 27/11/2020 14:32, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
> 
>>> +{
>>> +  /* Avoid implicit array coercion in syscall macros.  */
>>> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
>>> +#ifndef __ASSUME_EXECVEAT
>>> +  if (errno != ENOSYS)
>>> +    return -1;
>>
>> You need get the INLINE_SYSCALL_CALL and check if it was sucessful as well,
>> instead of just check for the errno value. Also, this implementation always 
>> return '-1' (as below):
>>
>>     int r = INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0],
>>                                  flags);
>>   #if __ASSUME_EXECVEAT
>>     return r;
>>   #else
>>     if (r == 0 || errno != ENOSYS)
>>       return r;
>>     [...]
> 
>>> +  return -1;
>>> +}
>>
>> This will make the function always return -1.  Hasn't it shown in
>> testing?
> 
> This is the expected behavior for execve and execveat.  It does not
> return successfully, which is why it is not necessary to check the value
> of the INLINE_SYSCALL_CALL macro, either.

Right, forgot about the non return in case of success. So please ignore
that part of the review.


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-11-09 20:39 ` Adhemerval Zanella
@ 2020-12-03 13:55   ` Florian Weimer
  0 siblings, 0 replies; 46+ messages in thread
From: Florian Weimer @ 2020-12-03 13:55 UTC (permalink / raw)
  To: Adhemerval Zanella via Libc-alpha
  Cc: Alexandra Hájková, Adhemerval Zanella

* Adhemerval Zanella via Libc-alpha:

>> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
>> new file mode 100644
>> index 0000000000..7ebf397091
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/execveat.c
>> @@ -0,0 +1,67 @@
>> +/* Copyright (C) 1994-2020 Free Software Foundation, Inc.
>
> I think it should be solely 2020.

Some of the code was copied from fexecve.c, which has claims the years
1994-2020.  In general, I think we should preserve copyright years when
copying files.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


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

* [PATCH]  Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (7 preceding siblings ...)
  2020-11-26 21:28 ` Alexandra Hájková
@ 2020-12-03 14:20 ` Alexandra Hájková
  2020-12-03 14:37   ` Andreas Schwab
  2020-12-08 14:44   ` Adhemerval Zanella
  2021-03-15 21:42 ` Alexandra Hájková
                   ` (4 subsequent siblings)
  13 siblings, 2 replies; 46+ messages in thread
From: Alexandra Hájková @ 2020-12-03 14:20 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

 Also add the test for the new wrapper.
---
This version:
 * extends NEWS entry
 * adds various one line comments
 * uses exit $FOO instead of exit 3 to test if FOO was set properly
 * removes the implicit check
 * improves comments
 * removes unnecessary Makefile change
 * returns INLINE_SYSCALL_CALL return value



 NEWS                                          |   5 +
 posix/Makefile                                |   5 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  41 ++++
 posix/tst-execveat.c                          | 180 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
 sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  82 ++++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/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 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 38 files changed, 350 insertions(+), 2 deletions(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c

diff --git a/NEWS b/NEWS
index aa7bbf033b..5ffe99fa81 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,11 @@ Major new features:
   The 32-bit RISC-V port requires at least Linux 5.4, GCC 7.1 and binutils
   2.28.
 
+* The function execveat have been added and it operates similar to execve.
+  The syscall is already used to implement fexecve without require /proc to
+  be mounted.  Similar to fexecve, if the syscall is not supported a fallback
+  which access /proc is used.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The mallinfo function is marked deprecated.  Callers should call
diff --git a/posix/Makefile b/posix/Makefile
index 4bfc8d942c..ca678ad781 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -65,7 +65,8 @@ routines :=								      \
 	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
-	streams-compat
+	streams-compat                                            \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -102,7 +103,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
 		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
 		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
-		   tst-wordexp-nocmd
+		   tst-wordexp-nocmd tst-execveat
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
 		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
 		   tst-glob_lstat_compat tst-spawn4-compat
diff --git a/posix/Versions b/posix/Versions
index 7d06a6d0c0..9d07ce6c96 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.33 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..035ce50b28
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,41 @@
+/* execveat - execute program relative to a directory file descriptor
+   Copyright (C) 2020 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to DIFRD with
+ * arguments ARGV and environment ENVP.
+ * ARGV and ENVP are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (difrd < 0 || path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..7da501b2a7
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,180 @@
+/* Test execveat at the various corner cases.
+   Copyright (C) 2020 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit 3", NULL };
+  char *envp[] = { (char *) "FOO=BAR", NULL };
+  pid_t pid;
+  int status;
+
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail != 0)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations  */
+
+  /* Check the pathname relative to a valid dirfd.  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  chdir ("/bin");
+  /* Use the special value AT_FDCWD as dirfd.
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process.  */
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* Check the pathname relative to a valid dirfd with O_PATH.  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  /* Check absolute pathname, dirfd should be ignored.  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* Check relative pathname, where dirfd does not point to a directory.  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
+     should be ignored. */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  /* O_PATH
+     Obtain a file descriptor that can be used for two purposes: to
+     indicate a location in the filesystem tree and to perform
+     operations that act purely at the file descriptor level. */
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* Check the empty pathname. Dirfd is a regular file with O_PATH.  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
+     (If oldpath is an empty string, create a link to the file referenced
+     by olddirfd (which may have been obtained using the open(2) O_PATH flag) */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+ /* Same check for an empty pathname, but the different flags.  */
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  stat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  fchmod (fd_out, 0777);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+ /* Check the empty pathname. Dirfd is a symbolic link.  */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+ /* Same check for an empty pathname, but the different flags.  */
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+ /* Same check for an empty pathname, but the different flags.  */
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 32b8161619..b1117f2eda 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 7a5eb66b85..5afcd48075 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2181,6 +2181,7 @@ GLIBC_2.3.4 xdr_quad_t F
 GLIBC_2.3.4 xdr_u_quad_t F
 GLIBC_2.30 twalk_r F
 GLIBC_2.32 __libc_single_threaded D 0x1
+GLIBC_2.32 execveat F
 GLIBC_2.32 mach_print F
 GLIBC_2.32 mremap F
 GLIBC_2.32 sigabbrev_np F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4cc1c6a591..d281749621 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2155,6 +2155,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 26ad9845e4..9bbcda105e 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2237,6 +2237,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 3b0a47e967..25ce4024a8 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -139,6 +139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 9ab3924888..31675a4068 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -136,6 +136,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 14a84dac8f..b4b760fbc5 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2099,6 +2099,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..af3193e1d5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,82 @@
+/* execveat - execute program relative to a directory file descriptor
+   Copyright (C) 2020 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+    int ret;
+
+  /* Avoid implicit array coercion in syscall macros.  */
+    ret = INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return ret;
+
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+    return EINVAL;
+
+  int fd;
+  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
+    fd = dirfd;
+  else
+    {
+      int oflags = O_CLOEXEC;
+      if (flags & AT_SYMLINK_NOFOLLOW)
+        oflags |= O_NOFOLLOW;
+      fd = __openat_nocancel (dirfd, path, oflags);
+    }
+  if (fd < 0)
+    return ret;
+
+  struct fd_to_filename fdfilename;
+  const char *gfilename = __fd_to_filename (fd, &fdfilename);
+
+  /* We do not need the return value.  */
+  __execve (gfilename, argv, envp);
+
+  int save = errno;
+
+  /* We come here only if the 'execve' call fails.  Determine whether
+     /proc is mounted.  If not we return ENOSYS.  */
+  struct stat64 st;
+  if (stat64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
+    save = ENOSYS;
+
+  if (fd != dirfd)
+    __close_nocancel_nostatus (fd);
+  __set_errno (save);
+#endif
+
+  return ret;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 5c8502f3d3..71ddaa2930 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2058,6 +2058,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 4f0d3c1eb5..350687bf6f 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2224,6 +2224,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index e3b345b803..8ac4337b70 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2090,6 +2090,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 25f2d1c08f..425a44bc5f 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -140,6 +140,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index c4891479d3..057c77119b 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2170,6 +2170,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 143b0163b4..a85ea5a0bd 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2150,6 +2150,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 13d374a031..5822ab2896 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index b2295f1937..30ead20668 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 4c786070d0..ac35f615aa 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2139,6 +2139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index aa9c6a4dca..76ae132755 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 5939588ad5..45ddc18ec1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 92556c4237..3887748b90 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2188,6 +2188,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 26c93dff05..a32a53e330 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2197,6 +2197,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index f04b167788..a787e224fc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2230,6 +2230,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index c2ca00709e..fc8a0a5e1c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2060,6 +2060,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 0ea50dc851..e1aaaedfbd 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2350,6 +2350,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 1626c5351f..35a6b7829b 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2117,6 +2117,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a66426eb4d..efa1bb3d9e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2195,6 +2195,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ab351873ae..27958ec30c 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2096,6 +2096,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 22ceaa3d87..40a904ac55 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2065,6 +2065,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index d36f228192..621c547e32 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2062,6 +2062,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 59b4313280..f01f085b5b 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2186,6 +2186,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 266dcdfa08..c9225ae42e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2113,6 +2113,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 4fff61818b..5e1cb8b63c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2071,6 +2071,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 102ed47a9c..de1d452320 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2168,6 +2168,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
 GLIBC_2.32 pthread_attr_setsigmask_np F
 GLIBC_2.32 pthread_getaffinity_np F
 GLIBC_2.32 pthread_getattr_np F
+GLIBC_2.33 execveat F
 GLIBC_2.32 pthread_sigmask F
 GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
-- 
2.26.2


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

* Re: [PATCH]  Linux: Add execveat system call wrapper
  2020-12-03 14:20 ` Alexandra Hájková
@ 2020-12-03 14:37   ` Andreas Schwab
  2020-12-08 14:44   ` Adhemerval Zanella
  1 sibling, 0 replies; 46+ messages in thread
From: Andreas Schwab @ 2020-12-03 14:37 UTC (permalink / raw)
  To: Alexandra Hájková via Libc-alpha
  Cc: Alexandra Hájková, Alexandra Hájková

On Dez 03 2020, Alexandra Hájková via Libc-alpha wrote:

> +* The function execveat have been added and it operates similar to execve.
> +  The syscall is already used to implement fexecve without require /proc to

I think that should be "without requiring".

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 4cc1c6a591..d281749621 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2155,6 +2155,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F

The list must be sorted.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-12-03 14:20 ` Alexandra Hájková
  2020-12-03 14:37   ` Andreas Schwab
@ 2020-12-08 14:44   ` Adhemerval Zanella
  2020-12-08 15:18     ` Florian Weimer
  1 sibling, 1 reply; 46+ messages in thread
From: Adhemerval Zanella @ 2020-12-08 14:44 UTC (permalink / raw)
  To: libc-alpha, Alexandra Hájková; +Cc: Florian Weimer



On 03/12/2020 11:20, Alexandra Hájková via Libc-alpha wrote:
> From: Alexandra Hájková <ahajkova@redhat.com>
> 
>  Also add the test for the new wrapper.
> ---
> This version:
>  * extends NEWS entry
>  * adds various one line comments
>  * uses exit $FOO instead of exit 3 to test if FOO was set properly
>  * removes the implicit check
>  * improves comments
>  * removes unnecessary Makefile change
>  * returns INLINE_SYSCALL_CALL return value
> 
> 

There are some formatting issues on comment the test, I think we should
nonnull for envp as well, and some changes on the Linux implementation
fallback.  Also, you did not state if and how you have tested both the 
__NR_execveat syscall and the fallback. 

I also wondering if we could always check the fallback mechanism with
an internal test.  It would require to move implementation to
a different file (sysdeps/unix/sysv/linux/execveat_fallback.c) which
does:

  static int
  execveat_fallback (int dirfd, const char *path, char *const argv[],
                     char *const envp[], int flags)
  {
     if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
       [...]
  }

And on the Linux execveat.c does something like:

  #ifndef __ASSUME_EXECVEAT
  # include "execveat_fallback.c"
  #endif
  [...]
  int
  execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
            int flags)
  {
    INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
  #ifndef __ASSUME_EXECVEAT
    if (errno != ENOSYS)
      return -1;
  
    return execveat_fallback (dirfd, path, argv, envp, flags);
  #endif


And test similar to the one done for copy_file_range compat (added by
bad7a0c81f501fbbcc79af9eaa4b8254441c4a1f).

> 
>  NEWS                                          |   5 +
>  posix/Makefile                                |   5 +-
>  posix/Versions                                |   3 +
>  posix/execveat.c                              |  41 ++++
>  posix/tst-execveat.c                          | 180 ++++++++++++++++++
>  posix/unistd.h                                |   5 +
>  sysdeps/mach/hurd/i386/libc.abilist           |   1 +
>  sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
>  sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/execveat.c            |  82 ++++++++
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/ia64/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 +
>  .../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/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 +
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
>  38 files changed, 350 insertions(+), 2 deletions(-)
>  create mode 100644 posix/execveat.c
>  create mode 100644 posix/tst-execveat.c
>  create mode 100644 sysdeps/unix/sysv/linux/execveat.c
> 
> diff --git a/NEWS b/NEWS
> index aa7bbf033b..5ffe99fa81 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -28,6 +28,11 @@ Major new features:
>    The 32-bit RISC-V port requires at least Linux 5.4, GCC 7.1 and binutils
>    2.28.
>  
> +* The function execveat have been added and it operates similar to execve.
> +  The syscall is already used to implement fexecve without require /proc to
> +  be mounted.  Similar to fexecve, if the syscall is not supported a fallback
> +  which access /proc is used.
> +
>  Deprecated and removed features, and other changes affecting compatibility:
>  
>  * The mallinfo function is marked deprecated.  Callers should call

Ok.

> diff --git a/posix/Makefile b/posix/Makefile
> index 4bfc8d942c..ca678ad781 100644
> --- a/posix/Makefile
> +++ b/posix/Makefile
> @@ -65,7 +65,8 @@ routines :=								      \
>  	spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \
>  	posix_madvise							      \
>  	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
> -	streams-compat
> +	streams-compat                                            \
> +	execveat
>  
>  aux		:= init-posix environ
>  tests		:= test-errno tstgetopt testfnm runtests runptests \

Ok.

> @@ -102,7 +103,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
>  		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
>  		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
>  		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
> -		   tst-wordexp-nocmd
> +		   tst-wordexp-nocmd tst-execveat
>  tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
>  		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
>  		   tst-glob_lstat_compat tst-spawn4-compat

Ok.

> diff --git a/posix/Versions b/posix/Versions
> index 7d06a6d0c0..9d07ce6c96 100644
> --- a/posix/Versions
> +++ b/posix/Versions
> @@ -147,6 +147,9 @@ libc {
>    }
>    GLIBC_2.30 {
>    }
> +  GLIBC_2.33 {
> +    execveat;
> +  }
>    GLIBC_PRIVATE {
>      __libc_fork; __libc_pread; __libc_pwrite;
>      __nanosleep_nocancel; __pause_nocancel;
> diff --git a/posix/execveat.c b/posix/execveat.c
> new file mode 100644
> index 0000000000..035ce50b28
> --- /dev/null
> +++ b/posix/execveat.c
> @@ -0,0 +1,41 @@
> +/* execveat - execute program relative to a directory file descriptor
> +   Copyright (C) 2020 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 <errno.h>
> +#include <stddef.h>
> +#include <unistd.h>
> +
> +/* Replace the current process, executing PATH relative to DIFRD with
> + * arguments ARGV and environment ENVP.
> + * ARGV and ENVP are terminated by NULL pointers.  */
> +int
> +__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +            int flags)
> +{
> +  if (difrd < 0 || path == NULL || argv == NULL || envp == NULL)
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  __set_errno (ENOSYS);
> +  return -1;
> +}
> +stub_warning (execveat)
> +
> +weak_alias (__execveat, execveat)

Ok.

> diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
> new file mode 100644
> index 0000000000..7da501b2a7
> --- /dev/null
> +++ b/posix/tst-execveat.c
> @@ -0,0 +1,180 @@
> +/* Test execveat at the various corner cases.
> +   Copyright (C) 2020 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 <fcntl.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <support/xdlfcn.h>
> +#include <support/xstdio.h>
> +#include <support/xunistd.h>
> +#include <wait.h>
> +#include <support/test-driver.h>
> +
> +int
> +call_execveat (int fd, const char *pathname, int flags, int expected_fail,
> +               int num)
> +{
> +  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit 3", NULL };
> +  char *envp[] = { (char *) "FOO=BAR", NULL };
> +  pid_t pid;
> +  int status;
> +
> +  if (test_verbose > 0)
> +    printf ("call line number: %d\n", num);
> +
> +  pid = xfork ();
> +  if (pid == 0)
> +    {
> +      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
> +      if (errno == ENOSYS)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (errno == expected_fail)
> +        {
> +          if (test_verbose > 0)
> +            printf ("expected fail: errno %d\n", errno);
> +          _exit (0);
> +        }
> +      else
> +        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
> +    }
> +  xwaitpid (pid, &status, 0);
> +
> +  if (WIFEXITED (status))
> +    {
> +      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (expected_fail != 0)
> +        TEST_COMPARE (WEXITSTATUS (status), 0);
> +      else
> +        TEST_COMPARE (WEXITSTATUS (status), 3);
> +    }
> +  return 0;
> +}

Ok.

> +
> +static int
> +do_test (void)
> +{
> +  DIR *dirp;
> +  int fd, fd_out;
> +  char *tmp_dir, *symlink_name, *tmp_sh;
> +  struct stat st;
> +
> +  dirp = opendir ("/bin");
> +  if (dirp == NULL)
> +    FAIL_EXIT1 ("failed to open /bin");
> +  fd = dirfd (dirp);
> +
> +  /* Call execveat for various fd/pathname combinations  */

Missing period.

> +
> +  /* Check the pathname relative to a valid dirfd.  */
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  chdir ("/bin");

Check chdir return value or add a xchdir on libsupport.

> +  /* Use the special value AT_FDCWD as dirfd.
> +     If pathname is relative and dirfd is the special value AT_FDCWD, then
> +     pathname is interpreted relative to the current working directory of
> +     the calling process.  */
> +  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
> +  xclose (fd);

Ok.

> +#ifdef O_PATH
> +  /* Check the pathname relative to a valid dirfd with O_PATH.  */
> +  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +

Ok.

> +  /* Check absolute pathname, dirfd should be ignored.  */
> +  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
> +  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
> +  /* Same check for absolute pathname, but with input file descriptor
> +     openend with different flags.  The dirfd should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +#endif
> +

Ok.

> +  fd = xopen ("/usr", O_RDONLY, 0);
> +  /* Same check for absolute pathname, but with input file descriptor
> +     openend with different flags.  The dirfd should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +

Ok.

> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  /* Check relative pathname, where dirfd does not point to a directory.  */
> +  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
> +  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
> +     should be ignored. */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +

Ok.

> +#ifdef O_PATH
> +  /* O_PATH

I think this line in dangling here.

> +     Obtain a file descriptor that can be used for two purposes: to
> +     indicate a location in the filesystem tree and to perform
> +     operations that act purely at the file descriptor level. */

Double space after period.  There also other occurences below.

> +  fd = xopen ("/bin/sh", O_PATH, 0);
> +  /* Check the empty pathname. Dirfd is a regular file with O_PATH.  */
> +  call_execveat (fd, "", 0, ENOENT, __LINE__);
> +  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
> +     (If oldpath is an empty string, create a link to the file referenced
> +     by olddirfd (which may have been obtained using the open(2) O_PATH flag) */
> +  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);

Ok.

> + /* Same check for an empty pathname, but the different flags.  */
> +  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
> +  xclose (fd);
> +

Ok.

> +  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
> +  symlink_name = xasprintf ("%s/symlink", tmp_dir);
> +  xsymlink ("tmp_sh", symlink_name);
> +  add_temp_file (symlink_name);
> +  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
> +  add_temp_file (tmp_sh);
> +  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
> +  stat ("/bin/sh", &st);

Use xstat (it would require use a stat64 for 'st' as well). 

> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
> +  fchmod (fd_out, 0777);

Check the return value of fchmod or add a xfchmod on libsupport.

> +  xclose (fd);
> +  xclose (fd_out);
> +  fd_out = xopen (symlink_name, O_PATH, 0);
> +
> + /* Check the empty pathname. Dirfd is a symbolic link.  */
> +  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
> + /* Same check for an empty pathname, but the different flags.  */
> +  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
> + /* Same check for an empty pathname, but the different flags.  */
> +  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
> +                 __LINE__);
> +  xclose (fd_out);
> +  free (symlink_name);
> +  free (tmp_sh);
> +  free (tmp_dir);
> +#endif

Ok.

> +
> +  /* Call execveat with closed fd, we expect this to fail with EBADF  */
> +  call_execveat (fd, "sh", 0, EBADF, __LINE__);
> +  /* Call execveat with closed fd, we expect this to pass because the pathname is
> +     absolute  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/posix/unistd.h b/posix/unistd.h
> index 32b8161619..b1117f2eda 100644
> --- a/posix/unistd.h
> +++ b/posix/unistd.h
> @@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
>  /* An alias for `euidaccess', used by some other systems.  */
>  extern int eaccess (const char *__name, int __type)
>       __THROW __nonnull ((1));
> +
> +/* Execute program relative to a directory file descriptor.  */
> +extern int execveat (int __fd, const char *__path, char *const __argv[],
> +                     char *const __envp[], int __flags)
> +    __THROW __nonnull ((2, 3));
>  #endif

I think we should make '__envp' as nonull as well, POSIX indicates that 
is should be an array of character pointers to null-terminated strings.

Linux does allow NULL envp though.

>  
>  #ifdef __USE_ATFILE
> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 7a5eb66b85..5afcd48075 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2181,6 +2181,7 @@ GLIBC_2.3.4 xdr_quad_t F
>  GLIBC_2.3.4 xdr_u_quad_t F
>  GLIBC_2.30 twalk_r F
>  GLIBC_2.32 __libc_single_threaded D 0x1
> +GLIBC_2.32 execveat F
>  GLIBC_2.32 mach_print F
>  GLIBC_2.32 mremap F
>  GLIBC_2.32 sigabbrev_np F
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 4cc1c6a591..d281749621 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2155,6 +2155,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 26ad9845e4..9bbcda105e 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2237,6 +2237,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index 3b0a47e967..25ce4024a8 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -139,6 +139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index 9ab3924888..31675a4068 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -136,6 +136,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index 14a84dac8f..b4b760fbc5 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2099,6 +2099,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
> new file mode 100644
> index 0000000000..af3193e1d5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat.c
> @@ -0,0 +1,82 @@
> +/* execveat - execute program relative to a directory file descriptor
> +   Copyright (C) 2020 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +    int ret;
> +
> +  /* Avoid implicit array coercion in syscall macros.  */
> +    ret = INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return ret;

As Florian has pointed out, the ret code is not really required here
(it will be always -1 for INLINE_SYSCALL_CALL).

> +
> +  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
> +    return EINVAL;

It should be INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL) (which set
errno to EINVAL and returns -1).

> +
> +  int fd;
> +  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
> +    fd = dirfd;
> +  else
> +    {
> +      int oflags = O_CLOEXEC;
> +      if (flags & AT_SYMLINK_NOFOLLOW)
> +        oflags |= O_NOFOLLOW;
> +      fd = __openat_nocancel (dirfd, path, oflags);
> +    }
> +  if (fd < 0)
> +    return ret;

It should be INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADFD), for the
case where 'dirfd' is negative.

> +
> +  struct fd_to_filename fdfilename;
> +  const char *gfilename = __fd_to_filename (fd, &fdfilename);
> +
> +  /* We do not need the return value.  */
> +  __execve (gfilename, argv, envp);
> +
> +  int save = errno;
> +
> +  /* We come here only if the 'execve' call fails.  Determine whether
> +     /proc is mounted.  If not we return ENOSYS.  */
> +  struct stat64 st;
> +  if (stat64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)

Maybe use FD_TO_FILENAME_PREFIX here.

> +    save = ENOSYS;
> +
> +  if (fd != dirfd)
> +    __close_nocancel_nostatus (fd);
> +  __set_errno (save);
> +#endif
> +
> +  return ret;
> +}
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 5c8502f3d3..71ddaa2930 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2058,6 +2058,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index 4f0d3c1eb5..350687bf6f 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2224,6 +2224,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index e3b345b803..8ac4337b70 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2090,6 +2090,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 25f2d1c08f..425a44bc5f 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -140,6 +140,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index c4891479d3..057c77119b 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2170,6 +2170,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 143b0163b4..a85ea5a0bd 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2150,6 +2150,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index 13d374a031..5822ab2896 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index b2295f1937..30ead20668 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 4c786070d0..ac35f615aa 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2139,6 +2139,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index aa9c6a4dca..76ae132755 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2147,6 +2147,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 5939588ad5..45ddc18ec1 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2141,6 +2141,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 92556c4237..3887748b90 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2188,6 +2188,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 26c93dff05..a32a53e330 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2197,6 +2197,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index f04b167788..a787e224fc 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2230,6 +2230,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index c2ca00709e..fc8a0a5e1c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2060,6 +2060,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index 0ea50dc851..e1aaaedfbd 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2350,6 +2350,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 1626c5351f..35a6b7829b 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2117,6 +2117,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index a66426eb4d..efa1bb3d9e 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2195,6 +2195,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index ab351873ae..27958ec30c 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2096,6 +2096,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index 22ceaa3d87..40a904ac55 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2065,6 +2065,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index d36f228192..621c547e32 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2062,6 +2062,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 59b4313280..f01f085b5b 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2186,6 +2186,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 266dcdfa08..c9225ae42e 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2113,6 +2113,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 4fff61818b..5e1cb8b63c 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2071,6 +2071,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index 102ed47a9c..de1d452320 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2168,6 +2168,7 @@ GLIBC_2.32 pthread_attr_setaffinity_np F
>  GLIBC_2.32 pthread_attr_setsigmask_np F
>  GLIBC_2.32 pthread_getaffinity_np F
>  GLIBC_2.32 pthread_getattr_np F
> +GLIBC_2.33 execveat F
>  GLIBC_2.32 pthread_sigmask F
>  GLIBC_2.32 sigabbrev_np F
>  GLIBC_2.32 sigdescr_np F
> 

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-12-08 14:44   ` Adhemerval Zanella
@ 2020-12-08 15:18     ` Florian Weimer
  2020-12-08 16:41       ` Adhemerval Zanella
  0 siblings, 1 reply; 46+ messages in thread
From: Florian Weimer @ 2020-12-08 15:18 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Alexandra Hájková

* Adhemerval Zanella:

> On 03/12/2020 11:20, Alexandra Hájková via Libc-alpha wrote:
>> From: Alexandra Hájková <ahajkova@redhat.com>
>> 
>>  Also add the test for the new wrapper.
>> ---
>> This version:
>>  * extends NEWS entry
>>  * adds various one line comments
>>  * uses exit $FOO instead of exit 3 to test if FOO was set properly
>>  * removes the implicit check
>>  * improves comments
>>  * removes unnecessary Makefile change
>>  * returns INLINE_SYSCALL_CALL return value
>> 
>> 
>
> There are some formatting issues on comment the test, I think we should
> nonnull for envp as well, and some changes on the Linux implementation

I think envp == NULL is a well-documented Linux extension, in wide use
with execve.

Thanks,
Florian
-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2020-12-08 15:18     ` Florian Weimer
@ 2020-12-08 16:41       ` Adhemerval Zanella
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2020-12-08 16:41 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha, Alexandra Hájková



On 08/12/2020 12:18, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 03/12/2020 11:20, Alexandra Hájková via Libc-alpha wrote:
>>> From: Alexandra Hájková <ahajkova@redhat.com>
>>>
>>>  Also add the test for the new wrapper.
>>> ---
>>> This version:
>>>  * extends NEWS entry
>>>  * adds various one line comments
>>>  * uses exit $FOO instead of exit 3 to test if FOO was set properly
>>>  * removes the implicit check
>>>  * improves comments
>>>  * removes unnecessary Makefile change
>>>  * returns INLINE_SYSCALL_CALL return value
>>>
>>>
>>
>> There are some formatting issues on comment the test, I think we should
>> nonnull for envp as well, and some changes on the Linux implementation
> 
> I think envp == NULL is a well-documented Linux extension, in wide use
> with execve.

But the generic interface returns EINVAL for NULL envp.  Should we change
it to accept NULL then?

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

* [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (8 preceding siblings ...)
  2020-12-03 14:20 ` Alexandra Hájková
@ 2021-03-15 21:42 ` Alexandra Hájková
  2021-03-15 22:12   ` Joseph Myers
  2021-03-15 22:17   ` Dmitry V. Levin
  2021-03-24 13:54 ` Alexandra Hájková
                   ` (3 subsequent siblings)
  13 siblings, 2 replies; 46+ messages in thread
From: Alexandra Hájková @ 2021-03-15 21:42 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

 Also add the test for the new wrapper.
---
This patch depends on Florian Weimer's patch: "Add support for static
internal tests" which haven't been reviewed yet
This versiond adds:
* check the fallback mechanism with
an internal test
* uses xfchmod, xchdir and xstat
* some cosmetics

 NEWS                                          |   5 +
 include/unistd.h                              |   4 +
 posix/Makefile                                |   4 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  41 ++++
 posix/tst-execveat-compat.c                   |  32 ++++
 posix/tst-execveat.c                          | 180 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
 sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  54 ++++++
 sysdeps/unix/sysv/linux/execveat_fallback.c   |  69 +++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/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 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   2 +-
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 41 files changed, 427 insertions(+), 2 deletions(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat-compat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat_fallback.c

diff --git a/NEWS b/NEWS
index aa0f10a891..4fa20e2fa3 100644
--- a/NEWS
+++ b/NEWS
@@ -88,6 +88,11 @@ Major new features:
   The latest GCC available at this time (10.2) does not support this level of
   fortification.
 
+* The function execveat has been added and it operates similar to execve.
+  The syscall is already used to implement fexecve without requiring /proc to
+  be mounted.  Similar to fexecve, if the syscall is not supported a fallback
+  which access /proc is used.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The mallinfo function is marked deprecated.  Callers should call
diff --git a/include/unistd.h b/include/unistd.h
index 54becbc9eb..7296164af8 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -192,6 +192,10 @@ extern int __libc_pause (void);
 extern int __getlogin_r_loginuid (char *name, size_t namesize)
      attribute_hidden;
 
+extern int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                     char *const envp[], int flags);
+
 #  if IS_IN (rtld)
 #   include <dl-unistd.h>
 #  endif
diff --git a/posix/Makefile b/posix/Makefile
index be0c72f0bb..f0ebe34c8e 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -66,7 +66,8 @@ routines :=								      \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
 	streams-compat \
-	shm-directory
+	shm-directory                                                         \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -118,6 +119,7 @@ endif
 
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
 		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3
+tests-static-internal += tst-execveat-compat
 tests-container := bug-ga2
 xtests		:= tst-getaddrinfo4 tst-getaddrinfo5 tst-sched_rr_get_interval
 ifeq (yes,$(build-shared))
diff --git a/posix/Versions b/posix/Versions
index cfd3819966..486c03d8f2 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.33 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..b79492bf93
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,41 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to DIFRD with
+ * arguments ARGV and environment ENVP.
+ * ARGV and ENVP are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (difrd < 0 || path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat-compat.c b/posix/tst-execveat-compat.c
new file mode 100644
index 0000000000..082c67690d
--- /dev/null
+++ b/posix/tst-execveat-compat.c
@@ -0,0 +1,32 @@
+/* Test the fallback implementation of execveat.
+   Copyright (C) 2021 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Get the declaration of the official execveat function.  */
+#include <unistd.h>
+
+/* Compile a local version of execveat.  */
+#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
+
+int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                     char *const envp[], int flags);
+
+/* Re-use the test, but run it against copy_file_range_compat defined
+   above.  */
+#define execveat execveat_fallback
+#include "tst-execveat.c"
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..52779de8cd
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,180 @@
+/* Test execveat at the various corner cases.
+   Copyright (C) 2021 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *envp[] = { (char *) "FOO=3", NULL };
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
+  pid_t pid;
+  int status;
+
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail != 0)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat64 st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations.  */
+
+  /* Check the pathname relative to a valid dirfd.  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xchdir ("/bin");
+  /* Use the special value AT_FDCWD as dirfd. Quoting open(2):
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process.  */
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* Check the pathname relative to a valid dirfd with O_PATH.  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  /* Check absolute pathname, dirfd should be ignored.  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* Check relative pathname, where dirfd does not point to a directory.  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
+     should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  /* Quoting open(2): O_PATH
+     Obtain a file descriptor that can be used for two purposes: to
+     indicate a location in the filesystem tree and to perform
+     operations that act purely at the file descriptor level.  */
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* Check the empty pathname.  Dirfd is a regular file with O_PATH.  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
+     Quoting open(2):
+     If oldpath is an empty string, create a link to the file referenced
+     by olddirfd (which may have been obtained using the open(2) O_PATH flag. */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  /* Create a temporary directory "tmp_dir" and create a symbolik link tmp_sh
+     pointing to /bin/sh inside the tmp_dir. Open dirfd as a symbolic link.  */
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  xstat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  xfchmod (fd_out, 0700);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+ /* Check the empty pathname. Dirfd is a symbolic link.  */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF.  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 3f22763379..d9d8929f71 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index e10a286d2e..6571c0483a 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2192,6 +2192,7 @@ GLIBC_2.32 thrd_equal F
 GLIBC_2.32 thrd_sleep F
 GLIBC_2.32 thrd_yield F
 GLIBC_2.33 __x86_get_cpuid_feature_leaf F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index bac795262d..30b0a2b6f5 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2160,6 +2160,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 897f70db22..af137727ae 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2242,6 +2242,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 094236f713..99dbdc8108 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -144,6 +144,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 2bb4d31e81..c63f471d05 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -141,6 +141,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index d4291fecfb..a2757b60c2 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2104,6 +2104,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..0576f36b98
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,54 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+#ifndef __ASSUME_EXECVEAT
+# include "execveat_fallback.c"
+#endif
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+    INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return -1;
+
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  return __execveat_fallback (dirfd, path, argv, envp, flags);
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
new file mode 100644
index 0000000000..c4a37d3799
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
@@ -0,0 +1,69 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                   char *const envp[], int flags)
+{
+    int fd;
+
+    if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
+        fd = dirfd;
+    else
+    {
+        int oflags = O_CLOEXEC;
+        if (flags & AT_SYMLINK_NOFOLLOW)
+            oflags |= O_NOFOLLOW;
+        fd = __openat_nocancel (dirfd, path, oflags);
+    }
+    if (fd < 0)
+        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADFD);
+
+    struct fd_to_filename fdfilename;
+    const char *gfilename = __fd_to_filename (fd, &fdfilename);
+
+    /* We do not need the return value.  */
+    __execve (gfilename, argv, envp);
+
+    int save = errno;
+
+    /* We come here only if the 'execve' call fails.  Determine whether
+       /proc is mounted.  If not we return ENOSYS.  */
+    struct stat64 st;
+    if (__stat64 (FD_TO_FILENAME_PREFIX, &st) != 0 && errno == ENOENT)
+        save = ENOSYS;
+
+    if (fd != dirfd)
+        __close_nocancel_nostatus (fd);
+    __set_errno (save);
+
+    return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 1fd2a862f6..adb1ec3045 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2063,6 +2063,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 943331f01e..c49865ffb6 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2230,6 +2230,7 @@ GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
 GLIBC_2.33 __x86_get_cpuid_feature_leaf F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f530151bde..ca2c0325a5 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2095,6 +2095,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 6e76b6dcaa..f7e2a1c1c6 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -145,6 +145,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 7541b8289f..41c37f5ec2 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2175,6 +2175,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 6cf1936c42..e39ccd2e30 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2155,6 +2155,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 98730ebcda..7d8c254d35 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2152,6 +2152,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 92fa6cbc73..7232f19c34 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2146,6 +2146,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 265a49e74e..b6877dec6a 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2144,6 +2144,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index cfa5e1111b..1000248984 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2152,6 +2152,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 8c03ac52cd..289d9d9131 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2146,6 +2146,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 17f5609e06..7023145dfe 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2193,6 +2193,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 76a16e2a6d..66ad1cf003 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2202,6 +2202,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 697f072fd4..134265e333 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2235,6 +2235,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 2647bb51f1..ba1dda9adc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2065,6 +2065,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 036b1c8345..b814ea3217 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2355,6 +2355,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index fb5ad9909f..c191ed5573 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2122,6 +2122,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index cead75acc5..e0ea7697c8 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2200,6 +2200,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 31366dd7e6..e81390ffe9 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2101,6 +2101,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index a3a8be8910..2d0a38c7c7 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2070,6 +2070,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 8f505c5045..7bbeb33ae7 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2067,6 +2067,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 53ef6304f1..3ce6be125a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2191,6 +2191,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index eba0cb156d..2ab9d0e7fd 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2118,6 +2118,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 17ce5dfd58..d555d074e3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2076,7 +2076,7 @@ GLIBC_2.32 sigabbrev_np F
 GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
-GLIBC_2.33 __x86_get_cpuid_feature_leaf F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 17a1c83903..b12a0a4520 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2174,6 +2174,7 @@ GLIBC_2.32 sigdescr_np F
 GLIBC_2.32 strerrordesc_np F
 GLIBC_2.32 strerrorname_np F
 GLIBC_2.33 __x86_get_cpuid_feature_leaf F
+GLIBC_2.33 execveat F
 GLIBC_2.33 fstat F
 GLIBC_2.33 fstat64 F
 GLIBC_2.33 fstatat F
-- 
2.26.2


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-03-15 21:42 ` Alexandra Hájková
@ 2021-03-15 22:12   ` Joseph Myers
  2021-03-15 22:17   ` Dmitry V. Levin
  1 sibling, 0 replies; 46+ messages in thread
From: Joseph Myers @ 2021-03-15 22:12 UTC (permalink / raw)
  To: Alexandra Hájková; +Cc: libc-alpha, Alexandra Hájková

Since 2.33 has been released, this needs updating to use 2.34 symbol 
versions and to put the NEWS entry in the NEWS section for 2.34 not that 
for 2.33.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-03-15 21:42 ` Alexandra Hájková
  2021-03-15 22:12   ` Joseph Myers
@ 2021-03-15 22:17   ` Dmitry V. Levin
  1 sibling, 0 replies; 46+ messages in thread
From: Dmitry V. Levin @ 2021-03-15 22:17 UTC (permalink / raw)
  To: Alexandra Hájková; +Cc: libc-alpha, Alexandra Hájková

On Mon, Mar 15, 2021 at 10:42:05PM +0100, Alexandra Hájková via Libc-alpha wrote:
[...]
> +/* Replace the current process, executing PATH relative to DIFRD with
> + * arguments ARGV and environment ENVP.
> + * ARGV and ENVP are terminated by NULL pointers.  */
> +int
> +__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +            int flags)
> +{
> +  if (difrd < 0 || path == NULL || argv == NULL || envp == NULL)
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  __set_errno (ENOSYS);
> +  return -1;
> +}
> +stub_warning (execveat)

I'm not sure how picky we are about stubs, but "difrd < 0" looks odd
anyway: it rules out AT_FDCWD, and if "path" is absolute, then "dirfd"
shall be ignored anyway.  I suggest to drop this "difrd < 0" check.


-- 
ldv

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

* [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (9 preceding siblings ...)
  2021-03-15 21:42 ` Alexandra Hájková
@ 2021-03-24 13:54 ` Alexandra Hájková
  2021-03-26 20:36   ` Adhemerval Zanella
  2021-04-05 16:32 ` Alexandra Hájková
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 46+ messages in thread
From: Alexandra Hájková @ 2021-03-24 13:54 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

 Also add the test for the new wrapper.
---
This version:
* was updated  to use 2.24 symbol version
* "difrd < 0" check was dropped

 NEWS                                          |   5 +
 include/unistd.h                              |   4 +
 posix/Makefile                                |   4 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  41 ++++
 posix/tst-execveat-compat.c                   |  32 ++++
 posix/tst-execveat.c                          | 180 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
 sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  54 ++++++
 sysdeps/unix/sysv/linux/execveat_fallback.c   |  69 +++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/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 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 41 files changed, 427 insertions(+), 1 deletion(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat-compat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat_fallback.c

diff --git a/NEWS b/NEWS
index aa0f10a891..a61071b494 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,11 @@ Major new features:
   a dump of information related to IFUNC resolver operation and
   glibc-hwcaps subdirectory selection.
 
+* The function execveat has been added and it operates similar to execve.
+  The syscall is already used to implement fexecve without requiring /proc to
+  be mounted.  Similar to fexecve, if the syscall is not supported a fallback
+  which access /proc is used.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/include/unistd.h b/include/unistd.h
index 54becbc9eb..2dd901ed09 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -192,6 +192,10 @@ extern int __libc_pause (void);
 extern int __getlogin_r_loginuid (char *name, size_t namesize)
      attribute_hidden;
 
+extern int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                   char *const envp[], int flags);
+
 #  if IS_IN (rtld)
 #   include <dl-unistd.h>
 #  endif
diff --git a/posix/Makefile b/posix/Makefile
index be0c72f0bb..f0ebe34c8e 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -66,7 +66,8 @@ routines :=								      \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
 	streams-compat \
-	shm-directory
+	shm-directory                                                         \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -118,6 +119,7 @@ endif
 
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
 		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3
+tests-static-internal += tst-execveat-compat
 tests-container := bug-ga2
 xtests		:= tst-getaddrinfo4 tst-getaddrinfo5 tst-sched_rr_get_interval
 ifeq (yes,$(build-shared))
diff --git a/posix/Versions b/posix/Versions
index cfd3819966..b77e251e00 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.34 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..3f0d0820e7
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,41 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to DIFRD with
+ * arguments ARGV and environment ENVP.
+ * ARGV and ENVP are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat-compat.c b/posix/tst-execveat-compat.c
new file mode 100644
index 0000000000..082c67690d
--- /dev/null
+++ b/posix/tst-execveat-compat.c
@@ -0,0 +1,32 @@
+/* Test the fallback implementation of execveat.
+   Copyright (C) 2021 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Get the declaration of the official execveat function.  */
+#include <unistd.h>
+
+/* Compile a local version of execveat.  */
+#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
+
+int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                     char *const envp[], int flags);
+
+/* Re-use the test, but run it against copy_file_range_compat defined
+   above.  */
+#define execveat execveat_fallback
+#include "tst-execveat.c"
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..52779de8cd
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,180 @@
+/* Test execveat at the various corner cases.
+   Copyright (C) 2021 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *envp[] = { (char *) "FOO=3", NULL };
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
+  pid_t pid;
+  int status;
+
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail != 0)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat64 st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations.  */
+
+  /* Check the pathname relative to a valid dirfd.  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xchdir ("/bin");
+  /* Use the special value AT_FDCWD as dirfd. Quoting open(2):
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process.  */
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* Check the pathname relative to a valid dirfd with O_PATH.  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  /* Check absolute pathname, dirfd should be ignored.  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* Check relative pathname, where dirfd does not point to a directory.  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
+     should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  /* Quoting open(2): O_PATH
+     Obtain a file descriptor that can be used for two purposes: to
+     indicate a location in the filesystem tree and to perform
+     operations that act purely at the file descriptor level.  */
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* Check the empty pathname.  Dirfd is a regular file with O_PATH.  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
+     Quoting open(2):
+     If oldpath is an empty string, create a link to the file referenced
+     by olddirfd (which may have been obtained using the open(2) O_PATH flag. */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  /* Create a temporary directory "tmp_dir" and create a symbolik link tmp_sh
+     pointing to /bin/sh inside the tmp_dir. Open dirfd as a symbolic link.  */
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  xstat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  xfchmod (fd_out, 0700);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+ /* Check the empty pathname. Dirfd is a symbolic link.  */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF.  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 3f22763379..d9d8929f71 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index e10a286d2e..bef66d105c 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2204,6 +2204,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index bac795262d..51f34d0f6d 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2172,3 +2172,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 897f70db22..7da53174ef 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2254,6 +2254,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 094236f713..108c41ae24 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -156,6 +156,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 2bb4d31e81..a995a356a4 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -153,6 +153,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index d4291fecfb..33d0dfb2b7 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2116,3 +2116,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..0576f36b98
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,54 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+#ifndef __ASSUME_EXECVEAT
+# include "execveat_fallback.c"
+#endif
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+    INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return -1;
+
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  return __execveat_fallback (dirfd, path, argv, envp, flags);
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
new file mode 100644
index 0000000000..c4a37d3799
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
@@ -0,0 +1,69 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                   char *const envp[], int flags)
+{
+    int fd;
+
+    if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
+        fd = dirfd;
+    else
+    {
+        int oflags = O_CLOEXEC;
+        if (flags & AT_SYMLINK_NOFOLLOW)
+            oflags |= O_NOFOLLOW;
+        fd = __openat_nocancel (dirfd, path, oflags);
+    }
+    if (fd < 0)
+        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADFD);
+
+    struct fd_to_filename fdfilename;
+    const char *gfilename = __fd_to_filename (fd, &fdfilename);
+
+    /* We do not need the return value.  */
+    __execve (gfilename, argv, envp);
+
+    int save = errno;
+
+    /* We come here only if the 'execve' call fails.  Determine whether
+       /proc is mounted.  If not we return ENOSYS.  */
+    struct stat64 st;
+    if (__stat64 (FD_TO_FILENAME_PREFIX, &st) != 0 && errno == ENOENT)
+        save = ENOSYS;
+
+    if (fd != dirfd)
+        __close_nocancel_nostatus (fd);
+    __set_errno (save);
+
+    return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 1fd2a862f6..e1430bb232 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2075,6 +2075,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 943331f01e..7cb2d0dd6d 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2242,6 +2242,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f530151bde..2171cd3cb2 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2107,6 +2107,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 6e76b6dcaa..388eb76abf 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -157,6 +157,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 7541b8289f..067ed53f2b 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2187,6 +2187,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 6cf1936c42..a792461b45 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2167,3 +2167,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 98730ebcda..0e09fe6322 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2164,3 +2164,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 92fa6cbc73..5d1b0b3d78 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2158,6 +2158,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 265a49e74e..a278c0a092 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2156,6 +2156,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index cfa5e1111b..054d3436eb 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2164,6 +2164,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 8c03ac52cd..c22ef9f196 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2158,6 +2158,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 17f5609e06..c356e9f863 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2205,3 +2205,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 76a16e2a6d..d1de01f91d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2214,6 +2214,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 697f072fd4..a1d52887bb 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2247,6 +2247,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 2647bb51f1..10cdabb11c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2077,6 +2077,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 036b1c8345..70792ed87b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2367,3 +2367,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index fb5ad9909f..9b71083136 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2134,3 +2134,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index cead75acc5..aba76fbadd 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 31366dd7e6..6a5a765f4b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2113,6 +2113,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index a3a8be8910..b6629c244f 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2082,6 +2082,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 8f505c5045..e15ab4c569 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2079,6 +2079,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 53ef6304f1..11cad082d8 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2203,6 +2203,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index eba0cb156d..0ff8cb8739 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2130,6 +2130,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 17ce5dfd58..040d44d3a8 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2089,6 +2089,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 17a1c83903..4355e06891 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2186,3 +2186,4 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
-- 
2.26.3


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-03-24 13:54 ` Alexandra Hájková
@ 2021-03-26 20:36   ` Adhemerval Zanella
  2021-04-02 12:13     ` Alexandra Hájková
  0 siblings, 1 reply; 46+ messages in thread
From: Adhemerval Zanella @ 2021-03-26 20:36 UTC (permalink / raw)
  To: libc-alpha, Alexandra Hájková



On 24/03/2021 10:54, Alexandra Hájková via Libc-alpha wrote:
> From: Alexandra Hájková <ahajkova@redhat.com>
> 
>  Also add the test for the new wrapper.
> ---
> This version:
> * was updated  to use 2.24 symbol version
> * "difrd < 0" check was dropped

Patch looks in general, some comments below.

> 
>  NEWS                                          |   5 +
>  include/unistd.h                              |   4 +
>  posix/Makefile                                |   4 +-
>  posix/Versions                                |   3 +
>  posix/execveat.c                              |  41 ++++
>  posix/tst-execveat-compat.c                   |  32 ++++
>  posix/tst-execveat.c                          | 180 ++++++++++++++++++
>  posix/unistd.h                                |   5 +
>  sysdeps/mach/hurd/i386/libc.abilist           |   1 +
>  sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   1 +
>  sysdeps/unix/sysv/linux/alpha/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/csky/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/execveat.c            |  54 ++++++
>  sysdeps/unix/sysv/linux/execveat_fallback.c   |  69 +++++++
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/ia64/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 +
>  .../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/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 +
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
>  41 files changed, 427 insertions(+), 1 deletion(-)
>  create mode 100644 posix/execveat.c
>  create mode 100644 posix/tst-execveat-compat.c
>  create mode 100644 posix/tst-execveat.c
>  create mode 100644 sysdeps/unix/sysv/linux/execveat.c
>  create mode 100644 sysdeps/unix/sysv/linux/execveat_fallback.c
> 
> diff --git a/NEWS b/NEWS
> index aa0f10a891..a61071b494 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -18,6 +18,11 @@ Major new features:
>    a dump of information related to IFUNC resolver operation and
>    glibc-hwcaps subdirectory selection.
>  
> +* The function execveat has been added and it operates similar to execve.
> +  The syscall is already used to implement fexecve without requiring /proc to
> +  be mounted.  Similar to fexecve, if the syscall is not supported a fallback
> +  which access /proc is used.
> +
>  Deprecated and removed features, and other changes affecting compatibility:
>  
>    [Add deprecations, removals and changes affecting compatibility here]

Ok.

> diff --git a/include/unistd.h b/include/unistd.h
> index 54becbc9eb..2dd901ed09 100644
> --- a/include/unistd.h
> +++ b/include/unistd.h
> @@ -192,6 +192,10 @@ extern int __libc_pause (void);
>  extern int __getlogin_r_loginuid (char *name, size_t namesize)
>       attribute_hidden;
>  
> +extern int
> +__execveat_fallback (int dirfd, const char *path, char *const argv[],
> +                   char *const envp[], int flags);

Add attribute_hidden since it is an internal function.  But I think 
this is not really required, since you include the fallback file
directly on both the testcase and the execveat.c (so there is no need
of forward declaration).

> +
>  #  if IS_IN (rtld)
>  #   include <dl-unistd.h>
>  #  endif
> diff --git a/posix/Makefile b/posix/Makefile
> index be0c72f0bb..f0ebe34c8e 100644
> --- a/posix/Makefile
> +++ b/posix/Makefile
> @@ -66,7 +66,8 @@ routines :=								      \
>  	posix_madvise							      \
>  	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
>  	streams-compat \
> -	shm-directory
> +	shm-directory                                                         \
> +	execveat
>  
>  aux		:= init-posix environ
>  tests		:= test-errno tstgetopt testfnm runtests runptests \

Ok.

> @@ -118,6 +119,7 @@ endif
>  
>  tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
>  		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3
> +tests-static-internal += tst-execveat-compat
>  tests-container := bug-ga2
>  xtests		:= tst-getaddrinfo4 tst-getaddrinfo5 tst-sched_rr_get_interval
>  ifeq (yes,$(build-shared))

Ok.

> diff --git a/posix/Versions b/posix/Versions
> index cfd3819966..b77e251e00 100644
> --- a/posix/Versions
> +++ b/posix/Versions
> @@ -147,6 +147,9 @@ libc {
>    }
>    GLIBC_2.30 {
>    }
> +  GLIBC_2.34 {
> +    execveat;
> +  }
>    GLIBC_PRIVATE {
>      __libc_fork; __libc_pread; __libc_pwrite;
>      __nanosleep_nocancel; __pause_nocancel;

Ok.

> diff --git a/posix/execveat.c b/posix/execveat.c
> new file mode 100644
> index 0000000000..3f0d0820e7
> --- /dev/null
> +++ b/posix/execveat.c
> @@ -0,0 +1,41 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <unistd.h>
> +
> +/* Replace the current process, executing PATH relative to DIFRD with
> + * arguments ARGV and environment ENVP.
> + * ARGV and ENVP are terminated by NULL pointers.  */
> +int
> +__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +            int flags)
> +{
> +  if (path == NULL || argv == NULL || envp == NULL)
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  __set_errno (ENOSYS);
> +  return -1;
> +}
> +stub_warning (execveat)
> +
> +weak_alias (__execveat, execveat)

Ok.

> diff --git a/posix/tst-execveat-compat.c b/posix/tst-execveat-compat.c
> new file mode 100644
> index 0000000000..082c67690d
> --- /dev/null
> +++ b/posix/tst-execveat-compat.c
> @@ -0,0 +1,32 @@
> +/* Test the fallback implementation of execveat.
> +   Copyright (C) 2021 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* Get the declaration of the official execveat function.  */
> +#include <unistd.h>
> +
> +/* Compile a local version of execveat.  */
> +#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
> +
> +int
> +__execveat_fallback (int dirfd, const char *path, char *const argv[],
> +                     char *const envp[], int flags);

Same as before, the protype declaration here is not required.

> +
> +/* Re-use the test, but run it against copy_file_range_compat defined
> +   above.  */
> +#define execveat execveat_fallback
> +#include "tst-execveat.c"

Move this test to be Linux-only, since the fallback is only defined
for Linux.

> diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
> new file mode 100644
> index 0000000000..52779de8cd
> --- /dev/null
> +++ b/posix/tst-execveat.c
> @@ -0,0 +1,180 @@
> +/* Test execveat at the various corner cases.
> +   Copyright (C) 2021 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 <fcntl.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <support/xdlfcn.h>
> +#include <support/xstdio.h>
> +#include <support/xunistd.h>
> +#include <wait.h>
> +#include <support/test-driver.h>
> +
> +int
> +call_execveat (int fd, const char *pathname, int flags, int expected_fail,
> +               int num)
> +{
> +  char *envp[] = { (char *) "FOO=3", NULL };
> +  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
> +  pid_t pid;
> +  int status;
> +
> +  if (test_verbose > 0)
> +    printf ("call line number: %d\n", num);
> +
> +  pid = xfork ();
> +  if (pid == 0)
> +    {
> +      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
> +      if (errno == ENOSYS)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (errno == expected_fail)
> +        {
> +          if (test_verbose > 0)
> +            printf ("expected fail: errno %d\n", errno);
> +          _exit (0);
> +        }
> +      else
> +        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
> +    }
> +  xwaitpid (pid, &status, 0);
> +
> +  if (WIFEXITED (status))
> +    {
> +      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (expected_fail != 0)
> +        TEST_COMPARE (WEXITSTATUS (status), 0);
> +      else
> +        TEST_COMPARE (WEXITSTATUS (status), 3);
> +    }

Also log a failure for !WIFEXITED (status).

> +  return 0;
> +}> +
> +static int
> +do_test (void)
> +{
> +  DIR *dirp;
> +  int fd, fd_out;
> +  char *tmp_dir, *symlink_name, *tmp_sh;
> +  struct stat64 st;
> +
> +  dirp = opendir ("/bin");
> +  if (dirp == NULL)
> +    FAIL_EXIT1 ("failed to open /bin");
> +  fd = dirfd (dirp);
> +
> +  /* Call execveat for various fd/pathname combinations.  */
> +
> +  /* Check the pathname relative to a valid dirfd.  */
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  xchdir ("/bin");
> +  /* Use the special value AT_FDCWD as dirfd. Quoting open(2):
> +     If pathname is relative and dirfd is the special value AT_FDCWD, then
> +     pathname is interpreted relative to the current working directory of
> +     the calling process.  */
> +  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
> +  xclose (fd);

Ok.

> +#ifdef O_PATH
> +  /* Check the pathname relative to a valid dirfd with O_PATH.  */
> +  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +  /* Check absolute pathname, dirfd should be ignored.  */
> +  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
> +  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
> +  /* Same check for absolute pathname, but with input file descriptor
> +     openend with different flags.  The dirfd should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);

Ok.

> +#endif
> +
> +  fd = xopen ("/usr", O_RDONLY, 0);
> +  /* Same check for absolute pathname, but with input file descriptor
> +     openend with different flags.  The dirfd should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +

Ok.

> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  /* Check relative pathname, where dirfd does not point to a directory.  */
> +  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
> +  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
> +     should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +

Ok.

> +#ifdef O_PATH
> +  /* Quoting open(2): O_PATH
> +     Obtain a file descriptor that can be used for two purposes: to
> +     indicate a location in the filesystem tree and to perform
> +     operations that act purely at the file descriptor level.  */
> +  fd = xopen ("/bin/sh", O_PATH, 0);
> +  /* Check the empty pathname.  Dirfd is a regular file with O_PATH.  */
> +  call_execveat (fd, "", 0, ENOENT, __LINE__);

Ok.

> +  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
> +     Quoting open(2):
> +     If oldpath is an empty string, create a link to the file referenced
> +     by olddirfd (which may have been obtained using the open(2) O_PATH flag. */
> +  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
> +  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
> +  xclose (fd);
> +

Ok.

> +  /* Create a temporary directory "tmp_dir" and create a symbolik link tmp_sh
> +     pointing to /bin/sh inside the tmp_dir. Open dirfd as a symbolic link.  */

Missing double space after period.

> +  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
> +  symlink_name = xasprintf ("%s/symlink", tmp_dir);
> +  xsymlink ("tmp_sh", symlink_name);
> +  add_temp_file (symlink_name);
> +  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
> +  add_temp_file (tmp_sh);
> +  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
> +  xstat ("/bin/sh", &st);
> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
> +  xfchmod (fd_out, 0700);
> +  xclose (fd);
> +  xclose (fd_out);
> +  fd_out = xopen (symlink_name, O_PATH, 0);
> +
> + /* Check the empty pathname. Dirfd is a symbolic link.  */
> +  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
> +  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
> +  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
> +                 __LINE__);
> +  xclose (fd_out);
> +  free (symlink_name);
> +  free (tmp_sh);
> +  free (tmp_dir);

Ok.

> +#endif
> +
> +  /* Call execveat with closed fd, we expect this to fail with EBADF.  */
> +  call_execveat (fd, "sh", 0, EBADF, __LINE__);
> +  /* Call execveat with closed fd, we expect this to pass because the pathname is
> +     absolute.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/posix/unistd.h b/posix/unistd.h
> index 3f22763379..d9d8929f71 100644
> --- a/posix/unistd.h
> +++ b/posix/unistd.h
> @@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
>  /* An alias for `euidaccess', used by some other systems.  */
>  extern int eaccess (const char *__name, int __type)
>       __THROW __nonnull ((1));
> +
> +/* Execute program relative to a directory file descriptor.  */
> +extern int execveat (int __fd, const char *__path, char *const __argv[],
> +                     char *const __envp[], int __flags)
> +    __THROW __nonnull ((2, 3));
>  #endif
>  
>  #ifdef __USE_ATFILE

Ok.

> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index e10a286d2e..bef66d105c 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2204,6 +2204,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index bac795262d..51f34d0f6d 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2172,3 +2172,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 897f70db22..7da53174ef 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2254,6 +2254,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index 094236f713..108c41ae24 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -156,6 +156,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
>  GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index 2bb4d31e81..a995a356a4 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -153,6 +153,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
>  GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index d4291fecfb..33d0dfb2b7 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2116,3 +2116,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F

Ok.

> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
> new file mode 100644
> index 0000000000..0576f36b98
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat.c
> @@ -0,0 +1,54 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>

Add a space here to outline that the execveat_fallback is not an header
(although this is not really a code guideline enforcement).

> +#ifndef __ASSUME_EXECVEAT
> +# include "execveat_fallback.c"
> +#endif
> +
> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +    INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;
> +
> +  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
> +      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
> +
> +  return __execveat_fallback (dirfd, path, argv, envp, flags);
> +#endif
> +
> +  return -1;
> +}

Ok.

> diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
> new file mode 100644
> index 0000000000..c4a37d3799
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
> @@ -0,0 +1,69 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +int
> +__execveat_fallback (int dirfd, const char *path, char *const argv[],
> +                   char *const envp[], int flags)
> +{
> +    int fd;
> +
> +    if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
> +        fd = dirfd;
> +    else
> +    {
> +        int oflags = O_CLOEXEC;
> +        if (flags & AT_SYMLINK_NOFOLLOW)
> +            oflags |= O_NOFOLLOW;
> +        fd = __openat_nocancel (dirfd, path, oflags);
> +    }
> +    if (fd < 0)
> +        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADFD);

Wrong indentation (4 space instead of 2) and open bracket should have a
space:

  if (....)
    fd = ...
  else
    {
      ...
    }

This also applies to the rest of the file.

> +
> +    struct fd_to_filename fdfilename;
> +    const char *gfilename = __fd_to_filename (fd, &fdfilename);
> +
> +    /* We do not need the return value.  */
> +    __execve (gfilename, argv, envp);
> +
> +    int save = errno;
> +
> +    /* We come here only if the 'execve' call fails.  Determine whether
> +       /proc is mounted.  If not we return ENOSYS.  */
> +    struct stat64 st;
> +    if (__stat64 (FD_TO_FILENAME_PREFIX, &st) != 0 && errno == ENOENT)
> +        save = ENOSYS;
> +
> +    if (fd != dirfd)
> +        __close_nocancel_nostatus (fd);
> +    __set_errno (save);
> +
> +    return -1;
> +}

Ok.

> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 1fd2a862f6..e1430bb232 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2075,6 +2075,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index 943331f01e..7cb2d0dd6d 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2242,6 +2242,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index f530151bde..2171cd3cb2 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2107,6 +2107,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 6e76b6dcaa..388eb76abf 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -157,6 +157,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0x98
>  GLIBC_2.4 _IO_2_1_stdin_ D 0x98
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 7541b8289f..067ed53f2b 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2187,6 +2187,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 6cf1936c42..a792461b45 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2167,3 +2167,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index 98730ebcda..0e09fe6322 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2164,3 +2164,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index 92fa6cbc73..5d1b0b3d78 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2158,6 +2158,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index 265a49e74e..a278c0a092 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2156,6 +2156,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index cfa5e1111b..054d3436eb 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2164,6 +2164,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 8c03ac52cd..c22ef9f196 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2158,6 +2158,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 17f5609e06..c356e9f863 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2205,3 +2205,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 76a16e2a6d..d1de01f91d 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2214,6 +2214,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index 697f072fd4..a1d52887bb 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2247,6 +2247,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index 2647bb51f1..10cdabb11c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2077,6 +2077,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index 036b1c8345..70792ed87b 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2367,3 +2367,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index fb5ad9909f..9b71083136 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2134,3 +2134,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index cead75acc5..aba76fbadd 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index 31366dd7e6..6a5a765f4b 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2113,6 +2113,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index a3a8be8910..b6629c244f 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2082,6 +2082,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 8f505c5045..e15ab4c569 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2079,6 +2079,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 53ef6304f1..11cad082d8 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2203,6 +2203,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index eba0cb156d..0ff8cb8739 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2130,6 +2130,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index 17ce5dfd58..040d44d3a8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2089,6 +2089,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index 17a1c83903..4355e06891 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2186,3 +2186,4 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F

It misses the abifile update for arc-linux-gnu{hf} and risc32-linux-gnu-rv32*

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-03-26 20:36   ` Adhemerval Zanella
@ 2021-04-02 12:13     ` Alexandra Hájková
  2021-04-02 13:29       ` Adhemerval Zanella
  0 siblings, 1 reply; 46+ messages in thread
From: Alexandra Hájková @ 2021-04-02 12:13 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha, Alexandra Hájková

Thank you for the review.

> > +  if (WIFEXITED (status))
> > +    {
> > +      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
> > +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> > +      else if (expected_fail != 0)
Isn't comparing WEXITSTATUS (status) with 0 sufficient?
> > +        TEST_COMPARE (WEXITSTATUS (status), 0);
> > +      else
> > +        TEST_COMPARE (WEXITSTATUS (status), 3);
> > +    }
>
> Also log a failure for !WIFEXITED (status).

Thank you,
Alexandra

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-04-02 12:13     ` Alexandra Hájková
@ 2021-04-02 13:29       ` Adhemerval Zanella
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2021-04-02 13:29 UTC (permalink / raw)
  To: alexandra.khirnova; +Cc: libc-alpha, Alexandra Hájková



On 02/04/2021 09:13, Alexandra Hájková wrote:
> Thank you for the review.
> 
>>> +  if (WIFEXITED (status))
>>> +    {
>>> +      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
>>> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
>>> +      else if (expected_fail != 0)
> Isn't comparing WEXITSTATUS (status) with 0 sufficient?

It just to handle possible return code due signaling or other possible
value, similar to what support/support_capture_subprocess_check.c does.

>>> +        TEST_COMPARE (WEXITSTATUS (status), 0);
>>> +      else
>>> +        TEST_COMPARE (WEXITSTATUS (status), 3);
>>> +    }
>>
>> Also log a failure for !WIFEXITED (status).

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

* [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (10 preceding siblings ...)
  2021-03-24 13:54 ` Alexandra Hájková
@ 2021-04-05 16:32 ` Alexandra Hájková
  2021-04-12 10:26   ` Alexandra Hájková
  2021-04-12 11:14   ` Andreas Schwab
  2021-04-12 19:26 ` Alexandra Hájková
  2021-04-21 18:11 ` Alexandra Hájková
  13 siblings, 2 replies; 46+ messages in thread
From: Alexandra Hájková @ 2021-04-05 16:32 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

 Also add the test for the new wrapper.
---
This version:
* adds attribute_hidden to the unistd.h declaration
* removes the prototype declaration in tst-execveat-compat.c
* moves tst-execveat-compat.c to /sysdeps/unix/sysv/linux
* logs a failure for !WIFEXITED (status) in tst-execveat.c
* makes some cosmetic changes such as changing indentation and such
* adds execveat symbol to sysdeps/unix/sysv/linux/arc/libc.abilist
* and sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist

NEWS                                          |   5 +
 include/unistd.h                              |   4 +
 posix/Makefile                                |   5 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  41 ++++
 posix/tst-execveat.c                          | 183 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/Makefile              |   1 +
 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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  54 ++++++
 sysdeps/unix/sysv/linux/execveat_fallback.c   |  69 +++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/tst-execveat-compat.c |  28 +++
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 44 files changed, 429 insertions(+), 2 deletions(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat_fallback.c
 create mode 100644 sysdeps/unix/sysv/linux/tst-execveat-compat.c

diff --git a/NEWS b/NEWS
index aa0f10a891..a61071b494 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,11 @@ Major new features:
   a dump of information related to IFUNC resolver operation and
   glibc-hwcaps subdirectory selection.
 
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/include/unistd.h b/include/unistd.h
index 1363976161..d694563837 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -191,6 +191,10 @@ extern int __libc_pause (void);
 extern int __getlogin_r_loginuid (char *name, size_t namesize)
      attribute_hidden;
 
+extern int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                   char *const envp[], int flags) attribute_hidden;
+
 #  if IS_IN (rtld)
 #   include <dl-unistd.h>
 #  endif
diff --git a/posix/Makefile b/posix/Makefile
index be0c72f0bb..4968affaf9 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -66,7 +66,8 @@ routines :=								      \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
 	streams-compat \
-	shm-directory
+	shm-directory                                                         \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -103,7 +104,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
 		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
 		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
-		   tst-wordexp-nocmd
+		   tst-wordexp-nocmd tst-execveat
 
 # Test for the glob symbol version that was replaced in glibc 2.27.
 ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes)
diff --git a/posix/Versions b/posix/Versions
index cfd3819966..b77e251e00 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.34 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..3f0d0820e7
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,41 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to DIFRD with
+ * arguments ARGV and environment ENVP.
+ * ARGV and ENVP are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..186134564f
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,183 @@
+/* Test execveat at the various corner cases.
+   Copyright (C) 2021 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *envp[] = { (char *) "FOO=3", NULL };
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
+  pid_t pid;
+  int status;
+
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (!WIFEXITED (status))
+    FAIL_RET ("child hasn't exited normally");
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail != 0)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat64 st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations.  */
+
+  /* Check the pathname relative to a valid dirfd.  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xchdir ("/bin");
+  /* Use the special value AT_FDCWD as dirfd. Quoting open(2):
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process.  */
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* Check the pathname relative to a valid dirfd with O_PATH.  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  /* Check absolute pathname, dirfd should be ignored.  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* Check relative pathname, where dirfd does not point to a directory.  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
+     should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  /* Quoting open(2): O_PATH
+     Obtain a file descriptor that can be used for two purposes: to
+     indicate a location in the filesystem tree and to perform
+     operations that act purely at the file descriptor level.  */
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* Check the empty pathname.  Dirfd is a regular file with O_PATH.  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
+     Quoting open(2):
+     If oldpath is an empty string, create a link to the file referenced
+     by olddirfd (which may have been obtained using the open(2) O_PATH flag. */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  /* Create a temporary directory "tmp_dir" and create a symbolik link tmp_sh
+     pointing to /bin/sh inside the tmp_dir. Open dirfd as a symbolic link.  */
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  xstat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  xfchmod (fd_out, 0700);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+ /* Check the empty pathname. Dirfd is a symbolic link.  */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF.  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 3f22763379..d9d8929f71 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 7424dc9166..bb2fe83e21 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2206,6 +2206,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 303fa297bc..36bc188b55 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -117,6 +117,7 @@ tests += tst-ofdlocks-compat
 endif
 
 tests-internal += tst-sigcontext-get_pc
+tests-static-internal += tst-execveat-compat
 
 CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 851f15a566..132589648e 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2174,4 +2174,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 33b426ef20..891e20f5e6 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2263,6 +2263,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index c09947ad58..d86333c354 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1933,4 +1933,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 57be971f81..78d7d19f79 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -156,6 +156,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 2db02fae07..4242914991 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -153,6 +153,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 0dd3527892..e6d2a4f09b 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2117,4 +2117,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..9deab0a2b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,55 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+#ifndef __ASSUME_EXECVEAT
+# include "execveat_fallback.c"
+#endif
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+    INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return -1;
+
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  return __execveat_fallback (dirfd, path, argv, envp, flags);
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
new file mode 100644
index 0000000000..6249c76079
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
@@ -0,0 +1,69 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                     char *const envp[], int flags)
+{
+  int fd;
+
+  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
+    fd = dirfd;
+  else
+    {
+      int oflags = O_CLOEXEC;
+      if (flags & AT_SYMLINK_NOFOLLOW)
+        oflags |= O_NOFOLLOW;
+      fd = __openat_nocancel (dirfd, path, oflags);
+    }
+  if (fd < 0)
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADFD);
+
+  struct fd_to_filename fdfilename;
+  const char *gfilename = __fd_to_filename (fd, &fdfilename);
+
+  /* We do not need the return value.  */
+  __execve (gfilename, argv, envp);
+
+  int save = errno;
+
+  /* We come here only if the 'execve' call fails.  Determine whether
+     /proc is mounted.  If not we return ENOSYS.  */
+  struct stat64 st;
+  if (__stat64 (FD_TO_FILENAME_PREFIX, &st) != 0 && errno == ENOENT)
+    save = ENOSYS;
+
+  if (fd != dirfd)
+    __close_nocancel_nostatus (fd);
+  __set_errno (save);
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 04c32f9b65..aebcb2cda5 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2076,6 +2076,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index cfd4e55e57..026dc67c14 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 426e15f4f6..2c2c16e9e1 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2110,6 +2110,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index bdecf60fae..7a00dd7869 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -157,6 +157,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index eaa5a97a61..a1fdc560a5 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2196,6 +2196,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 571315511b..c5ab412504 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2168,4 +2168,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 9d4c1f53f7..d4e9ff1675 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2165,4 +2165,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 6de58a4680..4d9dbb3901 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index e1c971c361..488f2aa6de 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2157,6 +2157,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 28d6d3284d..bac10468b7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2165,6 +2165,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 3060a503ab..95200c2064 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 24e0a6f16a..b5b3bc7bd4 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2207,4 +2207,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index b9cccc3fe5..38e4e3cb21 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2223,6 +2223,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 5c81a23740..41b4abd7ef 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2256,6 +2256,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index a61d2502d5..7ea617f84f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2078,6 +2078,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index ec9ae25539..6b3de81190 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2370,4 +2370,5 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index b08ece30b8..ff85889ea1 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1935,4 +1935,5 @@ GLIBC_2.33 write F
 GLIBC_2.33 writev F
 GLIBC_2.33 wscanf F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 12ced01cf7..f18bc160c4 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2135,4 +2135,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 7ed5e4c515..eb80905f99 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2221,6 +2221,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 73a46b01b2..360817ff74 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2114,6 +2114,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 2aa68f1def..535b0a329b 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2083,6 +2083,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 07f3c23873..82ee8a8203 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2080,6 +2080,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index cc1d278c72..af3be1fd59 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index cc1d278c72..af3be1fd59 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 79ca3d5d9c..8b41b11497 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2131,6 +2131,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/tst-execveat-compat.c b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
new file mode 100644
index 0000000000..a0ba77bb1d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
@@ -0,0 +1,28 @@
+/* Test the fallback implementation of execveat.
+   Copyright (C) 2021 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Get the declaration of the official execveat function.  */
+#include <unistd.h>
+
+/* Compile a local version of execveat.  */
+#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
+
+/* Re-use the test, but run it against copy_file_range_compat defined
+   above.  */
+#define execveat execveat_fallback
+#include <posix/tst-execveat.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index da0974f11a..3d1089a3e8 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2092,6 +2092,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index d3d155e7c0..593beb66d9 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2189,4 +2189,5 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
-- 
2.26.3


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-04-05 16:32 ` Alexandra Hájková
@ 2021-04-12 10:26   ` Alexandra Hájková
  2021-04-12 11:14   ` Andreas Schwab
  1 sibling, 0 replies; 46+ messages in thread
From: Alexandra Hájková @ 2021-04-12 10:26 UTC (permalink / raw)
  To: libc-alpha

ping

On Mon, Apr 5, 2021 at 6:32 PM Alexandra Hájková
<alexandra.khirnova@gmail.com> wrote:
>
> From: Alexandra Hájková <ahajkova@redhat.com>
>
>  Also add the test for the new wrapper.
> ---
> This version:
> * adds attribute_hidden to the unistd.h declaration
> * removes the prototype declaration in tst-execveat-compat.c
> * moves tst-execveat-compat.c to /sysdeps/unix/sysv/linux
> * logs a failure for !WIFEXITED (status) in tst-execveat.c
> * makes some cosmetic changes such as changing indentation and such
> * adds execveat symbol to sysdeps/unix/sysv/linux/arc/libc.abilist
> * and sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
>
> NEWS                                          |   5 +
>  include/unistd.h                              |   4 +
>  posix/Makefile                                |   5 +-
>  posix/Versions                                |   3 +
>  posix/execveat.c                              |  41 ++++
>  posix/tst-execveat.c                          | 183 ++++++++++++++++++
>  posix/unistd.h                                |   5 +
>  sysdeps/mach/hurd/i386/libc.abilist           |   1 +
>  sysdeps/unix/sysv/linux/Makefile              |   1 +
>  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/csky/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/execveat.c            |  54 ++++++
>  sysdeps/unix/sysv/linux/execveat_fallback.c   |  69 +++++++
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
>  sysdeps/unix/sysv/linux/ia64/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 +
>  .../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/tst-execveat-compat.c |  28 +++
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
>  44 files changed, 429 insertions(+), 2 deletions(-)
>  create mode 100644 posix/execveat.c
>  create mode 100644 posix/tst-execveat.c
>  create mode 100644 sysdeps/unix/sysv/linux/execveat.c
>  create mode 100644 sysdeps/unix/sysv/linux/execveat_fallback.c
>  create mode 100644 sysdeps/unix/sysv/linux/tst-execveat-compat.c
>
> diff --git a/NEWS b/NEWS
> index aa0f10a891..a61071b494 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -18,6 +18,11 @@ Major new features:
>    a dump of information related to IFUNC resolver operation and
>    glibc-hwcaps subdirectory selection.
>
>
>    [Add deprecations, removals and changes affecting compatibility here]
> diff --git a/include/unistd.h b/include/unistd.h
> index 1363976161..d694563837 100644
> --- a/include/unistd.h
> +++ b/include/unistd.h
> @@ -191,6 +191,10 @@ extern int __libc_pause (void);
>  extern int __getlogin_r_loginuid (char *name, size_t namesize)
>       attribute_hidden;
>
> +extern int
> +__execveat_fallback (int dirfd, const char *path, char *const argv[],
> +                   char *const envp[], int flags) attribute_hidden;
> +
>  #  if IS_IN (rtld)
>  #   include <dl-unistd.h>
>  #  endif
> diff --git a/posix/Makefile b/posix/Makefile
> index be0c72f0bb..4968affaf9 100644
> --- a/posix/Makefile
> +++ b/posix/Makefile
> @@ -66,7 +66,8 @@ routines :=                                                                 \
>         posix_madvise                                                         \
>         get_child_max sched_cpucount sched_cpualloc sched_cpufree \
>         streams-compat \
> -       shm-directory
> +       shm-directory                                                         \
> +       execveat
>
>  aux            := init-posix environ
>  tests          := test-errno tstgetopt testfnm runtests runptests \
> @@ -103,7 +104,7 @@ tests               := test-errno tstgetopt testfnm runtests runptests \
>                    tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
>                    tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
>                    bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
> -                  tst-wordexp-nocmd
> +                  tst-wordexp-nocmd tst-execveat
>
>  # Test for the glob symbol version that was replaced in glibc 2.27.
>  ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes)
> diff --git a/posix/Versions b/posix/Versions
> index cfd3819966..b77e251e00 100644
> --- a/posix/Versions
> +++ b/posix/Versions
> @@ -147,6 +147,9 @@ libc {
>    }
>    GLIBC_2.30 {
>    }
> +  GLIBC_2.34 {
> +    execveat;
> +  }
>    GLIBC_PRIVATE {
>      __libc_fork; __libc_pread; __libc_pwrite;
>      __nanosleep_nocancel; __pause_nocancel;
> diff --git a/posix/execveat.c b/posix/execveat.c
> new file mode 100644
> index 0000000000..3f0d0820e7
> --- /dev/null
> +++ b/posix/execveat.c
> @@ -0,0 +1,41 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <unistd.h>
> +
> +/* Replace the current process, executing PATH relative to DIFRD with
> + * arguments ARGV and environment ENVP.
> + * ARGV and ENVP are terminated by NULL pointers.  */
> +int
> +__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +            int flags)
> +{
> +  if (path == NULL || argv == NULL || envp == NULL)
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  __set_errno (ENOSYS);
> +  return -1;
> +}
> +stub_warning (execveat)
> +
> +weak_alias (__execveat, execveat)
> diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
> new file mode 100644
> index 0000000000..186134564f
> --- /dev/null
> +++ b/posix/tst-execveat.c
> @@ -0,0 +1,183 @@
> +/* Test execveat at the various corner cases.
> +   Copyright (C) 2021 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 <fcntl.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <support/check.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <support/xdlfcn.h>
> +#include <support/xstdio.h>
> +#include <support/xunistd.h>
> +#include <wait.h>
> +#include <support/test-driver.h>
> +
> +int
> +call_execveat (int fd, const char *pathname, int flags, int expected_fail,
> +               int num)
> +{
> +  char *envp[] = { (char *) "FOO=3", NULL };
> +  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
> +  pid_t pid;
> +  int status;
> +
> +  if (test_verbose > 0)
> +    printf ("call line number: %d\n", num);
> +
> +  pid = xfork ();
> +  if (pid == 0)
> +    {
> +      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
> +      if (errno == ENOSYS)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (errno == expected_fail)
> +        {
> +          if (test_verbose > 0)
> +            printf ("expected fail: errno %d\n", errno);
> +          _exit (0);
> +        }
> +      else
> +        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
> +    }
> +  xwaitpid (pid, &status, 0);
> +
> +  if (!WIFEXITED (status))
> +    FAIL_RET ("child hasn't exited normally");
> +
> +  if (WIFEXITED (status))
> +    {
> +      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");
> +      else if (expected_fail != 0)
> +        TEST_COMPARE (WEXITSTATUS (status), 0);
> +      else
> +        TEST_COMPARE (WEXITSTATUS (status), 3);
> +    }
> +  return 0;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  DIR *dirp;
> +  int fd, fd_out;
> +  char *tmp_dir, *symlink_name, *tmp_sh;
> +  struct stat64 st;
> +
> +  dirp = opendir ("/bin");
> +  if (dirp == NULL)
> +    FAIL_EXIT1 ("failed to open /bin");
> +  fd = dirfd (dirp);
> +
> +  /* Call execveat for various fd/pathname combinations.  */
> +
> +  /* Check the pathname relative to a valid dirfd.  */
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  xchdir ("/bin");
> +  /* Use the special value AT_FDCWD as dirfd. Quoting open(2):
> +     If pathname is relative and dirfd is the special value AT_FDCWD, then
> +     pathname is interpreted relative to the current working directory of
> +     the calling process.  */
> +  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +#ifdef O_PATH
> +  /* Check the pathname relative to a valid dirfd with O_PATH.  */
> +  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
> +  call_execveat (fd, "sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +  /* Check absolute pathname, dirfd should be ignored.  */
> +  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
> +  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
> +  /* Same check for absolute pathname, but with input file descriptor
> +     openend with different flags.  The dirfd should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +#endif
> +
> +  fd = xopen ("/usr", O_RDONLY, 0);
> +  /* Same check for absolute pathname, but with input file descriptor
> +     openend with different flags.  The dirfd should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  /* Check relative pathname, where dirfd does not point to a directory.  */
> +  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
> +  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
> +     should be ignored.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +  xclose (fd);
> +
> +#ifdef O_PATH
> +  /* Quoting open(2): O_PATH
> +     Obtain a file descriptor that can be used for two purposes: to
> +     indicate a location in the filesystem tree and to perform
> +     operations that act purely at the file descriptor level.  */
> +  fd = xopen ("/bin/sh", O_PATH, 0);
> +  /* Check the empty pathname.  Dirfd is a regular file with O_PATH.  */
> +  call_execveat (fd, "", 0, ENOENT, __LINE__);
> +  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
> +     Quoting open(2):
> +     If oldpath is an empty string, create a link to the file referenced
> +     by olddirfd (which may have been obtained using the open(2) O_PATH flag. */
> +  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
> +  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
> +  xclose (fd);
> +
> +  /* Create a temporary directory "tmp_dir" and create a symbolik link tmp_sh
> +     pointing to /bin/sh inside the tmp_dir. Open dirfd as a symbolic link.  */
> +  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
> +  symlink_name = xasprintf ("%s/symlink", tmp_dir);
> +  xsymlink ("tmp_sh", symlink_name);
> +  add_temp_file (symlink_name);
> +  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
> +  add_temp_file (tmp_sh);
> +  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
> +  xstat ("/bin/sh", &st);
> +  fd = xopen ("/bin/sh", O_RDONLY, 0);
> +  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
> +  xfchmod (fd_out, 0700);
> +  xclose (fd);
> +  xclose (fd_out);
> +  fd_out = xopen (symlink_name, O_PATH, 0);
> +
> + /* Check the empty pathname. Dirfd is a symbolic link.  */
> +  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
> +  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
> +  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
> +                 __LINE__);
> +  xclose (fd_out);
> +  free (symlink_name);
> +  free (tmp_sh);
> +  free (tmp_dir);
> +#endif
> +
> +  /* Call execveat with closed fd, we expect this to fail with EBADF.  */
> +  call_execveat (fd, "sh", 0, EBADF, __LINE__);
> +  /* Call execveat with closed fd, we expect this to pass because the pathname is
> +     absolute.  */
> +  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/posix/unistd.h b/posix/unistd.h
> index 3f22763379..d9d8929f71 100644
> --- a/posix/unistd.h
> +++ b/posix/unistd.h
> @@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
>  /* An alias for `euidaccess', used by some other systems.  */
>  extern int eaccess (const char *__name, int __type)
>       __THROW __nonnull ((1));
> +
> +/* Execute program relative to a directory file descriptor.  */
> +extern int execveat (int __fd, const char *__path, char *const __argv[],
> +                     char *const __envp[], int __flags)
> +    __THROW __nonnull ((2, 3));
>  #endif
>
>  #ifdef __USE_ATFILE
> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 7424dc9166..bb2fe83e21 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2206,6 +2206,7 @@ GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __isnanf128 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 303fa297bc..36bc188b55 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -117,6 +117,7 @@ tests += tst-ofdlocks-compat
>  endif
>
>  tests-internal += tst-sigcontext-get_pc
> +tests-static-internal += tst-execveat-compat
>
>  CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
>
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 851f15a566..132589648e 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2174,4 +2174,5 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index 33b426ef20..891e20f5e6 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2263,6 +2263,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> index c09947ad58..d86333c354 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> @@ -1933,4 +1933,5 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index 57be971f81..78d7d19f79 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -156,6 +156,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index 2db02fae07..4242914991 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -153,6 +153,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index 0dd3527892..e6d2a4f09b 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2117,4 +2117,5 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
> new file mode 100644
> index 0000000000..9deab0a2b4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat.c
> @@ -0,0 +1,55 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +#ifndef __ASSUME_EXECVEAT
> +# include "execveat_fallback.c"
> +#endif
> +
> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +    INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;
> +
> +  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
> +      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
> +
> +  return __execveat_fallback (dirfd, path, argv, envp, flags);
> +#endif
> +
> +  return -1;
> +}
> diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
> new file mode 100644
> index 0000000000..6249c76079
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
> @@ -0,0 +1,69 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +int
> +__execveat_fallback (int dirfd, const char *path, char *const argv[],
> +                     char *const envp[], int flags)
> +{
> +  int fd;
> +
> +  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
> +    fd = dirfd;
> +  else
> +    {
> +      int oflags = O_CLOEXEC;
> +      if (flags & AT_SYMLINK_NOFOLLOW)
> +        oflags |= O_NOFOLLOW;
> +      fd = __openat_nocancel (dirfd, path, oflags);
> +    }
> +  if (fd < 0)
> +    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADFD);
> +
> +  struct fd_to_filename fdfilename;
> +  const char *gfilename = __fd_to_filename (fd, &fdfilename);
> +
> +  /* We do not need the return value.  */
> +  __execve (gfilename, argv, envp);
> +
> +  int save = errno;
> +
> +  /* We come here only if the 'execve' call fails.  Determine whether
> +     /proc is mounted.  If not we return ENOSYS.  */
> +  struct stat64 st;
> +  if (__stat64 (FD_TO_FILENAME_PREFIX, &st) != 0 && errno == ENOENT)
> +    save = ENOSYS;
> +
> +  if (fd != dirfd)
> +    __close_nocancel_nostatus (fd);
> +  __set_errno (save);
> +
> +  return -1;
> +}
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 04c32f9b65..aebcb2cda5 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2076,6 +2076,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index cfd4e55e57..026dc67c14 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2253,6 +2253,7 @@ GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __isnanf128 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index 426e15f4f6..2c2c16e9e1 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2110,6 +2110,7 @@ GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __isnanf128 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index bdecf60fae..7a00dd7869 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -157,6 +157,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0x98
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index eaa5a97a61..a1fdc560a5 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2196,6 +2196,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index 571315511b..c5ab412504 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2168,4 +2168,5 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index 9d4c1f53f7..d4e9ff1675 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2165,4 +2165,5 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index 6de58a4680..4d9dbb3901 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index e1c971c361..488f2aa6de 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2157,6 +2157,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index 28d6d3284d..bac10468b7 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2165,6 +2165,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 3060a503ab..95200c2064 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index 24e0a6f16a..b5b3bc7bd4 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2207,4 +2207,5 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index b9cccc3fe5..38e4e3cb21 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2223,6 +2223,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index 5c81a23740..41b4abd7ef 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2256,6 +2256,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index a61d2502d5..7ea617f84f 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2078,6 +2078,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index ec9ae25539..6b3de81190 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2370,4 +2370,5 @@ GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __isnanf128 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> index b08ece30b8..ff85889ea1 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> @@ -1935,4 +1935,5 @@ GLIBC_2.33 write F
>  GLIBC_2.33 writev F
>  GLIBC_2.33 wscanf F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 12ced01cf7..f18bc160c4 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2135,4 +2135,5 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index 7ed5e4c515..eb80905f99 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2221,6 +2221,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index 73a46b01b2..360817ff74 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2114,6 +2114,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index 2aa68f1def..535b0a329b 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2083,6 +2083,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 07f3c23873..82ee8a8203 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2080,6 +2080,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index cc1d278c72..af3be1fd59 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index cc1d278c72..af3be1fd59 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index 79ca3d5d9c..8b41b11497 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2131,6 +2131,7 @@ GLIBC_2.33 mknodat F
>  GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/tst-execveat-compat.c b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
> new file mode 100644
> index 0000000000..a0ba77bb1d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
> @@ -0,0 +1,28 @@
> +/* Test the fallback implementation of execveat.
> +   Copyright (C) 2021 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* Get the declaration of the official execveat function.  */
> +#include <unistd.h>
> +
> +/* Compile a local version of execveat.  */
> +#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
> +
> +/* Re-use the test, but run it against copy_file_range_compat defined
> +   above.  */
> +#define execveat execveat_fallback
> +#include <posix/tst-execveat.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index da0974f11a..3d1089a3e8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2092,6 +2092,7 @@ GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __isnanf128 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index d3d155e7c0..593beb66d9 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2189,4 +2189,5 @@ GLIBC_2.33 stat F
>  GLIBC_2.33 stat64 F
>  GLIBC_2.34 __isnanf128 F
>  GLIBC_2.34 __libc_start_main F
> +GLIBC_2.34 execveat F
>  GLIBC_2.34 pthread_kill F
> --
> 2.26.3
>

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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-04-05 16:32 ` Alexandra Hájková
  2021-04-12 10:26   ` Alexandra Hájková
@ 2021-04-12 11:14   ` Andreas Schwab
  1 sibling, 0 replies; 46+ messages in thread
From: Andreas Schwab @ 2021-04-12 11:14 UTC (permalink / raw)
  To: Alexandra Hájková via Libc-alpha
  Cc: Alexandra Hájková, Alexandra Hájková

On Apr 05 2021, Alexandra Hájková via Libc-alpha wrote:

> diff --git a/NEWS b/NEWS
> index aa0f10a891..a61071b494 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -18,6 +18,11 @@ Major new features:
>    a dump of information related to IFUNC resolver operation and
>    glibc-hwcaps subdirectory selection.
>  
>  
>    [Add deprecations, removals and changes affecting compatibility here]

There is something missing here.

> diff --git a/posix/execveat.c b/posix/execveat.c
> new file mode 100644
> index 0000000000..3f0d0820e7
> --- /dev/null
> +++ b/posix/execveat.c
> @@ -0,0 +1,41 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <unistd.h>
> +
> +/* Replace the current process, executing PATH relative to DIFRD with
> + * arguments ARGV and environment ENVP.
> + * ARGV and ENVP are terminated by NULL pointers.  */

Comment style.

> diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
> new file mode 100644
> index 0000000000..9deab0a2b4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat.c
> @@ -0,0 +1,55 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +#ifndef __ASSUME_EXECVEAT
> +# include "execveat_fallback.c"
> +#endif
> +
> +/* Execute the file FD refers to, overlaying the running program image.
> +   ARGV and ENVP are passed to the new program, as for `execve'.  */
> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +    INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);

Wrong indentation.

> +#ifndef __ASSUME_EXECVEAT
> +  if (errno != ENOSYS)
> +    return -1;
> +
> +  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
> +      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);

Wrong indentation.

> diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
> new file mode 100644
> index 0000000000..6249c76079
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
> @@ -0,0 +1,69 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +int
> +__execveat_fallback (int dirfd, const char *path, char *const argv[],
> +                     char *const envp[], int flags)
> +{
> +  int fd;
> +
> +  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
> +    fd = dirfd;
> +  else
> +    {
> +      int oflags = O_CLOEXEC;
> +      if (flags & AT_SYMLINK_NOFOLLOW)
> +        oflags |= O_NOFOLLOW;
> +      fd = __openat_nocancel (dirfd, path, oflags);
> +    }
> +  if (fd < 0)
> +    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADFD);

I think this should return the errno from __openat_nocancel.

> diff --git a/sysdeps/unix/sysv/linux/tst-execveat-compat.c b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
> new file mode 100644
> index 0000000000..a0ba77bb1d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
> @@ -0,0 +1,28 @@
> +/* Test the fallback implementation of execveat.
> +   Copyright (C) 2021 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* Get the declaration of the official execveat function.  */
> +#include <unistd.h>
> +
> +/* Compile a local version of execveat.  */
> +#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
> +
> +/* Re-use the test, but run it against copy_file_range_compat defined

Pasto: execveat_fallback

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

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

* [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (11 preceding siblings ...)
  2021-04-05 16:32 ` Alexandra Hájková
@ 2021-04-12 19:26 ` Alexandra Hájková
  2021-04-13 19:27   ` Adhemerval Zanella
  2021-04-21 18:11 ` Alexandra Hájková
  13 siblings, 1 reply; 46+ messages in thread
From: Alexandra Hájková @ 2021-04-12 19:26 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

 Also add the test for the new wrapper.
---
This version:
* fixes some indentation
* nothing is missing in NEWS
* returns the errno after calling openat_nocancel
* fixes copy paste comment error

 NEWS                                          |   5 +
 include/unistd.h                              |   4 +
 posix/Makefile                                |   5 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  41 ++++
 posix/tst-execveat.c                          | 183 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 sysdeps/unix/sysv/linux/Makefile              |   1 +
 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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  55 ++++++
 sysdeps/unix/sysv/linux/execveat_fallback.c   |  69 +++++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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/tst-execveat-compat.c |  28 +++
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 44 files changed, 430 insertions(+), 2 deletions(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat_fallback.c
 create mode 100644 sysdeps/unix/sysv/linux/tst-execveat-compat.c

diff --git a/NEWS b/NEWS
index aa0f10a891..a61071b494 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,11 @@ Major new features:
   a dump of information related to IFUNC resolver operation and
   glibc-hwcaps subdirectory selection.
 
+* The function execveat has been added and it operates similar to execve.
+  The syscall is already used to implement fexecve without requiring /proc to
+  be mounted.  Similar to fexecve, if the syscall is not supported a fallback
+  which access /proc is used.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/include/unistd.h b/include/unistd.h
index 1363976161..d694563837 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -191,6 +191,10 @@ extern int __libc_pause (void);
 extern int __getlogin_r_loginuid (char *name, size_t namesize)
      attribute_hidden;
 
+extern int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                   char *const envp[], int flags) attribute_hidden;
+
 #  if IS_IN (rtld)
 #   include <dl-unistd.h>
 #  endif
diff --git a/posix/Makefile b/posix/Makefile
index be0c72f0bb..4968affaf9 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -66,7 +66,8 @@ routines :=								      \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
 	streams-compat \
-	shm-directory
+	shm-directory                                                         \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -103,7 +104,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
 		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
 		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
-		   tst-wordexp-nocmd
+		   tst-wordexp-nocmd tst-execveat
 
 # Test for the glob symbol version that was replaced in glibc 2.27.
 ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes)
diff --git a/posix/Versions b/posix/Versions
index cfd3819966..b77e251e00 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.34 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..7ae95f72f6
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,41 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to difrd with
+   arguments argv and environment envp.
+   argv and envp are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..186134564f
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,183 @@
+/* Test execveat at the various corner cases.
+   Copyright (C) 2021 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *envp[] = { (char *) "FOO=3", NULL };
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
+  pid_t pid;
+  int status;
+
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (!WIFEXITED (status))
+    FAIL_RET ("child hasn't exited normally");
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail != 0)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat64 st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations.  */
+
+  /* Check the pathname relative to a valid dirfd.  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xchdir ("/bin");
+  /* Use the special value AT_FDCWD as dirfd. Quoting open(2):
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process.  */
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* Check the pathname relative to a valid dirfd with O_PATH.  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  /* Check absolute pathname, dirfd should be ignored.  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* Check relative pathname, where dirfd does not point to a directory.  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
+     should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  /* Quoting open(2): O_PATH
+     Obtain a file descriptor that can be used for two purposes: to
+     indicate a location in the filesystem tree and to perform
+     operations that act purely at the file descriptor level.  */
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* Check the empty pathname.  Dirfd is a regular file with O_PATH.  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
+     Quoting open(2):
+     If oldpath is an empty string, create a link to the file referenced
+     by olddirfd (which may have been obtained using the open(2) O_PATH flag. */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  /* Create a temporary directory "tmp_dir" and create a symbolik link tmp_sh
+     pointing to /bin/sh inside the tmp_dir. Open dirfd as a symbolic link.  */
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  xstat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  xfchmod (fd_out, 0700);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+ /* Check the empty pathname. Dirfd is a symbolic link.  */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF.  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 3f22763379..d9d8929f71 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index fcba25ee5e..fb2683edc2 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2207,6 +2207,7 @@ GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 _hurd_libc_proc_init F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 303fa297bc..36bc188b55 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -117,6 +117,7 @@ tests += tst-ofdlocks-compat
 endif
 
 tests-internal += tst-sigcontext-get_pc
+tests-static-internal += tst-execveat-compat
 
 CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 851f15a566..132589648e 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2174,4 +2174,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 33b426ef20..891e20f5e6 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2263,6 +2263,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index c09947ad58..d86333c354 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1933,4 +1933,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 57be971f81..78d7d19f79 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -156,6 +156,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 2db02fae07..4242914991 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -153,6 +153,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 0dd3527892..e6d2a4f09b 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2117,4 +2117,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..dbbcf01295
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,55 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+#ifndef __ASSUME_EXECVEAT
+#include "execveat_fallback.c"
+#endif
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if (errno != ENOSYS)
+    return -1;
+
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  return __execveat_fallback (dirfd, path, argv, envp, flags);
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
new file mode 100644
index 0000000000..db67dd0321
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
@@ -0,0 +1,69 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+int
+__execveat_fallback (int dirfd, const char *path, char *const argv[],
+                     char *const envp[], int flags)
+{
+  int fd;
+
+  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
+    fd = dirfd;
+  else
+    {
+      int oflags = O_CLOEXEC;
+      if (flags & AT_SYMLINK_NOFOLLOW)
+        oflags |= O_NOFOLLOW;
+      fd = __openat_nocancel (dirfd, path, oflags);
+    }
+  if (fd < 0)
+    return errno;
+
+  struct fd_to_filename fdfilename;
+  const char *gfilename = __fd_to_filename (fd, &fdfilename);
+ 
+  /* We do not need the return value.  */
+  __execve (gfilename, argv, envp);
+
+  int save = errno;
+
+  /* We come here only if the 'execve' call fails.  Determine whether
+     /proc is mounted.  If not we return ENOSYS.  */
+  struct stat64 st;
+  if (__stat64 (FD_TO_FILENAME_PREFIX, &st) != 0 && errno == ENOENT)
+    save = ENOSYS;
+
+  if (fd != dirfd)
+    __close_nocancel_nostatus (fd);
+  __set_errno (save);
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 04c32f9b65..aebcb2cda5 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2076,6 +2076,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index cfd4e55e57..026dc67c14 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 426e15f4f6..2c2c16e9e1 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2110,6 +2110,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index bdecf60fae..7a00dd7869 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -157,6 +157,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index eaa5a97a61..a1fdc560a5 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2196,6 +2196,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 571315511b..c5ab412504 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2168,4 +2168,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 9d4c1f53f7..d4e9ff1675 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2165,4 +2165,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 6de58a4680..4d9dbb3901 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index e1c971c361..488f2aa6de 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2157,6 +2157,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 28d6d3284d..bac10468b7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2165,6 +2165,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 3060a503ab..95200c2064 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 24e0a6f16a..b5b3bc7bd4 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2207,4 +2207,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index b9cccc3fe5..38e4e3cb21 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2223,6 +2223,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 5c81a23740..41b4abd7ef 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2256,6 +2256,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index a61d2502d5..7ea617f84f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2078,6 +2078,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index ec9ae25539..6b3de81190 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2370,4 +2370,5 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index b08ece30b8..ff85889ea1 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1935,4 +1935,5 @@ GLIBC_2.33 write F
 GLIBC_2.33 writev F
 GLIBC_2.33 wscanf F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 12ced01cf7..f18bc160c4 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2135,4 +2135,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 7ed5e4c515..eb80905f99 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2221,6 +2221,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 73a46b01b2..360817ff74 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2114,6 +2114,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 2aa68f1def..535b0a329b 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2083,6 +2083,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 07f3c23873..82ee8a8203 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2080,6 +2080,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index cc1d278c72..af3be1fd59 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 79ca3d5d9c..8b41b11497 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2131,6 +2131,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/tst-execveat-compat.c b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
new file mode 100644
index 0000000000..a37e2329a5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
@@ -0,0 +1,28 @@
+/* Test the fallback implementation of execveat.
+   Copyright (C) 2021 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Get the declaration of the official execveat function.  */
+#include <unistd.h>
+
+/* Compile a local version of execveat.  */
+#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
+
+/* Re-use the test, but run it against execveat_fallback defined
+   above.  */
+#define execveat execveat_fallback
+#include <posix/tst-execveat.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index da0974f11a..3d1089a3e8 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2092,6 +2092,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index d3d155e7c0..593beb66d9 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2189,4 +2189,5 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
-- 
2.26.3


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-04-12 19:26 ` Alexandra Hájková
@ 2021-04-13 19:27   ` Adhemerval Zanella
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2021-04-13 19:27 UTC (permalink / raw)
  To: libc-alpha, Alexandra Hájková, Florian Weimer



On 12/04/2021 16:26, Alexandra Hájková via Libc-alpha wrote:
> From: Alexandra Hájková <ahajkova@redhat.com>
> 
>  Also add the test for the new wrapper.
> ---
> This version:
> * fixes some indentation
> * nothing is missing in NEWS
> * returns the errno after calling openat_nocancel
> * fixes copy paste comment error


> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 303fa297bc..36bc188b55 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -117,6 +117,7 @@ tests += tst-ofdlocks-compat
>  endif
>  
>  tests-internal += tst-sigcontext-get_pc
> +tests-static-internal += tst-execveat-compat
>  
>  CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables
>  

This not build the tst-execveat-compat since 'tests-static-internal' is
not a generic rule.  The elf/Makefile does define it, but it ended adding
is on test-internal and test-static to actually enable the test.

You need to mimic it:

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile                                                                                                                                    index 36bc188b55..49df102257 100644                                                                                                                                                                                 --- a/sysdeps/unix/sysv/linux/Makefile                                                                                                                                                                              +++ b/sysdeps/unix/sysv/linux/Makefile                                                                                                                                                                              @@ -117,7 +117,9 @@ tests += tst-ofdlocks-compat                                                                                                                                                                     endif                                                                                                                                                                                                                                                                                                                                                                                                                                   tests-internal += tst-sigcontext-get_pc                                                                                                                                                                            -tests-static-internal += tst-execveat-compat                                                                                                                                                                       +                                                                                                                                                                                                                   +tests-static += tst-execveat-compat                                                                                                                                                                                +tests-internal += tst-execveat-compat                                                                                                                                                                                                                                                                                                                                                                                                   CFLAGS-tst-sigcontext-get_pc.c = -fasynchronous-unwind-tables                                                                                                                                                                                                                                                    

> diff --git a/sysdeps/unix/sysv/linux/execveat_fallback.c b/sysdeps/unix/sysv/linux/execveat_fallback.c
> new file mode 100644
> index 0000000000..db67dd0321
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/execveat_fallback.c
> @@ -0,0 +1,69 @@
> +/* Execute program relative to a directory file descriptor.
> +   Copyright (C) 2021 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 <errno.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +#include <kernel-features.h>
> +#include <fd_to_filename.h>
> +#include <not-cancel.h>
> +
> +int
> +__execveat_fallback (int dirfd, const char *path, char *const argv[],
> +                     char *const envp[], int flags)
> +{
> +  int fd;
> +
> +  if (path[0] == '\0' && (flags & AT_EMPTY_PATH) && dirfd >= 0)
> +    fd = dirfd;
> +  else
> +    {
> +      int oflags = O_CLOEXEC;

The default O_CLOEXEC leads the same issue described by fexecve man 
page [1]: if path[0] refers to an executable script with a shebang 
execveat will fail with ENOENT:

$ cat script
#!/bin/sh
exit $*
$ cat test.c 
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>

extern int __attribute__((weak)) execveat (int __fd, const char *__path,
                                           char *const __argv[],
                                           char *const __envp[], int __flags);

int main (int argc, char *argv[])
{
  char *pathname = "script";

  pid_t pid = fork ();
  assert (pid >= 0);
  if (pid == 0)
    {
      char *args[] = { pathname, "99", NULL };
      char *envp[] = { NULL };
      execveat (AT_FDCWD, pathname, args, envp, 0);
      _exit (EXIT_FAILURE);
    }

  int status;
  int rc = waitpid (pid, &status, 0);
  assert (rc == pid);
  assert (WIFEXITED(status));
  assert (WEXITSTATUS(status) == 99);

  return 0;
}
$ gcc test.c -o test
$ ./testrun.sh ./test
/bin/sh: 0: Can't open /proc/self/fd/3
test: test.c:34: main: Assertion `WEXITSTATUS(status) == 99' failed.
Aborted (core dumped)

The fexecve call could be mitigated since it moves the responsability
of adding the O_CLOEXEC to caller.  I still think it is not ideal,
but since fexecve is POSIX interface it should be better to always
fail with ENOSYS on older kernels.

There is another corner cases that the fallback do not mimic exactly
the syscall:

  execveat (99 /* invalid fd  */, "", AT_EMPTY_PATH)

which returns ENOENT instead of EBADF, but I do not considere this
a deal break.

So we have some options here:

  1. Leave as is and document properly that using with an executable
     script with shebang might fail.

  2. Remove the O_CLOEXEC from fallback, which leads to file leakage.

  3. Remove the fallback and return ENOSYS on kernel without execveat
     support.

I personally prefer to go for 3. instead of providing a broken fallback.


[1] https://man7.org/linux/man-pages/man3/fexecve.3.html

> +      if (flags & AT_SYMLINK_NOFOLLOW)
> +        oflags |= O_NOFOLLOW;
> +      fd = __openat_nocancel (dirfd, path, oflags);
> +    }
> +  if (fd < 0)
> +    return errno;

This returns the wrong value, it should return 'fd' or just '-1'

> +
> +  struct fd_to_filename fdfilename;
> +  const char *gfilename = __fd_to_filename (fd, &fdfilename);
> + 
> +  /* We do not need the return value.  */
> +  __execve (gfilename, argv, envp);
> +
> +  int save = errno;
> +
> +  /* We come here only if the 'execve' call fails.  Determine whether
> +     /proc is mounted.  If not we return ENOSYS.  */
> +  struct stat64 st;
> +  if (__stat64 (FD_TO_FILENAME_PREFIX, &st) != 0 && errno == ENOENT)
> +    save = ENOSYS;
> +
> +  if (fd != dirfd)
> +    __close_nocancel_nostatus (fd);
> +  __set_errno (save);
> +
> +  return -1;
> +}

> diff --git a/sysdeps/unix/sysv/linux/tst-execveat-compat.c b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
> new file mode 100644
> index 0000000000..a37e2329a5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
> @@ -0,0 +1,28 @@
> +/* Test the fallback implementation of execveat.
> +   Copyright (C) 2021 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* Get the declaration of the official execveat function.  */
> +#include <unistd.h>
> +
> +/* Compile a local version of execveat.  */
> +#include <sysdeps/unix/sysv/linux/execveat_fallback.c>
> +
> +/* Re-use the test, but run it against execveat_fallback defined
> +   above.  */
> +#define execveat execveat_fallback

Because you weren't building the tests the failure was not showing itself:
execveat_fallback.c defined __execveat_fallback not execveat_fallback.
You need to fix it with:

diff --git a/sysdeps/unix/sysv/linux/tst-execveat-compat.c b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
index a37e2329a5..9374018627 100644
--- a/sysdeps/unix/sysv/linux/tst-execveat-compat.c
+++ b/sysdeps/unix/sysv/linux/tst-execveat-compat.c
@@ -24,5 +24,5 @@
 
 /* Re-use the test, but run it against execveat_fallback defined
    above.  */
-#define execveat execveat_fallback
+#define execveat __execveat_fallback
 #include <posix/tst-execveat.c>

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

* [PATCH] Linux: Add execveat system call wrapper
  2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
                   ` (12 preceding siblings ...)
  2021-04-12 19:26 ` Alexandra Hájková
@ 2021-04-21 18:11 ` Alexandra Hájková
  2021-05-03 19:20   ` Adhemerval Zanella
  13 siblings, 1 reply; 46+ messages in thread
From: Alexandra Hájková @ 2021-04-21 18:11 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alexandra Hájková

From: Alexandra Hájková <ahajkova@redhat.com>

 Also add the test for the new wrapper.
---
This version drops the fallback support.

 NEWS                                          |   5 +
 posix/Makefile                                |   5 +-
 posix/Versions                                |   3 +
 posix/execveat.c                              |  41 ++++
 posix/tst-execveat.c                          | 183 ++++++++++++++++++
 posix/unistd.h                                |   5 +
 sysdeps/mach/hurd/i386/libc.abilist           |   1 +
 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/csky/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/execveat.c            |  51 +++++
 sysdeps/unix/sysv/linux/hppa/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/i386/libc.abilist     |   1 +
 sysdeps/unix/sysv/linux/ia64/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 +
 .../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 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |   1 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |   1 +
 40 files changed, 324 insertions(+), 2 deletions(-)
 create mode 100644 posix/execveat.c
 create mode 100644 posix/tst-execveat.c
 create mode 100644 sysdeps/unix/sysv/linux/execveat.c

diff --git a/NEWS b/NEWS
index aa0f10a891..0765db4543 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,11 @@ Major new features:
   a dump of information related to IFUNC resolver operation and
   glibc-hwcaps subdirectory selection.
 
+* The function execveat has been added and it operates similar to execve.
+  The syscall is already used to implement fexecve without requiring /proc to
+  be mounted.  Similar to fexecve, if the syscall is not supported ENOSYS is
+  returned.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/posix/Makefile b/posix/Makefile
index 64494557f1..fa0dc0ea20 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -66,7 +66,8 @@ routines :=								      \
 	posix_madvise							      \
 	get_child_max sched_cpucount sched_cpualloc sched_cpufree \
 	streams-compat \
-	shm-directory
+	shm-directory                                                         \
+	execveat
 
 aux		:= init-posix environ
 tests		:= test-errno tstgetopt testfnm runtests runptests \
@@ -103,7 +104,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
 		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
 		   bug-regex38 tst-regcomp-truncated tst-spawn-chdir \
-		   tst-wordexp-nocmd
+		   tst-wordexp-nocmd tst-execveat
 
 # Test for the glob symbol version that was replaced in glibc 2.27.
 ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes)
diff --git a/posix/Versions b/posix/Versions
index cfd3819966..b77e251e00 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -147,6 +147,9 @@ libc {
   }
   GLIBC_2.30 {
   }
+  GLIBC_2.34 {
+    execveat;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
     __nanosleep_nocancel; __pause_nocancel;
diff --git a/posix/execveat.c b/posix/execveat.c
new file mode 100644
index 0000000000..7ae95f72f6
--- /dev/null
+++ b/posix/execveat.c
@@ -0,0 +1,41 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Replace the current process, executing PATH relative to difrd with
+   arguments argv and environment envp.
+   argv and envp are terminated by NULL pointers.  */
+int
+__execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+            int flags)
+{
+  if (path == NULL || argv == NULL || envp == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (execveat)
+
+weak_alias (__execveat, execveat)
diff --git a/posix/tst-execveat.c b/posix/tst-execveat.c
new file mode 100644
index 0000000000..186134564f
--- /dev/null
+++ b/posix/tst-execveat.c
@@ -0,0 +1,183 @@
+/* Test execveat at the various corner cases.
+   Copyright (C) 2021 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 <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <wait.h>
+#include <support/test-driver.h>
+
+int
+call_execveat (int fd, const char *pathname, int flags, int expected_fail,
+               int num)
+{
+  char *envp[] = { (char *) "FOO=3", NULL };
+  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
+  pid_t pid;
+  int status;
+
+  if (test_verbose > 0)
+    printf ("call line number: %d\n", num);
+
+  pid = xfork ();
+  if (pid == 0)
+    {
+      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
+      if (errno == ENOSYS)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (errno == expected_fail)
+        {
+          if (test_verbose > 0)
+            printf ("expected fail: errno %d\n", errno);
+          _exit (0);
+        }
+      else
+        FAIL_EXIT1 ("execveat failed: %m (%d)", errno);
+    }
+  xwaitpid (pid, &status, 0);
+
+  if (!WIFEXITED (status))
+    FAIL_RET ("child hasn't exited normally");
+
+  if (WIFEXITED (status))
+    {
+      if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+        FAIL_UNSUPPORTED ("execveat is unimplemented");
+      else if (expected_fail != 0)
+        TEST_COMPARE (WEXITSTATUS (status), 0);
+      else
+        TEST_COMPARE (WEXITSTATUS (status), 3);
+    }
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  DIR *dirp;
+  int fd, fd_out;
+  char *tmp_dir, *symlink_name, *tmp_sh;
+  struct stat64 st;
+
+  dirp = opendir ("/bin");
+  if (dirp == NULL)
+    FAIL_EXIT1 ("failed to open /bin");
+  fd = dirfd (dirp);
+
+  /* Call execveat for various fd/pathname combinations.  */
+
+  /* Check the pathname relative to a valid dirfd.  */
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xchdir ("/bin");
+  /* Use the special value AT_FDCWD as dirfd. Quoting open(2):
+     If pathname is relative and dirfd is the special value AT_FDCWD, then
+     pathname is interpreted relative to the current working directory of
+     the calling process.  */
+  call_execveat (AT_FDCWD, "sh", 0, 0, __LINE__);
+  xclose (fd);
+#ifdef O_PATH
+  /* Check the pathname relative to a valid dirfd with O_PATH.  */
+  fd = xopen ("/bin", O_PATH | O_DIRECTORY, O_RDONLY);
+  call_execveat (fd, "sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  /* Check absolute pathname, dirfd should be ignored.  */
+  call_execveat (AT_FDCWD, "/bin/sh", 0, 0, __LINE__);
+  fd = xopen ("/usr", O_PATH | O_DIRECTORY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+#endif
+
+  fd = xopen ("/usr", O_RDONLY, 0);
+  /* Same check for absolute pathname, but with input file descriptor
+     openend with different flags.  The dirfd should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  /* Check relative pathname, where dirfd does not point to a directory.  */
+  call_execveat (fd, "sh", 0, ENOTDIR, __LINE__);
+  /* Check absolute pathname, but dirfd is a regular file.  The dirfd
+     should be ignored.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+  xclose (fd);
+
+#ifdef O_PATH
+  /* Quoting open(2): O_PATH
+     Obtain a file descriptor that can be used for two purposes: to
+     indicate a location in the filesystem tree and to perform
+     operations that act purely at the file descriptor level.  */
+  fd = xopen ("/bin/sh", O_PATH, 0);
+  /* Check the empty pathname.  Dirfd is a regular file with O_PATH.  */
+  call_execveat (fd, "", 0, ENOENT, __LINE__);
+  /* Same check for an empty pathname, but with AT_EMPTY_PATH flag.
+     Quoting open(2):
+     If oldpath is an empty string, create a link to the file referenced
+     by olddirfd (which may have been obtained using the open(2) O_PATH flag. */
+  call_execveat (fd, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0, __LINE__);
+  xclose (fd);
+
+  /* Create a temporary directory "tmp_dir" and create a symbolik link tmp_sh
+     pointing to /bin/sh inside the tmp_dir. Open dirfd as a symbolic link.  */
+  tmp_dir = support_create_temp_directory ("tst-execveat_dir");
+  symlink_name = xasprintf ("%s/symlink", tmp_dir);
+  xsymlink ("tmp_sh", symlink_name);
+  add_temp_file (symlink_name);
+  tmp_sh = xasprintf ("%s/tmp_sh", tmp_dir);
+  add_temp_file (tmp_sh);
+  fd_out = xopen (symlink_name, O_CREAT | O_WRONLY, 0);
+  xstat ("/bin/sh", &st);
+  fd = xopen ("/bin/sh", O_RDONLY, 0);
+  xcopy_file_range (fd, 0, fd_out, 0, st.st_size, 0);
+  xfchmod (fd_out, 0700);
+  xclose (fd);
+  xclose (fd_out);
+  fd_out = xopen (symlink_name, O_PATH, 0);
+
+ /* Check the empty pathname. Dirfd is a symbolic link.  */
+  call_execveat (fd_out, "", 0, ENOENT, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH, 0, __LINE__);
+  call_execveat (fd_out, "", AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, 0,
+                 __LINE__);
+  xclose (fd_out);
+  free (symlink_name);
+  free (tmp_sh);
+  free (tmp_dir);
+#endif
+
+  /* Call execveat with closed fd, we expect this to fail with EBADF.  */
+  call_execveat (fd, "sh", 0, EBADF, __LINE__);
+  /* Call execveat with closed fd, we expect this to pass because the pathname is
+     absolute.  */
+  call_execveat (fd, "/bin/sh", 0, 0, __LINE__);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/unistd.h b/posix/unistd.h
index 3f22763379..d9d8929f71 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -295,6 +295,11 @@ extern int euidaccess (const char *__name, int __type)
 /* An alias for `euidaccess', used by some other systems.  */
 extern int eaccess (const char *__name, int __type)
      __THROW __nonnull ((1));
+
+/* Execute program relative to a directory file descriptor.  */
+extern int execveat (int __fd, const char *__path, char *const __argv[],
+                     char *const __envp[], int __flags)
+    __THROW __nonnull ((2, 3));
 #endif
 
 #ifdef __USE_ATFILE
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index fcba25ee5e..fb2683edc2 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2207,6 +2207,7 @@ GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
 GLIBC_2.34 _hurd_libc_proc_init F
+GLIBC_2.34 execveat F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 851f15a566..132589648e 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2174,4 +2174,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 33b426ef20..891e20f5e6 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2263,6 +2263,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index c09947ad58..d86333c354 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1933,4 +1933,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 57be971f81..78d7d19f79 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -156,6 +156,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 2db02fae07..4242914991 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -153,6 +153,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 0dd3527892..e6d2a4f09b 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2117,4 +2117,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/execveat.c b/sysdeps/unix/sysv/linux/execveat.c
new file mode 100644
index 0000000000..a11b3ca46d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/execveat.c
@@ -0,0 +1,51 @@
+/* Execute program relative to a directory file descriptor.
+   Copyright (C) 2021 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <kernel-features.h>
+#include <fd_to_filename.h>
+#include <not-cancel.h>
+
+/* Execute the file FD refers to, overlaying the running program image.
+   ARGV and ENVP are passed to the new program, as for `execve'.  */
+int
+execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
+          int flags)
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
+#ifndef __ASSUME_EXECVEAT
+  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  if (errno != ENOSYS)
+    return -1;
+  else
+    return ENOSYS;
+#endif
+
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 04c32f9b65..aebcb2cda5 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2076,6 +2076,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index cfd4e55e57..026dc67c14 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 426e15f4f6..2c2c16e9e1 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2110,6 +2110,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index bdecf60fae..7a00dd7869 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -157,6 +157,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index eaa5a97a61..a1fdc560a5 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2196,6 +2196,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 571315511b..c5ab412504 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2168,4 +2168,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 9d4c1f53f7..d4e9ff1675 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2165,4 +2165,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 6de58a4680..4d9dbb3901 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index e1c971c361..488f2aa6de 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2157,6 +2157,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 28d6d3284d..bac10468b7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2165,6 +2165,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 3060a503ab..95200c2064 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2159,6 +2159,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 24e0a6f16a..b5b3bc7bd4 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2207,4 +2207,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index b9cccc3fe5..38e4e3cb21 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2223,6 +2223,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 5c81a23740..41b4abd7ef 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2256,6 +2256,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index a61d2502d5..7ea617f84f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2078,6 +2078,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index ec9ae25539..6b3de81190 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2370,4 +2370,5 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index b08ece30b8..ff85889ea1 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1935,4 +1935,5 @@ GLIBC_2.33 write F
 GLIBC_2.33 writev F
 GLIBC_2.33 wscanf F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 12ced01cf7..f18bc160c4 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2135,4 +2135,5 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 7ed5e4c515..eb80905f99 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2221,6 +2221,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 73a46b01b2..360817ff74 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2114,6 +2114,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 2aa68f1def..535b0a329b 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2083,6 +2083,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 07f3c23873..82ee8a8203 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2080,6 +2080,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index cc1d278c72..af3be1fd59 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2212,6 +2212,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 79ca3d5d9c..8b41b11497 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2131,6 +2131,7 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index da0974f11a..3d1089a3e8 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2092,6 +2092,7 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index d3d155e7c0..593beb66d9 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2189,4 +2189,5 @@ GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __isnanf128 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 execveat F
 GLIBC_2.34 pthread_kill F
-- 
2.26.3


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

* Re: [PATCH] Linux: Add execveat system call wrapper
  2021-04-21 18:11 ` Alexandra Hájková
@ 2021-05-03 19:20   ` Adhemerval Zanella
  0 siblings, 0 replies; 46+ messages in thread
From: Adhemerval Zanella @ 2021-05-03 19:20 UTC (permalink / raw)
  To: libc-alpha, Alexandra Hájková



On 21/04/2021 15:11, Alexandra Hájková via Libc-alpha wrote:
> From: Alexandra Hájková <ahajkova@redhat.com>
> 
>  Also add the test for the new wrapper.

Patch looks ok in general, but there are minor issues. Since it is being
back and forth for some time, I took the liberty to fix them and I will
push it upstream.

> 
> diff --git a/NEWS b/NEWS
> index aa0f10a891..0765db4543 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -18,6 +18,11 @@ Major new features:
>    a dump of information related to IFUNC resolver operation and
>    glibc-hwcaps subdirectory selection.
>  
> +* The function execveat has been added and it operates similar to execve.
> +  The syscall is already used to implement fexecve without requiring /proc to
> +  be mounted.  Similar to fexecve, if the syscall is not supported ENOSYS is
> +  returned.
> +

With the fallback removal, execveat does not act similar to fexecve.  I changed
the NEWS entry to:

  * On Linux, the function execveat has been added.  It operates similar to
    execve and it is is already used to implement fexecve without requiring
    /proc to be mounted.  However, different than fexecve, if the syscall is not
    supported by the kernel an error is returned instead of trying a fallback.


> +int
> +call_execveat (int fd, const char *pathname, int flags, int expected_fail,
> +               int num)
> +{
> +  char *envp[] = { (char *) "FOO=3", NULL };
> +  char *argv[] = { (char *) "sh", (char *) "-c", (char *) "exit $FOO", NULL };
> +  pid_t pid;
> +  int status;
> +
> +  if (test_verbose > 0)
> +    printf ("call line number: %d\n", num);
> +
> +  pid = xfork ();
> +  if (pid == 0)
> +    {
> +      TEST_COMPARE (execveat (fd, pathname, argv, envp, flags), -1);
> +      if (errno == ENOSYS)
> +        FAIL_UNSUPPORTED ("execveat is unimplemented");

This will print 'execveat is unimplemented', since the WEXITSTATUS below
will already handle it.  Instead I replace it with:

  exit (EXIT_UNSUPPORTED); 


> +int
> +execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
> +          int flags)
> +{
> +  /* Avoid implicit array coercion in syscall macros.  */
> +  INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0], flags);
> +#ifndef __ASSUME_EXECVEAT
> +  if ((flags & ~(AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) != 0)
> +    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
> +
> +  if (errno != ENOSYS)
> +    return -1;
> +  else
> +    return ENOSYS;
> +#endif
> +
> +  return -1;
> +}

Since there is no fallback anymore, there is no need to check for flag
support neither handle the errno value.  It can be simple as:

  int
  execveat (int dirfd, const char *path, char *const argv[], char *const envp[],
            int flags)
  {
    /* Avoid implicit array coercion in syscall macros.  */
    return INLINE_SYSCALL_CALL (execveat, dirfd, path, &argv[0], &envp[0],
                                flags);
  }

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

end of thread, other threads:[~2021-05-03 19:20 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-28 12:20 [PATCH] Linux: Add execveat system call wrapper Alexandra Hájková
2020-04-28 14:17 ` Florian Weimer
2020-04-28 15:03   ` Joseph Myers
2020-04-28 15:03 ` Joseph Myers
2020-04-28 15:08   ` Florian Weimer
2020-04-28 15:29     ` Joseph Myers
2020-04-28 17:15       ` Florian Weimer
2020-04-28 17:19         ` Joseph Myers
2020-04-28 17:44 ` Adhemerval Zanella
2020-04-28 17:50   ` Florian Weimer
2020-04-28 18:31     ` Adhemerval Zanella
2020-04-30 11:15 ` Florian Weimer
2020-04-30 12:28   ` Adhemerval Zanella
2020-04-30 12:55     ` Florian Weimer
2020-04-30 19:03       ` Adhemerval Zanella
2020-04-30 12:32 ` Adhemerval Zanella
2020-11-06 21:03 ` Alexandra Hájková
2020-11-06 22:15   ` Joseph Myers
2020-11-09 18:43     ` Florian Weimer
2020-11-09 21:34   ` Yann Droneaud
2020-11-26 11:31     ` Alexandra Petlanova Hajkova
2020-11-09 20:39 ` Adhemerval Zanella
2020-12-03 13:55   ` Florian Weimer
2020-11-26 21:28 ` Alexandra Hájková
2020-11-27 14:58   ` Adhemerval Zanella
2020-11-27 17:32     ` Florian Weimer
2020-11-27 17:38       ` Adhemerval Zanella
2020-12-03 14:20 ` Alexandra Hájková
2020-12-03 14:37   ` Andreas Schwab
2020-12-08 14:44   ` Adhemerval Zanella
2020-12-08 15:18     ` Florian Weimer
2020-12-08 16:41       ` Adhemerval Zanella
2021-03-15 21:42 ` Alexandra Hájková
2021-03-15 22:12   ` Joseph Myers
2021-03-15 22:17   ` Dmitry V. Levin
2021-03-24 13:54 ` Alexandra Hájková
2021-03-26 20:36   ` Adhemerval Zanella
2021-04-02 12:13     ` Alexandra Hájková
2021-04-02 13:29       ` Adhemerval Zanella
2021-04-05 16:32 ` Alexandra Hájková
2021-04-12 10:26   ` Alexandra Hájková
2021-04-12 11:14   ` Andreas Schwab
2021-04-12 19:26 ` Alexandra Hájková
2021-04-13 19:27   ` Adhemerval Zanella
2021-04-21 18:11 ` Alexandra Hájková
2021-05-03 19:20   ` Adhemerval Zanella

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).