Files
clang-p2996/compiler-rt/test/asan/TestCases/Linux/preinstalled_signal.cpp
Hubert Tong 403d5a5e35 [test][compiler-rt] Avoid LD_PRELOAD for "outer" dynamic linkers
Summary:
This patch moves the setting of `LD_PRELOAD` "inwards" to avoid issues
where the built library needs to be loaded with the dynamic linker that
was configured with the build (and cannot, for example, be loaded by the
dynamic linker associated with the `env` utility).

Reviewed By: vitalybuka, nemanjai, jsji

Differential Revision: https://reviews.llvm.org/D79695
2020-05-31 16:33:42 -04:00

112 lines
3.4 KiB
C++

// RUN: %clangxx -std=c++11 %s -o %t
// RUN: %env_asan_opts=handle_segv=1 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=handle_segv=2 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_HANDLER %s -o %t
// RUN: %env_asan_opts=handle_segv=0 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HANDLER
// RUN: %env_asan_opts=handle_segv=1 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=handle_segv=2 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_ACTION %s -o %t
// RUN: %env_asan_opts=handle_segv=0 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ACTION
// RUN: %env_asan_opts=handle_segv=1 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=handle_segv=2 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s
// REQUIRES: asan-dynamic-runtime
// This way of setting LD_PRELOAD does not work with Android test runner.
// REQUIRES: !android
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
const char *handler = nullptr;
void SigHandler(int signum) { handler = "TestSigHandler"; }
void SigAction(int, siginfo_t *, void *) { handler = "TestSigAction"; }
struct KernelSigaction {
#if defined(__mips__)
unsigned long flags;
__sighandler_t handler;
#else
__sighandler_t handler;
unsigned long flags;
#endif
void (*restorer)();
char unused[1024];
};
#if defined(__x86_64__)
extern "C" void restorer();
asm("restorer:mov $15,%rax\nsyscall");
#endif
int InternalSigaction(int sig, KernelSigaction *act, KernelSigaction *oact) {
if (act) {
#if defined(__x86_64__)
act->flags |= 0x04000000;
act->restorer = &restorer;
#endif
}
return syscall(__NR_rt_sigaction, sig, act, oact, NSIG / 8);
}
struct KernelSigaction pre_asan = {};
static void Init() {
int res = InternalSigaction(SIGSEGV, nullptr, &pre_asan);
assert(res >= 0);
assert(pre_asan.handler == SIG_DFL || pre_asan.handler == SIG_IGN);
#if defined(TEST_INSTALL_SIG_HANDLER)
pre_asan = {};
pre_asan.handler = &SigHandler;
res = InternalSigaction(SIGSEGV, &pre_asan, nullptr);
assert(res >= 0);
#elif defined(TEST_INSTALL_SIG_ACTION)
pre_asan = {};
pre_asan.flags = SA_SIGINFO | SA_NODEFER;
pre_asan.handler = (__sighandler_t)&SigAction;
res = InternalSigaction(SIGSEGV, &pre_asan, nullptr);
assert(res >= 0);
#endif
}
__attribute__((section(".preinit_array"), used))
void (*__local_test_preinit)(void) = Init;
bool ExpectUserHandler() {
#if defined(TEST_INSTALL_SIG_HANDLER) || defined(TEST_INSTALL_SIG_ACTION)
return !strcmp(getenv("ASAN_OPTIONS"), "handle_segv=0");
#endif
return false;
}
int main(int argc, char *argv[]) {
KernelSigaction post_asan = {};
InternalSigaction(SIGSEGV, nullptr, &post_asan);
assert(post_asan.handler != SIG_DFL);
assert(post_asan.handler != SIG_IGN);
assert(ExpectUserHandler() ==
(post_asan.handler == pre_asan.handler));
raise(SIGSEGV);
printf("%s\n", handler);
return 1;
}
// CHECK-NOT: TestSig
// CHECK: AddressSanitizer:DEADLYSIGNAL
// CHECK-HANDLER-NOT: AddressSanitizer:DEADLYSIGNAL
// CHECK-HANDLER: TestSigHandler
// CHECK-ACTION-NOT: AddressSanitizer:DEADLYSIGNAL
// CHECK-ACTION: TestSigAction