[llvm] r282995 - [libFuzzer] implement the -shrink=1 option that tires to make elements of the corpus smaller, off by default

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 30 18:04:29 PDT 2016


Author: kcc
Date: Fri Sep 30 20:04:29 2016
New Revision: 282995

URL: http://llvm.org/viewvc/llvm-project?rev=282995&view=rev
Log:
[libFuzzer] implement the -shrink=1 option that tires to make elements of the corpus smaller, off by default 

Modified:
    llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerFlags.def
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
    llvm/trunk/lib/Fuzzer/FuzzerOptions.h
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
    llvm/trunk/lib/Fuzzer/FuzzerTracePC.h

Modified: llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCorpus.h?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerCorpus.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerCorpus.h Fri Sep 30 20:04:29 2016
@@ -58,6 +58,7 @@ class InputCorpus {
   ConstIter end() const { return Inputs.end(); }
 
   bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
+  bool HasUnit(const std::string &H) { return Hashes.count(H); }
   InputInfo &ChooseUnitToMutate(Random &Rand) {
     return Inputs[ChooseUnitIdxToMutate(Rand)];
   };
@@ -81,7 +82,7 @@ class InputCorpus {
   }
 
   void PrintFeatureSet() {
-    Printf("Features [id: cnt idx sz] ");
+    Printf("Features [id: idx sz] ");
     for (size_t i = 0; i < kFeatureSetSize; i++) {
       auto &Fe = FeatureSet[i];
       if (!Fe.Count) continue;

Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Fri Sep 30 20:04:29 2016
@@ -398,6 +398,7 @@ int FuzzerDriver(int *argc, char ***argv
   Options.UseMemcmp = Flags.use_memcmp;
   Options.UseMemmem = Flags.use_memmem;
   Options.UseValueProfile = Flags.use_value_profile;
+  Options.Shrink = Flags.shrink;
   Options.ShuffleAtStartUp = Flags.shuffle;
   Options.PreferSmall = Flags.prefer_small;
   Options.Reload = Flags.reload;
@@ -429,6 +430,8 @@ int FuzzerDriver(int *argc, char ***argv
   Options.PrintCoverage = Flags.print_coverage;
   if (Flags.exit_on_src_pos)
     Options.ExitOnSrcPos = Flags.exit_on_src_pos;
+  if (Flags.exit_on_item)
+    Options.ExitOnItem = Flags.exit_on_item;
 
   unsigned Seed = Flags.seed;
   // Initialize Seed.

Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Fri Sep 30 20:04:29 2016
@@ -49,6 +49,7 @@ FUZZER_FLAG_INT(use_memmem, 1,
                 "Use hints from intercepting memmem, strstr, etc")
 FUZZER_FLAG_INT(use_value_profile, 0,
                 "Experimental. Use value profile to guide fuzzing.")
+FUZZER_FLAG_INT(shrink, 0, "Experimental. Try to shrink corpus elements.")
 FUZZER_FLAG_INT(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
                           " this number of jobs in separate worker processes"
                           " with stdout/stderr redirected to fuzz-JOB.log.")
@@ -95,6 +96,9 @@ FUZZER_FLAG_INT(rss_limit_mb, 2048, "If
 FUZZER_FLAG_STRING(exit_on_src_pos, "Exit if a newly found PC originates"
     " from the given source location. Example: -exit_on_src_pos=foo.cc:123. "
     "Used primarily for testing libFuzzer itself.")
+FUZZER_FLAG_STRING(exit_on_item, "Exit if an item with a given sha1 sum"
+    " was added to the corpus. "
+    "Used primarily for testing libFuzzer itself.")
 
 FUZZER_DEPRECATED_FLAG(exit_on_first)
 FUZZER_DEPRECATED_FLAG(save_minimized_corpus)

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Fri Sep 30 20:04:29 2016
@@ -117,6 +117,7 @@ private:
                                bool DuringInitialCorpusExecution);
   void AddToCorpus(const Unit &U);
   void CheckExitOnSrcPos();
+  void CheckExitOnItem();
 
   // Trace-based fuzzing: we run a unit with some kind of tracing
   // enabled and record potentially useful mutations. Then

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Fri Sep 30 20:04:29 2016
@@ -79,8 +79,6 @@ void Fuzzer::PrepareCounters(Fuzzer::Cov
 bool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) {
   bool Res = false;
 
-  TPC.FinalizeTrace();
-
   uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();
   if (NewBlockCoverage > C->BlockCoverage) {
     Res = true;
@@ -107,12 +105,6 @@ bool Fuzzer::RecordMaxCoverage(Fuzzer::C
     }
   }
 
-  if (TPC.UpdateCounterMap(&C->TPCMap))
-    Res = true;
-
-  if (TPC.UpdateValueProfileMap(&C->VPMap))
-    Res = true;
-
   return Res;
 }
 
@@ -353,6 +345,16 @@ void Fuzzer::SetMaxMutationLen(size_t Ma
   this->MaxMutationLen = MaxMutationLen;
 }
 
+void Fuzzer::CheckExitOnItem() {
+  if (!Options.ExitOnItem.empty()) {
+    if (Corpus.HasUnit(Options.ExitOnItem)) {
+      Printf("INFO: found item with checksum '%s', exiting.\n",
+             Options.ExitOnItem.c_str());
+      _Exit(0);
+    }
+  }
+}
+
 void Fuzzer::CheckExitOnSrcPos() {
   if (!Options.ExitOnSrcPos.empty()) {
     uintptr_t *PCIDs;
@@ -422,7 +424,22 @@ bool Fuzzer::RunOne(const uint8_t *Data,
   TotalNumberOfRuns++;
 
   ExecuteCallback(Data, Size);
-  bool Res = RecordMaxCoverage(&MaxCoverage);
+  bool Res = false;
+
+  if (TPC.FinalizeTrace(Size))
+    if (Options.Shrink)
+      Res = true;
+
+  if (!Res) {
+    if (TPC.UpdateCounterMap(&MaxCoverage.TPCMap))
+      Res = true;
+
+    if (TPC.UpdateValueProfileMap(&MaxCoverage.VPMap))
+      Res = true;
+  }
+
+  if (RecordMaxCoverage(&MaxCoverage))
+    Res = true;
 
   CheckExitOnSrcPos();
   auto TimeOfUnit =
@@ -667,6 +684,7 @@ void Fuzzer::MutateAndTestOne() {
     if (RunOne(CurrentUnitData, Size)) {
       Corpus.AddToCorpus({CurrentUnitData, CurrentUnitData + Size});
       ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size});
+      CheckExitOnItem();
     }
     StopTraceRecording();
     TryDetectingAMemoryLeak(CurrentUnitData, Size,

Modified: llvm/trunk/lib/Fuzzer/FuzzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerOptions.h?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerOptions.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerOptions.h Fri Sep 30 20:04:29 2016
@@ -31,6 +31,7 @@ struct FuzzingOptions {
   bool UseMemcmp = true;
   bool UseMemmem = true;
   bool UseValueProfile = false;
+  bool Shrink = false;
   bool Reload = true;
   bool ShuffleAtStartUp = true;
   bool PreferSmall = true;
@@ -41,6 +42,7 @@ struct FuzzingOptions {
   std::string ArtifactPrefix = "./";
   std::string ExactArtifactPath;
   std::string ExitOnSrcPos;
+  std::string ExitOnItem;
   bool SaveArtifacts = true;
   bool PrintNEW = true; // Print a status line when new units are found;
   bool OutputCSV = false;

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.cpp Fri Sep 30 20:04:29 2016
@@ -68,7 +68,8 @@ void TracePC::ResetGuards() {
   assert(N == NumGuards);
 }
 
-void TracePC::FinalizeTrace() {
+bool TracePC::FinalizeTrace(size_t InputSize) {
+  bool Res = false;
   if (TotalPCCoverage) {
     const size_t Step = 8;
     assert(reinterpret_cast<uintptr_t>(Counters) % Step == 0);
@@ -89,10 +90,17 @@ void TracePC::FinalizeTrace() {
         else if (Counter >= 4) Bit = 3;
         else if (Counter >= 3) Bit = 2;
         else if (Counter >= 2) Bit = 1;
-        CounterMap.AddValue(i * 8 + Bit);
+        size_t Feature = i * 8 + Bit;
+        CounterMap.AddValue(Feature);
+        uint32_t *SizePtr = &InputSizesPerFeature[Feature];
+        if (!*SizePtr || *SizePtr > InputSize) {
+          *SizePtr = InputSize;
+          Res = true;
+        }
       }
     }
   }
+  return Res;
 }
 
 void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {

Modified: llvm/trunk/lib/Fuzzer/FuzzerTracePC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTracePC.h?rev=282995&r1=282994&r2=282995&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTracePC.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTracePC.h Fri Sep 30 20:04:29 2016
@@ -35,7 +35,7 @@ class TracePC {
   bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {
     return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap);
   }
-  void FinalizeTrace();
+  bool FinalizeTrace(size_t InputSize);
 
   size_t GetNewPCIDs(uintptr_t **NewPCIDsPtr) {
     *NewPCIDsPtr = NewPCIDs;
@@ -90,6 +90,7 @@ private:
 
   ValueBitMap CounterMap;
   ValueBitMap ValueProfileMap;
+  uint32_t InputSizesPerFeature[kFeatureSetSize];
 };
 
 extern TracePC TPC;




More information about the llvm-commits mailing list