[llvm] r251078 - [libFuzzer] use the indirect caller-callee counter as an independent search heuristic

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 22 16:55:40 PDT 2015


Author: kcc
Date: Thu Oct 22 18:55:39 2015
New Revision: 251078

URL: http://llvm.org/viewvc/llvm-project?rev=251078&view=rev
Log:
[libFuzzer] use the indirect caller-callee counter as an independent search heuristic

Added:
    llvm/trunk/lib/Fuzzer/test/CallerCalleeTest.cpp
Modified:
    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/test/CMakeLists.txt
    llvm/trunk/lib/Fuzzer/test/fuzzer.test

Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=251078&r1=251077&r2=251078&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Thu Oct 22 18:55:39 2015
@@ -234,6 +234,7 @@ int FuzzerDriver(const std::vector<std::
   Options.MutateDepth = Flags.mutate_depth;
   Options.ExitOnFirst = Flags.exit_on_first;
   Options.UseCounters = Flags.use_counters;
+  Options.UseIndirCalls = Flags.use_indir_calls;
   Options.UseTraces = Flags.use_traces;
   Options.ShuffleAtStartUp = Flags.shuffle;
   Options.PreferSmallDuringInitialShuffle =

Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=251078&r1=251077&r2=251078&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Thu Oct 22 18:55:39 2015
@@ -37,6 +37,7 @@ FUZZER_FLAG_INT(
     "If 1, the minimized corpus is saved into the first input directory. "
     "Example: ./fuzzer -save_minimized_corpus=1 NEW_EMPTY_DIR OLD_CORPUS")
 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(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
                           " this number of jobs in separate worker processes"

Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=251078&r1=251077&r2=251078&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Thu Oct 22 18:55:39 2015
@@ -79,6 +79,7 @@ class Fuzzer {
     int  MutateDepth = 5;
     bool ExitOnFirst = false;
     bool UseCounters = false;
+    bool UseIndirCalls = true;
     bool UseTraces = false;
     bool UseFullCoverageSet  = false;
     bool Reload = true;
@@ -134,6 +135,7 @@ class Fuzzer {
   void SyncCorpus();
 
   size_t RecordBlockCoverage();
+  size_t RecordCallerCalleeCoverage();
   void PrepareCoverageBeforeRun();
   bool CheckCoverageAfterRun();
 
@@ -176,6 +178,7 @@ class Fuzzer {
   long TimeOfLongestUnitInSeconds = 0;
   long EpochOfLastReadOfOutputCorpus = 0;
   size_t LastRecordedBlockCoverage = 0;
+  size_t LastRecordedCallerCalleeCoverage = 0;
 };
 
 class SimpleUserSuppliedFuzzer: public UserSuppliedFuzzer {

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=251078&r1=251077&r2=251078&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Thu Oct 22 18:55:39 2015
@@ -92,6 +92,8 @@ void Fuzzer::PrintStats(const char *Wher
     Printf(" cov: %zd", LastRecordedBlockCoverage);
   if (auto TB = TotalBits())
     Printf(" bits: %zd", TB);
+  if (LastRecordedCallerCalleeCoverage)
+    Printf(" indir: %zd", LastRecordedCallerCalleeCoverage);
   Printf(" units: %zd exec/s: %zd", Corpus.size(), ExecPerSec);
   if (TotalNumberOfExecutedTraceBasedMutations)
     Printf(" tbm: %zd", TotalNumberOfExecutedTraceBasedMutations);
@@ -202,6 +204,13 @@ size_t Fuzzer::RecordBlockCoverage() {
   return LastRecordedBlockCoverage = __sanitizer_get_total_unique_coverage();
 }
 
+size_t Fuzzer::RecordCallerCalleeCoverage() {
+  if (!Options.UseIndirCalls)
+    return 0;
+  return LastRecordedCallerCalleeCoverage =
+             __sanitizer_get_total_unique_caller_callee_pairs();
+}
+
 void Fuzzer::PrepareCoverageBeforeRun() {
   if (Options.UseCounters) {
     size_t NumCounters = __sanitizer_get_number_of_counters();
@@ -209,16 +218,20 @@ void Fuzzer::PrepareCoverageBeforeRun()
     __sanitizer_update_counter_bitset_and_clear_counters(0);
   }
   RecordBlockCoverage();
+  RecordCallerCalleeCoverage();
 }
 
 bool Fuzzer::CheckCoverageAfterRun() {
   size_t OldCoverage = LastRecordedBlockCoverage;
   size_t NewCoverage = RecordBlockCoverage();
+  size_t OldCallerCalleeCoverage = LastRecordedCallerCalleeCoverage;
+  size_t NewCallerCalleeCoverage = RecordCallerCalleeCoverage();
   size_t NumNewBits = 0;
   if (Options.UseCounters)
     NumNewBits = __sanitizer_update_counter_bitset_and_clear_counters(
         CounterBitmap.data());
-  return NewCoverage > OldCoverage || NumNewBits;
+  return NewCoverage > OldCoverage ||
+         NewCallerCalleeCoverage > OldCallerCalleeCoverage || NumNewBits;
 }
 
 void Fuzzer::WriteToOutputCorpus(const Unit &U) {

Modified: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/CMakeLists.txt?rev=251078&r1=251077&r2=251078&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt (original)
+++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt Thu Oct 22 18:55:39 2015
@@ -13,6 +13,7 @@ set(DFSanTests
   )
 
 set(Tests
+  CallerCalleeTest
   CounterTest
   FourIndependentBranchesTest
   FullCoverageSetTest

Added: llvm/trunk/lib/Fuzzer/test/CallerCalleeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/CallerCalleeTest.cpp?rev=251078&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/CallerCalleeTest.cpp (added)
+++ llvm/trunk/lib/Fuzzer/test/CallerCalleeTest.cpp Thu Oct 22 18:55:39 2015
@@ -0,0 +1,56 @@
+// Simple test for a fuzzer.
+// Try to find the target using the indirect caller-callee pairs.
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#include <cstring>
+#include <iostream>
+
+typedef void (*F)();
+static F t[256];
+
+void f34() {
+  std::cerr << "BINGO\n";
+  exit(1);
+}
+void f23() { t[(unsigned)'d'] = f34;}
+void f12() { t[(unsigned)'c'] = f23;}
+void f01() { t[(unsigned)'b'] = f12;}
+void f00() {}
+
+static F t0[256] = {
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+  f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00, f00,
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  if (Size < 4) return 0;
+  // Spoof the counters.
+  for (int i = 0; i < 200; i++) {
+    f23();
+    f12();
+    f01();
+  }
+  memcpy(t, t0, sizeof(t));
+  t[(unsigned)'a'] = f01;
+  t[Data[0]]();
+  t[Data[1]]();
+  t[Data[2]]();
+  t[Data[3]]();
+  return 0;
+}
+

Modified: llvm/trunk/lib/Fuzzer/test/fuzzer.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer.test?rev=251078&r1=251077&r2=251078&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/fuzzer.test (original)
+++ llvm/trunk/lib/Fuzzer/test/fuzzer.test Thu Oct 22 18:55:39 2015
@@ -35,6 +35,9 @@ NullDerefTestPrefix: Test unit written t
 
 RUN: not LLVMFuzzer-CounterTest -use_counters=1 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s
 
+RUN: not LLVMFuzzer-CallerCalleeTest                     -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s
+RUN:     LLVMFuzzer-CallerCalleeTest  -use_indir_calls=0 -max_len=6 -seed=1 -runs=1000000 2>&1 | FileCheck %s  --check-prefix=Done1000000
+
 RUN: not LLVMFuzzer-SimpleCmpTest -use_traces=1 -seed=1 -runs=1000000 -timeout=5 2>&1 | FileCheck %s
 
 RUN: not LLVMFuzzer-UserSuppliedFuzzerTest -seed=1 -timeout=15 2>&1 | FileCheck %s




More information about the llvm-commits mailing list