steleman / address-sanitizer

Automatically exported from code.google.com/p/address-sanitizer
0 stars 0 forks source link

Add ability to forward SEGVs to ASAN handler #302

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,

I have a program that intercepts some SEGV and, as such, is incompatible with 
handle_segv=1 from ASan. However, when my handler detects a SEGV it does not 
handle, it would be nice to be able to forward the signal to ASAN's SEGV 
handler in order to get a clean report about the issue.

A quick workaround currently is to always register the handler in ASAN, and 
only take care of the handle_segv=1 in the signal/sigaction overloading:

diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc
index bcc6b38..e60c2dc 100644
--- a/lib/asan/asan_posix.cc
+++ b/lib/asan/asan_posix.cc
@@ -36,8 +36,6 @@ namespace __asan {

 static void MaybeInstallSigaction(int signum,
                                   void (*handler)(int, siginfo_t *, void *)) {
-  if (!AsanInterceptsSignal(signum))
-    return;
   struct sigaction sigact;
   REAL(memset)(&sigact, 0, sizeof(sigact));
   sigact.sa_sigaction = handler;

Then, in the application code, we could do:

 my_handler(int, siginfo, void*) {
    do_stuff();
    if (signal_not_handled) {
        forward_action(signo, si, ptr);
    }
 }

 sigaction(SEGV, my_act, prev_act)
 forward_action = prev_act.sa_action;

However, this is a problem since we have to forward all the parameters 
properly. 

Original issue reported on code.google.com by florent....@intersec.com on 29 Apr 2014 at 10:18

GoogleCodeExporter commented 9 years ago
Hm.. Why would you need asan's SEGV handler if you have your own?
asan does not provide much useful information on SEGV, just a stack trace.
Maye it would be enough for you to simply call __sanitizer_print_stack_trace
in your handler? 

Original comment by konstant...@gmail.com on 29 Apr 2014 at 10:27

GoogleCodeExporter commented 9 years ago
As far as I know, this has already been fixed by adding the 
"allow_user_segv_handler" flag. With that flag set, you can add your own signal 
handler and chain up to the original (ASan) signal handler if yours doesn't 
want to handle the crash. We're using that in Firefox.

Original comment by decoder...@googlemail.com on 29 Apr 2014 at 10:36

GoogleCodeExporter commented 9 years ago
Well, both of you are right. That said, calling __sanitizer_print_stack_trace() 
does not feel very "future-proof"... ASan SEGV handler may get richer features 
in the future.

And allow_user_segv_handler fix my "workaround" case (well, make it 
asan-hacking free at least). However, I still would like something more 
"packaged". Having some built-in chaining facility in asan would help making 
the code both simpler and safer.

Original comment by florent....@intersec.com on 29 Apr 2014 at 11:24

GoogleCodeExporter commented 9 years ago
I don't fully understand why putting this into ASan would make it 
simpler/safer. The way this flag works is the standard way for all C signal 
handling, plus it works in the presence of even more signal handlers for the 
same signal (e.g. your signal handler, third party signal handler and ASan 
signal handler).

And I'm not sure if you're aware of that, but you can make 
allow_user_segv_handler=1 the default for your program, by directly compiling 
the default options into your program (no ASan modification required, no ASan 
flags required at runtime).

Original comment by decoder...@googlemail.com on 29 Apr 2014 at 12:00

GoogleCodeExporter commented 9 years ago
I was not aware of this. This clearly solve my issue. Thanks!

Original comment by florent....@intersec.com on 29 Apr 2014 at 1:16

GoogleCodeExporter commented 9 years ago
Glad I could help :)

For an example, see also https://bugzilla.mozilla.org/show_bug.cgi?id=857189

In particular the last hunk of the patch:

+# ifdef MOZ_ASAN
+// When running with asm.js under AddressSanitizer, we need to explicitely
+// tell AddressSanitizer to allow custom signal handlers because it will 
+// otherwise trigger ASan's SIGSEGV handler for the internal SIGSEGVs that 
+// asm.js would otherwise handle.
+extern "C" MOZ_ASAN_BLACKLIST
+const char* __asan_default_options() {
+    return "allow_user_segv_handler=1";
+}
+# endif

Original comment by decoder...@googlemail.com on 29 Apr 2014 at 1:52

GoogleCodeExporter commented 9 years ago
Closing, right? 

Original comment by konstant...@gmail.com on 7 May 2014 at 8:42

GoogleCodeExporter commented 9 years ago

Original comment by konstant...@gmail.com on 14 May 2014 at 1:34