[compiler-rt] r359610 - [libFuzzer] Replace -seed_corpus to better support fork mode on Win

Jonathan Metzman via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 30 13:56:19 PDT 2019


Author: metzman
Date: Tue Apr 30 13:56:18 2019
New Revision: 359610

URL: http://llvm.org/viewvc/llvm-project?rev=359610&view=rev
Log:
[libFuzzer] Replace -seed_corpus to better support fork mode on Win

Summary:
Pass seed corpus list in a file to get around argument length limits on Windows.
This limit was preventing many uses of fork mode on Windows.

Reviewers: kcc, morehouse

Reviewed By: kcc

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D60980

Added:
    compiler-rt/trunk/test/fuzzer/seed_inputs.test
Modified:
    compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
    compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerIO.h

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp?rev=359610&r1=359609&r2=359610&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp Tue Apr 30 13:56:18 2019
@@ -763,16 +763,25 @@ int FuzzerDriver(int *argc, char ***argv
     exit(0);
   }
 
-  // Parse -seed_inputs=file1,file2,...
+  // Parse -seed_inputs=file1,file2,... or -seed_inputs=@seed_inputs_file
   Vector<std::string> ExtraSeedFiles;
   if (Flags.seed_inputs) {
-    std::string s = Flags.seed_inputs;
-    size_t comma_pos;
-    while ((comma_pos = s.find_last_of(',')) != std::string::npos) {
-      ExtraSeedFiles.push_back(s.substr(comma_pos + 1));
-      s = s.substr(0, comma_pos);
+    std::string SeedInputs;
+    if (Flags.seed_inputs[0] == '@')
+      SeedInputs = FileToString(Flags.seed_inputs + 1); // File contains list.
+    else
+      SeedInputs = Flags.seed_inputs; // seed_inputs contains the list.
+    if (SeedInputs.empty()) {
+      Printf("seed_inputs is empty or @file does not exist.\n");
+      exit(1);
     }
-    ExtraSeedFiles.push_back(s);
+    // Parse SeedInputs.
+    size_t comma_pos = 0;
+    while ((comma_pos = SeedInputs.find_last_of(',')) != std::string::npos) {
+      ExtraSeedFiles.push_back(SeedInputs.substr(comma_pos + 1));
+      SeedInputs = SeedInputs.substr(0, comma_pos);
+    }
+    ExtraSeedFiles.push_back(SeedInputs);
   }
 
   F->Loop(*Inputs, ExtraSeedFiles);

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def?rev=359610&r1=359609&r2=359610&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def Tue Apr 30 13:56:18 2019
@@ -21,7 +21,8 @@ FUZZER_FLAG_INT(len_control, 100, "Try g
   "limit is increased (smaller == faster).  If 0, immediately try inputs with "
   "size up to max_len.")
 FUZZER_FLAG_STRING(seed_inputs, "A comma-separated list of input files "
-  "to use as an additional seed corpus")
+  "to use as an additional seed corpus. Alternatively, an \"@\" followed by "
+  "the name of a file containing the comma-seperated list.")
 FUZZER_FLAG_INT(cross_over, 1, "If 1, cross over inputs.")
 FUZZER_FLAG_INT(mutate_depth, 5,
             "Apply this number of consecutive mutations to each input.")

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp?rev=359610&r1=359609&r2=359610&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp Tue Apr 30 13:56:18 2019
@@ -66,6 +66,7 @@ struct FuzzJob {
   std::string CorpusDir;
   std::string FeaturesDir;
   std::string LogPath;
+  std::string SeedListPath;
   std::string CFPath;
 
   // Fuzzing Outputs.
@@ -74,6 +75,7 @@ struct FuzzJob {
   ~FuzzJob() {
     RemoveFile(CFPath);
     RemoveFile(LogPath);
+    RemoveFile(SeedListPath);
     RmDirRecursive(CorpusDir);
     RmDirRecursive(FeaturesDir);
   }
@@ -121,8 +123,11 @@ struct GlobalEnv {
       for (size_t i = 0; i < CorpusSubsetSize; i++)
         Seeds += (Seeds.empty() ? "" : ",") +
                  Files[Rand->SkewTowardsLast(Files.size())];
-    if (!Seeds.empty())
-      Cmd.addFlag("seed_inputs", Seeds);
+    if (!Seeds.empty()) {
+      Job->SeedListPath = std::to_string(JobId) + ".seeds";
+      WriteToFile(Seeds, Job->SeedListPath);
+      Cmd.addFlag("seed_inputs", "@" + Job->SeedListPath);
+    }
     Job->LogPath = DirPlusFile(TempDir, std::to_string(JobId) + ".log");
     Job->CorpusDir = DirPlusFile(TempDir, "C" + std::to_string(JobId));
     Job->FeaturesDir = DirPlusFile(TempDir, "F" + std::to_string(JobId));

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp?rev=359610&r1=359609&r2=359610&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp Tue Apr 30 13:56:18 2019
@@ -64,6 +64,11 @@ void WriteToFile(const Unit &U, const st
   WriteToFile(U.data(), U.size(), Path);
 }
 
+void WriteToFile(const std::string &Data, const std::string &Path) {
+  WriteToFile(reinterpret_cast<const uint8_t *>(Data.c_str()), Data.size(),
+              Path);
+}
+
 void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
   // Use raw C interface because this function may be called from a sig handler.
   FILE *Out = fopen(Path.c_str(), "wb");

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerIO.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerIO.h?rev=359610&r1=359609&r2=359610&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerIO.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerIO.h Tue Apr 30 13:56:18 2019
@@ -25,6 +25,8 @@ std::string FileToString(const std::stri
 void CopyFileToErr(const std::string &Path);
 
 void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path);
+// Write Data.c_str() to the file without terminating null character.
+void WriteToFile(const std::string &Data, const std::string &Path);
 void WriteToFile(const Unit &U, const std::string &Path);
 
 void ReadDirToVectorOfUnits(const char *Path, Vector<Unit> *V,

Added: compiler-rt/trunk/test/fuzzer/seed_inputs.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/seed_inputs.test?rev=359610&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/seed_inputs.test (added)
+++ compiler-rt/trunk/test/fuzzer/seed_inputs.test Tue Apr 30 13:56:18 2019
@@ -0,0 +1,24 @@
+RUN: %cpp_compiler %S/SimpleTest.cpp -o %t-SimpleTest
+
+USE-1: INFO: seed corpus: files: 1
+RUN: echo -n "%t-SimpleTest" > %t.seed-inputs
+# Test both formats of -seed_inputs argument.
+RUN: %run %t-SimpleTest -runs=1 -seed_inputs=@%t.seed-inputs 2>&1 | FileCheck %s --check-prefix=USE-1
+RUN: %run %t-SimpleTest -runs=1 -seed_inputs=%t-SimpleTest 2>&1 | FileCheck %s --check-prefix=USE-1
+
+USE-2: INFO: seed corpus: files: 2
+RUN: echo -n "%t-SimpleTest,%t-SimpleTest" > %t.seed-inputs
+RUN: %run %t-SimpleTest -runs=1 -seed_inputs=@%t.seed-inputs 2>&1 | FileCheck %s --check-prefix=USE-2
+RUN: %run %t-SimpleTest -runs=1 -seed_inputs=%t-SimpleTest,%t-SimpleTest 2>&1 | FileCheck %s --check-prefix=USE-2
+
+# Test that missing files and trailing commas are tolerated.
+RUN: echo -n "%t-SimpleTest,%t-SimpleTest,nonexistent-file," > %t.seed-inputs
+RUN: %run %t-SimpleTest -runs=1 -seed_inputs=@%t.seed-inputs 2>&1 | FileCheck %s --check-prefix=USE-2
+RUN: %run %t-SimpleTest -runs=1 -seed_inputs=%t-SimpleTest,%t-SimpleTest,nonexistent-file, 2>&1 | FileCheck %s --check-prefix=USE-2
+
+# Test that using a non existent file or an empty seed list fails.
+EMPTY: seed_inputs is empty or @file does not exist.
+RUN: not %run %t-SimpleTest -runs=1 -seed_inputs=@nonexistent-file 2>&1 | FileCheck %s --check-prefix=EMPTY
+RUN: echo -n "" > %t.seed-inputs
+RUN: not %run %t-SimpleTest -runs=1 -seed_inputs=@%t.seed-inputs 2>&1 | FileCheck %s --check-prefix=EMPTY
+RUN: not %run %t-SimpleTest -runs=1 -seed_inputs= 2>&1 | FileCheck %s --check-prefix=EMPTY




More information about the llvm-commits mailing list