Message ID | 49be319a6cc60341a437ba186ef701b9095e00d7.1722193092.git.fweimer@redhat.com |
---|---|
State | New |
Headers | show |
Series | getenv/environ thread safety | expand |
On 28/07/24 16:02, Florian Weimer wrote: > 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. LGTM, thanks. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > --- > sysdeps/unix/sysv/linux/fexecve.c | 53 ++++++++++++++++--------------- > 1 file changed, 28 insertions(+), 25 deletions(-) > > 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; Ok, replace stat with faccessat (I had to remind myself that only faccessat2 accepts a flag). > + } > +#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); > }
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); }