On Wed, Jul 13, 2022 at 08:17:09AM +0200, Stefano Brivio wrote: > ...instead of argv[0], which might or might not contain a valid path > to the executable itself. Instead of mangling argv[0], use the same > link to find out if we're already running the AVX2 build where > supported. Ah.. yeah, I remember seeing that usage of argv[0] and suspecting it might be a problem. > Alternatively, we could use execvpe(), but that might result in > running a different installed version, in case e.g. the set of > binaries is present in both /usr/bin and /usr/local/bin, with both > being in $PATH. > > Reported-by: Wenli Quan > Link: https://bugzilla.redhat.com/show_bug.cgi?id=2101310 > Signed-off-by: Stefano Brivio > --- > arch.c | 25 +++++++++++++++---------- > passt.c | 9 ++++++--- > 2 files changed, 21 insertions(+), 13 deletions(-) > > diff --git a/arch.c b/arch.c > index ae21d59..71feda3 100644 > --- a/arch.c > +++ b/arch.c > @@ -14,26 +14,31 @@ > > #include > #include > +#include > #include > #include > > /** > - * arch_avx2_exec() - Run AVX2 build if supported, drop suffix from argv[0] > + * arch_avx2_exec() - Switch to AVX2 build if supported > * @argv: Arguments from command line > */ > #ifdef __x86_64__ > -static char avx2_path[PATH_MAX]; > - > void arch_avx2_exec(char **argv) > { > - char *p = strstr(argv[0], ".avx2"); > + char exe[PATH_MAX], new_path[PATH_MAX + sizeof(".avx2")], *p; > + > + if (readlink("/proc/self/exe", exe, PATH_MAX) < 0) { > + perror("readlink /proc/self/exe"); > + exit(EXIT_FAILURE); > + } > + > + p = strstr(exe, ".avx2"); > + if (p && strlen(p) == strlen(".avx2")) > + return; > > - if (p) { > - *p = 0; > - } else if (__builtin_cpu_supports("avx2")) { > - snprintf(avx2_path, PATH_MAX, "%s.avx2", argv[0]); > - argv[0] = avx2_path; > - execve(avx2_path, argv, environ); > + if (__builtin_cpu_supports("avx2")) { > + snprintf(new_path, PATH_MAX + sizeof(".avx2"), "%s.avx2", exe); > + execve(new_path, argv, environ); > perror("Can't run AVX2 build, using non-AVX2 version"); > } > } > diff --git a/passt.c b/passt.c > index dd0229a..56fcf5f 100644 > --- a/passt.c > +++ b/passt.c > @@ -35,6 +35,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -283,11 +284,11 @@ int main(int argc, char **argv) > { > int nfds, i, devnull_fd = -1, pidfile_fd = -1, quit_fd; > struct epoll_event events[EPOLL_EVENTS]; > + char *log_name, argv0[PATH_MAX], *name; > struct ctx c = { 0 }; > struct rlimit limit; > struct timespec now; > struct sigaction sa; > - char *log_name; > > arch_avx2_exec(argv); > > @@ -304,14 +305,16 @@ int main(int argc, char **argv) > if (argc < 1) > exit(EXIT_FAILURE); > > - if (strstr(argv[0], "pasta")) { > + strncpy(argv0, argv[0], PATH_MAX - 1); > + name = basename(argv0); > + if (strstr(name, "pasta")) { > sa.sa_handler = pasta_child_handler; > sigaction(SIGCHLD, &sa, NULL); > signal(SIGPIPE, SIG_IGN); > > c.mode = MODE_PASTA; > log_name = "pasta"; > - } else if (strstr(argv[0], "passt")) { > + } else if (strstr(name, "passt")) { > c.mode = MODE_PASST; > log_name = "passt"; > } else { -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson