[compiler-rt] r180255 - [ASan] Add allow_user_segv_handler to let users override SEGV handler installed by ASan

Alexey Samsonov samsonov at google.com
Thu Apr 25 03:52:15 PDT 2013


Author: samsonov
Date: Thu Apr 25 05:52:15 2013
New Revision: 180255

URL: http://llvm.org/viewvc/llvm-project?rev=180255&view=rev
Log:
[ASan] Add allow_user_segv_handler to let users override SEGV handler installed by ASan

Added:
    compiler-rt/trunk/lib/asan/lit_tests/allow_user_segv.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_flags.h
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc

Modified: compiler-rt/trunk/lib/asan/asan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=180255&r1=180254&r2=180255&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Thu Apr 25 05:52:15 2013
@@ -71,6 +71,8 @@ struct Flags {
   int  sleep_before_dying;
   // If set, registers ASan custom segv handler.
   bool handle_segv;
+  // If set, allows user register segv handler even if ASan registers one.
+  bool allow_user_segv_handler;
   // If set, uses alternate stack for signal handling.
   bool use_sigaltstack;
   // Allow the users to work around the bug in Nvidia drivers prior to 295.*.

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=180255&r1=180254&r2=180255&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Thu Apr 25 05:52:15 2013
@@ -154,7 +154,7 @@ INTERCEPTOR(int, pthread_create, void *t
 
 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
 INTERCEPTOR(void*, signal, int signum, void *handler) {
-  if (!AsanInterceptsSignal(signum)) {
+  if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) {
     return REAL(signal)(signum, handler);
   }
   return 0;
@@ -162,7 +162,7 @@ INTERCEPTOR(void*, signal, int signum, v
 
 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
                             struct sigaction *oldact) {
-  if (!AsanInterceptsSignal(signum)) {
+  if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) {
     return REAL(sigaction)(signum, act, oldact);
   }
   return 0;

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=180255&r1=180254&r2=180255&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Thu Apr 25 05:52:15 2013
@@ -107,6 +107,7 @@ static void ParseFlagsFromString(Flags *
   ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning");
   ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying");
   ParseFlag(str, &f->handle_segv, "handle_segv");
+  ParseFlag(str, &f->allow_user_segv_handler, "allow_user_segv_handler");
   ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack");
   ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size");
   ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit");
@@ -151,6 +152,7 @@ void InitializeFlags(Flags *f, const cha
   f->allow_user_poisoning = true;
   f->sleep_before_dying = 0;
   f->handle_segv = ASAN_NEEDS_SEGV;
+  f->allow_user_segv_handler = false;
   f->use_sigaltstack = false;
   f->check_malloc_usable_size = true;
   f->unmap_shadow_on_exit = false;

Added: compiler-rt/trunk/lib/asan/lit_tests/allow_user_segv.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/allow_user_segv.cc?rev=180255&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/allow_user_segv.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/allow_user_segv.cc Thu Apr 25 05:52:15 2013
@@ -0,0 +1,42 @@
+// Regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=180
+
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m64 -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m32 -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -m32 -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s
+
+#include <signal.h>
+#include <stdio.h>
+
+struct sigaction user_sigaction;
+struct sigaction original_sigaction;
+
+void User_OnSIGSEGV(int signum, siginfo_t *siginfo, void *context) {
+  fprintf(stderr, "User sigaction called\n");
+  if (original_sigaction.sa_flags | SA_SIGINFO)
+    original_sigaction.sa_sigaction(signum, siginfo, context);
+  else
+    original_sigaction.sa_handler(signum);
+}
+
+int DoSEGV() {
+  volatile int *x = 0;
+  return *x;
+}
+
+int main() {
+  user_sigaction.sa_sigaction = User_OnSIGSEGV;
+  user_sigaction.sa_flags = SA_SIGINFO;
+  if (sigaction(SIGSEGV, &user_sigaction, &original_sigaction)) {
+    perror("sigaction");
+    return 1;
+  }
+  fprintf(stderr, "User sigaction installed\n");
+  return DoSEGV();
+}
+
+// CHECK: User sigaction installed
+// CHECK-NEXT: User sigaction called
+// CHECK-NEXT: ASAN:SIGSEGV
+// CHECK: AddressSanitizer: SEGV on unknown address





More information about the llvm-commits mailing list