blob: 31c6585a91d24dea6a34903b772624534b28e1bc [file] [log] [blame]
Aaron Ballmanef116982015-01-29 16:58:29 +00001//===- 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//===----------------------------------------------------------------------===//
Yaron Keren347663b2015-08-10 16:37:40 +000011
12#ifndef LLVM_FUZZER_INTERNAL_H
13#define LLVM_FUZZER_INTERNAL_H
14
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000015#include "FuzzerDefs.h"
Kostya Serebryanybceadcf2016-08-24 01:38:42 +000016#include "FuzzerExtFunctions.h"
17#include "FuzzerInterface.h"
Kostya Serebryany556894f2016-09-21 02:05:39 +000018#include "FuzzerOptions.h"
Zachary Turner24a148b2016-11-30 19:06:14 +000019#include "FuzzerSHA1.h"
Kostya Serebryanybceadcf2016-08-24 01:38:42 +000020#include "FuzzerValueBitMap.h"
Marcos Pividori178fe582016-12-13 17:46:11 +000021#include <algorithm>
22#include <atomic>
23#include <chrono>
24#include <climits>
25#include <cstdlib>
26#include <string.h>
Kostya Serebryanybceadcf2016-08-24 01:38:42 +000027
Aaron Ballmanef116982015-01-29 16:58:29 +000028namespace fuzzer {
Kostya Serebryany8b0d90a2016-05-13 18:04:35 +000029
Aaron Ballmanef116982015-01-29 16:58:29 +000030using namespace std::chrono;
Kostya Serebryany9690fcf2015-05-12 18:51:57 +000031
Aaron Ballmanef116982015-01-29 16:58:29 +000032class Fuzzer {
Ivan Krasindf919102016-01-22 22:28:27 +000033public:
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000034
35 // Aggregates all available coverage measurements.
36 struct Coverage {
37 Coverage() { Reset(); }
38
39 void Reset() {
40 BlockCoverage = 0;
41 CallerCalleeCoverage = 0;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000042 CounterBitmapBits = 0;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000043 CounterBitmap.clear();
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000044 }
45
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000046 size_t BlockCoverage;
47 size_t CallerCalleeCoverage;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000048 // Precalculated number of bits in CounterBitmap.
49 size_t CounterBitmapBits;
50 std::vector<uint8_t> CounterBitmap;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +000051 };
52
Kostya Serebryany29bb6642016-09-21 22:42:17 +000053 Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
54 FuzzingOptions Options);
Mike Aizatskyb4bbc3b2016-08-05 20:09:53 +000055 ~Fuzzer();
Kostya Serebryany468ed782015-09-08 17:30:35 +000056 void Loop();
Kostya Serebryanyf9b8e8b2016-10-15 01:00:24 +000057 void MinimizeCrashLoop(const Unit &U);
Kostya Serebryany09aa01a2016-09-21 01:04:43 +000058 void ShuffleAndMinimize(UnitVector *V);
Kostya Serebryany22526252015-05-11 21:16:27 +000059 void InitializeTraceState();
Kostya Serebryany64d24572016-03-12 01:57:04 +000060 void RereadOutputCorpus(size_t MaxSize);
Aaron Ballmanef116982015-01-29 16:58:29 +000061
Kostya Serebryany92e04762015-02-04 23:42:42 +000062 size_t secondsSinceProcessStartUp() {
63 return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
64 .count();
65 }
Kostya Serebryanyf9b8e8b2016-10-15 01:00:24 +000066
67 bool TimedOut() {
68 return Options.MaxTotalTimeSec > 0 &&
69 secondsSinceProcessStartUp() >
70 static_cast<size_t>(Options.MaxTotalTimeSec);
71 }
72
Kostya Serebryany66ff0752016-02-26 22:42:23 +000073 size_t execPerSec() {
74 size_t Seconds = secondsSinceProcessStartUp();
75 return Seconds ? TotalNumberOfRuns / Seconds : 0;
76 }
Kostya Serebryany92e04762015-02-04 23:42:42 +000077
78 size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
79
Kostya Serebryany52a788e2015-03-31 20:13:20 +000080 static void StaticAlarmCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +000081 static void StaticCrashSignalCallback();
82 static void StaticInterruptCallback();
Kostya Serebryany4aa05902017-01-05 22:05:47 +000083 static void StaticFileSizeExceedCallback();
Kostya Serebryany52a788e2015-03-31 20:13:20 +000084
Kostya Serebryany8a5bef02016-02-13 17:56:51 +000085 void ExecuteCallback(const uint8_t *Data, size_t Size);
Kostya Serebryany1c73f1b2016-10-05 22:56:21 +000086 size_t RunOne(const uint8_t *Data, size_t Size);
Aaron Ballmanef116982015-01-29 16:58:29 +000087
Kostya Serebryany9cc3b0d2015-10-24 01:16:40 +000088 // Merge Corpora[1:] into Corpora[0].
89 void Merge(const std::vector<std::string> &Corpora);
Kostya Serebryany111e1d62016-12-09 01:17:24 +000090 void CrashResistantMerge(const std::vector<std::string> &Args,
91 const std::vector<std::string> &Corpora);
92 void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
Kostya Serebryany945761b2016-03-18 00:23:29 +000093 // Returns a subset of 'Extra' that adds coverage to 'Initial'.
94 UnitVector FindExtraUnits(const UnitVector &Initial, const UnitVector &Extra);
Kostya Serebryany1deb0492016-02-13 06:24:18 +000095 MutationDispatcher &GetMD() { return MD; }
Kostya Serebryany66ff0752016-02-26 22:42:23 +000096 void PrintFinalStats();
Kostya Serebryanybe0ed592016-09-22 23:16:36 +000097 void SetMaxInputLen(size_t MaxInputLen);
98 void SetMaxMutationLen(size_t MaxMutationLen);
Kostya Serebryany8b8f7a32016-05-06 23:38:07 +000099 void RssLimitCallback();
Kostya Serebryany9cc3b0d2015-10-24 01:16:40 +0000100
Mike Aizatskyaf432a42016-05-24 23:14:29 +0000101 // Public for tests.
102 void ResetCoverage();
103
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000104 bool InFuzzingThread() const { return IsMyThread; }
Kostya Serebryanyd8384122016-05-26 22:17:32 +0000105 size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
Kostya Serebryanybb59ef72016-10-18 18:38:08 +0000106 void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
107 bool DuringInitialCorpusExecution);
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000108
Kostya Serebryany05f77912016-11-30 22:39:35 +0000109 void HandleMalloc(size_t Size);
Kostya Serebryany98d592c2017-01-20 20:57:07 +0000110 void AnnounceOutput(const uint8_t *Data, size_t Size);
Kostya Serebryany05f77912016-11-30 22:39:35 +0000111
Ivan Krasindf919102016-01-22 22:28:27 +0000112private:
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000113 void AlarmCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +0000114 void CrashCallback();
115 void InterruptCallback();
Kostya Serebryany27ab2d72015-12-19 02:49:09 +0000116 void MutateAndTestOne();
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000117 void ReportNewCoverage(InputInfo *II, const Unit &U);
Kostya Serebryany1c73f1b2016-10-05 22:56:21 +0000118 size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
Aaron Ballmanef116982015-01-29 16:58:29 +0000119 void WriteToOutputCorpus(const Unit &U);
Kostya Serebryany2b7d2e92015-07-23 18:37:22 +0000120 void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
Kostya Serebryany16a145f2016-09-23 01:58:51 +0000121 void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
Kostya Serebryanydc3135d2015-11-12 01:02:01 +0000122 void PrintStatusForNewUnit(const Unit &U);
Kostya Serebryany945761b2016-03-18 00:23:29 +0000123 void ShuffleCorpus(UnitVector *V);
Kostya Serebryany90f8f362016-09-30 23:29:27 +0000124 void AddToCorpus(const Unit &U);
Kostya Serebryany8dfed452016-10-18 18:06:05 +0000125 void CheckExitOnSrcPosOrItem();
Kostya Serebryany945761b2016-03-18 00:23:29 +0000126
Kostya Serebryanybeb24c32015-05-07 21:02:11 +0000127 // 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();
Kostya Serebryanyb65805a2016-01-09 03:08:58 +0000133 // Stop tracing.
134 void StopTraceRecording();
Kostya Serebryanybeb24c32015-05-07 21:02:11 +0000135
Aaron Ballmanef116982015-01-29 16:58:29 +0000136 void SetDeathCallback();
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000137 static void StaticDeathCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +0000138 void DumpCurrentUnit(const char *Prefix);
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000139 void DeathCallback();
Kostya Serebryany98abb2c2016-01-13 23:46:01 +0000140
Kostya Serebryanyf67357c2016-08-25 01:25:03 +0000141 void ResetEdgeCoverage();
Kostya Serebryanyb76a2a52016-09-09 02:38:28 +0000142 void ResetCounters();
Kostya Serebryanyf67357c2016-08-25 01:25:03 +0000143 void PrepareCounters(Fuzzer::Coverage *C);
144 bool RecordMaxCoverage(Fuzzer::Coverage *C);
145
Kostya Serebryanybe0ed592016-09-22 23:16:36 +0000146 void AllocateCurrentUnitData();
Kostya Serebryany8fc3a272016-05-27 00:21:33 +0000147 uint8_t *CurrentUnitData = nullptr;
Kostya Serebryany0edb5632016-05-27 00:54:15 +0000148 std::atomic<size_t> CurrentUnitSize;
Kostya Serebryanya9a54802016-08-17 20:45:23 +0000149 uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
Marcos Pividori64d41472016-12-13 17:46:25 +0000150 bool RunningCB = false;
Aaron Ballmanef116982015-01-29 16:58:29 +0000151
152 size_t TotalNumberOfRuns = 0;
Kostya Serebryany66ff0752016-02-26 22:42:23 +0000153 size_t NumberOfNewUnitsAdded = 0;
Aaron Ballmanef116982015-01-29 16:58:29 +0000154
Kostya Serebryany1bfd5832016-04-20 00:24:21 +0000155 bool HasMoreMallocsThanFrees = false;
Kostya Serebryany7018a1a2016-04-27 19:52:34 +0000156 size_t NumberOfLeakDetectionAttempts = 0;
Kostya Serebryany1bfd5832016-04-20 00:24:21 +0000157
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000158 UserCallback CB;
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000159 InputCorpus &Corpus;
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000160 MutationDispatcher &MD;
Aaron Ballmanef116982015-01-29 16:58:29 +0000161 FuzzingOptions Options;
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000162
Aaron Ballmanef116982015-01-29 16:58:29 +0000163 system_clock::time_point ProcessStartTime = system_clock::now();
Kostya Serebryany624f59f2016-09-22 01:34:58 +0000164 system_clock::time_point UnitStartTime, UnitStopTime;
Kostya Serebryany16901a92015-03-30 23:04:35 +0000165 long TimeOfLongestUnitInSeconds = 0;
Kostya Serebryany1ac80552015-05-08 21:30:55 +0000166 long EpochOfLastReadOfOutputCorpus = 0;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +0000167
168 // Maximum recorded coverage.
169 Coverage MaxCoverage;
Kostya Serebryanyf67357c2016-08-25 01:25:03 +0000170
Kostya Serebryanybe0ed592016-09-22 23:16:36 +0000171 size_t MaxInputLen = 0;
172 size_t MaxMutationLen = 0;
173
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000174 // Need to know our own thread.
175 static thread_local bool IsMyThread;
Kostya Serebryanyb991cc12016-09-10 00:15:41 +0000176
177 bool InMergeMode = false;
Aaron Ballmanef116982015-01-29 16:58:29 +0000178};
179
Ivan Krasindf919102016-01-22 22:28:27 +0000180}; // namespace fuzzer
Yaron Keren347663b2015-08-10 16:37:40 +0000181
182#endif // LLVM_FUZZER_INTERNAL_H