diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2018-11-06 08:53:38 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2018-11-06 08:53:38 +0000 |
commit | 178d26fa18d3132d1b7d48bd2e64aaec2ee5966e (patch) | |
tree | ec7a43858f7c5edcb1a3237359cdb65314b21b06 | |
parent | 25f8d204b828c534dabd90700e4efa6764508094 (diff) | |
download | llvm-178d26fa18d3132d1b7d48bd2e64aaec2ee5966e.zip llvm-178d26fa18d3132d1b7d48bd2e64aaec2ee5966e.tar.gz llvm-178d26fa18d3132d1b7d48bd2e64aaec2ee5966e.tar.bz2 |
[sanitizer] Use AT_EXECFN in ReExec() if available
execve("/proc/self/exe") will not work if the binary relies on
$EXEC_ORIGIN in an rpath. Query AT_EXECFN instead, which will give the
same string that the current binary was exec'd with.
Differential Revision: https://reviews.llvm.org/D54113
llvm-svn: 346215
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_linux.cc | 4 | ||||
-rw-r--r-- | compiler-rt/test/msan/Linux/reexec_unlimited_stack.cc | 23 |
2 files changed, 27 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc index d6ffc70..1a3cbf8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -640,6 +640,10 @@ void ReExec() { #elif SANITIZER_SOLARIS pathname = getexecname(); CHECK_NE(pathname, NULL); +#elif SANITIZER_USE_GETAUXVAL + // Calling execve with /proc/self/exe sets that as $EXEC_ORIGIN. Binaries that + // rely on that will fail to load shared libraries. Query AT_EXECFN instead. + pathname = reinterpret_cast<const char *>(getauxval(AT_EXECFN)); #endif GetArgsAndEnv(&argv, &envp); diff --git a/compiler-rt/test/msan/Linux/reexec_unlimited_stack.cc b/compiler-rt/test/msan/Linux/reexec_unlimited_stack.cc new file mode 100644 index 0000000..61492ec --- /dev/null +++ b/compiler-rt/test/msan/Linux/reexec_unlimited_stack.cc @@ -0,0 +1,23 @@ +// MSAN re-execs on unlimited stacks. We use that to verify ReExec() uses the +// right path. +// RUN: %clangxx_msan -O0 %s -o %t && ulimit -s unlimited && %run %t | FileCheck %s + +#include <stdio.h> + +#if !defined(__GLIBC_PREREQ) +#define __GLIBC_PREREQ(a, b) 0 +#endif + +#if __GLIBC_PREREQ(2, 16) +#include <sys/auxv.h> +#endif + +int main() { +#if __GLIBC_PREREQ(2, 16) + // Make sure AT_EXECFN didn't get overwritten by re-exec. + puts(reinterpret_cast<const char *>(getauxval(AT_EXECFN))); +#else + puts("No getauxval"); +#endif + // CHECK-NOT: /proc/self/exe +} |