1 // RUN: %clangxx -std=c++11 %s -o %t 2 // RUN: %env_asan_opts=handle_segv=1 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s 3 // RUN: %env_asan_opts=handle_segv=2 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s 4 5 // RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_HANDLER %s -o %t 6 // RUN: %env_asan_opts=handle_segv=0 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HANDLER 7 // RUN: %env_asan_opts=handle_segv=1 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s 8 // RUN: %env_asan_opts=handle_segv=2 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s 9 10 // RUN: %clangxx -std=c++11 -DTEST_INSTALL_SIG_ACTION %s -o %t 11 // RUN: %env_asan_opts=handle_segv=0 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ACTION 12 // RUN: %env_asan_opts=handle_segv=1 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s 13 // RUN: %env_asan_opts=handle_segv=2 LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s 14 15 // REQUIRES: asan-dynamic-runtime 16 17 // This way of setting LD_PRELOAD does not work with Android test runner. 18 // REQUIRES: !android 19 20 #include <assert.h> 21 #include <signal.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <sys/syscall.h> 26 #include <unistd.h> 27 28 const char *handler = nullptr; 29 void SigHandler(int signum) { handler = "TestSigHandler"; } 30 void SigAction(int, siginfo_t *, void *) { handler = "TestSigAction"; } 31 32 struct KernelSigaction { 33 34 #if defined(__mips__) 35 unsigned long flags; 36 __sighandler_t handler; 37 #else 38 __sighandler_t handler; 39 unsigned long flags; 40 #endif 41 void (*restorer)(); 42 char unused[1024]; 43 }; 44 45 #if defined(__x86_64__) 46 extern "C" void restorer(); 47 asm("restorer:mov $15,%rax\nsyscall"); 48 #endif 49 50 int InternalSigaction(int sig, KernelSigaction *act, KernelSigaction *oact) { 51 if (act) { 52 #if defined(__x86_64__) 53 act->flags |= 0x04000000; 54 act->restorer = &restorer; 55 #endif 56 } 57 return syscall(__NR_rt_sigaction, sig, act, oact, NSIG / 8); 58 } 59 60 struct KernelSigaction pre_asan = {}; 61 62 static void Init() { 63 int res = InternalSigaction(SIGSEGV, nullptr, &pre_asan); 64 assert(res >= 0); 65 assert(pre_asan.handler == SIG_DFL || pre_asan.handler == SIG_IGN); 66 #if defined(TEST_INSTALL_SIG_HANDLER) 67 pre_asan = {}; 68 pre_asan.handler = &SigHandler; 69 res = InternalSigaction(SIGSEGV, &pre_asan, nullptr); 70 assert(res >= 0); 71 #elif defined(TEST_INSTALL_SIG_ACTION) 72 pre_asan = {}; 73 pre_asan.flags = SA_SIGINFO | SA_NODEFER; 74 pre_asan.handler = (__sighandler_t)&SigAction; 75 res = InternalSigaction(SIGSEGV, &pre_asan, nullptr); 76 assert(res >= 0); 77 #endif 78 } 79 80 __attribute__((section(".preinit_array"), used)) 81 void (*__local_test_preinit)(void) = Init; 82 83 bool ExpectUserHandler() { 84 #if defined(TEST_INSTALL_SIG_HANDLER) || defined(TEST_INSTALL_SIG_ACTION) 85 return !strcmp(getenv("ASAN_OPTIONS"), "handle_segv=0"); 86 #endif 87 return false; 88 } 89 90 int main(int argc, char *argv[]) { 91 KernelSigaction post_asan = {}; 92 InternalSigaction(SIGSEGV, nullptr, &post_asan); 93 94 assert(post_asan.handler != SIG_DFL); 95 assert(post_asan.handler != SIG_IGN); 96 assert(ExpectUserHandler() == 97 (post_asan.handler == pre_asan.handler)); 98 99 raise(SIGSEGV); 100 printf("%s\n", handler); 101 return 1; 102 } 103 104 // CHECK-NOT: TestSig 105 // CHECK: AddressSanitizer:DEADLYSIGNAL 106 107 // CHECK-HANDLER-NOT: AddressSanitizer:DEADLYSIGNAL 108 // CHECK-HANDLER: TestSigHandler 109 110 // CHECK-ACTION-NOT: AddressSanitizer:DEADLYSIGNAL 111 // CHECK-ACTION: TestSigAction 112