diff options
author | Matt Morehouse <mascasa@google.com> | 2018-05-01 21:01:53 +0000 |
---|---|---|
committer | Matt Morehouse <mascasa@google.com> | 2018-05-01 21:01:53 +0000 |
commit | 42ed860e35e7d30dc37b5dd548eeb7b1cb5dd902 (patch) | |
tree | ccb5e69be4a71d5f0cc03def1d2487009b4f0129 /lib/fuzzer | |
parent | dcd249132f2d06fb3209b0f965ad1b09ef61feb0 (diff) |
[libFuzzer] Report at most one crash per input.
Summary:
Fixes https://github.com/google/sanitizers/issues/788/, a deadlock
caused by multiple crashes happening at the same time. Before printing
a crash report, we now test and set an atomic flag. If the flag was
already set, the crash handler returns immediately.
Reviewers: kcc
Reviewed By: kcc
Subscribers: llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D46277
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@331310 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/fuzzer')
-rw-r--r-- | lib/fuzzer/FuzzerExtFunctions.def | 1 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerLoop.cpp | 12 |
2 files changed, 13 insertions, 0 deletions
diff --git a/lib/fuzzer/FuzzerExtFunctions.def b/lib/fuzzer/FuzzerExtFunctions.def index 25a655bfd..70f4b27fd 100644 --- a/lib/fuzzer/FuzzerExtFunctions.def +++ b/lib/fuzzer/FuzzerExtFunctions.def @@ -29,6 +29,7 @@ EXT_FUNC(LLVMFuzzerCustomCrossOver, size_t, EXT_FUNC(__lsan_enable, void, (), false); EXT_FUNC(__lsan_disable, void, (), false); EXT_FUNC(__lsan_do_recoverable_leak_check, int, (), false); +EXT_FUNC(__sanitizer_acquire_crash_state, bool, (), true); EXT_FUNC(__sanitizer_install_malloc_and_free_hooks, int, (void (*malloc_hook)(const volatile void *, size_t), void (*free_hook)(const volatile void *)), diff --git a/lib/fuzzer/FuzzerLoop.cpp b/lib/fuzzer/FuzzerLoop.cpp index cd835bea5..7a26370b3 100644 --- a/lib/fuzzer/FuzzerLoop.cpp +++ b/lib/fuzzer/FuzzerLoop.cpp @@ -228,6 +228,9 @@ void Fuzzer::StaticFileSizeExceedCallback() { } void Fuzzer::CrashCallback() { + if (EF->__sanitizer_acquire_crash_state && + !EF->__sanitizer_acquire_crash_state()) + return; Printf("==%lu== ERROR: libFuzzer: deadly signal\n", GetPid()); if (EF->__sanitizer_print_stack_trace) EF->__sanitizer_print_stack_trace(); @@ -243,6 +246,9 @@ void Fuzzer::CrashCallback() { void Fuzzer::ExitCallback() { if (!RunningCB) return; // This exit did not come from the user callback + if (EF->__sanitizer_acquire_crash_state && + !EF->__sanitizer_acquire_crash_state()) + return; Printf("==%lu== ERROR: libFuzzer: fuzz target exited\n", GetPid()); if (EF->__sanitizer_print_stack_trace) EF->__sanitizer_print_stack_trace(); @@ -282,6 +288,9 @@ void Fuzzer::AlarmCallback() { if (Options.Verbosity >= 2) Printf("AlarmCallback %zd\n", Seconds); if (Seconds >= (size_t)Options.UnitTimeoutSec) { + if (EF->__sanitizer_acquire_crash_state && + !EF->__sanitizer_acquire_crash_state()) + return; Printf("ALARM: working on the last Unit for %zd seconds\n", Seconds); Printf(" and the timeout value is %d (use -timeout=N to change)\n", Options.UnitTimeoutSec); @@ -297,6 +306,9 @@ void Fuzzer::AlarmCallback() { } void Fuzzer::RssLimitCallback() { + if (EF->__sanitizer_acquire_crash_state && + !EF->__sanitizer_acquire_crash_state()) + return; Printf( "==%lu== ERROR: libFuzzer: out-of-memory (used: %zdMb; limit: %zdMb)\n", GetPid(), GetPeakRSSMb(), Options.RssLimitMb); |