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); 101360784Sdim void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0, 102360784Sdim size_t Features = 0); 103326943Sdim void PrintStatusForNewUnit(const Unit &U, const char *Text); 104326943Sdim void CheckExitOnSrcPosOrItem(); 105326943Sdim 106326943Sdim static void StaticDeathCallback(); 107326943Sdim void DumpCurrentUnit(const char *Prefix); 108326943Sdim void DeathCallback(); 109326943Sdim 110326943Sdim void AllocateCurrentUnitData(); 111326943Sdim uint8_t *CurrentUnitData = nullptr; 112326943Sdim std::atomic<size_t> CurrentUnitSize; 113326943Sdim uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit. 114326943Sdim 115326943Sdim bool GracefulExitRequested = false; 116326943Sdim 117326943Sdim size_t TotalNumberOfRuns = 0; 118326943Sdim size_t NumberOfNewUnitsAdded = 0; 119326943Sdim 120326943Sdim size_t LastCorpusUpdateRun = 0; 121326943Sdim 122326943Sdim bool HasMoreMallocsThanFrees = false; 123326943Sdim size_t NumberOfLeakDetectionAttempts = 0; 124326943Sdim 125326943Sdim system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now(); 126326943Sdim 127326943Sdim UserCallback CB; 128326943Sdim InputCorpus &Corpus; 129326943Sdim MutationDispatcher &MD; 130326943Sdim FuzzingOptions Options; 131336817Sdim DataFlowTrace DFT; 132326943Sdim 133326943Sdim system_clock::time_point ProcessStartTime = system_clock::now(); 134326943Sdim system_clock::time_point UnitStartTime, UnitStopTime; 135326943Sdim long TimeOfLongestUnitInSeconds = 0; 136326943Sdim long EpochOfLastReadOfOutputCorpus = 0; 137326943Sdim 138326943Sdim size_t MaxInputLen = 0; 139326943Sdim size_t MaxMutationLen = 0; 140326943Sdim size_t TmpMaxMutationLen = 0; 141326943Sdim 142326943Sdim Vector<uint32_t> UniqFeatureSetTmp; 143326943Sdim 144326943Sdim // Need to know our own thread. 145326943Sdim static thread_local bool IsMyThread; 146326943Sdim}; 147326943Sdim 148336817Sdimstruct ScopedEnableMsanInterceptorChecks { 149336817Sdim ScopedEnableMsanInterceptorChecks() { 150336817Sdim if (EF->__msan_scoped_enable_interceptor_checks) 151336817Sdim EF->__msan_scoped_enable_interceptor_checks(); 152336817Sdim } 153336817Sdim ~ScopedEnableMsanInterceptorChecks() { 154336817Sdim if (EF->__msan_scoped_disable_interceptor_checks) 155336817Sdim EF->__msan_scoped_disable_interceptor_checks(); 156336817Sdim } 157336817Sdim}; 158336817Sdim 159336817Sdimstruct ScopedDisableMsanInterceptorChecks { 160336817Sdim ScopedDisableMsanInterceptorChecks() { 161336817Sdim if (EF->__msan_scoped_disable_interceptor_checks) 162336817Sdim EF->__msan_scoped_disable_interceptor_checks(); 163336817Sdim } 164336817Sdim ~ScopedDisableMsanInterceptorChecks() { 165336817Sdim if (EF->__msan_scoped_enable_interceptor_checks) 166336817Sdim EF->__msan_scoped_enable_interceptor_checks(); 167336817Sdim } 168336817Sdim}; 169336817Sdim 170326943Sdim} // namespace fuzzer 171326943Sdim 172326943Sdim#endif // LLVM_FUZZER_INTERNAL_H 173