LLVM  4.0.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 
12 #ifndef LLVM_FUZZER_INTERNAL_H
13 #define LLVM_FUZZER_INTERNAL_H
14 
15 #include "FuzzerDefs.h"
16 #include "FuzzerExtFunctions.h"
17 #include "FuzzerInterface.h"
18 #include "FuzzerOptions.h"
19 #include "FuzzerSHA1.h"
20 #include "FuzzerValueBitMap.h"
21 #include <algorithm>
22 #include <atomic>
23 #include <chrono>
24 #include <climits>
25 #include <cstdlib>
26 #include <string.h>
27 
28 namespace fuzzer {
29 
30 using namespace std::chrono;
31 
32 class Fuzzer {
33 public:
34 
35  // Aggregates all available coverage measurements.
36  struct Coverage {
37  Coverage() { Reset(); }
38 
39  void Reset() {
40  BlockCoverage = 0;
41  CallerCalleeCoverage = 0;
42  CounterBitmapBits = 0;
43  CounterBitmap.clear();
44  VPMap.Reset();
45  }
46 
47  size_t BlockCoverage;
49  // Precalculated number of bits in CounterBitmap.
51  std::vector<uint8_t> CounterBitmap;
53  };
54 
56  FuzzingOptions Options);
57  ~Fuzzer();
58  void Loop();
59  void MinimizeCrashLoop(const Unit &U);
60  void ShuffleAndMinimize(UnitVector *V);
61  void InitializeTraceState();
62  void RereadOutputCorpus(size_t MaxSize);
63 
65  return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
66  .count();
67  }
68 
69  bool TimedOut() {
70  return Options.MaxTotalTimeSec > 0 &&
71  secondsSinceProcessStartUp() >
72  static_cast<size_t>(Options.MaxTotalTimeSec);
73  }
74 
75  size_t execPerSec() {
76  size_t Seconds = secondsSinceProcessStartUp();
77  return Seconds ? TotalNumberOfRuns / Seconds : 0;
78  }
79 
80  size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
81 
82  static void StaticAlarmCallback();
83  static void StaticCrashSignalCallback();
84  static void StaticInterruptCallback();
85  static void StaticFileSizeExceedCallback();
86 
87  void ExecuteCallback(const uint8_t *Data, size_t Size);
88  size_t RunOne(const uint8_t *Data, size_t Size);
89 
90  // Merge Corpora[1:] into Corpora[0].
91  void Merge(const std::vector<std::string> &Corpora);
92  void CrashResistantMerge(const std::vector<std::string> &Args,
93  const std::vector<std::string> &Corpora);
94  void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
95  // Returns a subset of 'Extra' that adds coverage to 'Initial'.
96  UnitVector FindExtraUnits(const UnitVector &Initial, const UnitVector &Extra);
97  MutationDispatcher &GetMD() { return MD; }
98  void PrintFinalStats();
99  void SetMaxInputLen(size_t MaxInputLen);
100  void SetMaxMutationLen(size_t MaxMutationLen);
101  void RssLimitCallback();
102 
103  // Public for tests.
104  void ResetCoverage();
105 
106  bool InFuzzingThread() const { return IsMyThread; }
107  size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
108  void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
109  bool DuringInitialCorpusExecution);
110 
111  void HandleMalloc(size_t Size);
112 
113 private:
114  void AlarmCallback();
115  void CrashCallback();
116  void InterruptCallback();
117  void MutateAndTestOne();
118  void ReportNewCoverage(InputInfo *II, const Unit &U);
119  size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
120  void WriteToOutputCorpus(const Unit &U);
121  void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
122  void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
123  void PrintStatusForNewUnit(const Unit &U);
124  void ShuffleCorpus(UnitVector *V);
125  void AddToCorpus(const Unit &U);
126  void CheckExitOnSrcPosOrItem();
127 
128  // Trace-based fuzzing: we run a unit with some kind of tracing
129  // enabled and record potentially useful mutations. Then
130  // We apply these mutations one by one to the unit and run it again.
131 
132  // Start tracing; forget all previously proposed mutations.
133  void StartTraceRecording();
134  // Stop tracing.
135  void StopTraceRecording();
136 
137  void SetDeathCallback();
138  static void StaticDeathCallback();
139  void DumpCurrentUnit(const char *Prefix);
140  void DeathCallback();
141 
142  void ResetEdgeCoverage();
143  void ResetCounters();
144  void PrepareCounters(Fuzzer::Coverage *C);
145  bool RecordMaxCoverage(Fuzzer::Coverage *C);
146 
147  void AllocateCurrentUnitData();
148  uint8_t *CurrentUnitData = nullptr;
149  std::atomic<size_t> CurrentUnitSize;
150  uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
151  bool RunningCB = false;
152 
153  size_t TotalNumberOfRuns = 0;
154  size_t NumberOfNewUnitsAdded = 0;
155 
156  bool HasMoreMallocsThanFrees = false;
157  size_t NumberOfLeakDetectionAttempts = 0;
158 
159  UserCallback CB;
160  InputCorpus &Corpus;
161  MutationDispatcher &MD;
162  FuzzingOptions Options;
163 
164  system_clock::time_point ProcessStartTime = system_clock::now();
165  system_clock::time_point UnitStartTime, UnitStopTime;
166  long TimeOfLongestUnitInSeconds = 0;
167  long EpochOfLastReadOfOutputCorpus = 0;
168 
169  // Maximum recorded coverage.
170  Coverage MaxCoverage;
171 
172  size_t MaxInputLen = 0;
173  size_t MaxMutationLen = 0;
174 
175  // Need to know our own thread.
176  static thread_local bool IsMyThread;
177 
178  bool InMergeMode = false;
179 };
180 
181 }; // namespace fuzzer
182 
183 #endif // LLVM_FUZZER_INTERNAL_H
size_t getTotalNumberOfRuns()
int(* UserCallback)(const uint8_t *Data, size_t Size)
Definition: FuzzerDefs.h:73
bool InFuzzingThread() const
size_t secondsSinceProcessStartUp()
MutationDispatcher & GetMD()
size_t execPerSec()
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:791
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
static const unsigned End
static void Merge(const std::string &Input, const std::vector< std::string > Result, size_t NumNewFeatures)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
std::vector< Unit > UnitVector
Definition: FuzzerDefs.h:72
std::vector< uint8_t > CounterBitmap
std::vector< uint8_t > Unit
Definition: FuzzerDefs.h:71
static const int kSHA1NumBytes
Definition: FuzzerSHA1.h:22