LLVM  3.7.0
FuzzerInternal.h
Go to the documentation of this file.
1 //===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Define the main class fuzzer::Fuzzer and most functions.
10 //===----------------------------------------------------------------------===//
11 #include <cassert>
12 #include <climits>
13 #include <chrono>
14 #include <cstddef>
15 #include <cstdlib>
16 #include <string>
17 #include <vector>
18 #include <unordered_set>
19 
20 #include "FuzzerInterface.h"
21 
22 namespace fuzzer {
23 typedef std::vector<uint8_t> Unit;
24 using namespace std::chrono;
25 
26 std::string FileToString(const std::string &Path);
27 Unit FileToVector(const std::string &Path);
28 void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
29  long *Epoch);
30 void WriteToFile(const Unit &U, const std::string &Path);
31 void CopyFileToErr(const std::string &Path);
32 // Returns "Dir/FileName" or equivalent for the current OS.
33 std::string DirPlusFile(const std::string &DirPath,
34  const std::string &FileName);
35 
36 size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
37 
38 size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
39  size_t Size2, uint8_t *Out, size_t MaxOutSize);
40 
41 void Printf(const char *Fmt, ...);
42 void Print(const Unit &U, const char *PrintAfter = "");
43 void PrintASCII(const Unit &U, const char *PrintAfter = "");
44 std::string Hash(const Unit &U);
45 void SetTimer(int Seconds);
46 void PrintFileAsBase64(const std::string &Path);
47 void ExecuteCommand(const std::string &Command);
48 
49 // Private copy of SHA1 implementation.
50 static const int kSHA1NumBytes = 20;
51 // Computes SHA1 hash of 'Len' bytes in 'Data', writes kSHA1NumBytes to 'Out'.
52 void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out);
53 
54 int NumberOfCpuCores();
55 
56 class Fuzzer {
57  public:
58  struct FuzzingOptions {
59  int Verbosity = 1;
60  int MaxLen = 0;
61  int UnitTimeoutSec = 300;
62  bool DoCrossOver = true;
63  int MutateDepth = 5;
64  bool ExitOnFirst = false;
65  bool UseCounters = false;
66  bool UseTraces = false;
67  bool UseFullCoverageSet = false;
68  bool Reload = true;
69  int PreferSmallDuringInitialShuffle = -1;
70  size_t MaxNumberOfRuns = ULONG_MAX;
71  int SyncTimeout = 600;
72  std::string OutputCorpus;
73  std::string SyncCommand;
74  std::vector<std::string> Tokens;
75  };
77  void AddToCorpus(const Unit &U) { Corpus.push_back(U); }
78  void Loop(size_t NumIterations);
79  void ShuffleAndMinimize();
80  void InitializeTraceState();
81  size_t CorpusSize() const { return Corpus.size(); }
82  void ReadDir(const std::string &Path, long *Epoch) {
83  ReadDirToVectorOfUnits(Path.c_str(), &Corpus, Epoch);
84  }
85  void RereadOutputCorpus();
86  // Save the current corpus to OutputCorpus.
87  void SaveCorpus();
88 
90  return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
91  .count();
92  }
93 
94  size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
95 
96  static void StaticAlarmCallback();
97 
98  Unit SubstituteTokens(const Unit &U) const;
99 
100  private:
101  void AlarmCallback();
102  void ExecuteCallback(const Unit &U);
103  void MutateAndTestOne(Unit *U);
104  void ReportNewCoverage(size_t NewCoverage, const Unit &U);
105  size_t RunOne(const Unit &U);
106  void RunOneAndUpdateCorpus(const Unit &U);
107  size_t RunOneMaximizeTotalCoverage(const Unit &U);
108  size_t RunOneMaximizeFullCoverageSet(const Unit &U);
109  size_t RunOneMaximizeCoveragePairs(const Unit &U);
110  void WriteToOutputCorpus(const Unit &U);
111  void WriteToCrash(const Unit &U, const char *Prefix);
112  void PrintStats(const char *Where, size_t Cov, const char *End = "\n");
113  void PrintUnitInASCIIOrTokens(const Unit &U, const char *PrintAfter = "");
114 
115  void SyncCorpus();
116 
117  // Trace-based fuzzing: we run a unit with some kind of tracing
118  // enabled and record potentially useful mutations. Then
119  // We apply these mutations one by one to the unit and run it again.
120 
121  // Start tracing; forget all previously proposed mutations.
122  void StartTraceRecording();
123  // Stop tracing and return the number of proposed mutations.
124  size_t StopTraceRecording();
125  // Apply Idx-th trace-based mutation to U.
126  void ApplyTraceBasedMutation(size_t Idx, Unit *U);
127 
128  void SetDeathCallback();
129  static void StaticDeathCallback();
130  void DeathCallback();
131  Unit CurrentUnit;
132 
133  size_t TotalNumberOfRuns = 0;
134 
135  std::vector<Unit> Corpus;
136  std::unordered_set<std::string> UnitHashesAddedToCorpus;
137  std::unordered_set<uintptr_t> FullCoverageSets;
138 
139  // For UseCounters
140  std::vector<uint8_t> CounterBitmap;
141  size_t TotalBits() { // Slow. Call it only for printing stats.
142  size_t Res = 0;
143  for (auto x : CounterBitmap) Res += __builtin_popcount(x);
144  return Res;
145  }
146 
147  UserSuppliedFuzzer &USF;
148  FuzzingOptions Options;
149  system_clock::time_point ProcessStartTime = system_clock::now();
150  system_clock::time_point LastExternalSync = system_clock::now();
151  system_clock::time_point UnitStartTime;
152  long TimeOfLongestUnitInSeconds = 0;
153  long EpochOfLastReadOfOutputCorpus = 0;
154 };
155 
157  public:
158  SimpleUserSuppliedFuzzer(UserCallback Callback) : Callback(Callback) {}
159  virtual void TargetFunction(const uint8_t *Data, size_t Size) {
160  return Callback(Data, Size);
161  }
162 
163  private:
164  UserCallback Callback;
165 };
166 
167 }; // namespace fuzzer
size_t getTotalNumberOfRuns()
void PrintASCII(const Unit &U, const char *PrintAfter="")
Definition: FuzzerUtil.cpp:29
void ReadDir(const std::string &Path, long *Epoch)
void Print(const Unit &U, const char *PrintAfter="")
Definition: FuzzerUtil.cpp:23
void SetTimer(int Seconds)
Definition: FuzzerUtil.cpp:52
void(* UserCallback)(const uint8_t *Data, size_t Size)
std::vector< std::string > Tokens
size_t secondsSinceProcessStartUp()
void ExecuteCommand(const std::string &Command)
Definition: FuzzerUtil.cpp:72
SimpleUserSuppliedFuzzer(UserCallback Callback)
void PrintFileAsBase64(const std::string &Path)
Definition: FuzzerIO.cpp:82
std::string FileToString(const std::string &Path)
Definition: FuzzerIO.cpp:52
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize)
size_t CorpusSize() const
int NumberOfCpuCores()
Definition: FuzzerUtil.cpp:64
void Printf(const char *Fmt,...)
Definition: FuzzerIO.cpp:87
void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out)
Definition: FuzzerSHA1.cpp:197
static PassOptionList PrintAfter("print-after", llvm::cl::desc("Print IR after specified passes"), cl::Hidden)
virtual void TargetFunction(const uint8_t *Data, size_t Size)
Executes the target function on 'Size' bytes of 'Data'.
size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2, size_t Size2, uint8_t *Out, size_t MaxOutSize)
void AddToCorpus(const Unit &U)
std::string DirPlusFile(const std::string &DirPath, const std::string &FileName)
Definition: FuzzerIO.cpp:77
An abstract class that allows to use user-supplied mutators with libFuzzer.
void CopyFileToErr(const std::string &Path)
Definition: FuzzerIO.cpp:58
void WriteToFile(const Unit &U, const std::string &Path)
Definition: FuzzerIO.cpp:62
Unit FileToVector(const std::string &Path)
Definition: FuzzerIO.cpp:46
std::vector< uint8_t > Unit
void ReadDirToVectorOfUnits(const char *Path, std::vector< Unit > *V, long *Epoch)
Definition: FuzzerIO.cpp:67
std::string Hash(const Unit &U)
Definition: FuzzerUtil.cpp:39
static const int kSHA1NumBytes
static sys::TimeValue now(bool Deterministic)