Path: blob/main/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerInternal.h
35262 views
//===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7// Define the main class fuzzer::Fuzzer and most functions.8//===----------------------------------------------------------------------===//910#ifndef LLVM_FUZZER_INTERNAL_H11#define LLVM_FUZZER_INTERNAL_H1213#include "FuzzerDataFlowTrace.h"14#include "FuzzerDefs.h"15#include "FuzzerExtFunctions.h"16#include "FuzzerInterface.h"17#include "FuzzerOptions.h"18#include "FuzzerSHA1.h"19#include "FuzzerValueBitMap.h"20#include <algorithm>21#include <atomic>22#include <chrono>23#include <climits>24#include <cstdlib>25#include <string.h>2627namespace fuzzer {2829using namespace std::chrono;3031class Fuzzer final {32public:33Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,34const FuzzingOptions &Options);35~Fuzzer() = delete;36void Loop(std::vector<SizedFile> &CorporaFiles);37void ReadAndExecuteSeedCorpora(std::vector<SizedFile> &CorporaFiles);38void MinimizeCrashLoop(const Unit &U);39void RereadOutputCorpus(size_t MaxSize);4041size_t secondsSinceProcessStartUp() {42return duration_cast<seconds>(system_clock::now() - ProcessStartTime)43.count();44}4546bool TimedOut() {47return Options.MaxTotalTimeSec > 0 &&48secondsSinceProcessStartUp() >49static_cast<size_t>(Options.MaxTotalTimeSec);50}5152size_t execPerSec() {53size_t Seconds = secondsSinceProcessStartUp();54return Seconds ? TotalNumberOfRuns / Seconds : 0;55}5657size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }5859static void StaticAlarmCallback();60static void StaticCrashSignalCallback();61static void StaticExitCallback();62static void StaticInterruptCallback();63static void StaticFileSizeExceedCallback();64static void StaticGracefulExitCallback();6566// Executes the target callback on {Data, Size} once.67// Returns false if the input was rejected by the target (target returned -1),68// and true otherwise.69bool ExecuteCallback(const uint8_t *Data, size_t Size);70bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,71InputInfo *II = nullptr, bool ForceAddToCorpus = false,72bool *FoundUniqFeatures = nullptr);73void TPCUpdateObservedPCs();7475// Merge Corpora[1:] into Corpora[0].76void Merge(const std::vector<std::string> &Corpora);77void CrashResistantMergeInternalStep(const std::string &ControlFilePath,78bool IsSetCoverMerge);79MutationDispatcher &GetMD() { return MD; }80void PrintFinalStats();81void SetMaxInputLen(size_t MaxInputLen);82void SetMaxMutationLen(size_t MaxMutationLen);83void RssLimitCallback();8485bool InFuzzingThread() const { return IsMyThread; }86size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;87void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,88bool DuringInitialCorpusExecution);8990void HandleMalloc(size_t Size);91static void MaybeExitGracefully();92static int InterruptExitCode();93std::string WriteToOutputCorpus(const Unit &U);9495private:96void AlarmCallback();97void CrashCallback();98void ExitCallback();99void CrashOnOverwrittenData();100void InterruptCallback();101void MutateAndTestOne();102void PurgeAllocator();103void ReportNewCoverage(InputInfo *II, const Unit &U);104void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);105void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);106void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0,107size_t Features = 0);108void PrintStatusForNewUnit(const Unit &U, const char *Text);109void CheckExitOnSrcPosOrItem();110111static void StaticDeathCallback();112void DumpCurrentUnit(const char *Prefix);113void DeathCallback();114115void AllocateCurrentUnitData();116uint8_t *CurrentUnitData = nullptr;117std::atomic<size_t> CurrentUnitSize;118uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.119120bool GracefulExitRequested = false;121122size_t TotalNumberOfRuns = 0;123size_t NumberOfNewUnitsAdded = 0;124125size_t LastCorpusUpdateRun = 0;126127bool HasMoreMallocsThanFrees = false;128size_t NumberOfLeakDetectionAttempts = 0;129130system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now();131132UserCallback CB;133InputCorpus &Corpus;134MutationDispatcher &MD;135FuzzingOptions Options;136DataFlowTrace DFT;137138system_clock::time_point ProcessStartTime = system_clock::now();139system_clock::time_point UnitStartTime, UnitStopTime;140long TimeOfLongestUnitInSeconds = 0;141long EpochOfLastReadOfOutputCorpus = 0;142143size_t MaxInputLen = 0;144size_t MaxMutationLen = 0;145size_t TmpMaxMutationLen = 0;146147std::vector<uint32_t> UniqFeatureSetTmp;148149// Need to know our own thread.150static thread_local bool IsMyThread;151};152153struct ScopedEnableMsanInterceptorChecks {154ScopedEnableMsanInterceptorChecks() {155if (EF->__msan_scoped_enable_interceptor_checks)156EF->__msan_scoped_enable_interceptor_checks();157}158~ScopedEnableMsanInterceptorChecks() {159if (EF->__msan_scoped_disable_interceptor_checks)160EF->__msan_scoped_disable_interceptor_checks();161}162};163164struct ScopedDisableMsanInterceptorChecks {165ScopedDisableMsanInterceptorChecks() {166if (EF->__msan_scoped_disable_interceptor_checks)167EF->__msan_scoped_disable_interceptor_checks();168}169~ScopedDisableMsanInterceptorChecks() {170if (EF->__msan_scoped_enable_interceptor_checks)171EF->__msan_scoped_enable_interceptor_checks();172}173};174175} // namespace fuzzer176177#endif // LLVM_FUZZER_INTERNAL_H178179180