[PATCH] D43672: [libFuzzer] Adds experimental flag -ngram that changes the fuzzer fitness function

Bhargava Shastry via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 23 02:03:10 PST 2018


bshastry created this revision.
bshastry added reviewers: kcc, morehouse.
Herald added subscribers: Sanitizers, llvm-commits.

At the moment, PC guards (CFG edge hit counters) are used to select interesting fuzzer mutations. This patch allows the user to specify an optional -ngram=k (an integer that defaults to 1 i.e., vanilla libFuzzer) that uses an XOR of "k" previous PC guards encountered for selecting interesting mutations.

Requires a/b testing to qualify merit of patch.


Repository:
  rCRT Compiler Runtime

https://reviews.llvm.org/D43672

Files:
  FuzzerDriver.cpp
  FuzzerFlags.def
  FuzzerOptions.h
  FuzzerTracePC.cpp
  FuzzerTracePC.h


Index: FuzzerTracePC.h
===================================================================
--- FuzzerTracePC.h
+++ FuzzerTracePC.h
@@ -72,6 +72,8 @@
   static const size_t kNumPCs = 1 << 21;
   // How many bits of PC are used from __sanitizer_cov_trace_pc.
   static const size_t kTracePcBits = 18;
+  static const uint8_t nGramMax = 1 << 7;
+  uint8_t Ngram = 1;
 
   void HandleInit(uint32_t *Start, uint32_t *Stop);
   void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop);
@@ -83,6 +85,7 @@
   void SetUseClangCoverage(bool UCC) { UseClangCoverage = UCC; }
   void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
   void SetPrintNewPCs(bool P) { DoPrintNewPCs = P; }
+  void SetNgram(uint8_t N) { if (N <= nGramMax) Ngram = N; else Ngram = nGramMax; }
   void SetPrintNewFuncs(size_t P) { NumPrintNewFuncs = P; }
   void UpdateObservedPCs();
   template <class Callback> void CollectFeatures(Callback CB) const;
Index: FuzzerTracePC.cpp
===================================================================
--- FuzzerTracePC.cpp
+++ FuzzerTracePC.cpp
@@ -372,13 +372,23 @@
 } // namespace fuzzer
 
 extern "C" {
+static uint32_t GuardHist[fuzzer::TracePC::nGramMax] = {0};
+static uint32_t XorState = 0;
+//static uint8_t Ngram = fuzzer::TPC.Ngram;//NGRAM_MAX;
 ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
   uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
   uint32_t Idx = *Guard;
+  uint32_t Idx8bit = Idx;
+  if (fuzzer::TPC.Ngram > 1) {
+    uint32_t Idx8bit = XorState ^ Idx;
+    XorState = XorState ^ *Guard ^ GuardHist[fuzzer::TPC.Ngram-1];
+    for (uint8_t i=fuzzer::TPC.Ngram-1; i>0;i--) GuardHist[i] = GuardHist[i-1];
+    GuardHist[0] = *Guard;
+  }
   __sancov_trace_pc_pcs[Idx] = PC;
-  __sancov_trace_pc_guard_8bit_counters[Idx]++;
+  __sancov_trace_pc_guard_8bit_counters[Idx8bit]++;
 }
 
 // Best-effort support for -fsanitize-coverage=trace-pc, which is available
Index: FuzzerOptions.h
===================================================================
--- FuzzerOptions.h
+++ FuzzerOptions.h
@@ -40,6 +40,7 @@
   size_t MaxNumberOfRuns = -1L;
   int ReportSlowUnits = 10;
   bool OnlyASCII = false;
+  int Ngram = 1;
   std::string OutputCorpus;
   std::string ArtifactPrefix = "./";
   std::string ExactArtifactPath;
Index: FuzzerFlags.def
===================================================================
--- FuzzerFlags.def
+++ FuzzerFlags.def
@@ -151,3 +151,5 @@
 FUZZER_FLAG_INT(analyze_dict, 0, "Experimental")
 FUZZER_FLAG_INT(use_clang_coverage, 0, "Experimental")
 FUZZER_FLAG_INT(use_feature_frequency, 0, "Experimental/internal")
+FUZZER_FLAG_INT(ngram, 1, "Experimental. Use ngram of PCs.")
+
Index: FuzzerDriver.cpp
===================================================================
--- FuzzerDriver.cpp
+++ FuzzerDriver.cpp
@@ -565,6 +565,10 @@
     return RunInMultipleProcesses(Args, Flags.workers, Flags.jobs);
 
   FuzzingOptions Options;
+  Options.Ngram = Flags.ngram;
+  if (Options.Ngram > 1)
+    TPC.SetNgram(Options.Ngram);
+
   Options.Verbosity = Flags.verbosity;
   Options.MaxLen = Flags.max_len;
   Options.LenControl = Flags.len_control;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43672.135600.patch
Type: text/x-patch
Size: 3198 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180223/8bdb7ad3/attachment.bin>


More information about the llvm-commits mailing list