[llvm] r257873 - [libFuzzer] do mutations based on memcmp/strcmp interceptors under a separate flag (-use_memcmp, default=1)

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 14 22:24:06 PST 2016


Author: kcc
Date: Fri Jan 15 00:24:05 2016
New Revision: 257873

URL: http://llvm.org/viewvc/llvm-project?rev=257873&view=rev
Log:
[libFuzzer] do mutations based on memcmp/strcmp interceptors under a separate flag (-use_memcmp, default=1)

Modified:
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerFlags.def
    llvm/trunk/lib/Fuzzer/FuzzerInternal.h
    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=257873&r1=257872&r2=257873&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Fri Jan 15 00:24:05 2016
@@ -270,6 +270,7 @@ int FuzzerDriver(const std::vector<std::
   Options.UseCounters = Flags.use_counters;
   Options.UseIndirCalls = Flags.use_indir_calls;
   Options.UseTraces = Flags.use_traces;
+  Options.UseMemcmp = Flags.use_memcmp;
   Options.ShuffleAtStartUp = Flags.shuffle;
   Options.PreferSmallDuringInitialShuffle =
       Flags.prefer_small_during_initial_shuffle;

Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=257873&r1=257872&r2=257873&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Fri Jan 15 00:24:05 2016
@@ -38,6 +38,8 @@ FUZZER_FLAG_INT(merge, 0, "If 1, the 2-n
 FUZZER_FLAG_INT(use_counters, 1, "Use coverage counters")
 FUZZER_FLAG_INT(use_indir_calls, 1, "Use indirect caller-callee counters")
 FUZZER_FLAG_INT(use_traces, 0, "Experimental: use instruction traces")
+FUZZER_FLAG_INT(use_memcmp, 1,
+                "Use hints from intercepting memcmp, strcmp, etc")
 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.")

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=257873&r1=257872&r2=257873&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Fri Jan 15 00:24:05 2016
@@ -83,6 +83,7 @@ class Fuzzer {
     bool UseCounters = false;
     bool UseIndirCalls = true;
     bool UseTraces = false;
+    bool UseMemcmp = true;
     bool UseFullCoverageSet  = false;
     bool Reload = true;
     bool ShuffleAtStartUp = true;

Modified: llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp?rev=257873&r1=257872&r2=257873&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerTraceState.cpp Fri Jan 15 00:24:05 2016
@@ -172,6 +172,10 @@ struct TraceBasedMutation {
 
 const size_t TraceBasedMutation::kMaxSize;
 
+// Declared as static globals for faster checks inside the hooks.
+static bool RecordingTraces = false;
+static bool RecordingMemcmp = false;
+
 class TraceState {
  public:
    TraceState(UserSuppliedFuzzer &USF, const Fuzzer::FuzzingOptions &Options,
@@ -206,15 +210,17 @@ class TraceState {
                           const uint8_t *DesiredData, size_t DataSize);
 
   void StartTraceRecording() {
-    if (!Options.UseTraces) return;
-    RecordingTraces = true;
+    if (!Options.UseTraces && !Options.UseMemcmp) return;
+    RecordingTraces = Options.UseTraces;
+    RecordingMemcmp = Options.UseMemcmp;
     NumMutations = 0;
     USF.GetMD().ClearAutoDictionary();
   }
 
   void StopTraceRecording() {
-    if (!RecordingTraces) return;
+    if (!RecordingTraces && !RecordingMemcmp) return;
     RecordingTraces = false;
+    RecordingMemcmp = false;
     for (size_t i = 0; i < NumMutations; i++) {
       auto &M = Mutations[i];
       Unit U(M.Data, M.Data + M.Size);
@@ -260,7 +266,6 @@ class TraceState {
     Signed >>= 16;
     return Signed == 0 || Signed == -1L;
   }
-  bool RecordingTraces = false;
   static const size_t kMaxMutations = 1 << 16;
   size_t NumMutations;
   TraceBasedMutation Mutations[kMaxMutations];
@@ -320,7 +325,7 @@ void TraceState::DFSanMemcmpCallback(siz
                                      dfsan_label L2) {
 
   assert(ReallyHaveDFSan());
-  if (!RecordingTraces || !IsMyThread) return;
+  if (!RecordingMemcmp || !IsMyThread) return;
   if (L1 == 0 && L2 == 0)
     return;  // Not actionable.
   if (L1 != 0 && L2 != 0)
@@ -417,7 +422,7 @@ void TraceState::TraceCmpCallback(uintpt
 
 void TraceState::TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
                                      const uint8_t *Data2) {
-  if (!RecordingTraces || !IsMyThread) return;
+  if (!RecordingMemcmp || !IsMyThread) return;
   CmpSize = std::min(CmpSize, TraceBasedMutation::kMaxSize);
   int Added2 = TryToAddDesiredData(Data1, Data2, CmpSize);
   int Added1 = TryToAddDesiredData(Data2, Data1, CmpSize);
@@ -462,14 +467,14 @@ void Fuzzer::StopTraceRecording() {
 }
 
 void Fuzzer::AssignTaintLabels(uint8_t *Data, size_t Size) {
-  if (!Options.UseTraces) return;
+  if (!Options.UseTraces && !Options.UseMemcmp) return;
   if (!ReallyHaveDFSan()) return;
   for (size_t i = 0; i < Size; i++)
     dfsan_set_label(i + 1, &Data[i], 1);
 }
 
 void Fuzzer::InitializeTraceState() {
-  if (!Options.UseTraces) return;
+  if (!Options.UseTraces && !Options.UseMemcmp) return;
   TS = new TraceState(USF, Options, &CurrentUnitData, &CurrentUnitSize);
   if (ReallyHaveDFSan()) {
     for (size_t i = 0; i < static_cast<size_t>(Options.MaxLen); i++) {
@@ -492,12 +497,14 @@ static size_t InternalStrnlen(const char
 }  // namespace fuzzer
 
 using fuzzer::TS;
+using fuzzer::RecordingTraces;
+using fuzzer::RecordingMemcmp;
 
 extern "C" {
 void __dfsw___sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
                                       uint64_t Arg2, dfsan_label L0,
                                       dfsan_label L1, dfsan_label L2) {
-  if (!TS) return;
+  if (!RecordingTraces) return;
   assert(L0 == 0);
   uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
   uint64_t CmpSize = (SizeAndType >> 32) / 8;
@@ -507,7 +514,7 @@ void __dfsw___sanitizer_cov_trace_cmp(ui
 
 void __dfsw___sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases,
                                          dfsan_label L1, dfsan_label L2) {
-  if (!TS) return;
+  if (!RecordingTraces) return;
   uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
   TS->DFSanSwitchCallback(PC, Cases[1], Val, Cases[0], Cases+2, L1);
 }
@@ -515,7 +522,7 @@ void __dfsw___sanitizer_cov_trace_switch
 void dfsan_weak_hook_memcmp(void *caller_pc, const void *s1, const void *s2,
                             size_t n, dfsan_label s1_label,
                             dfsan_label s2_label, dfsan_label n_label) {
-  if (!TS) return;
+  if (!RecordingMemcmp) return;
   dfsan_label L1 = dfsan_read_label(s1, n);
   dfsan_label L2 = dfsan_read_label(s2, n);
   TS->DFSanMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),
@@ -525,7 +532,7 @@ void dfsan_weak_hook_memcmp(void *caller
 void dfsan_weak_hook_strncmp(void *caller_pc, const char *s1, const char *s2,
                              size_t n, dfsan_label s1_label,
                              dfsan_label s2_label, dfsan_label n_label) {
-  if (!TS) return;
+  if (!RecordingMemcmp) return;
   n = std::min(n, fuzzer::InternalStrnlen(s1, n));
   n = std::min(n, fuzzer::InternalStrnlen(s2, n));
   dfsan_label L1 = dfsan_read_label(s1, n);
@@ -536,7 +543,7 @@ void dfsan_weak_hook_strncmp(void *calle
 
 void dfsan_weak_hook_strcmp(void *caller_pc, const char *s1, const char *s2,
                             dfsan_label s1_label, dfsan_label s2_label) {
-  if (!TS) return;
+  if (!RecordingMemcmp) return;
   size_t Len1 = strlen(s1);
   size_t Len2 = strlen(s2);
   size_t N = std::min(Len1, Len2);
@@ -555,7 +562,7 @@ void dfsan_weak_hook_strcmp(void *caller
 #if LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
 void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
                                   const void *s2, size_t n, int result) {
-  if (!TS) return;
+  if (!RecordingMemcmp) return;
   if (result == 0) return;  // No reason to mutate.
   if (n <= 1) return;  // Not interesting.
   TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),
@@ -564,7 +571,7 @@ void __sanitizer_weak_hook_memcmp(void *
 
 void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
                                    const char *s2, size_t n, int result) {
-  if (!TS) return;
+  if (!RecordingMemcmp) return;
   if (result == 0) return;  // No reason to mutate.
   size_t Len1 = fuzzer::InternalStrnlen(s1, n);
   size_t Len2 = fuzzer::InternalStrnlen(s2, n);
@@ -577,7 +584,7 @@ void __sanitizer_weak_hook_strncmp(void
 
 void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
                                    const char *s2, int result) {
-  if (!TS) return;
+  if (!RecordingMemcmp) return;
   if (result == 0) return;  // No reason to mutate.
   size_t Len1 = strlen(s1);
   size_t Len2 = strlen(s2);
@@ -592,7 +599,7 @@ void __sanitizer_weak_hook_strcmp(void *
 __attribute__((visibility("default")))
 void __sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1,
                                uint64_t Arg2) {
-  if (!TS) return;
+  if (!RecordingTraces) return;
   uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
   uint64_t CmpSize = (SizeAndType >> 32) / 8;
   uint64_t Type = (SizeAndType << 32) >> 32;
@@ -601,7 +608,7 @@ void __sanitizer_cov_trace_cmp(uint64_t
 
 __attribute__((visibility("default")))
 void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) {
-  if (!TS) return;
+  if (!RecordingTraces) return;
   uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
   TS->TraceSwitchCallback(PC, Cases[1], Val, Cases[0], Cases + 2);
 }

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=257873&r1=257872&r2=257873&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer-traces.test Fri Jan 15 00:24:05 2016
@@ -4,14 +4,14 @@ Done10000000: Done 10000000 runs in
 
 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
+RUN: not LLVMFuzzer-MemcmpTest               -seed=4294967295 -runs=100000   2>&1 | FileCheck %s
+RUN:     LLVMFuzzer-MemcmpTest -use_memcmp=0 -seed=4294967295 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000
 
-RUN: not LLVMFuzzer-StrncmpTest -use_traces=1 -seed=1 -runs=100000   2>&1 | FileCheck %s
-RUN:     LLVMFuzzer-StrncmpTest               -seed=1 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000
+RUN: not LLVMFuzzer-StrncmpTest               -seed=1 -runs=100000   2>&1 | FileCheck %s
+RUN:     LLVMFuzzer-StrncmpTest -use_memcmp=0 -seed=1 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000
 
-RUN: not LLVMFuzzer-StrcmpTest -use_traces=1 -seed=1 -runs=200000   2>&1 | FileCheck %s
-RUN:     LLVMFuzzer-StrcmpTest               -seed=1 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000
+RUN: not LLVMFuzzer-StrcmpTest               -seed=1 -runs=200000   2>&1 | FileCheck %s
+RUN:     LLVMFuzzer-StrcmpTest -use_memcmp=0 -seed=1 -runs=1000000  2>&1 | FileCheck %s --check-prefix=Done1000000
 
 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
@@ -19,7 +19,7 @@ RUN:     LLVMFuzzer-SwitchTest
 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
 
-RUN: LLVMFuzzer-RepeatedMemcmp -use_traces=1 -seed=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
+RUN: LLVMFuzzer-RepeatedMemcmp -seed=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
 RECOMMENDED_DICT:###### Recommended dictionary. ######
 RECOMMENDED_DICT-DAG: "foo"
 RECOMMENDED_DICT-DAG: "bar"




More information about the llvm-commits mailing list