Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 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 | //===----------------------------------------------------------------------===// |
Yaron Keren | 347663b | 2015-08-10 16:37:40 +0000 | [diff] [blame] | 11 | |
| 12 | #ifndef LLVM_FUZZER_INTERNAL_H |
| 13 | #define LLVM_FUZZER_INTERNAL_H |
| 14 | |
Kostya Serebryany | 6f5a804 | 2016-09-21 01:50:50 +0000 | [diff] [blame] | 15 | #include "FuzzerDefs.h" |
Kostya Serebryany | bceadcf | 2016-08-24 01:38:42 +0000 | [diff] [blame] | 16 | #include "FuzzerExtFunctions.h" |
| 17 | #include "FuzzerInterface.h" |
Kostya Serebryany | 556894f | 2016-09-21 02:05:39 +0000 | [diff] [blame] | 18 | #include "FuzzerOptions.h" |
Zachary Turner | 24a148b | 2016-11-30 19:06:14 +0000 | [diff] [blame] | 19 | #include "FuzzerSHA1.h" |
Kostya Serebryany | bceadcf | 2016-08-24 01:38:42 +0000 | [diff] [blame] | 20 | #include "FuzzerValueBitMap.h" |
Marcos Pividori | 178fe58 | 2016-12-13 17:46:11 +0000 | [diff] [blame] | 21 | #include <algorithm> |
| 22 | #include <atomic> |
| 23 | #include <chrono> |
| 24 | #include <climits> |
| 25 | #include <cstdlib> |
| 26 | #include <string.h> |
Kostya Serebryany | bceadcf | 2016-08-24 01:38:42 +0000 | [diff] [blame] | 27 | |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 28 | namespace fuzzer { |
Kostya Serebryany | 8b0d90a | 2016-05-13 18:04:35 +0000 | [diff] [blame] | 29 | |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 30 | using namespace std::chrono; |
Kostya Serebryany | 9690fcf | 2015-05-12 18:51:57 +0000 | [diff] [blame] | 31 | |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 32 | class Fuzzer { |
Ivan Krasin | df91910 | 2016-01-22 22:28:27 +0000 | [diff] [blame] | 33 | public: |
Mike Aizatsky | 1aa501e | 2016-05-10 23:43:15 +0000 | [diff] [blame] | 34 | |
Kostya Serebryany | 29bb664 | 2016-09-21 22:42:17 +0000 | [diff] [blame] | 35 | Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD, |
| 36 | FuzzingOptions Options); |
Mike Aizatsky | b4bbc3b | 2016-08-05 20:09:53 +0000 | [diff] [blame] | 37 | ~Fuzzer(); |
Kostya Serebryany | 468ed78 | 2015-09-08 17:30:35 +0000 | [diff] [blame] | 38 | void Loop(); |
Kostya Serebryany | f9b8e8b | 2016-10-15 01:00:24 +0000 | [diff] [blame] | 39 | void MinimizeCrashLoop(const Unit &U); |
Kostya Serebryany | 09aa01a | 2016-09-21 01:04:43 +0000 | [diff] [blame] | 40 | void ShuffleAndMinimize(UnitVector *V); |
Kostya Serebryany | 64d2457 | 2016-03-12 01:57:04 +0000 | [diff] [blame] | 41 | void RereadOutputCorpus(size_t MaxSize); |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 42 | |
Kostya Serebryany | 92e0476 | 2015-02-04 23:42:42 +0000 | [diff] [blame] | 43 | size_t secondsSinceProcessStartUp() { |
| 44 | return duration_cast<seconds>(system_clock::now() - ProcessStartTime) |
| 45 | .count(); |
| 46 | } |
Kostya Serebryany | f9b8e8b | 2016-10-15 01:00:24 +0000 | [diff] [blame] | 47 | |
| 48 | bool TimedOut() { |
| 49 | return Options.MaxTotalTimeSec > 0 && |
| 50 | secondsSinceProcessStartUp() > |
| 51 | static_cast<size_t>(Options.MaxTotalTimeSec); |
| 52 | } |
| 53 | |
Kostya Serebryany | 66ff075 | 2016-02-26 22:42:23 +0000 | [diff] [blame] | 54 | size_t execPerSec() { |
| 55 | size_t Seconds = secondsSinceProcessStartUp(); |
| 56 | return Seconds ? TotalNumberOfRuns / Seconds : 0; |
| 57 | } |
Kostya Serebryany | 92e0476 | 2015-02-04 23:42:42 +0000 | [diff] [blame] | 58 | |
| 59 | size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; } |
| 60 | |
Kostya Serebryany | 52a788e | 2015-03-31 20:13:20 +0000 | [diff] [blame] | 61 | static void StaticAlarmCallback(); |
Kostya Serebryany | 228d5b1 | 2016-03-01 22:19:21 +0000 | [diff] [blame] | 62 | static void StaticCrashSignalCallback(); |
Matt Morehouse | 9e68979 | 2017-07-20 20:43:39 +0000 | [diff] [blame] | 63 | static void StaticExitCallback(); |
Kostya Serebryany | 228d5b1 | 2016-03-01 22:19:21 +0000 | [diff] [blame] | 64 | static void StaticInterruptCallback(); |
Kostya Serebryany | 4aa0590 | 2017-01-05 22:05:47 +0000 | [diff] [blame] | 65 | static void StaticFileSizeExceedCallback(); |
Kostya Serebryany | 52a788e | 2015-03-31 20:13:20 +0000 | [diff] [blame] | 66 | |
Kostya Serebryany | 8a5bef0 | 2016-02-13 17:56:51 +0000 | [diff] [blame] | 67 | void ExecuteCallback(const uint8_t *Data, size_t Size); |
Kostya Serebryany | 1ca7388 | 2017-07-13 01:08:53 +0000 | [diff] [blame] | 68 | bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false, |
| 69 | InputInfo *II = nullptr); |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 70 | |
Kostya Serebryany | 9cc3b0d | 2015-10-24 01:16:40 +0000 | [diff] [blame] | 71 | // Merge Corpora[1:] into Corpora[0]. |
| 72 | void Merge(const std::vector<std::string> &Corpora); |
Kostya Serebryany | 111e1d6 | 2016-12-09 01:17:24 +0000 | [diff] [blame] | 73 | void CrashResistantMerge(const std::vector<std::string> &Args, |
Kostya Serebryany | 4fc6dd7 | 2017-03-22 20:32:44 +0000 | [diff] [blame] | 74 | const std::vector<std::string> &Corpora, |
| 75 | const char *CoverageSummaryInputPathOrNull, |
| 76 | const char *CoverageSummaryOutputPathOrNull); |
Kostya Serebryany | 111e1d6 | 2016-12-09 01:17:24 +0000 | [diff] [blame] | 77 | void CrashResistantMergeInternalStep(const std::string &ControlFilePath); |
Kostya Serebryany | 1deb049 | 2016-02-13 06:24:18 +0000 | [diff] [blame] | 78 | MutationDispatcher &GetMD() { return MD; } |
Kostya Serebryany | 66ff075 | 2016-02-26 22:42:23 +0000 | [diff] [blame] | 79 | void PrintFinalStats(); |
Kostya Serebryany | be0ed59 | 2016-09-22 23:16:36 +0000 | [diff] [blame] | 80 | void SetMaxInputLen(size_t MaxInputLen); |
| 81 | void SetMaxMutationLen(size_t MaxMutationLen); |
Kostya Serebryany | 8b8f7a3 | 2016-05-06 23:38:07 +0000 | [diff] [blame] | 82 | void RssLimitCallback(); |
Kostya Serebryany | 9cc3b0d | 2015-10-24 01:16:40 +0000 | [diff] [blame] | 83 | |
Kostya Serebryany | f26017b | 2016-05-26 21:32:30 +0000 | [diff] [blame] | 84 | bool InFuzzingThread() const { return IsMyThread; } |
Kostya Serebryany | d838412 | 2016-05-26 22:17:32 +0000 | [diff] [blame] | 85 | size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const; |
Kostya Serebryany | bb59ef7 | 2016-10-18 18:38:08 +0000 | [diff] [blame] | 86 | void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size, |
| 87 | bool DuringInitialCorpusExecution); |
Kostya Serebryany | f26017b | 2016-05-26 21:32:30 +0000 | [diff] [blame] | 88 | |
Kostya Serebryany | 05f7791 | 2016-11-30 22:39:35 +0000 | [diff] [blame] | 89 | void HandleMalloc(size_t Size); |
Kostya Serebryany | 98d592c | 2017-01-20 20:57:07 +0000 | [diff] [blame] | 90 | void AnnounceOutput(const uint8_t *Data, size_t Size); |
Kostya Serebryany | 05f7791 | 2016-11-30 22:39:35 +0000 | [diff] [blame] | 91 | |
Ivan Krasin | df91910 | 2016-01-22 22:28:27 +0000 | [diff] [blame] | 92 | private: |
Kostya Serebryany | 52a788e | 2015-03-31 20:13:20 +0000 | [diff] [blame] | 93 | void AlarmCallback(); |
Kostya Serebryany | 228d5b1 | 2016-03-01 22:19:21 +0000 | [diff] [blame] | 94 | void CrashCallback(); |
Matt Morehouse | 9e68979 | 2017-07-20 20:43:39 +0000 | [diff] [blame] | 95 | void ExitCallback(); |
Kostya Serebryany | fe4ed9b | 2017-05-09 01:17:29 +0000 | [diff] [blame] | 96 | void CrashOnOverwrittenData(); |
Kostya Serebryany | 228d5b1 | 2016-03-01 22:19:21 +0000 | [diff] [blame] | 97 | void InterruptCallback(); |
Kostya Serebryany | 27ab2d7 | 2015-12-19 02:49:09 +0000 | [diff] [blame] | 98 | void MutateAndTestOne(); |
Kostya Serebryany | 29bb664 | 2016-09-21 22:42:17 +0000 | [diff] [blame] | 99 | void ReportNewCoverage(InputInfo *II, const Unit &U); |
Kostya Serebryany | 1e99d54 | 2017-07-12 22:20:04 +0000 | [diff] [blame] | 100 | void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size); |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 101 | void WriteToOutputCorpus(const Unit &U); |
Kostya Serebryany | 2b7d2e9 | 2015-07-23 18:37:22 +0000 | [diff] [blame] | 102 | void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix); |
Kostya Serebryany | 16a145f | 2016-09-23 01:58:51 +0000 | [diff] [blame] | 103 | void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0); |
Kostya Serebryany | d01e956 | 2017-07-18 18:47:36 +0000 | [diff] [blame] | 104 | void PrintStatusForNewUnit(const Unit &U, const char *Text); |
Kostya Serebryany | 945761b | 2016-03-18 00:23:29 +0000 | [diff] [blame] | 105 | void ShuffleCorpus(UnitVector *V); |
Kostya Serebryany | 8dfed45 | 2016-10-18 18:06:05 +0000 | [diff] [blame] | 106 | void CheckExitOnSrcPosOrItem(); |
Kostya Serebryany | 945761b | 2016-03-18 00:23:29 +0000 | [diff] [blame] | 107 | |
Kostya Serebryany | 52a788e | 2015-03-31 20:13:20 +0000 | [diff] [blame] | 108 | static void StaticDeathCallback(); |
Kostya Serebryany | 228d5b1 | 2016-03-01 22:19:21 +0000 | [diff] [blame] | 109 | void DumpCurrentUnit(const char *Prefix); |
Kostya Serebryany | 52a788e | 2015-03-31 20:13:20 +0000 | [diff] [blame] | 110 | void DeathCallback(); |
Kostya Serebryany | 98abb2c | 2016-01-13 23:46:01 +0000 | [diff] [blame] | 111 | |
Kostya Serebryany | be0ed59 | 2016-09-22 23:16:36 +0000 | [diff] [blame] | 112 | void AllocateCurrentUnitData(); |
Kostya Serebryany | 8fc3a27 | 2016-05-27 00:21:33 +0000 | [diff] [blame] | 113 | uint8_t *CurrentUnitData = nullptr; |
Kostya Serebryany | 0edb563 | 2016-05-27 00:54:15 +0000 | [diff] [blame] | 114 | std::atomic<size_t> CurrentUnitSize; |
Kostya Serebryany | a9a5480 | 2016-08-17 20:45:23 +0000 | [diff] [blame] | 115 | uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit. |
Marcos Pividori | 64d4147 | 2016-12-13 17:46:25 +0000 | [diff] [blame] | 116 | bool RunningCB = false; |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 117 | |
| 118 | size_t TotalNumberOfRuns = 0; |
Kostya Serebryany | 66ff075 | 2016-02-26 22:42:23 +0000 | [diff] [blame] | 119 | size_t NumberOfNewUnitsAdded = 0; |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 120 | |
Kostya Serebryany | 8cb63ec | 2017-07-22 00:10:29 +0000 | [diff] [blame] | 121 | size_t LastCorpusUpdateRun = 0; |
| 122 | system_clock::time_point LastCorpusUpdateTime = system_clock::now(); |
| 123 | |
| 124 | |
Kostya Serebryany | 1bfd583 | 2016-04-20 00:24:21 +0000 | [diff] [blame] | 125 | bool HasMoreMallocsThanFrees = false; |
Kostya Serebryany | 7018a1a | 2016-04-27 19:52:34 +0000 | [diff] [blame] | 126 | size_t NumberOfLeakDetectionAttempts = 0; |
Kostya Serebryany | 1bfd583 | 2016-04-20 00:24:21 +0000 | [diff] [blame] | 127 | |
Kostya Serebryany | 7ec0c56 | 2016-02-13 03:25:16 +0000 | [diff] [blame] | 128 | UserCallback CB; |
Kostya Serebryany | 29bb664 | 2016-09-21 22:42:17 +0000 | [diff] [blame] | 129 | InputCorpus &Corpus; |
Kostya Serebryany | 7ec0c56 | 2016-02-13 03:25:16 +0000 | [diff] [blame] | 130 | MutationDispatcher &MD; |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 131 | FuzzingOptions Options; |
Kostya Serebryany | 29bb664 | 2016-09-21 22:42:17 +0000 | [diff] [blame] | 132 | |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 133 | system_clock::time_point ProcessStartTime = system_clock::now(); |
Kostya Serebryany | 624f59f | 2016-09-22 01:34:58 +0000 | [diff] [blame] | 134 | system_clock::time_point UnitStartTime, UnitStopTime; |
Kostya Serebryany | 16901a9 | 2015-03-30 23:04:35 +0000 | [diff] [blame] | 135 | long TimeOfLongestUnitInSeconds = 0; |
Kostya Serebryany | 1ac8055 | 2015-05-08 21:30:55 +0000 | [diff] [blame] | 136 | long EpochOfLastReadOfOutputCorpus = 0; |
Mike Aizatsky | 1aa501e | 2016-05-10 23:43:15 +0000 | [diff] [blame] | 137 | |
Kostya Serebryany | be0ed59 | 2016-09-22 23:16:36 +0000 | [diff] [blame] | 138 | size_t MaxInputLen = 0; |
| 139 | size_t MaxMutationLen = 0; |
Kostya Serebryany | 8cb63ec | 2017-07-22 00:10:29 +0000 | [diff] [blame] | 140 | size_t TmpMaxMutationLen = 0; |
Kostya Serebryany | be0ed59 | 2016-09-22 23:16:36 +0000 | [diff] [blame] | 141 | |
Kostya Serebryany | f1b5c64 | 2017-07-18 01:36:50 +0000 | [diff] [blame] | 142 | std::vector<uint32_t> UniqFeatureSetTmp; |
Kostya Serebryany | 1e99d54 | 2017-07-12 22:20:04 +0000 | [diff] [blame] | 143 | |
Kostya Serebryany | f26017b | 2016-05-26 21:32:30 +0000 | [diff] [blame] | 144 | // Need to know our own thread. |
| 145 | static thread_local bool IsMyThread; |
Aaron Ballman | ef11698 | 2015-01-29 16:58:29 +0000 | [diff] [blame] | 146 | }; |
| 147 | |
Sanjoy Das | 730edcc | 2017-04-28 04:49:32 +0000 | [diff] [blame] | 148 | } // namespace fuzzer |
Yaron Keren | 347663b | 2015-08-10 16:37:40 +0000 | [diff] [blame] | 149 | |
| 150 | #endif // LLVM_FUZZER_INTERNAL_H |