[llvm] r257248 - [libFuzzer] change the way trace-based mutations are applied. Instead of a custom code just rely on the automatically created dictionary

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 8 19:08:59 PST 2016


Author: kcc
Date: Fri Jan  8 21:08:58 2016
New Revision: 257248

URL: http://llvm.org/viewvc/llvm-project?rev=257248&view=rev
Log:
[libFuzzer] change the way trace-based mutations are applied. Instead of a custom code just rely on the automatically created dictionary

Modified:
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerFlags.def
    llvm/trunk/lib/Fuzzer/FuzzerInterface.h
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
    llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
    llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp
    llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test

Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Fri Jan  8 21:08:58 2016
@@ -259,8 +259,6 @@ int FuzzerDriver(const std::vector<std::
       Flags.prefer_small_during_initial_shuffle;
   Options.Reload = Flags.reload;
   Options.OnlyASCII = Flags.only_ascii;
-  Options.TBMDepth = Flags.tbm_depth;
-  Options.TBMWidth = Flags.tbm_width;
   Options.OutputCSV = Flags.output_csv;
   if (Flags.runs >= 0)
     Options.MaxNumberOfRuns = Flags.runs;

Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Fri Jan  8 21:08:58 2016
@@ -56,10 +56,6 @@ FUZZER_FLAG_INT(report_slow_units, 10,
 FUZZER_FLAG_INT(only_ascii, 0,
                 "If 1, generate only ASCII (isprint+isspace) inputs.")
 FUZZER_FLAG_STRING(dict, "Experimental. Use the dictionary file.")
-FUZZER_FLAG_INT(tbm_depth, 5, "Apply at most this number of consecutive"
-                               "trace-based-mutations (tbm).")
-FUZZER_FLAG_INT(tbm_width, 5, "Apply at most this number of independent"
-                               "trace-based-mutations (tbm)")
 FUZZER_FLAG_STRING(test_single_input, "Use specified file as test input.")
 FUZZER_FLAG_STRING(artifact_prefix, "Write fuzzing artifacts (crash, "
                                     "timeout, or slow inputs) as "

Modified: llvm/trunk/lib/Fuzzer/FuzzerInterface.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInterface.h?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInterface.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInterface.h Fri Jan  8 21:08:58 2016
@@ -110,7 +110,10 @@ class MutationDispatcher {
                    size_t Size2, uint8_t *Out, size_t MaxOutSize);
 
   void AddWordToManualDictionary(const Unit &Word);
+
   void AddWordToAutoDictionary(const Unit &Word, size_t PositionHint);
+  void ClearAutoDictionary();
+
   void SetCorpus(const std::vector<Unit> *Corpus);
 
  private:

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Fri Jan  8 21:08:58 2016
@@ -88,8 +88,6 @@ class Fuzzer {
     int SyncTimeout = 600;
     int ReportSlowUnits = 10;
     bool OnlyASCII = false;
-    int TBMDepth = 10;
-    int TBMWidth = 10;
     std::string OutputCorpus;
     std::string SyncCommand;
     std::string ArtifactPrefix = "./";
@@ -156,10 +154,8 @@ class Fuzzer {
 
   // Start tracing; forget all previously proposed mutations.
   void StartTraceRecording();
-  // Stop tracing and return the number of proposed mutations.
-  size_t StopTraceRecording();
-  // Apply Idx-th trace-based mutation to U.
-  void ApplyTraceBasedMutation(size_t Idx, Unit *U);
+  // Stop tracing.
+  void StopTraceRecording();
 
   void SetDeathCallback();
   static void StaticDeathCallback();

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Fri Jan  8 21:08:58 2016
@@ -390,7 +390,6 @@ void Fuzzer::MutateAndTestOne() {
   U = ChooseUnitToMutate();
 
   for (int i = 0; i < Options.MutateDepth; i++) {
-    StartTraceRecording();
     size_t Size = U.size();
     U.resize(Options.MaxLen);
     size_t NewSize = USF.Mutate(U.data(), Size, U.size());
@@ -398,21 +397,10 @@ void Fuzzer::MutateAndTestOne() {
     assert(NewSize <= (size_t)Options.MaxLen &&
            "Mutator return overisized unit");
     U.resize(NewSize);
+    if (i == 0)
+      StartTraceRecording();
     RunOneAndUpdateCorpus(U);
-    size_t NumTraceBasedMutations = StopTraceRecording();
-    size_t TBMWidth =
-        std::min((size_t)Options.TBMWidth, NumTraceBasedMutations);
-    size_t TBMDepth =
-        std::min((size_t)Options.TBMDepth, NumTraceBasedMutations);
-    Unit BackUp = U;
-    for (size_t w = 0; w < TBMWidth; w++) {
-      U = BackUp;
-      for (size_t d = 0; d < TBMDepth; d++) {
-        TotalNumberOfExecutedTraceBasedMutations++;
-        ApplyTraceBasedMutation(USF.GetRand()(NumTraceBasedMutations), &U);
-        RunOneAndUpdateCorpus(U);
-      }
-    }
+    StopTraceRecording();
   }
 }
 

Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Fri Jan  8 21:08:58 2016
@@ -250,9 +250,15 @@ void MutationDispatcher::AddWordToManual
 
 void MutationDispatcher::AddWordToAutoDictionary(const Unit &Word,
                                                  size_t PositionHint) {
+  static const size_t kMaxAutoDictSize = 1 << 14;
+  if (MDImpl->AutoDictionary.size() >= kMaxAutoDictSize) return;
   MDImpl->AutoDictionary.push_back({Word, PositionHint});
 }
 
+void MutationDispatcher::ClearAutoDictionary() {
+  MDImpl->AutoDictionary.clear();
+}
+
 MutationDispatcher::MutationDispatcher(FuzzerRandomBase &Rand) : Rand(Rand) {
   MDImpl = new Impl(Rand);
 }

Modified: llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp Fri Jan  8 21:08:58 2016
@@ -46,8 +46,6 @@
 //   * The __dfsw_* functions (implemented in this file) record the
 //     parameters (i.e. the application data and the corresponding taint labels)
 //     in a global state.
-//   * Fuzzer::ApplyTraceBasedMutation() tries to use the data recorded
-//     by __dfsw_* hooks to guide the fuzzing towards new application states.
 //
 // Parts of this code will not function when DFSan is not linked in.
 // Instead of using ifdefs and thus requiring a separate build of lib/Fuzzer
@@ -176,8 +174,9 @@ const size_t TraceBasedMutation::kMaxSiz
 
 class TraceState {
  public:
-  TraceState(const Fuzzer::FuzzingOptions &Options, const Unit &CurrentUnit)
-       : Options(Options), CurrentUnit(CurrentUnit) {
+  TraceState(UserSuppliedFuzzer &USF,
+             const Fuzzer::FuzzingOptions &Options, const Unit &CurrentUnit)
+       : USF(USF), Options(Options), CurrentUnit(CurrentUnit) {
     // Current trace collection is not thread-friendly and it probably
     // does not have to be such, but at least we should not crash in presence
     // of threads. So, just ignore all traces coming from all threads but one.
@@ -209,15 +208,18 @@ class TraceState {
     if (!Options.UseTraces) return;
     RecordingTraces = true;
     NumMutations = 0;
+    USF.GetMD().ClearAutoDictionary();
   }
 
-  size_t StopTraceRecording(FuzzerRandomBase &Rand) {
+  void StopTraceRecording() {
+    if (!RecordingTraces) return;
     RecordingTraces = false;
-    return NumMutations;
+    for (size_t i = 0; i < NumMutations; i++) {
+      auto &M = Mutations[i];
+      USF.GetMD().AddWordToAutoDictionary(Unit(M.Data, M.Data + M.Size), M.Pos);
+    }
   }
 
-  void ApplyTraceBasedMutation(size_t Idx, fuzzer::Unit *U);
-
   void AddMutation(uint32_t Pos, uint32_t Size, const uint8_t *Data) {
     if (NumMutations >= kMaxMutations) return;
     assert(Size <= TraceBasedMutation::kMaxSize);
@@ -243,6 +245,7 @@ class TraceState {
   size_t NumMutations;
   TraceBasedMutation Mutations[kMaxMutations];
   LabelRange LabelRanges[1 << (sizeof(dfsan_label) * 8)];
+  UserSuppliedFuzzer &USF;
   const Fuzzer::FuzzingOptions &Options;
   const Unit &CurrentUnit;
   static thread_local bool IsMyThread;
@@ -260,19 +263,6 @@ LabelRange TraceState::GetLabelRange(dfs
   return LR = LabelRange::Singleton(LI);
 }
 
-void TraceState::ApplyTraceBasedMutation(size_t Idx, fuzzer::Unit *U) {
-  assert(Idx < NumMutations);
-  auto &M = Mutations[Idx];
-  if (Options.Verbosity >= 3) {
-    Printf("TBM Pos %u Size %u ", M.Pos, M.Size);
-    for (uint32_t i = 0; i < M.Size; i++)
-      Printf("%02x", M.Data[i]);
-    Printf("\n");
-  }
-  if (M.Pos + M.Size > U->size()) return;
-  memcpy(U->data() + M.Pos, &M.Data[0], M.Size);
-}
-
 void TraceState::DFSanCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
                                   uint64_t Arg1, uint64_t Arg2, dfsan_label L1,
                                   dfsan_label L2) {
@@ -438,19 +428,14 @@ void Fuzzer::StartTraceRecording() {
   TS->StartTraceRecording();
 }
 
-size_t Fuzzer::StopTraceRecording() {
-  if (!TS) return 0;
-  return TS->StopTraceRecording(USF.GetRand());
-}
-
-void Fuzzer::ApplyTraceBasedMutation(size_t Idx, Unit *U) {
-  assert(TS);
-  TS->ApplyTraceBasedMutation(Idx, U);
+void Fuzzer::StopTraceRecording() {
+  if (!TS) return;
+  TS->StopTraceRecording();
 }
 
 void Fuzzer::InitializeTraceState() {
   if (!Options.UseTraces) return;
-  TS = new TraceState(Options, CurrentUnit);
+  TS = new TraceState(USF, Options, CurrentUnit);
   CurrentUnit.resize(Options.MaxLen);
   // The rest really requires DFSan.
   if (!ReallyHaveDFSan()) return;

Modified: llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test?rev=257248&r1=257247&r2=257248&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test Fri Jan  8 21:08:58 2016
@@ -1,7 +1,8 @@
 CHECK: BINGO
 Done1000000: Done 1000000 runs in
+Done10000000: Done 10000000 runs in
 
-RUN: not LLVMFuzzer-SimpleCmpTest -use_traces=1 -seed=1 -runs=1000001  2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-SimpleCmpTest -use_traces=1 -seed=1 -runs=10000001  2>&1 | FileCheck %s
 
 RUN: not LLVMFuzzer-MemcmpTest -use_traces=1 -seed=4294967295 -runs=100000   2>&1 | FileCheck %s
 RUN:     LLVMFuzzer-MemcmpTest               -seed=4294967295 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000
@@ -15,5 +16,5 @@ RUN:     LLVMFuzzer-StrcmpTest
 RUN: not LLVMFuzzer-SwitchTest -use_traces=1 -seed=1 -runs=1000002  2>&1 | FileCheck %s
 RUN:     LLVMFuzzer-SwitchTest               -seed=1 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000
 
-RUN: not LLVMFuzzer-SimpleHashTest -use_traces=1 -seed=1 -runs=100000  2>&1 | FileCheck %s
-RUN:     LLVMFuzzer-SimpleHashTest               -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+RUN: not LLVMFuzzer-SimpleHashTest -use_traces=1 -seed=1 -runs=10000000  2>&1 | FileCheck %s
+RUN:     LLVMFuzzer-SimpleHashTest               -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=Done10000000




More information about the llvm-commits mailing list