[compiler-rt] r317829 - [libFuzzer] handle SIGUSR1/SIGUSR2 and try to exit grafully on these signals

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 9 12:30:19 PST 2017


Author: kcc
Date: Thu Nov  9 12:30:19 2017
New Revision: 317829

URL: http://llvm.org/viewvc/llvm-project?rev=317829&view=rev
Log:
[libFuzzer] handle SIGUSR1/SIGUSR2 and try to exit grafully on these signals

Added:
    compiler-rt/trunk/test/fuzzer/SleepOneSecondTest.cpp
    compiler-rt/trunk/test/fuzzer/sigusr.test
Modified:
    compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
    compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h
    compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerMerge.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h
    compiler-rt/trunk/lib/fuzzer/FuzzerUtilPosix.cpp

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp?rev=317829&r1=317828&r2=317829&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp Thu Nov  9 12:30:19 2017
@@ -639,6 +639,8 @@ int FuzzerDriver(int *argc, char ***argv
   Options.HandleSegv = Flags.handle_segv;
   Options.HandleTerm = Flags.handle_term;
   Options.HandleXfsz = Flags.handle_xfsz;
+  Options.HandleUsr1 = Flags.handle_usr1;
+  Options.HandleUsr2 = Flags.handle_usr2;
   SetSignalHandler(Options);
 
   std::atexit(Fuzzer::StaticExitCallback);

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def?rev=317829&r1=317828&r2=317829&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def Thu Nov  9 12:30:19 2017
@@ -114,6 +114,8 @@ FUZZER_FLAG_INT(handle_fpe, 1, "If 1, tr
 FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.")
 FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.")
 FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
+FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
+FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")
 FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; "
     "if 2, close stderr; if 3, close both. "
     "Be careful, this will also close e.g. asan's stderr/stdout.")

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h?rev=317829&r1=317828&r2=317829&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h Thu Nov  9 12:30:19 2017
@@ -63,6 +63,7 @@ public:
   static void StaticExitCallback();
   static void StaticInterruptCallback();
   static void StaticFileSizeExceedCallback();
+  static void StaticGracefulExitCallback();
 
   void ExecuteCallback(const uint8_t *Data, size_t Size);
   bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
@@ -94,6 +95,7 @@ private:
   void AlarmCallback();
   void CrashCallback();
   void ExitCallback();
+  void MaybeExitGracefully();
   void CrashOnOverwrittenData();
   void InterruptCallback();
   void MutateAndTestOne();
@@ -116,6 +118,8 @@ private:
   uint8_t BaseSha1[kSHA1NumBytes];  // Checksum of the base unit.
   bool RunningCB = false;
 
+  bool GracefulExitRequested = false;
+
   size_t TotalNumberOfRuns = 0;
   size_t NumberOfNewUnitsAdded = 0;
 

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp?rev=317829&r1=317828&r2=317829&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp Thu Nov  9 12:30:19 2017
@@ -216,6 +216,12 @@ void Fuzzer::StaticInterruptCallback() {
   F->InterruptCallback();
 }
 
+void Fuzzer::StaticGracefulExitCallback() {
+  assert(F);
+  F->GracefulExitRequested = true;
+  Printf("INFO: signal received, trying to exit gracefully\n");
+}
+
 void Fuzzer::StaticFileSizeExceedCallback() {
   Printf("==%lu== ERROR: libFuzzer: file size exceeded\n", GetPid());
   exit(1);
@@ -246,6 +252,13 @@ void Fuzzer::ExitCallback() {
   _Exit(Options.ErrorExitCode);
 }
 
+void Fuzzer::MaybeExitGracefully() {
+  if (!GracefulExitRequested) return;
+  Printf("==%lu== INFO: libFuzzer: exiting as requested\n", GetPid());
+  PrintFinalStats();
+  _Exit(0);
+}
+
 void Fuzzer::InterruptCallback() {
   Printf("==%lu== libFuzzer: run interrupted; exiting\n", GetPid());
   PrintFinalStats();
@@ -621,6 +634,7 @@ void Fuzzer::MutateAndTestOne() {
   for (int i = 0; i < Options.MutateDepth; i++) {
     if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
       break;
+    MaybeExitGracefully();
     size_t NewSize = 0;
     NewSize = MD.Mutate(CurrentUnitData, Size, CurrentMaxMutationLen);
     assert(NewSize > 0 && "Mutator returned empty unit");

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerMerge.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerMerge.cpp?rev=317829&r1=317828&r2=317829&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerMerge.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerMerge.cpp Thu Nov  9 12:30:19 2017
@@ -223,6 +223,7 @@ void Fuzzer::CrashResistantMergeInternal
   std::ofstream OF(CFPath, std::ofstream::out | std::ofstream::app);
   Set<size_t> AllFeatures;
   for (size_t i = M.FirstNotProcessedFile; i < M.Files.size(); i++) {
+    MaybeExitGracefully();
     auto U = FileToVector(M.Files[i].Name);
     if (U.size() > MaxInputLen) {
       U.resize(MaxInputLen);
@@ -334,6 +335,7 @@ void Fuzzer::CrashResistantMerge(const V
                              CloneArgsWithoutX(Args, "merge"));
   bool Success = false;
   for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) {
+    MaybeExitGracefully();
     Printf("MERGE-OUTER: attempt %zd\n", Attempt);
     auto ExitCode =
         ExecuteCommand(BaseCmd.first + " -merge_control_file=" + CFPath +

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h?rev=317829&r1=317828&r2=317829&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h Thu Nov  9 12:30:19 2017
@@ -65,6 +65,8 @@ struct FuzzingOptions {
   bool HandleSegv = false;
   bool HandleTerm = false;
   bool HandleXfsz = false;
+  bool HandleUsr1 = false;
+  bool HandleUsr2 = false;
 };
 
 }  // namespace fuzzer

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerUtilPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerUtilPosix.cpp?rev=317829&r1=317828&r2=317829&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerUtilPosix.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerUtilPosix.cpp Thu Nov  9 12:30:19 2017
@@ -40,6 +40,10 @@ static void InterruptHandler(int, siginf
   Fuzzer::StaticInterruptCallback();
 }
 
+static void GracefulExitHandler(int, siginfo_t *, void *) {
+  Fuzzer::StaticGracefulExitCallback();
+}
+
 static void FileSizeExceedHandler(int, siginfo_t *, void *) {
   Fuzzer::StaticFileSizeExceedCallback();
 }
@@ -98,6 +102,10 @@ void SetSignalHandler(const FuzzingOptio
     SetSigaction(SIGFPE, CrashHandler);
   if (Options.HandleXfsz)
     SetSigaction(SIGXFSZ, FileSizeExceedHandler);
+  if (Options.HandleUsr1)
+    SetSigaction(SIGUSR1, GracefulExitHandler);
+  if (Options.HandleUsr2)
+    SetSigaction(SIGUSR2, GracefulExitHandler);
 }
 
 void SleepSeconds(int Seconds) {

Added: compiler-rt/trunk/test/fuzzer/SleepOneSecondTest.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/SleepOneSecondTest.cpp?rev=317829&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/SleepOneSecondTest.cpp (added)
+++ compiler-rt/trunk/test/fuzzer/SleepOneSecondTest.cpp Thu Nov  9 12:30:19 2017
@@ -0,0 +1,13 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer: it simply sleeps for 1 second.
+#include <cstddef>
+#include <cstdint>
+#include <thread>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  std::this_thread::sleep_for(std::chrono::seconds(1));
+  return 0;
+}
+

Added: compiler-rt/trunk/test/fuzzer/sigusr.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/sigusr.test?rev=317829&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/sigusr.test (added)
+++ compiler-rt/trunk/test/fuzzer/sigusr.test Thu Nov  9 12:30:19 2017
@@ -0,0 +1,29 @@
+# Check that libFuzzer honors SIGUSR1/SIGUSR2
+RUN: rm -rf %t
+RUN: mkdir -p %t
+RUN: %cpp_compiler %S/SleepOneSecondTest.cpp -o %t/LFSIGUSR
+
+RUN: %t/LFSIGUSR 2> %t/log & export PID=$!
+RUN: sleep 2
+RUN: kill -SIGUSR1 $PID
+RUN: cat %t/log | FileCheck %s
+
+RUN: mkdir -p %t/C1 %t/C2
+RUN: echo a > %t/C2/a
+RUN: echo b > %t/C2/b
+RUN: echo c > %t/C2/c
+RUN: echo d > %t/C2/d
+RUN: echo e > %t/C2/e
+RUN: echo f > %t/C2/f
+RUN: echo g > %t/C2/g
+
+RUN: %t/LFSIGUSR -merge=1 -merge_control_file=%t/MCF %t/C1 %t/C2  2>  %t/log & export PID=$!
+RUN: sleep 3
+RUN: killall -SIGUSR2 %t/LFSIGUSR
+RUN: cat %t/log | FileCheck %s
+RUN: grep C2/g %t/MCF
+RUN: grep STARTED %t/MCF
+RUN: grep DONE %t/MCF
+
+CHECK: INFO: signal received, trying to exit gracefully
+CHECK: INFO: libFuzzer: exiting as requested




More information about the llvm-commits mailing list