diff mbox series

[v2,03/13] Linux: Introduce __do_fexecve in fexecve

Message ID 49be319a6cc60341a437ba186ef701b9095e00d7.1722193092.git.fweimer@redhat.com
State New
Headers show
Series getenv/environ thread safety | expand

Commit Message

Florian Weimer July 28, 2024, 7:02 p.m. UTC
Call the execve system call directly, in preparation of
wrapping environ access in the *execve* family of function.

Make handling of errno more explicit on the fallback path
by using INTERNAL_SYSCALL_CALL.
---
 sysdeps/unix/sysv/linux/fexecve.c | 53 ++++++++++++++++---------------
 1 file changed, 28 insertions(+), 25 deletions(-)
diff mbox series

Patch

diff --git a/sysdeps/unix/sysv/linux/fexecve.c b/sysdeps/unix/sysv/linux/fexecve.c
index e0e5566fd7..46c8170092 100644
--- a/sysdeps/unix/sysv/linux/fexecve.c
+++ b/sysdeps/unix/sysv/linux/fexecve.c
@@ -27,6 +27,33 @@ 
 #include <sys/syscall.h>
 #include <kernel-features.h>
 
+static int
+__do_fexecve (int fd, char *const argv[], char *const envp[])
+{
+  /* Avoid implicit array coercion in syscall macros.  */
+  int err = -INTERNAL_SYSCALL_CALL (execveat, fd, "", &argv[0], &envp[0],
+                                    AT_EMPTY_PATH);
+
+#ifndef __ASSUME_EXECVEAT
+  if (err == ENOSYS)
+    {
+      /* We use the /proc filesystem to get the information.  If it is not
+         mounted we fail.  We do not need the return value.  */
+      struct fd_to_filename filename;
+      const char *path = __fd_to_filename (fd, &filename);
+      err = -INTERNAL_SYSCALL_CALL (execve, path, &argv[0], &envp[0]);
+
+      /* We come here only if the 'execve' call fails.  Determine whether
+         /proc is mounted.  If not we return ENOSYS.  */
+      if (INTERNAL_SYSCALL_CALL (faccessat, AT_FDCWD, "/proc/self/fd", 0)
+          == -ENOENT)
+        err = ENOSYS;
+    }
+#endif /* __ASSUME_EXECVEAT */
+
+  __set_errno (err);
+  return -1;
+}
 
 /* Execute the file FD refers to, overlaying the running program image.
    ARGV and ENVP are passed to the new program, as for `execve'.  */
@@ -39,29 +66,5 @@  fexecve (int fd, char *const argv[], char *const envp[])
       return -1;
     }
 
-  /* Avoid implicit array coercion in syscall macros.  */
-  INLINE_SYSCALL (execveat, 5, fd, "", &argv[0], &envp[0], AT_EMPTY_PATH);
-#ifndef __ASSUME_EXECVEAT
-  if (errno != ENOSYS)
-    return -1;
-#endif
-
-#ifndef __ASSUME_EXECVEAT
-  /* We use the /proc filesystem to get the information.  If it is not
-     mounted we fail.  We do not need the return value.  */
-  struct fd_to_filename filename;
-  __execve (__fd_to_filename (fd, &filename), 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_t64 st;
-  if (__stat64_time64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
-    save = ENOSYS;
-
-  __set_errno (save);
-#endif
-
-  return -1;
+  return __do_fexecve (fd, argv, envp);
 }