diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-07-13 03:20:45 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-07-14 01:36:05 +0200 |
commit | 17689cc9bf52feb5d31fdbf279f6137f1d6446cb (patch) | |
tree | d25dde3bae0ea05538286e03ea1be88af4096e13 /arch.c | |
parent | 30ac86823ba0f4b80e83a6bd8ccc562f0d79b9c9 (diff) | |
download | passt-17689cc9bf52feb5d31fdbf279f6137f1d6446cb.tar passt-17689cc9bf52feb5d31fdbf279f6137f1d6446cb.tar.gz passt-17689cc9bf52feb5d31fdbf279f6137f1d6446cb.tar.bz2 passt-17689cc9bf52feb5d31fdbf279f6137f1d6446cb.tar.lz passt-17689cc9bf52feb5d31fdbf279f6137f1d6446cb.tar.xz passt-17689cc9bf52feb5d31fdbf279f6137f1d6446cb.tar.zst passt-17689cc9bf52feb5d31fdbf279f6137f1d6446cb.zip |
arch, passt: Use executable link to form AVX2 binary path
...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.
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 <wquan@redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2101310
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'arch.c')
-rw-r--r-- | arch.c | 25 |
1 files changed, 15 insertions, 10 deletions
@@ -14,26 +14,31 @@ #include <limits.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> /** - * 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] = { 0 }, new_path[PATH_MAX + sizeof(".avx2")], *p; + + if (readlink("/proc/self/exe", exe, PATH_MAX - 1) < 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"); } } |