[lib/Fuzzer] when -sync_command=<CMD> is given, periodically execute 'CMD CORPUS...
authorKostya Serebryany <kcc@google.com>
Mon, 18 May 2015 21:34:20 +0000 (21:34 +0000)
committerKostya Serebryany <kcc@google.com>
Mon, 18 May 2015 21:34:20 +0000 (21:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237617 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerDriver.cpp
lib/Fuzzer/FuzzerFlags.def
lib/Fuzzer/FuzzerIO.cpp
lib/Fuzzer/FuzzerInternal.h
lib/Fuzzer/FuzzerLoop.cpp
lib/Fuzzer/FuzzerUtil.cpp

index d1f6953a748941925efc23d48a82e5ec16876faf..6b8a4b220ef9b3f1dea5b47395e3bc33f68af45a 100644 (file)
@@ -230,6 +230,9 @@ int FuzzerDriver(int argc, char **argv, UserCallback Callback) {
     Options.MaxNumberOfRuns = Flags.runs;
   if (!inputs.empty())
     Options.OutputCorpus = inputs[0];
+  if (Flags.sync_command)
+    Options.SyncCommand = Flags.sync_command;
+  Options.SyncTimeout = Flags.sync_timeout;
   Fuzzer F(Callback, Options);
 
   unsigned seed = Flags.seed;
index 942bd59cb7905d2f0b150a3ac54c983fda235b91..9d1b54524e95204122ae1c4cb51d9096ac60d223 100644 (file)
@@ -53,3 +53,7 @@ FUZZER_FLAG_STRING(tokens, "Use the file with tokens (one token per line) to"
                            " fuzz a token based input language.")
 FUZZER_FLAG_STRING(apply_tokens, "Read the given input file, substitute bytes "
                                  " with tokens and write the result to stdout.")
+FUZZER_FLAG_STRING(sync_command, "Execute an external command "
+                                 "\"<sync_command> <test_corpus>\" "
+                                 "to synchronize the test corpus.")
+FUZZER_FLAG_INT(sync_timeout, 600, "Minimal timeout between syncs.")
index 7136d38fb771b80e208f0efd5e6f801cfe0a9c5a..c6636c8681832fc318877871e089fc77fb5ba936 100644 (file)
@@ -83,7 +83,7 @@ std::string DirPlusFile(const std::string &DirPath,
 
 void PrintFileAsBase64(const std::string &Path) {
   std::string Cmd = "base64 -w 0 < " + Path + "; echo";
-  system(Cmd.c_str());
+  ExecuteCommand(Cmd);
 }
 
 }  // namespace fuzzer
index 89261895579aca2dc5a735d44730768f0e02e757..8d6193e9a229a0e1dd8d308846a6bb14d01eb7b0 100644 (file)
@@ -43,6 +43,7 @@ void PrintASCII(const Unit &U, const char *PrintAfter = "");
 std::string Hash(const Unit &U);
 void SetTimer(int Seconds);
 void PrintFileAsBase64(const std::string &Path);
+void ExecuteCommand(const std::string &Command);
 
 // Private copy of SHA1 implementation.
 static const int kSHA1NumBytes = 20;
@@ -66,7 +67,9 @@ class Fuzzer {
     bool Reload = true;
     int PreferSmallDuringInitialShuffle = -1;
     size_t MaxNumberOfRuns = ULONG_MAX;
+    int SyncTimeout = 600;
     std::string OutputCorpus;
+    std::string SyncCommand;
     std::vector<std::string> Tokens;
   };
   Fuzzer(UserCallback Callback, FuzzingOptions Options);
@@ -108,6 +111,8 @@ class Fuzzer {
   void PrintStats(const char *Where, size_t Cov, const char *End = "\n");
   void PrintUnitInASCIIOrTokens(const Unit &U, const char *PrintAfter = "");
 
+  void SyncCorpus();
+
   // Trace-based fuzzing: we run a unit with some kind of tracing
   // enabled and record potentially useful mutations. Then
   // We apply these mutations one by one to the unit and run it again.
@@ -142,6 +147,7 @@ class Fuzzer {
   UserCallback Callback;
   FuzzingOptions Options;
   system_clock::time_point ProcessStartTime = system_clock::now();
+  system_clock::time_point LastExternalSync = system_clock::now();
   system_clock::time_point UnitStartTime;
   long TimeOfLongestUnitInSeconds = 0;
   long EpochOfLastReadOfOutputCorpus = 0;
index 9200f6293fd99847b84f96d203367bcb5e7312e5..3a80d0d7e2317774080fd5414240baca50f19a01 100644 (file)
@@ -324,6 +324,7 @@ void Fuzzer::MutateAndTestOne(Unit *U) {
 void Fuzzer::Loop(size_t NumIterations) {
   for (size_t i = 1; i <= NumIterations; i++) {
     for (size_t J1 = 0; J1 < Corpus.size(); J1++) {
+      SyncCorpus();
       RereadOutputCorpus();
       if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
         return;
@@ -342,4 +343,14 @@ void Fuzzer::Loop(size_t NumIterations) {
   }
 }
 
+void Fuzzer::SyncCorpus() {
+  if (Options.SyncCommand.empty() || Options.OutputCorpus.empty()) return;
+  auto Now = system_clock::now();
+  if (duration_cast<seconds>(Now - LastExternalSync).count() <
+      Options.SyncTimeout)
+    return;
+  LastExternalSync = Now;
+  ExecuteCommand(Options.SyncCommand + " " + Options.OutputCorpus);
+}
+
 }  // namespace fuzzer
index c4b0afa55d597a8e0d7f9ce0d6789ac1fef89b6e..06852081f52fb38412505a363f481cfbc57c451c 100644 (file)
@@ -70,4 +70,8 @@ int NumberOfCpuCores() {
   return N;
 }
 
+void ExecuteCommand(const std::string &Command) {
+  system(Command.c_str());
+}
+
 }  // namespace fuzzer