]> granicus.if.org Git - llvm/commitdiff
[libFuzzer] improve error handling during the merge (handle various IO failures)
authorKostya Serebryany <kcc@google.com>
Thu, 5 Jan 2017 22:05:47 +0000 (22:05 +0000)
committerKostya Serebryany <kcc@google.com>
Thu, 5 Jan 2017 22:05:47 +0000 (22:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291182 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerDriver.cpp
lib/Fuzzer/FuzzerFlags.def
lib/Fuzzer/FuzzerInternal.h
lib/Fuzzer/FuzzerLoop.cpp
lib/Fuzzer/FuzzerMerge.cpp
lib/Fuzzer/FuzzerOptions.h
lib/Fuzzer/FuzzerUtilPosix.cpp
lib/Fuzzer/FuzzerUtilWindows.cpp
lib/Fuzzer/test/merge.test

index e6c9764f1133294c807a70ede20ab10f45410dbb..2bbcb25275e4920b633b130ceb940f7affe0544a 100644 (file)
@@ -468,6 +468,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
   Options.HandleInt = Flags.handle_int;
   Options.HandleSegv = Flags.handle_segv;
   Options.HandleTerm = Flags.handle_term;
+  Options.HandleXfsz = Flags.handle_xfsz;
   SetSignalHandler(Options);
 
   if (Flags.minimize_crash_internal_step)
index 08eaad9856bea9f77dc12024fc9558e378d7a930..22aad353acec70af9b957f3b86ac18b3ef1e351a 100644 (file)
@@ -91,6 +91,7 @@ FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.")
 FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.")
 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(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.")
index c041706092db7772c96e5314f3e7250585041fec..0d2c7a78aca81def0c0c29142dde0bd869847e1e 100644 (file)
@@ -82,6 +82,7 @@ public:
   static void StaticAlarmCallback();
   static void StaticCrashSignalCallback();
   static void StaticInterruptCallback();
+  static void StaticFileSizeExceedCallback();
 
   void ExecuteCallback(const uint8_t *Data, size_t Size);
   size_t RunOne(const uint8_t *Data, size_t Size);
index 1336f5e4aeeb9f3962d11d475dcfbacc821bec13..9f49d1557990476188ea89ef641328066820d358 100644 (file)
@@ -266,6 +266,11 @@ void Fuzzer::StaticInterruptCallback() {
   F->InterruptCallback();
 }
 
+void Fuzzer::StaticFileSizeExceedCallback() {
+  Printf("==%lu== ERROR: libFuzzer: file size exceeded\n", GetPid());
+  exit(1);
+}
+
 void Fuzzer::CrashCallback() {
   Printf("==%lu== ERROR: libFuzzer: deadly signal\n", GetPid());
   if (EF->__sanitizer_print_stack_trace)
index b3d46435fcd62e662dddddf54b818df9754de6da..9e559115680ccef8de856beaf046788f464a8fa3 100644 (file)
@@ -229,6 +229,11 @@ void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args,
   ControlFile << NumFilesInFirstCorpus << "\n";
   for (auto &Path: AllFiles)
     ControlFile << Path << "\n";
+  if (!ControlFile) {
+    Printf("MERGE-OUTER: failed to write to the control file: %s\n",
+           CFPath.c_str());
+    exit(1);
+  }
   ControlFile.close();
 
   // Execute the inner process untill it passes.
@@ -246,6 +251,9 @@ void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args,
   // Read the control file and do the merge.
   Merger M;
   std::ifstream IF(CFPath);
+  IF.seekg(0, IF.end);
+  Printf("MERGE-OUTER: the control file has %zd bytes\n", (size_t)IF.tellg());
+  IF.seekg(0, IF.beg);
   M.ParseOrExit(IF, true);
   IF.close();
   std::vector<std::string> NewFiles;
index cb702d28520088d7e2444c20cf964d2c5020fc31..6f72205600b92a1305dc016127a618a547594a36 100644 (file)
@@ -62,6 +62,7 @@ struct FuzzingOptions {
   bool HandleInt = false;
   bool HandleSegv = false;
   bool HandleTerm = false;
+  bool HandleXfsz = false;
 };
 
 }  // namespace fuzzer
index 8b484b8effa405ab800daa3bb15249c4ac0be345..e8d48dc81a3b87cd09bda334785371d7e4a8d784 100644 (file)
@@ -41,6 +41,10 @@ static void InterruptHandler(int, siginfo_t *, void *) {
   Fuzzer::StaticInterruptCallback();
 }
 
+static void FileSizeExceedHandler(int, siginfo_t *, void *) {
+  Fuzzer::StaticFileSizeExceedCallback();
+}
+
 static void SetSigaction(int signum,
                          void (*callback)(int, siginfo_t *, void *)) {
   struct sigaction sigact;
@@ -80,6 +84,8 @@ void SetSignalHandler(const FuzzingOptions& Options) {
     SetSigaction(SIGILL, CrashHandler);
   if (Options.HandleFpe)
     SetSigaction(SIGFPE, CrashHandler);
+  if (Options.HandleXfsz)
+    SetSigaction(SIGXFSZ, FileSizeExceedHandler);
 }
 
 void SleepSeconds(int Seconds) {
index 64adb7cd1380887ef9ebbcb9ea2baee2323675ad..3ca1f2c8f562dead764a9f06798c0776135f791b 100644 (file)
@@ -58,6 +58,7 @@ LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) {
       if (HandlerOpt->HandleFpe)
         Fuzzer::StaticCrashSignalCallback();
       break;
+    // TODO: handle (Options.HandleXfsz)
   }
   return EXCEPTION_CONTINUE_SEARCH;
 }
index 1f1810eb019536b4123d1a5813cc8a95d98486e4..5c7d30e41caa8db309b9d04c302c4f99576c4a60 100644 (file)
@@ -44,3 +44,11 @@ MERGE_WITH_CRASH: MERGE-OUTER: 3 new files
 # Check that we actually limit the size with max_len
 RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2  -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5
 MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s)
+
+# Check that we honor TMPDIR
+RUN: TMPDIR=DIR_DOES_NOT_EXIST not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR
+TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp
+
+# Check that we can report an error if file size exceeded
+RUN: (ulimit -f 1; not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ)
+SIGXFSZ: ERROR: libFuzzer: file size exceeded