FuzzerInternal.h revision 353358
1326943Sdim//===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===// 2326943Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326943Sdim// 7326943Sdim//===----------------------------------------------------------------------===// 8326943Sdim// Define the main class fuzzer::Fuzzer and most functions. 9326943Sdim//===----------------------------------------------------------------------===// 10326943Sdim 11326943Sdim#ifndef LLVM_FUZZER_INTERNAL_H 12326943Sdim#define LLVM_FUZZER_INTERNAL_H 13326943Sdim 14336817Sdim#include "FuzzerDataFlowTrace.h" 15326943Sdim#include "FuzzerDefs.h" 16326943Sdim#include "FuzzerExtFunctions.h" 17326943Sdim#include "FuzzerInterface.h" 18326943Sdim#include "FuzzerOptions.h" 19326943Sdim#include "FuzzerSHA1.h" 20326943Sdim#include "FuzzerValueBitMap.h" 21326943Sdim#include <algorithm> 22326943Sdim#include <atomic> 23326943Sdim#include <chrono> 24326943Sdim#include <climits> 25326943Sdim#include <cstdlib> 26326943Sdim#include <string.h> 27326943Sdim 28326943Sdimnamespace fuzzer { 29326943Sdim 30326943Sdimusing namespace std::chrono; 31326943Sdim 32326943Sdimclass Fuzzer { 33326943Sdimpublic: 34326943Sdim 35326943Sdim Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD, 36326943Sdim FuzzingOptions Options); 37326943Sdim ~Fuzzer(); 38353358Sdim void Loop(Vector<SizedFile> &CorporaFiles); 39353358Sdim void ReadAndExecuteSeedCorpora(Vector<SizedFile> &CorporaFiles); 40326943Sdim void MinimizeCrashLoop(const Unit &U); 41326943Sdim void RereadOutputCorpus(size_t MaxSize); 42326943Sdim 43326943Sdim size_t secondsSinceProcessStartUp() { 44326943Sdim return duration_cast<seconds>(system_clock::now() - ProcessStartTime) 45326943Sdim .count(); 46326943Sdim } 47326943Sdim 48326943Sdim bool TimedOut() { 49326943Sdim return Options.MaxTotalTimeSec > 0 && 50326943Sdim secondsSinceProcessStartUp() > 51326943Sdim static_cast<size_t>(Options.MaxTotalTimeSec); 52326943Sdim } 53326943Sdim 54326943Sdim size_t execPerSec() { 55326943Sdim size_t Seconds = secondsSinceProcessStartUp(); 56326943Sdim return Seconds ? TotalNumberOfRuns / Seconds : 0; 57326943Sdim } 58326943Sdim 59326943Sdim size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; } 60326943Sdim 61326943Sdim static void StaticAlarmCallback(); 62326943Sdim static void StaticCrashSignalCallback(); 63326943Sdim static void StaticExitCallback(); 64326943Sdim static void StaticInterruptCallback(); 65326943Sdim static void StaticFileSizeExceedCallback(); 66326943Sdim static void StaticGracefulExitCallback(); 67326943Sdim 68326943Sdim void ExecuteCallback(const uint8_t *Data, size_t Size); 69326943Sdim bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false, 70326943Sdim InputInfo *II = nullptr, bool *FoundUniqFeatures = nullptr); 71326943Sdim 72326943Sdim // Merge Corpora[1:] into Corpora[0]. 73326943Sdim void Merge(const Vector<std::string> &Corpora); 74326943Sdim void CrashResistantMergeInternalStep(const std::string &ControlFilePath); 75326943Sdim MutationDispatcher &GetMD() { return MD; } 76326943Sdim void PrintFinalStats(); 77326943Sdim void SetMaxInputLen(size_t MaxInputLen); 78326943Sdim void SetMaxMutationLen(size_t MaxMutationLen); 79326943Sdim void RssLimitCallback(); 80326943Sdim 81326943Sdim bool InFuzzingThread() const { return IsMyThread; } 82326943Sdim size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const; 83326943Sdim void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size, 84326943Sdim bool DuringInitialCorpusExecution); 85326943Sdim 86326943Sdim void HandleMalloc(size_t Size); 87353358Sdim static void MaybeExitGracefully(); 88353358Sdim std::string WriteToOutputCorpus(const Unit &U); 89326943Sdim 90326943Sdimprivate: 91326943Sdim void AlarmCallback(); 92326943Sdim void CrashCallback(); 93326943Sdim void ExitCallback(); 94326943Sdim void CrashOnOverwrittenData(); 95326943Sdim void InterruptCallback(); 96326943Sdim void MutateAndTestOne(); 97326943Sdim void PurgeAllocator(); 98326943Sdim void ReportNewCoverage(InputInfo *II, const Unit &U); 99326943Sdim void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size); 100326943Sdim void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix); 101326943Sdim void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0); 102326943Sdim void PrintStatusForNewUnit(const Unit &U, const char *Text); 103326943Sdim void CheckExitOnSrcPosOrItem(); 104326943Sdim 105326943Sdim static void StaticDeathCallback(); 106326943Sdim void DumpCurrentUnit(const char *Prefix); 107326943Sdim void DeathCallback(); 108326943Sdim 109326943Sdim void AllocateCurrentUnitData(); 110326943Sdim uint8_t *CurrentUnitData = nullptr; 111326943Sdim std::atomic<size_t> CurrentUnitSize; 112326943Sdim uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit. 113326943Sdim 114326943Sdim bool GracefulExitRequested = false; 115326943Sdim 116326943Sdim size_t TotalNumberOfRuns = 0; 117326943Sdim size_t NumberOfNewUnitsAdded = 0; 118326943Sdim 119326943Sdim size_t LastCorpusUpdateRun = 0; 120326943Sdim 121326943Sdim bool HasMoreMallocsThanFrees = false; 122326943Sdim size_t NumberOfLeakDetectionAttempts = 0; 123326943Sdim 124326943Sdim system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now(); 125326943Sdim 126326943Sdim UserCallback CB; 127326943Sdim InputCorpus &Corpus; 128326943Sdim MutationDispatcher &MD; 129326943Sdim FuzzingOptions Options; 130336817Sdim DataFlowTrace DFT; 131326943Sdim 132326943Sdim system_clock::time_point ProcessStartTime = system_clock::now(); 133326943Sdim system_clock::time_point UnitStartTime, UnitStopTime; 134326943Sdim long TimeOfLongestUnitInSeconds = 0; 135326943Sdim long EpochOfLastReadOfOutputCorpus = 0; 136326943Sdim 137326943Sdim size_t MaxInputLen = 0; 138326943Sdim size_t MaxMutationLen = 0; 139326943Sdim size_t TmpMaxMutationLen = 0; 140326943Sdim 141326943Sdim Vector<uint32_t> UniqFeatureSetTmp; 142326943Sdim 143326943Sdim // Need to know our own thread. 144326943Sdim static thread_local bool IsMyThread; 145326943Sdim}; 146326943Sdim 147336817Sdimstruct ScopedEnableMsanInterceptorChecks { 148336817Sdim ScopedEnableMsanInterceptorChecks() { 149336817Sdim if (EF->__msan_scoped_enable_interceptor_checks) 150336817Sdim EF->__msan_scoped_enable_interceptor_checks(); 151336817Sdim } 152336817Sdim ~ScopedEnableMsanInterceptorChecks() { 153336817Sdim if (EF->__msan_scoped_disable_interceptor_checks) 154336817Sdim EF->__msan_scoped_disable_interceptor_checks(); 155336817Sdim } 156336817Sdim}; 157336817Sdim 158336817Sdimstruct ScopedDisableMsanInterceptorChecks { 159336817Sdim ScopedDisableMsanInterceptorChecks() { 160336817Sdim if (EF->__msan_scoped_disable_interceptor_checks) 161336817Sdim EF->__msan_scoped_disable_interceptor_checks(); 162336817Sdim } 163336817Sdim ~ScopedDisableMsanInterceptorChecks() { 164336817Sdim if (EF->__msan_scoped_enable_interceptor_checks) 165336817Sdim EF->__msan_scoped_enable_interceptor_checks(); 166336817Sdim } 167336817Sdim}; 168336817Sdim 169326943Sdim} // namespace fuzzer 170326943Sdim 171326943Sdim#endif // LLVM_FUZZER_INTERNAL_H 172