• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
CoverageCoverage37     Coverage() { Reset(); }
38 
ResetCoverage39     void Reset() {
40       BlockCoverage = 0;
41       CallerCalleeCoverage = 0;
42       CounterBitmapBits = 0;
43       CounterBitmap.clear();
44       VPMap.Reset();
45     }
46 
47     size_t BlockCoverage;
48     size_t CallerCalleeCoverage;
49     // Precalculated number of bits in CounterBitmap.
50     size_t CounterBitmapBits;
51     std::vector<uint8_t> CounterBitmap;
52     ValueBitMap VPMap;
53   };
54 
55   Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
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 
secondsSinceProcessStartUp()64   size_t secondsSinceProcessStartUp() {
65     return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
66         .count();
67   }
68 
TimedOut()69   bool TimedOut() {
70     return Options.MaxTotalTimeSec > 0 &&
71            secondsSinceProcessStartUp() >
72                static_cast<size_t>(Options.MaxTotalTimeSec);
73   }
74 
execPerSec()75   size_t execPerSec() {
76     size_t Seconds = secondsSinceProcessStartUp();
77     return Seconds ? TotalNumberOfRuns / Seconds : 0;
78   }
79 
getTotalNumberOfRuns()80   size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
81 
82   static void StaticAlarmCallback();
83   static void StaticCrashSignalCallback();
84   static void StaticInterruptCallback();
85 
86   void ExecuteCallback(const uint8_t *Data, size_t Size);
87   size_t RunOne(const uint8_t *Data, size_t Size);
88 
89   // Merge Corpora[1:] into Corpora[0].
90   void Merge(const std::vector<std::string> &Corpora);
91   void CrashResistantMerge(const std::vector<std::string> &Args,
92                            const std::vector<std::string> &Corpora);
93   void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
94   // Returns a subset of 'Extra' that adds coverage to 'Initial'.
95   UnitVector FindExtraUnits(const UnitVector &Initial, const UnitVector &Extra);
GetMD()96   MutationDispatcher &GetMD() { return MD; }
97   void PrintFinalStats();
98   void SetMaxInputLen(size_t MaxInputLen);
99   void SetMaxMutationLen(size_t MaxMutationLen);
100   void RssLimitCallback();
101 
102   // Public for tests.
103   void ResetCoverage();
104 
InFuzzingThread()105   bool InFuzzingThread() const { return IsMyThread; }
106   size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
107   void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
108                                bool DuringInitialCorpusExecution);
109 
110   void HandleMalloc(size_t Size);
111 
112 private:
113   void AlarmCallback();
114   void CrashCallback();
115   void InterruptCallback();
116   void MutateAndTestOne();
117   void ReportNewCoverage(InputInfo *II, const Unit &U);
RunOne(const Unit & U)118   size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
119   void WriteToOutputCorpus(const Unit &U);
120   void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
121   void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
122   void PrintStatusForNewUnit(const Unit &U);
123   void ShuffleCorpus(UnitVector *V);
124   void AddToCorpus(const Unit &U);
125   void CheckExitOnSrcPosOrItem();
126 
127   // Trace-based fuzzing: we run a unit with some kind of tracing
128   // enabled and record potentially useful mutations. Then
129   // We apply these mutations one by one to the unit and run it again.
130 
131   // Start tracing; forget all previously proposed mutations.
132   void StartTraceRecording();
133   // Stop tracing.
134   void StopTraceRecording();
135 
136   void SetDeathCallback();
137   static void StaticDeathCallback();
138   void DumpCurrentUnit(const char *Prefix);
139   void DeathCallback();
140 
141   void ResetEdgeCoverage();
142   void ResetCounters();
143   void PrepareCounters(Fuzzer::Coverage *C);
144   bool RecordMaxCoverage(Fuzzer::Coverage *C);
145 
146   void AllocateCurrentUnitData();
147   uint8_t *CurrentUnitData = nullptr;
148   std::atomic<size_t> CurrentUnitSize;
149   uint8_t BaseSha1[kSHA1NumBytes];  // Checksum of the base unit.
150   bool RunningCB = false;
151 
152   size_t TotalNumberOfRuns = 0;
153   size_t NumberOfNewUnitsAdded = 0;
154 
155   bool HasMoreMallocsThanFrees = false;
156   size_t NumberOfLeakDetectionAttempts = 0;
157 
158   UserCallback CB;
159   InputCorpus &Corpus;
160   MutationDispatcher &MD;
161   FuzzingOptions Options;
162 
163   system_clock::time_point ProcessStartTime = system_clock::now();
164   system_clock::time_point UnitStartTime, UnitStopTime;
165   long TimeOfLongestUnitInSeconds = 0;
166   long EpochOfLastReadOfOutputCorpus = 0;
167 
168   // Maximum recorded coverage.
169   Coverage MaxCoverage;
170 
171   size_t MaxInputLen = 0;
172   size_t MaxMutationLen = 0;
173 
174   // Need to know our own thread.
175   static thread_local bool IsMyThread;
176 
177   bool InMergeMode = false;
178 };
179 
180 }; // namespace fuzzer
181 
182 #endif // LLVM_FUZZER_INTERNAL_H
183