1*9880d681SAndroid Build Coastguard Worker //===- FuzzerLoop.cpp - Fuzzer's main loop --------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker // Fuzzer's main loop.
10*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker #include "FuzzerInternal.h"
13*9880d681SAndroid Build Coastguard Worker #include <algorithm>
14*9880d681SAndroid Build Coastguard Worker #include <cstring>
15*9880d681SAndroid Build Coastguard Worker #include <memory>
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker #if defined(__has_include)
18*9880d681SAndroid Build Coastguard Worker #if __has_include(<sanitizer / coverage_interface.h>)
19*9880d681SAndroid Build Coastguard Worker #include <sanitizer/coverage_interface.h>
20*9880d681SAndroid Build Coastguard Worker #endif
21*9880d681SAndroid Build Coastguard Worker #if __has_include(<sanitizer / lsan_interface.h>)
22*9880d681SAndroid Build Coastguard Worker #include <sanitizer/lsan_interface.h>
23*9880d681SAndroid Build Coastguard Worker #endif
24*9880d681SAndroid Build Coastguard Worker #endif
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker #define NO_SANITIZE_MEMORY
27*9880d681SAndroid Build Coastguard Worker #if defined(__has_feature)
28*9880d681SAndroid Build Coastguard Worker #if __has_feature(memory_sanitizer)
29*9880d681SAndroid Build Coastguard Worker #undef NO_SANITIZE_MEMORY
30*9880d681SAndroid Build Coastguard Worker #define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
31*9880d681SAndroid Build Coastguard Worker #endif
32*9880d681SAndroid Build Coastguard Worker #endif
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker namespace fuzzer {
35*9880d681SAndroid Build Coastguard Worker static const size_t kMaxUnitSizeToPrint = 256;
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker thread_local bool Fuzzer::IsMyThread;
38*9880d681SAndroid Build Coastguard Worker
MissingExternalApiFunction(const char * FnName)39*9880d681SAndroid Build Coastguard Worker static void MissingExternalApiFunction(const char *FnName) {
40*9880d681SAndroid Build Coastguard Worker Printf("ERROR: %s is not defined. Exiting.\n"
41*9880d681SAndroid Build Coastguard Worker "Did you use -fsanitize-coverage=... to build your code?\n",
42*9880d681SAndroid Build Coastguard Worker FnName);
43*9880d681SAndroid Build Coastguard Worker exit(1);
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker #define CHECK_EXTERNAL_FUNCTION(fn) \
47*9880d681SAndroid Build Coastguard Worker do { \
48*9880d681SAndroid Build Coastguard Worker if (!(EF->fn)) \
49*9880d681SAndroid Build Coastguard Worker MissingExternalApiFunction(#fn); \
50*9880d681SAndroid Build Coastguard Worker } while (false)
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker // Only one Fuzzer per process.
53*9880d681SAndroid Build Coastguard Worker static Fuzzer *F;
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker struct CoverageController {
Resetfuzzer::CoverageController56*9880d681SAndroid Build Coastguard Worker static void Reset() {
57*9880d681SAndroid Build Coastguard Worker CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage);
58*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_reset_coverage();
59*9880d681SAndroid Build Coastguard Worker PcMapResetCurrent();
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
ResetCountersfuzzer::CoverageController62*9880d681SAndroid Build Coastguard Worker static void ResetCounters(const FuzzingOptions &Options) {
63*9880d681SAndroid Build Coastguard Worker if (Options.UseCounters) {
64*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_update_counter_bitset_and_clear_counters(0);
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker
Preparefuzzer::CoverageController68*9880d681SAndroid Build Coastguard Worker static void Prepare(const FuzzingOptions &Options, Fuzzer::Coverage *C) {
69*9880d681SAndroid Build Coastguard Worker if (Options.UseCounters) {
70*9880d681SAndroid Build Coastguard Worker size_t NumCounters = EF->__sanitizer_get_number_of_counters();
71*9880d681SAndroid Build Coastguard Worker C->CounterBitmap.resize(NumCounters);
72*9880d681SAndroid Build Coastguard Worker }
73*9880d681SAndroid Build Coastguard Worker }
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker // Records data to a maximum coverage tracker. Returns true if additional
76*9880d681SAndroid Build Coastguard Worker // coverage was discovered.
RecordMaxfuzzer::CoverageController77*9880d681SAndroid Build Coastguard Worker static bool RecordMax(const FuzzingOptions &Options, Fuzzer::Coverage *C) {
78*9880d681SAndroid Build Coastguard Worker bool Res = false;
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();
81*9880d681SAndroid Build Coastguard Worker if (NewBlockCoverage > C->BlockCoverage) {
82*9880d681SAndroid Build Coastguard Worker Res = true;
83*9880d681SAndroid Build Coastguard Worker C->BlockCoverage = NewBlockCoverage;
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker if (Options.UseIndirCalls &&
87*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_get_total_unique_caller_callee_pairs) {
88*9880d681SAndroid Build Coastguard Worker uint64_t NewCallerCalleeCoverage =
89*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_get_total_unique_caller_callee_pairs();
90*9880d681SAndroid Build Coastguard Worker if (NewCallerCalleeCoverage > C->CallerCalleeCoverage) {
91*9880d681SAndroid Build Coastguard Worker Res = true;
92*9880d681SAndroid Build Coastguard Worker C->CallerCalleeCoverage = NewCallerCalleeCoverage;
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker if (Options.UseCounters) {
97*9880d681SAndroid Build Coastguard Worker uint64_t CounterDelta =
98*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_update_counter_bitset_and_clear_counters(
99*9880d681SAndroid Build Coastguard Worker C->CounterBitmap.data());
100*9880d681SAndroid Build Coastguard Worker if (CounterDelta > 0) {
101*9880d681SAndroid Build Coastguard Worker Res = true;
102*9880d681SAndroid Build Coastguard Worker C->CounterBitmapBits += CounterDelta;
103*9880d681SAndroid Build Coastguard Worker }
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker uint64_t NewPcMapBits = PcMapMergeInto(&C->PCMap);
107*9880d681SAndroid Build Coastguard Worker if (NewPcMapBits > C->PcMapBits) {
108*9880d681SAndroid Build Coastguard Worker Res = true;
109*9880d681SAndroid Build Coastguard Worker C->PcMapBits = NewPcMapBits;
110*9880d681SAndroid Build Coastguard Worker }
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker uintptr_t *CoverageBuf;
113*9880d681SAndroid Build Coastguard Worker uint64_t NewPcBufferLen =
114*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);
115*9880d681SAndroid Build Coastguard Worker if (NewPcBufferLen > C->PcBufferLen) {
116*9880d681SAndroid Build Coastguard Worker Res = true;
117*9880d681SAndroid Build Coastguard Worker C->PcBufferLen = NewPcBufferLen;
118*9880d681SAndroid Build Coastguard Worker }
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker return Res;
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker };
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker // Leak detection is expensive, so we first check if there were more mallocs
125*9880d681SAndroid Build Coastguard Worker // than frees (using the sanitizer malloc hooks) and only then try to call lsan.
126*9880d681SAndroid Build Coastguard Worker struct MallocFreeTracer {
Startfuzzer::MallocFreeTracer127*9880d681SAndroid Build Coastguard Worker void Start() {
128*9880d681SAndroid Build Coastguard Worker Mallocs = 0;
129*9880d681SAndroid Build Coastguard Worker Frees = 0;
130*9880d681SAndroid Build Coastguard Worker }
131*9880d681SAndroid Build Coastguard Worker // Returns true if there were more mallocs than frees.
Stopfuzzer::MallocFreeTracer132*9880d681SAndroid Build Coastguard Worker bool Stop() { return Mallocs > Frees; }
133*9880d681SAndroid Build Coastguard Worker std::atomic<size_t> Mallocs;
134*9880d681SAndroid Build Coastguard Worker std::atomic<size_t> Frees;
135*9880d681SAndroid Build Coastguard Worker };
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker static MallocFreeTracer AllocTracer;
138*9880d681SAndroid Build Coastguard Worker
MallocHook(const volatile void * ptr,size_t size)139*9880d681SAndroid Build Coastguard Worker void MallocHook(const volatile void *ptr, size_t size) {
140*9880d681SAndroid Build Coastguard Worker AllocTracer.Mallocs++;
141*9880d681SAndroid Build Coastguard Worker }
FreeHook(const volatile void * ptr)142*9880d681SAndroid Build Coastguard Worker void FreeHook(const volatile void *ptr) {
143*9880d681SAndroid Build Coastguard Worker AllocTracer.Frees++;
144*9880d681SAndroid Build Coastguard Worker }
145*9880d681SAndroid Build Coastguard Worker
Fuzzer(UserCallback CB,MutationDispatcher & MD,FuzzingOptions Options)146*9880d681SAndroid Build Coastguard Worker Fuzzer::Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options)
147*9880d681SAndroid Build Coastguard Worker : CB(CB), MD(MD), Options(Options) {
148*9880d681SAndroid Build Coastguard Worker SetDeathCallback();
149*9880d681SAndroid Build Coastguard Worker InitializeTraceState();
150*9880d681SAndroid Build Coastguard Worker assert(!F);
151*9880d681SAndroid Build Coastguard Worker F = this;
152*9880d681SAndroid Build Coastguard Worker ResetCoverage();
153*9880d681SAndroid Build Coastguard Worker IsMyThread = true;
154*9880d681SAndroid Build Coastguard Worker if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks)
155*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_install_malloc_and_free_hooks(MallocHook, FreeHook);
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker
LazyAllocateCurrentUnitData()158*9880d681SAndroid Build Coastguard Worker void Fuzzer::LazyAllocateCurrentUnitData() {
159*9880d681SAndroid Build Coastguard Worker if (CurrentUnitData || Options.MaxLen == 0) return;
160*9880d681SAndroid Build Coastguard Worker CurrentUnitData = new uint8_t[Options.MaxLen];
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
SetDeathCallback()163*9880d681SAndroid Build Coastguard Worker void Fuzzer::SetDeathCallback() {
164*9880d681SAndroid Build Coastguard Worker CHECK_EXTERNAL_FUNCTION(__sanitizer_set_death_callback);
165*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_set_death_callback(StaticDeathCallback);
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
StaticDeathCallback()168*9880d681SAndroid Build Coastguard Worker void Fuzzer::StaticDeathCallback() {
169*9880d681SAndroid Build Coastguard Worker assert(F);
170*9880d681SAndroid Build Coastguard Worker F->DeathCallback();
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker
DumpCurrentUnit(const char * Prefix)173*9880d681SAndroid Build Coastguard Worker void Fuzzer::DumpCurrentUnit(const char *Prefix) {
174*9880d681SAndroid Build Coastguard Worker if (!CurrentUnitData) return; // Happens when running individual inputs.
175*9880d681SAndroid Build Coastguard Worker size_t UnitSize = CurrentUnitSize;
176*9880d681SAndroid Build Coastguard Worker if (UnitSize <= kMaxUnitSizeToPrint) {
177*9880d681SAndroid Build Coastguard Worker PrintHexArray(CurrentUnitData, UnitSize, "\n");
178*9880d681SAndroid Build Coastguard Worker PrintASCII(CurrentUnitData, UnitSize, "\n");
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker WriteUnitToFileWithPrefix({CurrentUnitData, CurrentUnitData + UnitSize},
181*9880d681SAndroid Build Coastguard Worker Prefix);
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker NO_SANITIZE_MEMORY
DeathCallback()185*9880d681SAndroid Build Coastguard Worker void Fuzzer::DeathCallback() {
186*9880d681SAndroid Build Coastguard Worker DumpCurrentUnit("crash-");
187*9880d681SAndroid Build Coastguard Worker PrintFinalStats();
188*9880d681SAndroid Build Coastguard Worker }
189*9880d681SAndroid Build Coastguard Worker
StaticAlarmCallback()190*9880d681SAndroid Build Coastguard Worker void Fuzzer::StaticAlarmCallback() {
191*9880d681SAndroid Build Coastguard Worker assert(F);
192*9880d681SAndroid Build Coastguard Worker F->AlarmCallback();
193*9880d681SAndroid Build Coastguard Worker }
194*9880d681SAndroid Build Coastguard Worker
StaticCrashSignalCallback()195*9880d681SAndroid Build Coastguard Worker void Fuzzer::StaticCrashSignalCallback() {
196*9880d681SAndroid Build Coastguard Worker assert(F);
197*9880d681SAndroid Build Coastguard Worker F->CrashCallback();
198*9880d681SAndroid Build Coastguard Worker }
199*9880d681SAndroid Build Coastguard Worker
StaticInterruptCallback()200*9880d681SAndroid Build Coastguard Worker void Fuzzer::StaticInterruptCallback() {
201*9880d681SAndroid Build Coastguard Worker assert(F);
202*9880d681SAndroid Build Coastguard Worker F->InterruptCallback();
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker
CrashCallback()205*9880d681SAndroid Build Coastguard Worker void Fuzzer::CrashCallback() {
206*9880d681SAndroid Build Coastguard Worker Printf("==%d== ERROR: libFuzzer: deadly signal\n", GetPid());
207*9880d681SAndroid Build Coastguard Worker if (EF->__sanitizer_print_stack_trace)
208*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_print_stack_trace();
209*9880d681SAndroid Build Coastguard Worker Printf("NOTE: libFuzzer has rudimentary signal handlers.\n"
210*9880d681SAndroid Build Coastguard Worker " Combine libFuzzer with AddressSanitizer or similar for better "
211*9880d681SAndroid Build Coastguard Worker "crash reports.\n");
212*9880d681SAndroid Build Coastguard Worker Printf("SUMMARY: libFuzzer: deadly signal\n");
213*9880d681SAndroid Build Coastguard Worker DumpCurrentUnit("crash-");
214*9880d681SAndroid Build Coastguard Worker PrintFinalStats();
215*9880d681SAndroid Build Coastguard Worker exit(Options.ErrorExitCode);
216*9880d681SAndroid Build Coastguard Worker }
217*9880d681SAndroid Build Coastguard Worker
InterruptCallback()218*9880d681SAndroid Build Coastguard Worker void Fuzzer::InterruptCallback() {
219*9880d681SAndroid Build Coastguard Worker Printf("==%d== libFuzzer: run interrupted; exiting\n", GetPid());
220*9880d681SAndroid Build Coastguard Worker PrintFinalStats();
221*9880d681SAndroid Build Coastguard Worker _Exit(0); // Stop right now, don't perform any at-exit actions.
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Worker NO_SANITIZE_MEMORY
AlarmCallback()225*9880d681SAndroid Build Coastguard Worker void Fuzzer::AlarmCallback() {
226*9880d681SAndroid Build Coastguard Worker assert(Options.UnitTimeoutSec > 0);
227*9880d681SAndroid Build Coastguard Worker if (!InFuzzingThread()) return;
228*9880d681SAndroid Build Coastguard Worker if (!CurrentUnitSize)
229*9880d681SAndroid Build Coastguard Worker return; // We have not started running units yet.
230*9880d681SAndroid Build Coastguard Worker size_t Seconds =
231*9880d681SAndroid Build Coastguard Worker duration_cast<seconds>(system_clock::now() - UnitStartTime).count();
232*9880d681SAndroid Build Coastguard Worker if (Seconds == 0)
233*9880d681SAndroid Build Coastguard Worker return;
234*9880d681SAndroid Build Coastguard Worker if (Options.Verbosity >= 2)
235*9880d681SAndroid Build Coastguard Worker Printf("AlarmCallback %zd\n", Seconds);
236*9880d681SAndroid Build Coastguard Worker if (Seconds >= (size_t)Options.UnitTimeoutSec) {
237*9880d681SAndroid Build Coastguard Worker Printf("ALARM: working on the last Unit for %zd seconds\n", Seconds);
238*9880d681SAndroid Build Coastguard Worker Printf(" and the timeout value is %d (use -timeout=N to change)\n",
239*9880d681SAndroid Build Coastguard Worker Options.UnitTimeoutSec);
240*9880d681SAndroid Build Coastguard Worker DumpCurrentUnit("timeout-");
241*9880d681SAndroid Build Coastguard Worker Printf("==%d== ERROR: libFuzzer: timeout after %d seconds\n", GetPid(),
242*9880d681SAndroid Build Coastguard Worker Seconds);
243*9880d681SAndroid Build Coastguard Worker if (EF->__sanitizer_print_stack_trace)
244*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_print_stack_trace();
245*9880d681SAndroid Build Coastguard Worker Printf("SUMMARY: libFuzzer: timeout\n");
246*9880d681SAndroid Build Coastguard Worker PrintFinalStats();
247*9880d681SAndroid Build Coastguard Worker _Exit(Options.TimeoutExitCode); // Stop right now.
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker
RssLimitCallback()251*9880d681SAndroid Build Coastguard Worker void Fuzzer::RssLimitCallback() {
252*9880d681SAndroid Build Coastguard Worker Printf(
253*9880d681SAndroid Build Coastguard Worker "==%d== ERROR: libFuzzer: out-of-memory (used: %zdMb; limit: %zdMb)\n",
254*9880d681SAndroid Build Coastguard Worker GetPid(), GetPeakRSSMb(), Options.RssLimitMb);
255*9880d681SAndroid Build Coastguard Worker Printf(" To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");
256*9880d681SAndroid Build Coastguard Worker if (EF->__sanitizer_print_memory_profile)
257*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_print_memory_profile(50);
258*9880d681SAndroid Build Coastguard Worker DumpCurrentUnit("oom-");
259*9880d681SAndroid Build Coastguard Worker Printf("SUMMARY: libFuzzer: out-of-memory\n");
260*9880d681SAndroid Build Coastguard Worker PrintFinalStats();
261*9880d681SAndroid Build Coastguard Worker _Exit(Options.ErrorExitCode); // Stop right now.
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker
PrintStats(const char * Where,const char * End)264*9880d681SAndroid Build Coastguard Worker void Fuzzer::PrintStats(const char *Where, const char *End) {
265*9880d681SAndroid Build Coastguard Worker size_t ExecPerSec = execPerSec();
266*9880d681SAndroid Build Coastguard Worker if (Options.OutputCSV) {
267*9880d681SAndroid Build Coastguard Worker static bool csvHeaderPrinted = false;
268*9880d681SAndroid Build Coastguard Worker if (!csvHeaderPrinted) {
269*9880d681SAndroid Build Coastguard Worker csvHeaderPrinted = true;
270*9880d681SAndroid Build Coastguard Worker Printf("runs,block_cov,bits,cc_cov,corpus,execs_per_sec,tbms,reason\n");
271*9880d681SAndroid Build Coastguard Worker }
272*9880d681SAndroid Build Coastguard Worker Printf("%zd,%zd,%zd,%zd,%zd,%zd,%s\n", TotalNumberOfRuns,
273*9880d681SAndroid Build Coastguard Worker MaxCoverage.BlockCoverage, MaxCoverage.CounterBitmapBits,
274*9880d681SAndroid Build Coastguard Worker MaxCoverage.CallerCalleeCoverage, Corpus.size(), ExecPerSec, Where);
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker if (!Options.Verbosity)
278*9880d681SAndroid Build Coastguard Worker return;
279*9880d681SAndroid Build Coastguard Worker Printf("#%zd\t%s", TotalNumberOfRuns, Where);
280*9880d681SAndroid Build Coastguard Worker if (MaxCoverage.BlockCoverage)
281*9880d681SAndroid Build Coastguard Worker Printf(" cov: %zd", MaxCoverage.BlockCoverage);
282*9880d681SAndroid Build Coastguard Worker if (MaxCoverage.PcMapBits)
283*9880d681SAndroid Build Coastguard Worker Printf(" path: %zd", MaxCoverage.PcMapBits);
284*9880d681SAndroid Build Coastguard Worker if (auto TB = MaxCoverage.CounterBitmapBits)
285*9880d681SAndroid Build Coastguard Worker Printf(" bits: %zd", TB);
286*9880d681SAndroid Build Coastguard Worker if (MaxCoverage.CallerCalleeCoverage)
287*9880d681SAndroid Build Coastguard Worker Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);
288*9880d681SAndroid Build Coastguard Worker Printf(" units: %zd exec/s: %zd", Corpus.size(), ExecPerSec);
289*9880d681SAndroid Build Coastguard Worker Printf("%s", End);
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker
PrintFinalStats()292*9880d681SAndroid Build Coastguard Worker void Fuzzer::PrintFinalStats() {
293*9880d681SAndroid Build Coastguard Worker if (!Options.PrintFinalStats) return;
294*9880d681SAndroid Build Coastguard Worker size_t ExecPerSec = execPerSec();
295*9880d681SAndroid Build Coastguard Worker Printf("stat::number_of_executed_units: %zd\n", TotalNumberOfRuns);
296*9880d681SAndroid Build Coastguard Worker Printf("stat::average_exec_per_sec: %zd\n", ExecPerSec);
297*9880d681SAndroid Build Coastguard Worker Printf("stat::new_units_added: %zd\n", NumberOfNewUnitsAdded);
298*9880d681SAndroid Build Coastguard Worker Printf("stat::slowest_unit_time_sec: %zd\n", TimeOfLongestUnitInSeconds);
299*9880d681SAndroid Build Coastguard Worker Printf("stat::peak_rss_mb: %zd\n", GetPeakRSSMb());
300*9880d681SAndroid Build Coastguard Worker }
301*9880d681SAndroid Build Coastguard Worker
MaxUnitSizeInCorpus() const302*9880d681SAndroid Build Coastguard Worker size_t Fuzzer::MaxUnitSizeInCorpus() const {
303*9880d681SAndroid Build Coastguard Worker size_t Res = 0;
304*9880d681SAndroid Build Coastguard Worker for (auto &X : Corpus)
305*9880d681SAndroid Build Coastguard Worker Res = std::max(Res, X.size());
306*9880d681SAndroid Build Coastguard Worker return Res;
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker
SetMaxLen(size_t MaxLen)309*9880d681SAndroid Build Coastguard Worker void Fuzzer::SetMaxLen(size_t MaxLen) {
310*9880d681SAndroid Build Coastguard Worker assert(Options.MaxLen == 0); // Can only reset MaxLen from 0 to non-0.
311*9880d681SAndroid Build Coastguard Worker assert(MaxLen);
312*9880d681SAndroid Build Coastguard Worker Options.MaxLen = MaxLen;
313*9880d681SAndroid Build Coastguard Worker Printf("INFO: -max_len is not provided, using %zd\n", Options.MaxLen);
314*9880d681SAndroid Build Coastguard Worker }
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker
RereadOutputCorpus(size_t MaxSize)317*9880d681SAndroid Build Coastguard Worker void Fuzzer::RereadOutputCorpus(size_t MaxSize) {
318*9880d681SAndroid Build Coastguard Worker if (Options.OutputCorpus.empty())
319*9880d681SAndroid Build Coastguard Worker return;
320*9880d681SAndroid Build Coastguard Worker std::vector<Unit> AdditionalCorpus;
321*9880d681SAndroid Build Coastguard Worker ReadDirToVectorOfUnits(Options.OutputCorpus.c_str(), &AdditionalCorpus,
322*9880d681SAndroid Build Coastguard Worker &EpochOfLastReadOfOutputCorpus, MaxSize);
323*9880d681SAndroid Build Coastguard Worker if (Corpus.empty()) {
324*9880d681SAndroid Build Coastguard Worker Corpus = AdditionalCorpus;
325*9880d681SAndroid Build Coastguard Worker return;
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker if (!Options.Reload)
328*9880d681SAndroid Build Coastguard Worker return;
329*9880d681SAndroid Build Coastguard Worker if (Options.Verbosity >= 2)
330*9880d681SAndroid Build Coastguard Worker Printf("Reload: read %zd new units.\n", AdditionalCorpus.size());
331*9880d681SAndroid Build Coastguard Worker for (auto &X : AdditionalCorpus) {
332*9880d681SAndroid Build Coastguard Worker if (X.size() > MaxSize)
333*9880d681SAndroid Build Coastguard Worker X.resize(MaxSize);
334*9880d681SAndroid Build Coastguard Worker if (UnitHashesAddedToCorpus.insert(Hash(X)).second) {
335*9880d681SAndroid Build Coastguard Worker if (RunOne(X)) {
336*9880d681SAndroid Build Coastguard Worker Corpus.push_back(X);
337*9880d681SAndroid Build Coastguard Worker UpdateCorpusDistribution();
338*9880d681SAndroid Build Coastguard Worker PrintStats("RELOAD");
339*9880d681SAndroid Build Coastguard Worker }
340*9880d681SAndroid Build Coastguard Worker }
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker }
343*9880d681SAndroid Build Coastguard Worker
ShuffleCorpus(UnitVector * V)344*9880d681SAndroid Build Coastguard Worker void Fuzzer::ShuffleCorpus(UnitVector *V) {
345*9880d681SAndroid Build Coastguard Worker std::random_shuffle(V->begin(), V->end(), MD.GetRand());
346*9880d681SAndroid Build Coastguard Worker if (Options.PreferSmall)
347*9880d681SAndroid Build Coastguard Worker std::stable_sort(V->begin(), V->end(), [](const Unit &A, const Unit &B) {
348*9880d681SAndroid Build Coastguard Worker return A.size() < B.size();
349*9880d681SAndroid Build Coastguard Worker });
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker // Tries random prefixes of corpus items.
TruncateUnits(std::vector<Unit> * NewCorpus)353*9880d681SAndroid Build Coastguard Worker void Fuzzer::TruncateUnits(std::vector<Unit> *NewCorpus) {
354*9880d681SAndroid Build Coastguard Worker std::vector<double> Fractions = {0.25, 0.5, 0.75, 1.0};
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker size_t TruncInputs = 0;
357*9880d681SAndroid Build Coastguard Worker for (double Fraction : Fractions) {
358*9880d681SAndroid Build Coastguard Worker for (const auto &U : Corpus) {
359*9880d681SAndroid Build Coastguard Worker uint64_t S = MD.GetRand()(U.size() * Fraction);
360*9880d681SAndroid Build Coastguard Worker if (!S || !RunOne(U.data(), S))
361*9880d681SAndroid Build Coastguard Worker continue;
362*9880d681SAndroid Build Coastguard Worker TruncInputs++;
363*9880d681SAndroid Build Coastguard Worker Unit U1(U.begin(), U.begin() + S);
364*9880d681SAndroid Build Coastguard Worker NewCorpus->push_back(U1);
365*9880d681SAndroid Build Coastguard Worker }
366*9880d681SAndroid Build Coastguard Worker }
367*9880d681SAndroid Build Coastguard Worker if (TruncInputs)
368*9880d681SAndroid Build Coastguard Worker Printf("\tINFO TRUNC %zd units added to in-memory corpus\n", TruncInputs);
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
ShuffleAndMinimize()371*9880d681SAndroid Build Coastguard Worker void Fuzzer::ShuffleAndMinimize() {
372*9880d681SAndroid Build Coastguard Worker PrintStats("READ ");
373*9880d681SAndroid Build Coastguard Worker std::vector<Unit> NewCorpus;
374*9880d681SAndroid Build Coastguard Worker if (Options.ShuffleAtStartUp)
375*9880d681SAndroid Build Coastguard Worker ShuffleCorpus(&Corpus);
376*9880d681SAndroid Build Coastguard Worker
377*9880d681SAndroid Build Coastguard Worker if (Options.TruncateUnits) {
378*9880d681SAndroid Build Coastguard Worker ResetCoverage();
379*9880d681SAndroid Build Coastguard Worker TruncateUnits(&NewCorpus);
380*9880d681SAndroid Build Coastguard Worker ResetCoverage();
381*9880d681SAndroid Build Coastguard Worker }
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Worker for (const auto &U : Corpus) {
384*9880d681SAndroid Build Coastguard Worker bool NewCoverage = RunOne(U);
385*9880d681SAndroid Build Coastguard Worker if (!Options.PruneCorpus || NewCoverage) {
386*9880d681SAndroid Build Coastguard Worker NewCorpus.push_back(U);
387*9880d681SAndroid Build Coastguard Worker if (Options.Verbosity >= 2)
388*9880d681SAndroid Build Coastguard Worker Printf("NEW0: %zd L %zd\n", MaxCoverage.BlockCoverage, U.size());
389*9880d681SAndroid Build Coastguard Worker }
390*9880d681SAndroid Build Coastguard Worker TryDetectingAMemoryLeak(U.data(), U.size(),
391*9880d681SAndroid Build Coastguard Worker /*DuringInitialCorpusExecution*/ true);
392*9880d681SAndroid Build Coastguard Worker }
393*9880d681SAndroid Build Coastguard Worker Corpus = NewCorpus;
394*9880d681SAndroid Build Coastguard Worker UpdateCorpusDistribution();
395*9880d681SAndroid Build Coastguard Worker for (auto &X : Corpus)
396*9880d681SAndroid Build Coastguard Worker UnitHashesAddedToCorpus.insert(Hash(X));
397*9880d681SAndroid Build Coastguard Worker PrintStats("INITED");
398*9880d681SAndroid Build Coastguard Worker if (Corpus.empty()) {
399*9880d681SAndroid Build Coastguard Worker Printf("ERROR: no interesting inputs were found. "
400*9880d681SAndroid Build Coastguard Worker "Is the code instrumented for coverage? Exiting.\n");
401*9880d681SAndroid Build Coastguard Worker exit(1);
402*9880d681SAndroid Build Coastguard Worker }
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker
UpdateMaxCoverage()405*9880d681SAndroid Build Coastguard Worker bool Fuzzer::UpdateMaxCoverage() {
406*9880d681SAndroid Build Coastguard Worker uintptr_t PrevBufferLen = MaxCoverage.PcBufferLen;
407*9880d681SAndroid Build Coastguard Worker bool Res = CoverageController::RecordMax(Options, &MaxCoverage);
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Worker if (Options.PrintNewCovPcs && PrevBufferLen != MaxCoverage.PcBufferLen) {
410*9880d681SAndroid Build Coastguard Worker uintptr_t *CoverageBuf;
411*9880d681SAndroid Build Coastguard Worker EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);
412*9880d681SAndroid Build Coastguard Worker assert(CoverageBuf);
413*9880d681SAndroid Build Coastguard Worker for (size_t I = PrevBufferLen; I < MaxCoverage.PcBufferLen; ++I) {
414*9880d681SAndroid Build Coastguard Worker Printf("%p\n", CoverageBuf[I]);
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker }
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker return Res;
419*9880d681SAndroid Build Coastguard Worker }
420*9880d681SAndroid Build Coastguard Worker
RunOne(const uint8_t * Data,size_t Size)421*9880d681SAndroid Build Coastguard Worker bool Fuzzer::RunOne(const uint8_t *Data, size_t Size) {
422*9880d681SAndroid Build Coastguard Worker TotalNumberOfRuns++;
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker // TODO(aizatsky): this Reset call seems to be not needed.
425*9880d681SAndroid Build Coastguard Worker CoverageController::ResetCounters(Options);
426*9880d681SAndroid Build Coastguard Worker ExecuteCallback(Data, Size);
427*9880d681SAndroid Build Coastguard Worker bool Res = UpdateMaxCoverage();
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Worker auto UnitStopTime = system_clock::now();
430*9880d681SAndroid Build Coastguard Worker auto TimeOfUnit =
431*9880d681SAndroid Build Coastguard Worker duration_cast<seconds>(UnitStopTime - UnitStartTime).count();
432*9880d681SAndroid Build Coastguard Worker if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&
433*9880d681SAndroid Build Coastguard Worker secondsSinceProcessStartUp() >= 2)
434*9880d681SAndroid Build Coastguard Worker PrintStats("pulse ");
435*9880d681SAndroid Build Coastguard Worker if (TimeOfUnit > TimeOfLongestUnitInSeconds &&
436*9880d681SAndroid Build Coastguard Worker TimeOfUnit >= Options.ReportSlowUnits) {
437*9880d681SAndroid Build Coastguard Worker TimeOfLongestUnitInSeconds = TimeOfUnit;
438*9880d681SAndroid Build Coastguard Worker Printf("Slowest unit: %zd s:\n", TimeOfLongestUnitInSeconds);
439*9880d681SAndroid Build Coastguard Worker WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-");
440*9880d681SAndroid Build Coastguard Worker }
441*9880d681SAndroid Build Coastguard Worker return Res;
442*9880d681SAndroid Build Coastguard Worker }
443*9880d681SAndroid Build Coastguard Worker
RunOneAndUpdateCorpus(const uint8_t * Data,size_t Size)444*9880d681SAndroid Build Coastguard Worker void Fuzzer::RunOneAndUpdateCorpus(const uint8_t *Data, size_t Size) {
445*9880d681SAndroid Build Coastguard Worker if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
446*9880d681SAndroid Build Coastguard Worker return;
447*9880d681SAndroid Build Coastguard Worker if (RunOne(Data, Size))
448*9880d681SAndroid Build Coastguard Worker ReportNewCoverage({Data, Data + Size});
449*9880d681SAndroid Build Coastguard Worker }
450*9880d681SAndroid Build Coastguard Worker
GetCurrentUnitInFuzzingThead(const uint8_t ** Data) const451*9880d681SAndroid Build Coastguard Worker size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
452*9880d681SAndroid Build Coastguard Worker assert(InFuzzingThread());
453*9880d681SAndroid Build Coastguard Worker *Data = CurrentUnitData;
454*9880d681SAndroid Build Coastguard Worker return CurrentUnitSize;
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker
ExecuteCallback(const uint8_t * Data,size_t Size)457*9880d681SAndroid Build Coastguard Worker void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
458*9880d681SAndroid Build Coastguard Worker assert(InFuzzingThread());
459*9880d681SAndroid Build Coastguard Worker LazyAllocateCurrentUnitData();
460*9880d681SAndroid Build Coastguard Worker UnitStartTime = system_clock::now();
461*9880d681SAndroid Build Coastguard Worker // We copy the contents of Unit into a separate heap buffer
462*9880d681SAndroid Build Coastguard Worker // so that we reliably find buffer overflows in it.
463*9880d681SAndroid Build Coastguard Worker std::unique_ptr<uint8_t[]> DataCopy(new uint8_t[Size]);
464*9880d681SAndroid Build Coastguard Worker memcpy(DataCopy.get(), Data, Size);
465*9880d681SAndroid Build Coastguard Worker if (CurrentUnitData && CurrentUnitData != Data)
466*9880d681SAndroid Build Coastguard Worker memcpy(CurrentUnitData, Data, Size);
467*9880d681SAndroid Build Coastguard Worker AssignTaintLabels(DataCopy.get(), Size);
468*9880d681SAndroid Build Coastguard Worker CurrentUnitSize = Size;
469*9880d681SAndroid Build Coastguard Worker AllocTracer.Start();
470*9880d681SAndroid Build Coastguard Worker int Res = CB(DataCopy.get(), Size);
471*9880d681SAndroid Build Coastguard Worker (void)Res;
472*9880d681SAndroid Build Coastguard Worker HasMoreMallocsThanFrees = AllocTracer.Stop();
473*9880d681SAndroid Build Coastguard Worker CurrentUnitSize = 0;
474*9880d681SAndroid Build Coastguard Worker assert(Res == 0);
475*9880d681SAndroid Build Coastguard Worker }
476*9880d681SAndroid Build Coastguard Worker
DebugString() const477*9880d681SAndroid Build Coastguard Worker std::string Fuzzer::Coverage::DebugString() const {
478*9880d681SAndroid Build Coastguard Worker std::string Result =
479*9880d681SAndroid Build Coastguard Worker std::string("Coverage{") + "BlockCoverage=" +
480*9880d681SAndroid Build Coastguard Worker std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
481*9880d681SAndroid Build Coastguard Worker std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
482*9880d681SAndroid Build Coastguard Worker std::to_string(CounterBitmapBits) + " PcMapBits=" +
483*9880d681SAndroid Build Coastguard Worker std::to_string(PcMapBits) + "}";
484*9880d681SAndroid Build Coastguard Worker return Result;
485*9880d681SAndroid Build Coastguard Worker }
486*9880d681SAndroid Build Coastguard Worker
WriteToOutputCorpus(const Unit & U)487*9880d681SAndroid Build Coastguard Worker void Fuzzer::WriteToOutputCorpus(const Unit &U) {
488*9880d681SAndroid Build Coastguard Worker if (Options.OnlyASCII)
489*9880d681SAndroid Build Coastguard Worker assert(IsASCII(U));
490*9880d681SAndroid Build Coastguard Worker if (Options.OutputCorpus.empty())
491*9880d681SAndroid Build Coastguard Worker return;
492*9880d681SAndroid Build Coastguard Worker std::string Path = DirPlusFile(Options.OutputCorpus, Hash(U));
493*9880d681SAndroid Build Coastguard Worker WriteToFile(U, Path);
494*9880d681SAndroid Build Coastguard Worker if (Options.Verbosity >= 2)
495*9880d681SAndroid Build Coastguard Worker Printf("Written to %s\n", Path.c_str());
496*9880d681SAndroid Build Coastguard Worker }
497*9880d681SAndroid Build Coastguard Worker
WriteUnitToFileWithPrefix(const Unit & U,const char * Prefix)498*9880d681SAndroid Build Coastguard Worker void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
499*9880d681SAndroid Build Coastguard Worker if (!Options.SaveArtifacts)
500*9880d681SAndroid Build Coastguard Worker return;
501*9880d681SAndroid Build Coastguard Worker std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);
502*9880d681SAndroid Build Coastguard Worker if (!Options.ExactArtifactPath.empty())
503*9880d681SAndroid Build Coastguard Worker Path = Options.ExactArtifactPath; // Overrides ArtifactPrefix.
504*9880d681SAndroid Build Coastguard Worker WriteToFile(U, Path);
505*9880d681SAndroid Build Coastguard Worker Printf("artifact_prefix='%s'; Test unit written to %s\n",
506*9880d681SAndroid Build Coastguard Worker Options.ArtifactPrefix.c_str(), Path.c_str());
507*9880d681SAndroid Build Coastguard Worker if (U.size() <= kMaxUnitSizeToPrint)
508*9880d681SAndroid Build Coastguard Worker Printf("Base64: %s\n", Base64(U).c_str());
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker
SaveCorpus()511*9880d681SAndroid Build Coastguard Worker void Fuzzer::SaveCorpus() {
512*9880d681SAndroid Build Coastguard Worker if (Options.OutputCorpus.empty())
513*9880d681SAndroid Build Coastguard Worker return;
514*9880d681SAndroid Build Coastguard Worker for (const auto &U : Corpus)
515*9880d681SAndroid Build Coastguard Worker WriteToFile(U, DirPlusFile(Options.OutputCorpus, Hash(U)));
516*9880d681SAndroid Build Coastguard Worker if (Options.Verbosity)
517*9880d681SAndroid Build Coastguard Worker Printf("Written corpus of %zd files to %s\n", Corpus.size(),
518*9880d681SAndroid Build Coastguard Worker Options.OutputCorpus.c_str());
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker
PrintStatusForNewUnit(const Unit & U)521*9880d681SAndroid Build Coastguard Worker void Fuzzer::PrintStatusForNewUnit(const Unit &U) {
522*9880d681SAndroid Build Coastguard Worker if (!Options.PrintNEW)
523*9880d681SAndroid Build Coastguard Worker return;
524*9880d681SAndroid Build Coastguard Worker PrintStats("NEW ", "");
525*9880d681SAndroid Build Coastguard Worker if (Options.Verbosity) {
526*9880d681SAndroid Build Coastguard Worker Printf(" L: %zd ", U.size());
527*9880d681SAndroid Build Coastguard Worker MD.PrintMutationSequence();
528*9880d681SAndroid Build Coastguard Worker Printf("\n");
529*9880d681SAndroid Build Coastguard Worker }
530*9880d681SAndroid Build Coastguard Worker }
531*9880d681SAndroid Build Coastguard Worker
ReportNewCoverage(const Unit & U)532*9880d681SAndroid Build Coastguard Worker void Fuzzer::ReportNewCoverage(const Unit &U) {
533*9880d681SAndroid Build Coastguard Worker Corpus.push_back(U);
534*9880d681SAndroid Build Coastguard Worker UpdateCorpusDistribution();
535*9880d681SAndroid Build Coastguard Worker UnitHashesAddedToCorpus.insert(Hash(U));
536*9880d681SAndroid Build Coastguard Worker MD.RecordSuccessfulMutationSequence();
537*9880d681SAndroid Build Coastguard Worker PrintStatusForNewUnit(U);
538*9880d681SAndroid Build Coastguard Worker WriteToOutputCorpus(U);
539*9880d681SAndroid Build Coastguard Worker NumberOfNewUnitsAdded++;
540*9880d681SAndroid Build Coastguard Worker }
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker // Finds minimal number of units in 'Extra' that add coverage to 'Initial'.
543*9880d681SAndroid Build Coastguard Worker // We do it by actually executing the units, sometimes more than once,
544*9880d681SAndroid Build Coastguard Worker // because we may be using different coverage-like signals and the only
545*9880d681SAndroid Build Coastguard Worker // common thing between them is that we can say "this unit found new stuff".
FindExtraUnits(const UnitVector & Initial,const UnitVector & Extra)546*9880d681SAndroid Build Coastguard Worker UnitVector Fuzzer::FindExtraUnits(const UnitVector &Initial,
547*9880d681SAndroid Build Coastguard Worker const UnitVector &Extra) {
548*9880d681SAndroid Build Coastguard Worker UnitVector Res = Extra;
549*9880d681SAndroid Build Coastguard Worker size_t OldSize = Res.size();
550*9880d681SAndroid Build Coastguard Worker for (int Iter = 0; Iter < 10; Iter++) {
551*9880d681SAndroid Build Coastguard Worker ShuffleCorpus(&Res);
552*9880d681SAndroid Build Coastguard Worker ResetCoverage();
553*9880d681SAndroid Build Coastguard Worker
554*9880d681SAndroid Build Coastguard Worker for (auto &U : Initial)
555*9880d681SAndroid Build Coastguard Worker RunOne(U);
556*9880d681SAndroid Build Coastguard Worker
557*9880d681SAndroid Build Coastguard Worker Corpus.clear();
558*9880d681SAndroid Build Coastguard Worker for (auto &U : Res)
559*9880d681SAndroid Build Coastguard Worker if (RunOne(U))
560*9880d681SAndroid Build Coastguard Worker Corpus.push_back(U);
561*9880d681SAndroid Build Coastguard Worker
562*9880d681SAndroid Build Coastguard Worker char Stat[7] = "MIN ";
563*9880d681SAndroid Build Coastguard Worker Stat[3] = '0' + Iter;
564*9880d681SAndroid Build Coastguard Worker PrintStats(Stat);
565*9880d681SAndroid Build Coastguard Worker
566*9880d681SAndroid Build Coastguard Worker size_t NewSize = Corpus.size();
567*9880d681SAndroid Build Coastguard Worker assert(NewSize <= OldSize);
568*9880d681SAndroid Build Coastguard Worker Res.swap(Corpus);
569*9880d681SAndroid Build Coastguard Worker
570*9880d681SAndroid Build Coastguard Worker if (NewSize + 5 >= OldSize)
571*9880d681SAndroid Build Coastguard Worker break;
572*9880d681SAndroid Build Coastguard Worker OldSize = NewSize;
573*9880d681SAndroid Build Coastguard Worker }
574*9880d681SAndroid Build Coastguard Worker return Res;
575*9880d681SAndroid Build Coastguard Worker }
576*9880d681SAndroid Build Coastguard Worker
Merge(const std::vector<std::string> & Corpora)577*9880d681SAndroid Build Coastguard Worker void Fuzzer::Merge(const std::vector<std::string> &Corpora) {
578*9880d681SAndroid Build Coastguard Worker if (Corpora.size() <= 1) {
579*9880d681SAndroid Build Coastguard Worker Printf("Merge requires two or more corpus dirs\n");
580*9880d681SAndroid Build Coastguard Worker return;
581*9880d681SAndroid Build Coastguard Worker }
582*9880d681SAndroid Build Coastguard Worker std::vector<std::string> ExtraCorpora(Corpora.begin() + 1, Corpora.end());
583*9880d681SAndroid Build Coastguard Worker
584*9880d681SAndroid Build Coastguard Worker assert(Options.MaxLen > 0);
585*9880d681SAndroid Build Coastguard Worker UnitVector Initial, Extra;
586*9880d681SAndroid Build Coastguard Worker ReadDirToVectorOfUnits(Corpora[0].c_str(), &Initial, nullptr, Options.MaxLen);
587*9880d681SAndroid Build Coastguard Worker for (auto &C : ExtraCorpora)
588*9880d681SAndroid Build Coastguard Worker ReadDirToVectorOfUnits(C.c_str(), &Extra, nullptr, Options.MaxLen);
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker if (!Initial.empty()) {
591*9880d681SAndroid Build Coastguard Worker Printf("=== Minimizing the initial corpus of %zd units\n", Initial.size());
592*9880d681SAndroid Build Coastguard Worker Initial = FindExtraUnits({}, Initial);
593*9880d681SAndroid Build Coastguard Worker }
594*9880d681SAndroid Build Coastguard Worker
595*9880d681SAndroid Build Coastguard Worker Printf("=== Merging extra %zd units\n", Extra.size());
596*9880d681SAndroid Build Coastguard Worker auto Res = FindExtraUnits(Initial, Extra);
597*9880d681SAndroid Build Coastguard Worker
598*9880d681SAndroid Build Coastguard Worker for (auto &U: Res)
599*9880d681SAndroid Build Coastguard Worker WriteToOutputCorpus(U);
600*9880d681SAndroid Build Coastguard Worker
601*9880d681SAndroid Build Coastguard Worker Printf("=== Merge: written %zd units\n", Res.size());
602*9880d681SAndroid Build Coastguard Worker }
603*9880d681SAndroid Build Coastguard Worker
604*9880d681SAndroid Build Coastguard Worker // Tries detecting a memory leak on the particular input that we have just
605*9880d681SAndroid Build Coastguard Worker // executed before calling this function.
TryDetectingAMemoryLeak(const uint8_t * Data,size_t Size,bool DuringInitialCorpusExecution)606*9880d681SAndroid Build Coastguard Worker void Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
607*9880d681SAndroid Build Coastguard Worker bool DuringInitialCorpusExecution) {
608*9880d681SAndroid Build Coastguard Worker if (!HasMoreMallocsThanFrees) return; // mallocs==frees, a leak is unlikely.
609*9880d681SAndroid Build Coastguard Worker if (!Options.DetectLeaks) return;
610*9880d681SAndroid Build Coastguard Worker if (!&(EF->__lsan_enable) || !&(EF->__lsan_disable) ||
611*9880d681SAndroid Build Coastguard Worker !(EF->__lsan_do_recoverable_leak_check))
612*9880d681SAndroid Build Coastguard Worker return; // No lsan.
613*9880d681SAndroid Build Coastguard Worker // Run the target once again, but with lsan disabled so that if there is
614*9880d681SAndroid Build Coastguard Worker // a real leak we do not report it twice.
615*9880d681SAndroid Build Coastguard Worker EF->__lsan_disable();
616*9880d681SAndroid Build Coastguard Worker RunOne(Data, Size);
617*9880d681SAndroid Build Coastguard Worker EF->__lsan_enable();
618*9880d681SAndroid Build Coastguard Worker if (!HasMoreMallocsThanFrees) return; // a leak is unlikely.
619*9880d681SAndroid Build Coastguard Worker if (NumberOfLeakDetectionAttempts++ > 1000) {
620*9880d681SAndroid Build Coastguard Worker Options.DetectLeaks = false;
621*9880d681SAndroid Build Coastguard Worker Printf("INFO: libFuzzer disabled leak detection after every mutation.\n"
622*9880d681SAndroid Build Coastguard Worker " Most likely the target function accumulates allocated\n"
623*9880d681SAndroid Build Coastguard Worker " memory in a global state w/o actually leaking it.\n"
624*9880d681SAndroid Build Coastguard Worker " If LeakSanitizer is enabled in this process it will still\n"
625*9880d681SAndroid Build Coastguard Worker " run on the process shutdown.\n");
626*9880d681SAndroid Build Coastguard Worker return;
627*9880d681SAndroid Build Coastguard Worker }
628*9880d681SAndroid Build Coastguard Worker // Now perform the actual lsan pass. This is expensive and we must ensure
629*9880d681SAndroid Build Coastguard Worker // we don't call it too often.
630*9880d681SAndroid Build Coastguard Worker if (EF->__lsan_do_recoverable_leak_check()) { // Leak is found, report it.
631*9880d681SAndroid Build Coastguard Worker if (DuringInitialCorpusExecution)
632*9880d681SAndroid Build Coastguard Worker Printf("\nINFO: a leak has been found in the initial corpus.\n\n");
633*9880d681SAndroid Build Coastguard Worker Printf("INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.\n\n");
634*9880d681SAndroid Build Coastguard Worker CurrentUnitSize = Size;
635*9880d681SAndroid Build Coastguard Worker DumpCurrentUnit("leak-");
636*9880d681SAndroid Build Coastguard Worker PrintFinalStats();
637*9880d681SAndroid Build Coastguard Worker _Exit(Options.ErrorExitCode); // not exit() to disable lsan further on.
638*9880d681SAndroid Build Coastguard Worker }
639*9880d681SAndroid Build Coastguard Worker }
640*9880d681SAndroid Build Coastguard Worker
MutateAndTestOne()641*9880d681SAndroid Build Coastguard Worker void Fuzzer::MutateAndTestOne() {
642*9880d681SAndroid Build Coastguard Worker LazyAllocateCurrentUnitData();
643*9880d681SAndroid Build Coastguard Worker MD.StartMutationSequence();
644*9880d681SAndroid Build Coastguard Worker
645*9880d681SAndroid Build Coastguard Worker auto &U = ChooseUnitToMutate();
646*9880d681SAndroid Build Coastguard Worker assert(CurrentUnitData);
647*9880d681SAndroid Build Coastguard Worker size_t Size = U.size();
648*9880d681SAndroid Build Coastguard Worker assert(Size <= Options.MaxLen && "Oversized Unit");
649*9880d681SAndroid Build Coastguard Worker memcpy(CurrentUnitData, U.data(), Size);
650*9880d681SAndroid Build Coastguard Worker
651*9880d681SAndroid Build Coastguard Worker for (int i = 0; i < Options.MutateDepth; i++) {
652*9880d681SAndroid Build Coastguard Worker size_t NewSize = 0;
653*9880d681SAndroid Build Coastguard Worker NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
654*9880d681SAndroid Build Coastguard Worker assert(NewSize > 0 && "Mutator returned empty unit");
655*9880d681SAndroid Build Coastguard Worker assert(NewSize <= Options.MaxLen &&
656*9880d681SAndroid Build Coastguard Worker "Mutator return overisized unit");
657*9880d681SAndroid Build Coastguard Worker Size = NewSize;
658*9880d681SAndroid Build Coastguard Worker if (i == 0)
659*9880d681SAndroid Build Coastguard Worker StartTraceRecording();
660*9880d681SAndroid Build Coastguard Worker RunOneAndUpdateCorpus(CurrentUnitData, Size);
661*9880d681SAndroid Build Coastguard Worker StopTraceRecording();
662*9880d681SAndroid Build Coastguard Worker TryDetectingAMemoryLeak(CurrentUnitData, Size,
663*9880d681SAndroid Build Coastguard Worker /*DuringInitialCorpusExecution*/ false);
664*9880d681SAndroid Build Coastguard Worker }
665*9880d681SAndroid Build Coastguard Worker }
666*9880d681SAndroid Build Coastguard Worker
667*9880d681SAndroid Build Coastguard Worker // Returns an index of random unit from the corpus to mutate.
668*9880d681SAndroid Build Coastguard Worker // Hypothesis: units added to the corpus last are more likely to be interesting.
669*9880d681SAndroid Build Coastguard Worker // This function gives more weight to the more recent units.
ChooseUnitIdxToMutate()670*9880d681SAndroid Build Coastguard Worker size_t Fuzzer::ChooseUnitIdxToMutate() {
671*9880d681SAndroid Build Coastguard Worker size_t Idx =
672*9880d681SAndroid Build Coastguard Worker static_cast<size_t>(CorpusDistribution(MD.GetRand().Get_mt19937()));
673*9880d681SAndroid Build Coastguard Worker assert(Idx < Corpus.size());
674*9880d681SAndroid Build Coastguard Worker return Idx;
675*9880d681SAndroid Build Coastguard Worker }
676*9880d681SAndroid Build Coastguard Worker
ResetCoverage()677*9880d681SAndroid Build Coastguard Worker void Fuzzer::ResetCoverage() {
678*9880d681SAndroid Build Coastguard Worker CoverageController::Reset();
679*9880d681SAndroid Build Coastguard Worker MaxCoverage.Reset();
680*9880d681SAndroid Build Coastguard Worker CoverageController::Prepare(Options, &MaxCoverage);
681*9880d681SAndroid Build Coastguard Worker }
682*9880d681SAndroid Build Coastguard Worker
683*9880d681SAndroid Build Coastguard Worker // Experimental search heuristic: drilling.
684*9880d681SAndroid Build Coastguard Worker // - Read, shuffle, execute and minimize the corpus.
685*9880d681SAndroid Build Coastguard Worker // - Choose one random unit.
686*9880d681SAndroid Build Coastguard Worker // - Reset the coverage.
687*9880d681SAndroid Build Coastguard Worker // - Start fuzzing as if the chosen unit was the only element of the corpus.
688*9880d681SAndroid Build Coastguard Worker // - When done, reset the coverage again.
689*9880d681SAndroid Build Coastguard Worker // - Merge the newly created corpus into the original one.
Drill()690*9880d681SAndroid Build Coastguard Worker void Fuzzer::Drill() {
691*9880d681SAndroid Build Coastguard Worker // The corpus is already read, shuffled, and minimized.
692*9880d681SAndroid Build Coastguard Worker assert(!Corpus.empty());
693*9880d681SAndroid Build Coastguard Worker Options.PrintNEW = false; // Don't print NEW status lines when drilling.
694*9880d681SAndroid Build Coastguard Worker
695*9880d681SAndroid Build Coastguard Worker Unit U = ChooseUnitToMutate();
696*9880d681SAndroid Build Coastguard Worker
697*9880d681SAndroid Build Coastguard Worker ResetCoverage();
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker std::vector<Unit> SavedCorpus;
700*9880d681SAndroid Build Coastguard Worker SavedCorpus.swap(Corpus);
701*9880d681SAndroid Build Coastguard Worker Corpus.push_back(U);
702*9880d681SAndroid Build Coastguard Worker UpdateCorpusDistribution();
703*9880d681SAndroid Build Coastguard Worker assert(Corpus.size() == 1);
704*9880d681SAndroid Build Coastguard Worker RunOne(U);
705*9880d681SAndroid Build Coastguard Worker PrintStats("DRILL ");
706*9880d681SAndroid Build Coastguard Worker std::string SavedOutputCorpusPath; // Don't write new units while drilling.
707*9880d681SAndroid Build Coastguard Worker SavedOutputCorpusPath.swap(Options.OutputCorpus);
708*9880d681SAndroid Build Coastguard Worker Loop();
709*9880d681SAndroid Build Coastguard Worker
710*9880d681SAndroid Build Coastguard Worker ResetCoverage();
711*9880d681SAndroid Build Coastguard Worker
712*9880d681SAndroid Build Coastguard Worker PrintStats("REINIT");
713*9880d681SAndroid Build Coastguard Worker SavedOutputCorpusPath.swap(Options.OutputCorpus);
714*9880d681SAndroid Build Coastguard Worker for (auto &U : SavedCorpus)
715*9880d681SAndroid Build Coastguard Worker RunOne(U);
716*9880d681SAndroid Build Coastguard Worker PrintStats("MERGE ");
717*9880d681SAndroid Build Coastguard Worker Options.PrintNEW = true;
718*9880d681SAndroid Build Coastguard Worker size_t NumMerged = 0;
719*9880d681SAndroid Build Coastguard Worker for (auto &U : Corpus) {
720*9880d681SAndroid Build Coastguard Worker if (RunOne(U)) {
721*9880d681SAndroid Build Coastguard Worker PrintStatusForNewUnit(U);
722*9880d681SAndroid Build Coastguard Worker NumMerged++;
723*9880d681SAndroid Build Coastguard Worker WriteToOutputCorpus(U);
724*9880d681SAndroid Build Coastguard Worker }
725*9880d681SAndroid Build Coastguard Worker }
726*9880d681SAndroid Build Coastguard Worker PrintStats("MERGED");
727*9880d681SAndroid Build Coastguard Worker if (NumMerged && Options.Verbosity)
728*9880d681SAndroid Build Coastguard Worker Printf("Drilling discovered %zd new units\n", NumMerged);
729*9880d681SAndroid Build Coastguard Worker }
730*9880d681SAndroid Build Coastguard Worker
Loop()731*9880d681SAndroid Build Coastguard Worker void Fuzzer::Loop() {
732*9880d681SAndroid Build Coastguard Worker system_clock::time_point LastCorpusReload = system_clock::now();
733*9880d681SAndroid Build Coastguard Worker if (Options.DoCrossOver)
734*9880d681SAndroid Build Coastguard Worker MD.SetCorpus(&Corpus);
735*9880d681SAndroid Build Coastguard Worker while (true) {
736*9880d681SAndroid Build Coastguard Worker auto Now = system_clock::now();
737*9880d681SAndroid Build Coastguard Worker if (duration_cast<seconds>(Now - LastCorpusReload).count()) {
738*9880d681SAndroid Build Coastguard Worker RereadOutputCorpus(Options.MaxLen);
739*9880d681SAndroid Build Coastguard Worker LastCorpusReload = Now;
740*9880d681SAndroid Build Coastguard Worker }
741*9880d681SAndroid Build Coastguard Worker if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
742*9880d681SAndroid Build Coastguard Worker break;
743*9880d681SAndroid Build Coastguard Worker if (Options.MaxTotalTimeSec > 0 &&
744*9880d681SAndroid Build Coastguard Worker secondsSinceProcessStartUp() >
745*9880d681SAndroid Build Coastguard Worker static_cast<size_t>(Options.MaxTotalTimeSec))
746*9880d681SAndroid Build Coastguard Worker break;
747*9880d681SAndroid Build Coastguard Worker // Perform several mutations and runs.
748*9880d681SAndroid Build Coastguard Worker MutateAndTestOne();
749*9880d681SAndroid Build Coastguard Worker }
750*9880d681SAndroid Build Coastguard Worker
751*9880d681SAndroid Build Coastguard Worker PrintStats("DONE ", "\n");
752*9880d681SAndroid Build Coastguard Worker MD.PrintRecommendedDictionary();
753*9880d681SAndroid Build Coastguard Worker }
754*9880d681SAndroid Build Coastguard Worker
UpdateCorpusDistribution()755*9880d681SAndroid Build Coastguard Worker void Fuzzer::UpdateCorpusDistribution() {
756*9880d681SAndroid Build Coastguard Worker size_t N = Corpus.size();
757*9880d681SAndroid Build Coastguard Worker std::vector<double> Intervals(N + 1);
758*9880d681SAndroid Build Coastguard Worker std::vector<double> Weights(N);
759*9880d681SAndroid Build Coastguard Worker std::iota(Intervals.begin(), Intervals.end(), 0);
760*9880d681SAndroid Build Coastguard Worker std::iota(Weights.begin(), Weights.end(), 1);
761*9880d681SAndroid Build Coastguard Worker CorpusDistribution = std::piecewise_constant_distribution<double>(
762*9880d681SAndroid Build Coastguard Worker Intervals.begin(), Intervals.end(), Weights.begin());
763*9880d681SAndroid Build Coastguard Worker }
764*9880d681SAndroid Build Coastguard Worker
765*9880d681SAndroid Build Coastguard Worker } // namespace fuzzer
766*9880d681SAndroid Build Coastguard Worker
767*9880d681SAndroid Build Coastguard Worker extern "C" {
768*9880d681SAndroid Build Coastguard Worker
LLVMFuzzerMutate(uint8_t * Data,size_t Size,size_t MaxSize)769*9880d681SAndroid Build Coastguard Worker size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
770*9880d681SAndroid Build Coastguard Worker assert(fuzzer::F);
771*9880d681SAndroid Build Coastguard Worker return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
772*9880d681SAndroid Build Coastguard Worker }
773*9880d681SAndroid Build Coastguard Worker } // extern "C"
774