/src/mozilla-central/tools/fuzzing/libfuzzer/FuzzerInternal.h
Line | Count | Source (jump to first uncovered line) |
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 "FuzzerDataFlowTrace.h" |
16 | | #include "FuzzerDefs.h" |
17 | | #include "FuzzerExtFunctions.h" |
18 | | #include "FuzzerInterface.h" |
19 | | #include "FuzzerOptions.h" |
20 | | #include "FuzzerSHA1.h" |
21 | | #include "FuzzerValueBitMap.h" |
22 | | #include <algorithm> |
23 | | #include <atomic> |
24 | | #include <chrono> |
25 | | #include <climits> |
26 | | #include <cstdlib> |
27 | | #include <string.h> |
28 | | |
29 | | namespace fuzzer { |
30 | | |
31 | | using namespace std::chrono; |
32 | | |
33 | | class Fuzzer { |
34 | | public: |
35 | | |
36 | | Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD, |
37 | | FuzzingOptions Options); |
38 | | ~Fuzzer(); |
39 | | void Loop(const Vector<std::string> &CorpusDirs); |
40 | | void ReadAndExecuteSeedCorpora(const Vector<std::string> &CorpusDirs); |
41 | | void MinimizeCrashLoop(const Unit &U); |
42 | | void RereadOutputCorpus(size_t MaxSize); |
43 | | |
44 | 51 | size_t secondsSinceProcessStartUp() { |
45 | 51 | return duration_cast<seconds>(system_clock::now() - ProcessStartTime) |
46 | 51 | .count(); |
47 | 51 | } |
48 | | |
49 | 0 | bool TimedOut() { |
50 | 0 | return Options.MaxTotalTimeSec > 0 && |
51 | 0 | secondsSinceProcessStartUp() > |
52 | 0 | static_cast<size_t>(Options.MaxTotalTimeSec); |
53 | 0 | } |
54 | | |
55 | 14 | size_t execPerSec() { |
56 | 14 | size_t Seconds = secondsSinceProcessStartUp(); |
57 | 14 | return Seconds ? TotalNumberOfRuns / Seconds : 0; |
58 | 14 | } |
59 | | |
60 | 3 | size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; } |
61 | | |
62 | | static void StaticAlarmCallback(); |
63 | | static void StaticCrashSignalCallback(); |
64 | | static void StaticExitCallback(); |
65 | | static void StaticInterruptCallback(); |
66 | | static void StaticFileSizeExceedCallback(); |
67 | | static void StaticGracefulExitCallback(); |
68 | | |
69 | | void ExecuteCallback(const uint8_t *Data, size_t Size); |
70 | | void CheckForUnstableCounters(const uint8_t *Data, size_t Size); |
71 | | bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false, |
72 | | InputInfo *II = nullptr, bool *FoundUniqFeatures = nullptr); |
73 | | |
74 | | // Merge Corpora[1:] into Corpora[0]. |
75 | | void Merge(const Vector<std::string> &Corpora); |
76 | | void CrashResistantMerge(const Vector<std::string> &Args, |
77 | | const Vector<std::string> &Corpora, |
78 | | const char *CoverageSummaryInputPathOrNull, |
79 | | const char *CoverageSummaryOutputPathOrNull, |
80 | | const char *MergeControlFilePathOrNull); |
81 | | void CrashResistantMergeInternalStep(const std::string &ControlFilePath); |
82 | 0 | MutationDispatcher &GetMD() { return MD; } |
83 | | void PrintFinalStats(); |
84 | | void SetMaxInputLen(size_t MaxInputLen); |
85 | | void SetMaxMutationLen(size_t MaxMutationLen); |
86 | | void RssLimitCallback(); |
87 | | |
88 | 14 | bool InFuzzingThread() const { return IsMyThread; } |
89 | | size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const; |
90 | | void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size, |
91 | | bool DuringInitialCorpusExecution); |
92 | | |
93 | | void HandleMalloc(size_t Size); |
94 | | void AnnounceOutput(const uint8_t *Data, size_t Size); |
95 | | |
96 | | private: |
97 | | void AlarmCallback(); |
98 | | void CrashCallback(); |
99 | | void ExitCallback(); |
100 | | void MaybeExitGracefully(); |
101 | | void CrashOnOverwrittenData(); |
102 | | void InterruptCallback(); |
103 | | void MutateAndTestOne(); |
104 | | void PurgeAllocator(); |
105 | | void ReportNewCoverage(InputInfo *II, const Unit &U); |
106 | | void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size); |
107 | | void WriteToOutputCorpus(const Unit &U); |
108 | | void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix); |
109 | | void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0); |
110 | | void PrintStatusForNewUnit(const Unit &U, const char *Text); |
111 | | void CheckExitOnSrcPosOrItem(); |
112 | | |
113 | | static void StaticDeathCallback(); |
114 | | void DumpCurrentUnit(const char *Prefix); |
115 | | void DeathCallback(); |
116 | | |
117 | | void AllocateCurrentUnitData(); |
118 | | uint8_t *CurrentUnitData = nullptr; |
119 | | std::atomic<size_t> CurrentUnitSize; |
120 | | uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit. |
121 | | |
122 | | bool GracefulExitRequested = false; |
123 | | |
124 | | size_t TotalNumberOfRuns = 0; |
125 | | size_t NumberOfNewUnitsAdded = 0; |
126 | | |
127 | | size_t LastCorpusUpdateRun = 0; |
128 | | |
129 | | bool HasMoreMallocsThanFrees = false; |
130 | | size_t NumberOfLeakDetectionAttempts = 0; |
131 | | |
132 | | system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now(); |
133 | | |
134 | | UserCallback CB; |
135 | | InputCorpus &Corpus; |
136 | | MutationDispatcher &MD; |
137 | | FuzzingOptions Options; |
138 | | DataFlowTrace DFT; |
139 | | |
140 | | system_clock::time_point ProcessStartTime = system_clock::now(); |
141 | | system_clock::time_point UnitStartTime, UnitStopTime; |
142 | | long TimeOfLongestUnitInSeconds = 0; |
143 | | long EpochOfLastReadOfOutputCorpus = 0; |
144 | | |
145 | | size_t MaxInputLen = 0; |
146 | | size_t MaxMutationLen = 0; |
147 | | size_t TmpMaxMutationLen = 0; |
148 | | |
149 | | Vector<uint32_t> UniqFeatureSetTmp; |
150 | | |
151 | | // Need to know our own thread. |
152 | | static thread_local bool IsMyThread; |
153 | | }; |
154 | | |
155 | | struct ScopedEnableMsanInterceptorChecks { |
156 | 16.2k | ScopedEnableMsanInterceptorChecks() { |
157 | 16.2k | if (EF->__msan_scoped_enable_interceptor_checks) |
158 | 0 | EF->__msan_scoped_enable_interceptor_checks(); |
159 | 16.2k | } |
160 | 16.2k | ~ScopedEnableMsanInterceptorChecks() { |
161 | 16.2k | if (EF->__msan_scoped_disable_interceptor_checks) |
162 | 0 | EF->__msan_scoped_disable_interceptor_checks(); |
163 | 16.2k | } |
164 | | }; |
165 | | |
166 | | struct ScopedDisableMsanInterceptorChecks { |
167 | 0 | ScopedDisableMsanInterceptorChecks() { |
168 | 0 | if (EF->__msan_scoped_disable_interceptor_checks) |
169 | 0 | EF->__msan_scoped_disable_interceptor_checks(); |
170 | 0 | } |
171 | 0 | ~ScopedDisableMsanInterceptorChecks() { |
172 | 0 | if (EF->__msan_scoped_enable_interceptor_checks) |
173 | 0 | EF->__msan_scoped_enable_interceptor_checks(); |
174 | 0 | } |
175 | | }; |
176 | | |
177 | | } // namespace fuzzer |
178 | | |
179 | | #endif // LLVM_FUZZER_INTERNAL_H |