[compiler-rt] r331310 - [libFuzzer] Report at most one crash per input.

Matt Morehouse via llvm-commits llvm-commits at lists.llvm.org
Tue May 1 14:01:53 PDT 2018


Author: morehouse
Date: Tue May  1 14:01:53 2018
New Revision: 331310

URL: http://llvm.org/viewvc/llvm-project?rev=331310&view=rev
Log:
[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

Added:
    compiler-rt/trunk/test/fuzzer/AcquireCrashStateTest.cpp
    compiler-rt/trunk/test/fuzzer/acquire-crash-state.test
Modified:
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h
    compiler-rt/trunk/lib/asan/asan_report.cc
    compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def
    compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interface.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_internal.h

Modified: compiler-rt/trunk/include/sanitizer/common_interface_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=331310&r1=331309&r2=331310&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Tue May  1 14:01:53 2018
@@ -65,6 +65,11 @@ extern "C" {
   void __sanitizer_unaligned_store32(void *p, uint32_t x);
   void __sanitizer_unaligned_store64(void *p, uint64_t x);
 
+  // Returns 1 on the first call, then returns 0 thereafter.  Called by the tool
+  // to ensure only one report is printed when multiple errors occur
+  // simultaneously.
+  int __sanitizer_acquire_crash_state();
+
   // Annotate the current state of a contiguous container, such as
   // std::vector, std::string or similar.
   // A contiguous container is a container that keeps all of its elements

Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=331310&r1=331309&r2=331310&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Tue May  1 14:01:53 2018
@@ -134,6 +134,10 @@ class ScopedInErrorReport {
   }
 
   ~ScopedInErrorReport() {
+    if (halt_on_error_ && !__sanitizer_acquire_crash_state()) {
+      asanThreadRegistry().Unlock();
+      return;
+    }
     ASAN_ON_ERROR();
     if (current_error_.IsValid()) current_error_.Print();
 

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def?rev=331310&r1=331309&r2=331310&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def Tue May  1 14:01:53 2018
@@ -29,6 +29,7 @@ EXT_FUNC(LLVMFuzzerCustomCrossOver, size
 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 *)),

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp?rev=331310&r1=331309&r2=331310&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp Tue May  1 14:01:53 2018
@@ -228,6 +228,9 @@ void Fuzzer::StaticFileSizeExceedCallbac
 }
 
 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);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=331310&r1=331309&r2=331310&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Tue May  1 14:01:53 2018
@@ -14,6 +14,7 @@
 #include "sanitizer_common.h"
 #include "sanitizer_allocator_interface.h"
 #include "sanitizer_allocator_internal.h"
+#include "sanitizer_atomic.h"
 #include "sanitizer_flags.h"
 #include "sanitizer_libc.h"
 #include "sanitizer_placement_new.h"
@@ -344,6 +345,12 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __san
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE
+int __sanitizer_acquire_crash_state() {
+  static atomic_uint8_t in_crash_state = {};
+  return !atomic_exchange(&in_crash_state, 1, memory_order_relaxed);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
 void __sanitizer_set_death_callback(void (*callback)(void)) {
   SetUserDieCallback(callback);
 }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interface.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interface.inc?rev=331310&r1=331309&r2=331310&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interface.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interface.inc Tue May  1 14:01:53 2018
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 // Sanitizer Common interface list.
 //===----------------------------------------------------------------------===//
+INTERFACE_FUNCTION(__sanitizer_acquire_crash_state)
 INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container)
 INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address)
 INTERFACE_FUNCTION(__sanitizer_set_death_callback)

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_internal.h?rev=331310&r1=331309&r2=331310&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_internal.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_internal.h Tue May  1 14:01:53 2018
@@ -52,6 +52,12 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_trace_pc_guard_coverage();
 
   SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(__sanitizer::u32 *guard);
+
+  // Returns 1 on the first call, then returns 0 thereafter.  Called by the tool
+  // to ensure only one report is printed when multiple errors occur
+  // simultaneously.
+  SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_acquire_crash_state();
+
   SANITIZER_INTERFACE_ATTRIBUTE
   void __sanitizer_annotate_contiguous_container(const void *beg,
                                                  const void *end,

Added: compiler-rt/trunk/test/fuzzer/AcquireCrashStateTest.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/AcquireCrashStateTest.cpp?rev=331310&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/AcquireCrashStateTest.cpp (added)
+++ compiler-rt/trunk/test/fuzzer/AcquireCrashStateTest.cpp Tue May  1 14:01:53 2018
@@ -0,0 +1,18 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Ensures that error reports are suppressed after
+// __sanitizer_acquire_crash_state() has been called the first time.
+#include "sanitizer/common_interface_defs.h"
+
+#include <cassert>
+#include <cstdint>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  assert(Data);
+  if (Size == 0) return 0;
+  __sanitizer_acquire_crash_state();
+  exit(0);  // No report should be generated here.
+}
+

Added: compiler-rt/trunk/test/fuzzer/acquire-crash-state.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/acquire-crash-state.test?rev=331310&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/acquire-crash-state.test (added)
+++ compiler-rt/trunk/test/fuzzer/acquire-crash-state.test Tue May  1 14:01:53 2018
@@ -0,0 +1,3 @@
+RUN: %cpp_compiler %S/AcquireCrashStateTest.cpp -o %t
+RUN: %t 2>&1 | FileCheck %s
+CHECK-NOT: fuzz target exited




More information about the llvm-commits mailing list