[v2,03/13] Linux: Introduce __do_fexecve in fexecve
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
fail
|
Patch failed to apply
|
Commit Message
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(-)
Comments
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);
> }
@@ -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);
}