* [PATCH] Use execveat syscall in fexecve @ 2017-09-07 9:06 Andreas Schwab 2017-09-07 11:27 ` Florian Weimer 0 siblings, 1 reply; 9+ messages in thread From: Andreas Schwab @ 2017-09-07 9:06 UTC (permalink / raw) To: libc-alpha By using execveat we no longer depend on /proc. The execveat syscall was introduced in 3.19, except for a few late comers. * sysdeps/unix/sysv/linux/fexecve.c (fexecve) [__NR_execveat]: Try execveat first. [!__ASSUME_EXECVEAT]: Fall back to /proc if execveat is unimplemented. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION >= 0x031300]: Define. * sysdeps/unix/sysv/linux/alpha/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040200]: Undef. * sysdeps/unix/sysv/linux/hppa/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040000]: Undef. * sysdeps/unix/sysv/linux/microblaze/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040000]: Undef. --- sysdeps/unix/sysv/linux/alpha/kernel-features.h | 5 +++++ sysdeps/unix/sysv/linux/fexecve.c | 15 +++++++++++++++ sysdeps/unix/sysv/linux/hppa/kernel-features.h | 5 +++++ sysdeps/unix/sysv/linux/kernel-features.h | 5 +++++ sysdeps/unix/sysv/linux/microblaze/kernel-features.h | 5 +++++ 5 files changed, 35 insertions(+) diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h index 53f7611f93..5bc2ddb713 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h @@ -35,4 +35,9 @@ #define __ASSUME_RECV_SYSCALL 1 #define __ASSUME_SEND_SYSCALL 1 +/* Support for the execveat syscall was added in 4.2. */ +#if __LINUX_KERNEL_VERSION < 0x040200 +# undef __ASSUME_EXECVEAT +#endif + #endif /* _KERNEL_FEATURES_H */ diff --git a/sysdeps/unix/sysv/linux/fexecve.c b/sysdeps/unix/sysv/linux/fexecve.c index 30fa719b56..3bf5de507f 100644 --- a/sysdeps/unix/sysv/linux/fexecve.c +++ b/sysdeps/unix/sysv/linux/fexecve.c @@ -19,8 +19,13 @@ #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> + /* Execute the file FD refers to, overlaying the running program image. ARGV and ENVP are passed to the new program, as for `execve'. */ @@ -33,6 +38,15 @@ fexecve (int fd, char *const argv[], char *const envp[]) return -1; } +#ifdef __NR_execveat + INLINE_SYSCALL (execveat, 5, fd, "", argv, envp, AT_EMPTY_PATH); +# ifndef __ASSUME_EXECVEAT + if (errno != ENOSYS) + return -1; +# endif +#endif + +#ifndef __ASSUME_EXECVEAT /* We use the /proc filesystem to get the information. If it is not mounted we fail. */ char buf[sizeof "/proc/self/fd/" + sizeof (int) * 3]; @@ -50,6 +64,7 @@ fexecve (int fd, char *const argv[], char *const envp[]) save = ENOSYS; __set_errno (save); +#endif return -1; } diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h index 0e73a5c0df..f25a840040 100644 --- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h +++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h @@ -27,3 +27,8 @@ #define __ASSUME_RECV_SYSCALL 1 #define __ASSUME_SEND_SYSCALL 1 + +/* Support for the execveat syscall was added in 4.0. */ +#if __LINUX_KERNEL_VERSION < 0x040000 +# undef __ASSUME_EXECVEAT +#endif diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 9495db4fef..2e1fe6597a 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -102,3 +102,8 @@ implementation does not assume the __ASSUME_* and instead use a fallback implementation based on p{read,write}v and returning an error for non supported flags. */ + +/* Support for the execveat syscall was added in 3.19. */ +#if __LINUX_KERNEL_VERSION >= 0x031300 +# define __ASSUME_EXECVEAT 1 +#endif diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h index 0257524777..6575df2a95 100644 --- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h @@ -47,3 +47,8 @@ #if __LINUX_KERNEL_VERSION < 0x030300 # undef __ASSUME_SENDMMSG_SYSCALL #endif + +/* Support for the execveat syscall was added in 4.0. */ +#if __LINUX_KERNEL_VERSION < 0x040000 +# undef __ASSUME_EXECVEAT +#endif -- 2.14.1 -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Use execveat syscall in fexecve 2017-09-07 9:06 [PATCH] Use execveat syscall in fexecve Andreas Schwab @ 2017-09-07 11:27 ` Florian Weimer 2017-09-11 10:23 ` [PATCH v2] " Andreas Schwab 0 siblings, 1 reply; 9+ messages in thread From: Florian Weimer @ 2017-09-07 11:27 UTC (permalink / raw) To: Andreas Schwab; +Cc: libc-alpha * Andreas Schwab: > By using execveat we no longer depend on /proc. The execveat syscall was > introduced in 3.19, except for a few late comers. Ideally, this should have a test that executing “/bin/sh -c true” works, both with an O_PATH descriptor and a regular descriptor. The implementation itself (including the AT_EMPTY_PATH flag) and the __ASSUME_EXECVEAT conditions look good to me. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] Use execveat syscall in fexecve 2017-09-07 11:27 ` Florian Weimer @ 2017-09-11 10:23 ` Andreas Schwab 2017-09-11 20:30 ` Adhemerval Zanella 0 siblings, 1 reply; 9+ messages in thread From: Andreas Schwab @ 2017-09-11 10:23 UTC (permalink / raw) To: libc-alpha By using execveat we no longer depend on /proc. The execveat syscall was introduced in 3.19, except for a few late comers. * sysdeps/unix/sysv/linux/fexecve.c (fexecve) [__NR_execveat]: Try execveat first. [!__ASSUME_EXECVEAT]: Fall back to /proc if execveat is unimplemented. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION >= 0x031300]: Define. * sysdeps/unix/sysv/linux/alpha/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040200]: Undef. * sysdeps/unix/sysv/linux/hppa/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040000]: Undef. * sysdeps/unix/sysv/linux/microblaze/kernel-features.h (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040000]: Undef. * posix/Makefile (tests): Add tst-fexecve. * posix/tst-fexecve.c: New file. --- posix/Makefile | 2 +- posix/tst-fexecve.c | 88 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/alpha/kernel-features.h | 5 ++ sysdeps/unix/sysv/linux/fexecve.c | 15 ++++ sysdeps/unix/sysv/linux/hppa/kernel-features.h | 5 ++ sysdeps/unix/sysv/linux/kernel-features.h | 5 ++ .../unix/sysv/linux/microblaze/kernel-features.h | 5 ++ 7 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 posix/tst-fexecve.c diff --git a/posix/Makefile b/posix/Makefile index 4021e4f19e..75d905b922 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -94,7 +94,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-fnmatch4 tst-fnmatch5 \ tst-posix_spawn-fd tst-posix_spawn-setsid \ tst-posix_fadvise tst-posix_fadvise64 \ - tst-sysconf-empty-chroot + tst-sysconf-empty-chroot tst-fexecve tests-internal := bug-regex5 bug-regex20 bug-regex33 \ tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 xtests := bug-ga2 diff --git a/posix/tst-fexecve.c b/posix/tst-fexecve.c new file mode 100644 index 0000000000..2409102e21 --- /dev/null +++ b/posix/tst-fexecve.c @@ -0,0 +1,88 @@ +/* Copyright (C) 2017 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/>. */ + +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/wait.h> + +#include <support/check.h> + +/* Try executing "/bin/sh -c true", using FD opened on /bin/sh. */ +static int +try_fexecve (int fd) +{ + pid_t pid = fork (); + + if (pid == 0) + { + static const char *const argv[] = { + "/bin/sh", "-c", "true", NULL + }; + fexecve (fd, (char *const *) argv, environ); + _exit (errno); + } + if (pid < 0) + FAIL_RET ("fork failed: %m"); + + pid_t termpid; + int status; + termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); + if (termpid == -1) + FAIL_RET ("waitpid failed: %m"); + if (termpid != pid) + FAIL_RET ("waitpid returned %ld != %ld", + (long int) termpid, (long int) pid); + if (!WIFEXITED (status)) + FAIL_RET ("child hasn't exited normally"); + + /* If fexecve is unimplemented mark this test as UNSUPPORTED. */ + if (WEXITSTATUS (status) == ENOSYS) + FAIL_UNSUPPORTED ("fexecve is unimplemented"); + + if (WEXITSTATUS (status) != 0) + { + errno = WEXITSTATUS (status); + FAIL_RET ("fexecve failed: %m"); + } + return 0; +} + +static int +do_test (void) +{ + int fd; + int ret; + + fd = open ("/bin/sh", O_RDONLY); + if (fd < 0) + FAIL_UNSUPPORTED ("/bin/sh cannot be opened: %m"); + ret = try_fexecve (fd); + close (fd); + +#ifdef O_PATH + fd = open ("/bin/sh", O_RDONLY | O_PATH); + if (fd < 0) + FAIL_UNSUPPORTED ("/bin/sh cannot be opened (O_PATH): %m"); + ret |= try_fexecve (fd); + close (fd); +#endif + + return ret; +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h index 53f7611f93..5bc2ddb713 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h @@ -35,4 +35,9 @@ #define __ASSUME_RECV_SYSCALL 1 #define __ASSUME_SEND_SYSCALL 1 +/* Support for the execveat syscall was added in 4.2. */ +#if __LINUX_KERNEL_VERSION < 0x040200 +# undef __ASSUME_EXECVEAT +#endif + #endif /* _KERNEL_FEATURES_H */ diff --git a/sysdeps/unix/sysv/linux/fexecve.c b/sysdeps/unix/sysv/linux/fexecve.c index 30fa719b56..3bf5de507f 100644 --- a/sysdeps/unix/sysv/linux/fexecve.c +++ b/sysdeps/unix/sysv/linux/fexecve.c @@ -19,8 +19,13 @@ #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> + /* Execute the file FD refers to, overlaying the running program image. ARGV and ENVP are passed to the new program, as for `execve'. */ @@ -33,6 +38,15 @@ fexecve (int fd, char *const argv[], char *const envp[]) return -1; } +#ifdef __NR_execveat + INLINE_SYSCALL (execveat, 5, fd, "", argv, envp, AT_EMPTY_PATH); +# ifndef __ASSUME_EXECVEAT + if (errno != ENOSYS) + return -1; +# endif +#endif + +#ifndef __ASSUME_EXECVEAT /* We use the /proc filesystem to get the information. If it is not mounted we fail. */ char buf[sizeof "/proc/self/fd/" + sizeof (int) * 3]; @@ -50,6 +64,7 @@ fexecve (int fd, char *const argv[], char *const envp[]) save = ENOSYS; __set_errno (save); +#endif return -1; } diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h index 0e73a5c0df..f25a840040 100644 --- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h +++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h @@ -27,3 +27,8 @@ #define __ASSUME_RECV_SYSCALL 1 #define __ASSUME_SEND_SYSCALL 1 + +/* Support for the execveat syscall was added in 4.0. */ +#if __LINUX_KERNEL_VERSION < 0x040000 +# undef __ASSUME_EXECVEAT +#endif diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 9495db4fef..2e1fe6597a 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -102,3 +102,8 @@ implementation does not assume the __ASSUME_* and instead use a fallback implementation based on p{read,write}v and returning an error for non supported flags. */ + +/* Support for the execveat syscall was added in 3.19. */ +#if __LINUX_KERNEL_VERSION >= 0x031300 +# define __ASSUME_EXECVEAT 1 +#endif diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h index 0257524777..6575df2a95 100644 --- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h @@ -47,3 +47,8 @@ #if __LINUX_KERNEL_VERSION < 0x030300 # undef __ASSUME_SENDMMSG_SYSCALL #endif + +/* Support for the execveat syscall was added in 4.0. */ +#if __LINUX_KERNEL_VERSION < 0x040000 +# undef __ASSUME_EXECVEAT +#endif -- 2.14.1 -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] Use execveat syscall in fexecve 2017-09-11 10:23 ` [PATCH v2] " Andreas Schwab @ 2017-09-11 20:30 ` Adhemerval Zanella 2017-09-11 20:38 ` Joseph Myers 2017-09-14 8:05 ` Andreas Schwab 0 siblings, 2 replies; 9+ messages in thread From: Adhemerval Zanella @ 2017-09-11 20:30 UTC (permalink / raw) To: libc-alpha On 11/09/2017 07:23, Andreas Schwab wrote: > By using execveat we no longer depend on /proc. The execveat syscall was > introduced in 3.19, except for a few late comers. > > * sysdeps/unix/sysv/linux/fexecve.c (fexecve) [__NR_execveat]: Try > execveat first. > [!__ASSUME_EXECVEAT]: Fall back to /proc if execveat is > unimplemented. > * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_EXECVEAT) > [__LINUX_KERNEL_VERSION >= 0x031300]: Define. > * sysdeps/unix/sysv/linux/alpha/kernel-features.h > (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040200]: Undef. > * sysdeps/unix/sysv/linux/hppa/kernel-features.h > (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040000]: Undef. > * sysdeps/unix/sysv/linux/microblaze/kernel-features.h > (__ASSUME_EXECVEAT) [__LINUX_KERNEL_VERSION < 0x040000]: Undef. > * posix/Makefile (tests): Add tst-fexecve. > * posix/tst-fexecve.c: New file. > --- > posix/Makefile | 2 +- > posix/tst-fexecve.c | 88 ++++++++++++++++++++++ > sysdeps/unix/sysv/linux/alpha/kernel-features.h | 5 ++ > sysdeps/unix/sysv/linux/fexecve.c | 15 ++++ > sysdeps/unix/sysv/linux/hppa/kernel-features.h | 5 ++ > sysdeps/unix/sysv/linux/kernel-features.h | 5 ++ > .../unix/sysv/linux/microblaze/kernel-features.h | 5 ++ > 7 files changed, 124 insertions(+), 1 deletion(-) > create mode 100644 posix/tst-fexecve.c > > diff --git a/posix/Makefile b/posix/Makefile > index 4021e4f19e..75d905b922 100644 > --- a/posix/Makefile > +++ b/posix/Makefile > @@ -94,7 +94,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ > tst-fnmatch4 tst-fnmatch5 \ > tst-posix_spawn-fd tst-posix_spawn-setsid \ > tst-posix_fadvise tst-posix_fadvise64 \ > - tst-sysconf-empty-chroot > + tst-sysconf-empty-chroot tst-fexecve > tests-internal := bug-regex5 bug-regex20 bug-regex33 \ > tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 > xtests := bug-ga2 > diff --git a/posix/tst-fexecve.c b/posix/tst-fexecve.c > new file mode 100644 > index 0000000000..2409102e21 > --- /dev/null > +++ b/posix/tst-fexecve.c > @@ -0,0 +1,88 @@ > +/* Copyright (C) 2017 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/>. */ > + > +#include <unistd.h> > +#include <errno.h> > +#include <fcntl.h> > +#include <sys/wait.h> > + > +#include <support/check.h> > + > +/* Try executing "/bin/sh -c true", using FD opened on /bin/sh. */ > +static int > +try_fexecve (int fd) > +{ > + pid_t pid = fork (); > + > + if (pid == 0) > + { > + static const char *const argv[] = { > + "/bin/sh", "-c", "true", NULL > + }; > + fexecve (fd, (char *const *) argv, environ); > + _exit (errno); > + } > + if (pid < 0) > + FAIL_RET ("fork failed: %m"); > + > + pid_t termpid; > + int status; > + termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); > + if (termpid == -1) > + FAIL_RET ("waitpid failed: %m"); > + if (termpid != pid) > + FAIL_RET ("waitpid returned %ld != %ld", > + (long int) termpid, (long int) pid); > + if (!WIFEXITED (status)) > + FAIL_RET ("child hasn't exited normally"); > + > + /* If fexecve is unimplemented mark this test as UNSUPPORTED. */ > + if (WEXITSTATUS (status) == ENOSYS) > + FAIL_UNSUPPORTED ("fexecve is unimplemented"); > + > + if (WEXITSTATUS (status) != 0) > + { > + errno = WEXITSTATUS (status); > + FAIL_RET ("fexecve failed: %m"); > + } > + return 0; > +} > + > +static int > +do_test (void) > +{ > + int fd; > + int ret; > + > + fd = open ("/bin/sh", O_RDONLY); > + if (fd < 0) > + FAIL_UNSUPPORTED ("/bin/sh cannot be opened: %m"); > + ret = try_fexecve (fd); > + close (fd); > + > +#ifdef O_PATH > + fd = open ("/bin/sh", O_RDONLY | O_PATH); > + if (fd < 0) > + FAIL_UNSUPPORTED ("/bin/sh cannot be opened (O_PATH): %m"); > + ret |= try_fexecve (fd); > + close (fd); > +#endif > + > + return ret; > +} > + > +#include <support/test-driver.c> > diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h > index 53f7611f93..5bc2ddb713 100644 > --- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h > @@ -35,4 +35,9 @@ > #define __ASSUME_RECV_SYSCALL 1 > #define __ASSUME_SEND_SYSCALL 1 > > +/* Support for the execveat syscall was added in 4.2. */ > +#if __LINUX_KERNEL_VERSION < 0x040200 > +# undef __ASSUME_EXECVEAT > +#endif > + > #endif /* _KERNEL_FEATURES_H */ > diff --git a/sysdeps/unix/sysv/linux/fexecve.c b/sysdeps/unix/sysv/linux/fexecve.c > index 30fa719b56..3bf5de507f 100644 > --- a/sysdeps/unix/sysv/linux/fexecve.c > +++ b/sysdeps/unix/sysv/linux/fexecve.c > @@ -19,8 +19,13 @@ > #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> > + > > /* Execute the file FD refers to, overlaying the running program image. > ARGV and ENVP are passed to the new program, as for `execve'. */ > @@ -33,6 +38,15 @@ fexecve (int fd, char *const argv[], char *const envp[]) > return -1; > } > > +#ifdef __NR_execveat > + INLINE_SYSCALL (execveat, 5, fd, "", argv, envp, AT_EMPTY_PATH); I would prefer it to use INLINE_SYSCALL_CALL. And since the idea is not to clobber errno I think we can do: #ifdef __NR_execvat INTERNAL_SYSCALL_DECL (err); int val = INTERNAL_SYSCALL_CALL (execveat, fd, argv, envp, AT_EMPTY_PATH); if (INTERNAL_SYSCALL_ERROR_P (val, err) != ENOSYS) return -1; #endif > +# ifndef __ASSUME_EXECVEAT > + if (errno != ENOSYS) > + return -1; > +# endif > +#endif Do we really need to add another __ASSUME_* that eventually we will need to cleanup? Can't we just check fo __NR_execvat, call it and if it fails with ENOSYS use the current code as fallback? The drawback would be that the fallback code would be mainly dead code for newer kernels. > + > +#ifndef __ASSUME_EXECVEAT > /* We use the /proc filesystem to get the information. If it is not > mounted we fail. */ > char buf[sizeof "/proc/self/fd/" + sizeof (int) * 3]; > @@ -50,6 +64,7 @@ fexecve (int fd, char *const argv[], char *const envp[]) > save = ENOSYS; > > __set_errno (save); > +#endif > > return -1; > } > diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h > index 0e73a5c0df..f25a840040 100644 > --- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h > @@ -27,3 +27,8 @@ > > #define __ASSUME_RECV_SYSCALL 1 > #define __ASSUME_SEND_SYSCALL 1 > + > +/* Support for the execveat syscall was added in 4.0. */ > +#if __LINUX_KERNEL_VERSION < 0x040000 > +# undef __ASSUME_EXECVEAT > +#endif > diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h > index 9495db4fef..2e1fe6597a 100644 > --- a/sysdeps/unix/sysv/linux/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/kernel-features.h > @@ -102,3 +102,8 @@ > implementation does not assume the __ASSUME_* and instead use a fallback > implementation based on p{read,write}v and returning an error for > non supported flags. */ > + > +/* Support for the execveat syscall was added in 3.19. */ > +#if __LINUX_KERNEL_VERSION >= 0x031300 > +# define __ASSUME_EXECVEAT 1 > +#endif > diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h > index 0257524777..6575df2a95 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h > @@ -47,3 +47,8 @@ > #if __LINUX_KERNEL_VERSION < 0x030300 > # undef __ASSUME_SENDMMSG_SYSCALL > #endif > + > +/* Support for the execveat syscall was added in 4.0. */ > +#if __LINUX_KERNEL_VERSION < 0x040000 > +# undef __ASSUME_EXECVEAT > +#endif > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] Use execveat syscall in fexecve 2017-09-11 20:30 ` Adhemerval Zanella @ 2017-09-11 20:38 ` Joseph Myers 2017-09-11 20:59 ` Florian Weimer 2017-09-14 8:05 ` Andreas Schwab 1 sibling, 1 reply; 9+ messages in thread From: Joseph Myers @ 2017-09-11 20:38 UTC (permalink / raw) To: Adhemerval Zanella; +Cc: libc-alpha On Mon, 11 Sep 2017, Adhemerval Zanella wrote: > > +# ifndef __ASSUME_EXECVEAT > > + if (errno != ENOSYS) > > + return -1; > > +# endif > > +#endif > > Do we really need to add another __ASSUME_* that eventually we will need to > cleanup? Can't we just check fo __NR_execvat, call it and if it fails with > ENOSYS use the current code as fallback? The drawback would be that the > fallback code would be mainly dead code for newer kernels. We have the ENOSYS code there and the subsequent fallback that will eventually need cleaning up *anyway*. Having the __ASSUME_* macro makes it obvious in future exactly what changes should be made for the cleanup and exactly when it is possible to do that cleanup. I think having such macros for any case with fallback code that can be cleaned up in future is a good idea for that reason. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] Use execveat syscall in fexecve 2017-09-11 20:38 ` Joseph Myers @ 2017-09-11 20:59 ` Florian Weimer 2017-09-11 22:58 ` Adhemerval Zanella 0 siblings, 1 reply; 9+ messages in thread From: Florian Weimer @ 2017-09-11 20:59 UTC (permalink / raw) To: Joseph Myers; +Cc: Adhemerval Zanella, libc-alpha * Joseph Myers: > We have the ENOSYS code there and the subsequent fallback that will > eventually need cleaning up *anyway*. Having the __ASSUME_* macro makes > it obvious in future exactly what changes should be made for the cleanup > and exactly when it is possible to do that cleanup. I think having such > macros for any case with fallback code that can be cleaned up in future is > a good idea for that reason. Agreed. As long as there is an expectation that we will eventually bump the minimum kernel requirement, __ASSUME_* macros are the way to go. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] Use execveat syscall in fexecve 2017-09-11 20:59 ` Florian Weimer @ 2017-09-11 22:58 ` Adhemerval Zanella 0 siblings, 0 replies; 9+ messages in thread From: Adhemerval Zanella @ 2017-09-11 22:58 UTC (permalink / raw) To: Florian Weimer, Joseph Myers; +Cc: libc-alpha On 11/09/2017 17:59, Florian Weimer wrote: > * Joseph Myers: > >> We have the ENOSYS code there and the subsequent fallback that will >> eventually need cleaning up *anyway*. Having the __ASSUME_* macro makes >> it obvious in future exactly what changes should be made for the cleanup >> and exactly when it is possible to do that cleanup. I think having such >> macros for any case with fallback code that can be cleaned up in future is >> a good idea for that reason. > > Agreed. As long as there is an expectation that we will eventually > bump the minimum kernel requirement, __ASSUME_* macros are the way to > go. > Fair enough then. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] Use execveat syscall in fexecve 2017-09-11 20:30 ` Adhemerval Zanella 2017-09-11 20:38 ` Joseph Myers @ 2017-09-14 8:05 ` Andreas Schwab 2017-09-14 13:44 ` Adhemerval Zanella 1 sibling, 1 reply; 9+ messages in thread From: Andreas Schwab @ 2017-09-14 8:05 UTC (permalink / raw) To: Adhemerval Zanella; +Cc: libc-alpha On Sep 11 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > I would prefer it to use INLINE_SYSCALL_CALL. And since the idea is not to > clobber errno I think we can do: > > #ifdef __NR_execvat > INTERNAL_SYSCALL_DECL (err); > int val = INTERNAL_SYSCALL_CALL (execveat, fd, argv, envp, AT_EMPTY_PATH); > if (INTERNAL_SYSCALL_ERROR_P (val, err) != ENOSYS) > return -1; > #endif No, that would be wrong. Either the exec succeeds, then errno no longer exits, otherwise errno needs to be set before we return. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] Use execveat syscall in fexecve 2017-09-14 8:05 ` Andreas Schwab @ 2017-09-14 13:44 ` Adhemerval Zanella 0 siblings, 0 replies; 9+ messages in thread From: Adhemerval Zanella @ 2017-09-14 13:44 UTC (permalink / raw) To: Andreas Schwab; +Cc: libc-alpha On 14/09/2017 05:04, Andreas Schwab wrote: > On Sep 11 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > >> I would prefer it to use INLINE_SYSCALL_CALL. And since the idea is not to >> clobber errno I think we can do: >> >> #ifdef __NR_execvat >> INTERNAL_SYSCALL_DECL (err); >> int val = INTERNAL_SYSCALL_CALL (execveat, fd, argv, envp, AT_EMPTY_PATH); >> if (INTERNAL_SYSCALL_ERROR_P (val, err) != ENOSYS) >> return -1; >> #endif > > No, that would be wrong. Either the exec succeeds, then errno no longer > exits, otherwise errno needs to be set before we return. > > Andreas. > Right, errno does need to be setup (I misread the man for some reason). ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-09-14 13:44 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-09-07 9:06 [PATCH] Use execveat syscall in fexecve Andreas Schwab 2017-09-07 11:27 ` Florian Weimer 2017-09-11 10:23 ` [PATCH v2] " Andreas Schwab 2017-09-11 20:30 ` Adhemerval Zanella 2017-09-11 20:38 ` Joseph Myers 2017-09-11 20:59 ` Florian Weimer 2017-09-11 22:58 ` Adhemerval Zanella 2017-09-14 8:05 ` Andreas Schwab 2017-09-14 13:44 ` 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).