blob: 1d68c01908f0fbb2ac5794f61b05d95c8a303518 [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
Kostya Serebryany29bb6642016-09-21 22:42:17 +000035 Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
36 FuzzingOptions Options);
Mike Aizatskyb4bbc3b2016-08-05 20:09:53 +000037 ~Fuzzer();
Kostya Serebryany468ed782015-09-08 17:30:35 +000038 void Loop();
Kostya Serebryanyf9b8e8b2016-10-15 01:00:24 +000039 void MinimizeCrashLoop(const Unit &U);
Kostya Serebryany09aa01a2016-09-21 01:04:43 +000040 void ShuffleAndMinimize(UnitVector *V);
Kostya Serebryany64d24572016-03-12 01:57:04 +000041 void RereadOutputCorpus(size_t MaxSize);
Aaron Ballmanef116982015-01-29 16:58:29 +000042
Kostya Serebryany92e04762015-02-04 23:42:42 +000043 size_t secondsSinceProcessStartUp() {
44 return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
45 .count();
46 }
Kostya Serebryanyf9b8e8b2016-10-15 01:00:24 +000047
48 bool TimedOut() {
49 return Options.MaxTotalTimeSec > 0 &&
50 secondsSinceProcessStartUp() >
51 static_cast<size_t>(Options.MaxTotalTimeSec);
52 }
53
Kostya Serebryany66ff0752016-02-26 22:42:23 +000054 size_t execPerSec() {
55 size_t Seconds = secondsSinceProcessStartUp();
56 return Seconds ? TotalNumberOfRuns / Seconds : 0;
57 }
Kostya Serebryany92e04762015-02-04 23:42:42 +000058
59 size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
60
Kostya Serebryany52a788e2015-03-31 20:13:20 +000061 static void StaticAlarmCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +000062 static void StaticCrashSignalCallback();
Matt Morehouse9e689792017-07-20 20:43:39 +000063 static void StaticExitCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +000064 static void StaticInterruptCallback();
Kostya Serebryany4aa05902017-01-05 22:05:47 +000065 static void StaticFileSizeExceedCallback();
Kostya Serebryany52a788e2015-03-31 20:13:20 +000066
Kostya Serebryany8a5bef02016-02-13 17:56:51 +000067 void ExecuteCallback(const uint8_t *Data, size_t Size);
Kostya Serebryany1ca73882017-07-13 01:08:53 +000068 bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
69 InputInfo *II = nullptr);
Aaron Ballmanef116982015-01-29 16:58:29 +000070
Kostya Serebryany9cc3b0d2015-10-24 01:16:40 +000071 // Merge Corpora[1:] into Corpora[0].
72 void Merge(const std::vector<std::string> &Corpora);
Kostya Serebryany111e1d62016-12-09 01:17:24 +000073 void CrashResistantMerge(const std::vector<std::string> &Args,
Kostya Serebryany4fc6dd72017-03-22 20:32:44 +000074 const std::vector<std::string> &Corpora,
75 const char *CoverageSummaryInputPathOrNull,
76 const char *CoverageSummaryOutputPathOrNull);
Kostya Serebryany111e1d62016-12-09 01:17:24 +000077 void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
Kostya Serebryany1deb0492016-02-13 06:24:18 +000078 MutationDispatcher &GetMD() { return MD; }
Kostya Serebryany66ff0752016-02-26 22:42:23 +000079 void PrintFinalStats();
Kostya Serebryanybe0ed592016-09-22 23:16:36 +000080 void SetMaxInputLen(size_t MaxInputLen);
81 void SetMaxMutationLen(size_t MaxMutationLen);
Kostya Serebryany8b8f7a32016-05-06 23:38:07 +000082 void RssLimitCallback();
Kostya Serebryany9cc3b0d2015-10-24 01:16:40 +000083
Kostya Serebryanyf26017b2016-05-26 21:32:30 +000084 bool InFuzzingThread() const { return IsMyThread; }
Kostya Serebryanyd8384122016-05-26 22:17:32 +000085 size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
Kostya Serebryanybb59ef72016-10-18 18:38:08 +000086 void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
87 bool DuringInitialCorpusExecution);
Kostya Serebryanyf26017b2016-05-26 21:32:30 +000088
Kostya Serebryany05f77912016-11-30 22:39:35 +000089 void HandleMalloc(size_t Size);
Kostya Serebryany98d592c2017-01-20 20:57:07 +000090 void AnnounceOutput(const uint8_t *Data, size_t Size);
Kostya Serebryany05f77912016-11-30 22:39:35 +000091
Ivan Krasindf919102016-01-22 22:28:27 +000092private:
Kostya Serebryany52a788e2015-03-31 20:13:20 +000093 void AlarmCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +000094 void CrashCallback();
Matt Morehouse9e689792017-07-20 20:43:39 +000095 void ExitCallback();
Kostya Serebryanyfe4ed9b2017-05-09 01:17:29 +000096 void CrashOnOverwrittenData();
Kostya Serebryany228d5b12016-03-01 22:19:21 +000097 void InterruptCallback();
Kostya Serebryany27ab2d72015-12-19 02:49:09 +000098 void MutateAndTestOne();
Kostya Serebryany29bb6642016-09-21 22:42:17 +000099 void ReportNewCoverage(InputInfo *II, const Unit &U);
Kostya Serebryany1e99d542017-07-12 22:20:04 +0000100 void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);
Aaron Ballmanef116982015-01-29 16:58:29 +0000101 void WriteToOutputCorpus(const Unit &U);
Kostya Serebryany2b7d2e92015-07-23 18:37:22 +0000102 void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
Kostya Serebryany16a145f2016-09-23 01:58:51 +0000103 void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
Kostya Serebryanyd01e9562017-07-18 18:47:36 +0000104 void PrintStatusForNewUnit(const Unit &U, const char *Text);
Kostya Serebryany945761b2016-03-18 00:23:29 +0000105 void ShuffleCorpus(UnitVector *V);
Kostya Serebryany8dfed452016-10-18 18:06:05 +0000106 void CheckExitOnSrcPosOrItem();
Kostya Serebryany945761b2016-03-18 00:23:29 +0000107
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000108 static void StaticDeathCallback();
Kostya Serebryany228d5b12016-03-01 22:19:21 +0000109 void DumpCurrentUnit(const char *Prefix);
Kostya Serebryany52a788e2015-03-31 20:13:20 +0000110 void DeathCallback();
Kostya Serebryany98abb2c2016-01-13 23:46:01 +0000111
Kostya Serebryanybe0ed592016-09-22 23:16:36 +0000112 void AllocateCurrentUnitData();
Kostya Serebryany8fc3a272016-05-27 00:21:33 +0000113 uint8_t *CurrentUnitData = nullptr;
Kostya Serebryany0edb5632016-05-27 00:54:15 +0000114 std::atomic<size_t> CurrentUnitSize;
Kostya Serebryanya9a54802016-08-17 20:45:23 +0000115 uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
Marcos Pividori64d41472016-12-13 17:46:25 +0000116 bool RunningCB = false;
Aaron Ballmanef116982015-01-29 16:58:29 +0000117
118 size_t TotalNumberOfRuns = 0;
Kostya Serebryany66ff0752016-02-26 22:42:23 +0000119 size_t NumberOfNewUnitsAdded = 0;
Aaron Ballmanef116982015-01-29 16:58:29 +0000120
Kostya Serebryany8cb63ec2017-07-22 00:10:29 +0000121 size_t LastCorpusUpdateRun = 0;
122 system_clock::time_point LastCorpusUpdateTime = system_clock::now();
123
124
Kostya Serebryany1bfd5832016-04-20 00:24:21 +0000125 bool HasMoreMallocsThanFrees = false;
Kostya Serebryany7018a1a2016-04-27 19:52:34 +0000126 size_t NumberOfLeakDetectionAttempts = 0;
Kostya Serebryany1bfd5832016-04-20 00:24:21 +0000127
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000128 UserCallback CB;
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000129 InputCorpus &Corpus;
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000130 MutationDispatcher &MD;
Aaron Ballmanef116982015-01-29 16:58:29 +0000131 FuzzingOptions Options;
Kostya Serebryany29bb6642016-09-21 22:42:17 +0000132
Aaron Ballmanef116982015-01-29 16:58:29 +0000133 system_clock::time_point ProcessStartTime = system_clock::now();
Kostya Serebryany624f59f2016-09-22 01:34:58 +0000134 system_clock::time_point UnitStartTime, UnitStopTime;
Kostya Serebryany16901a92015-03-30 23:04:35 +0000135 long TimeOfLongestUnitInSeconds = 0;
Kostya Serebryany1ac80552015-05-08 21:30:55 +0000136 long EpochOfLastReadOfOutputCorpus = 0;
Mike Aizatsky1aa501e2016-05-10 23:43:15 +0000137
Kostya Serebryanybe0ed592016-09-22 23:16:36 +0000138 size_t MaxInputLen = 0;
139 size_t MaxMutationLen = 0;
Kostya Serebryany8cb63ec2017-07-22 00:10:29 +0000140 size_t TmpMaxMutationLen = 0;
Kostya Serebryanybe0ed592016-09-22 23:16:36 +0000141
Kostya Serebryanyf1b5c642017-07-18 01:36:50 +0000142 std::vector<uint32_t> UniqFeatureSetTmp;
Kostya Serebryany1e99d542017-07-12 22:20:04 +0000143
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000144 // Need to know our own thread.
145 static thread_local bool IsMyThread;
Aaron Ballmanef116982015-01-29 16:58:29 +0000146};
147
Sanjoy Das730edcc2017-04-28 04:49:32 +0000148} // namespace fuzzer
Yaron Keren347663b2015-08-10 16:37:40 +0000149
150#endif // LLVM_FUZZER_INTERNAL_H