brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · 8850470 Raw
179 lines · c
1//===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// Define the main class fuzzer::Fuzzer and most functions.9//===----------------------------------------------------------------------===//10 11#ifndef LLVM_FUZZER_INTERNAL_H12#define LLVM_FUZZER_INTERNAL_H13 14#include "FuzzerDataFlowTrace.h"15#include "FuzzerDefs.h"16#include "FuzzerExtFunctions.h"17#include "FuzzerInterface.h"18#include "FuzzerOptions.h"19#include "FuzzerSHA1.h"20#include "FuzzerValueBitMap.h"21#include <algorithm>22#include <atomic>23#include <chrono>24#include <climits>25#include <cstdlib>26#include <string.h>27 28namespace fuzzer {29 30using namespace std::chrono;31 32class Fuzzer final {33public:34  Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,35         const FuzzingOptions &Options);36  ~Fuzzer() = delete;37  void Loop(std::vector<SizedFile> &CorporaFiles);38  void ReadAndExecuteSeedCorpora(std::vector<SizedFile> &CorporaFiles);39  void MinimizeCrashLoop(const Unit &U);40  void RereadOutputCorpus(size_t MaxSize);41 42  size_t secondsSinceProcessStartUp() {43    return duration_cast<seconds>(system_clock::now() - ProcessStartTime)44        .count();45  }46 47  bool TimedOut() {48    return Options.MaxTotalTimeSec > 0 &&49           secondsSinceProcessStartUp() >50               static_cast<size_t>(Options.MaxTotalTimeSec);51  }52 53  size_t execPerSec() {54    size_t Seconds = secondsSinceProcessStartUp();55    return Seconds ? TotalNumberOfRuns / Seconds : 0;56  }57 58  size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }59 60  static void StaticAlarmCallback();61  static void StaticCrashSignalCallback();62  static void StaticExitCallback();63  static void StaticInterruptCallback();64  static void StaticFileSizeExceedCallback();65  static void StaticGracefulExitCallback();66 67  // Executes the target callback on {Data, Size} once.68  // Returns false if the input was rejected by the target (target returned -1),69  // and true otherwise.70  bool ExecuteCallback(const uint8_t *Data, size_t Size);71  bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,72              InputInfo *II = nullptr, bool ForceAddToCorpus = false,73              bool *FoundUniqFeatures = nullptr);74  void TPCUpdateObservedPCs();75 76  // Merge Corpora[1:] into Corpora[0].77  void Merge(const std::vector<std::string> &Corpora);78  void CrashResistantMergeInternalStep(const std::string &ControlFilePath,79                                       bool IsSetCoverMerge);80  MutationDispatcher &GetMD() { return MD; }81  void PrintFinalStats();82  void SetMaxInputLen(size_t MaxInputLen);83  void SetMaxMutationLen(size_t MaxMutationLen);84  void RssLimitCallback();85 86  bool InFuzzingThread() const { return IsMyThread; }87  size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;88  void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,89                               bool DuringInitialCorpusExecution);90 91  void HandleMalloc(size_t Size);92  static void MaybeExitGracefully();93  static int InterruptExitCode();94  std::string WriteToOutputCorpus(const Unit &U);95 96private:97  void AlarmCallback();98  void CrashCallback();99  void ExitCallback();100  void CrashOnOverwrittenData();101  void InterruptCallback();102  void MutateAndTestOne();103  void PurgeAllocator();104  void ReportNewCoverage(InputInfo *II, const Unit &U);105  void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);106  void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);107  void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0,108                  size_t Features = 0);109  void PrintStatusForNewUnit(const Unit &U, const char *Text);110  void CheckExitOnSrcPosOrItem();111 112  static void StaticDeathCallback();113  void DumpCurrentUnit(const char *Prefix);114  void DeathCallback();115 116  void AllocateCurrentUnitData();117  uint8_t *CurrentUnitData = nullptr;118  std::atomic<size_t> CurrentUnitSize;119  uint8_t BaseSha1[kSHA1NumBytes];  // Checksum of the base unit.120 121  bool GracefulExitRequested = false;122 123  size_t TotalNumberOfRuns = 0;124  size_t NumberOfNewUnitsAdded = 0;125 126  size_t LastCorpusUpdateRun = 0;127 128  bool HasMoreMallocsThanFrees = false;129  size_t NumberOfLeakDetectionAttempts = 0;130 131  system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now();132 133  UserCallback CB;134  InputCorpus &Corpus;135  MutationDispatcher &MD;136  FuzzingOptions Options;137  DataFlowTrace DFT;138 139  system_clock::time_point ProcessStartTime = system_clock::now();140  system_clock::time_point UnitStartTime, UnitStopTime;141  long TimeOfLongestUnitInSeconds = 0;142  long EpochOfLastReadOfOutputCorpus = 0;143 144  size_t MaxInputLen = 0;145  size_t MaxMutationLen = 0;146  size_t TmpMaxMutationLen = 0;147 148  std::vector<uint32_t> UniqFeatureSetTmp;149 150  // Need to know our own thread.151  static thread_local bool IsMyThread;152};153 154struct ScopedEnableMsanInterceptorChecks {155  ScopedEnableMsanInterceptorChecks() {156    if (EF->__msan_scoped_enable_interceptor_checks)157      EF->__msan_scoped_enable_interceptor_checks();158  }159  ~ScopedEnableMsanInterceptorChecks() {160    if (EF->__msan_scoped_disable_interceptor_checks)161      EF->__msan_scoped_disable_interceptor_checks();162  }163};164 165struct ScopedDisableMsanInterceptorChecks {166  ScopedDisableMsanInterceptorChecks() {167    if (EF->__msan_scoped_disable_interceptor_checks)168      EF->__msan_scoped_disable_interceptor_checks();169  }170  ~ScopedDisableMsanInterceptorChecks() {171    if (EF->__msan_scoped_enable_interceptor_checks)172      EF->__msan_scoped_enable_interceptor_checks();173  }174};175 176} // namespace fuzzer177 178#endif // LLVM_FUZZER_INTERNAL_H179