FuzzerInternal.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // Define the main class fuzzer::Fuzzer and most functions.
  9. //===----------------------------------------------------------------------===//
  10. #ifndef LLVM_FUZZER_INTERNAL_H
  11. #define LLVM_FUZZER_INTERNAL_H
  12. #include "FuzzerDataFlowTrace.h"
  13. #include "FuzzerDefs.h"
  14. #include "FuzzerExtFunctions.h"
  15. #include "FuzzerInterface.h"
  16. #include "FuzzerOptions.h"
  17. #include "FuzzerSHA1.h"
  18. #include "FuzzerValueBitMap.h"
  19. #include <algorithm>
  20. #include <atomic>
  21. #include <chrono>
  22. #include <climits>
  23. #include <cstdlib>
  24. #include <string.h>
  25. namespace fuzzer {
  26. using namespace std::chrono;
  27. class Fuzzer {
  28. public:
  29. Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
  30. FuzzingOptions Options);
  31. ~Fuzzer();
  32. void Loop(std::vector<SizedFile> &CorporaFiles);
  33. void ReadAndExecuteSeedCorpora(std::vector<SizedFile> &CorporaFiles);
  34. void MinimizeCrashLoop(const Unit &U);
  35. void RereadOutputCorpus(size_t MaxSize);
  36. size_t secondsSinceProcessStartUp() {
  37. return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
  38. .count();
  39. }
  40. bool TimedOut() {
  41. return Options.MaxTotalTimeSec > 0 &&
  42. secondsSinceProcessStartUp() >
  43. static_cast<size_t>(Options.MaxTotalTimeSec);
  44. }
  45. size_t execPerSec() {
  46. size_t Seconds = secondsSinceProcessStartUp();
  47. return Seconds ? TotalNumberOfRuns / Seconds : 0;
  48. }
  49. size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
  50. static void StaticAlarmCallback();
  51. static void StaticCrashSignalCallback();
  52. static void StaticExitCallback();
  53. static void StaticInterruptCallback();
  54. static void StaticFileSizeExceedCallback();
  55. static void StaticGracefulExitCallback();
  56. // Executes the target callback on {Data, Size} once.
  57. // Returns false if the input was rejected by the target (target returned -1),
  58. // and true otherwise.
  59. bool ExecuteCallback(const uint8_t *Data, size_t Size);
  60. bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
  61. InputInfo *II = nullptr, bool ForceAddToCorpus = false,
  62. bool *FoundUniqFeatures = nullptr);
  63. void TPCUpdateObservedPCs();
  64. // Merge Corpora[1:] into Corpora[0].
  65. void Merge(const std::vector<std::string> &Corpora);
  66. void CrashResistantMergeInternalStep(const std::string &ControlFilePath,
  67. bool IsSetCoverMerge);
  68. MutationDispatcher &GetMD() { return MD; }
  69. void PrintFinalStats();
  70. void SetMaxInputLen(size_t MaxInputLen);
  71. void SetMaxMutationLen(size_t MaxMutationLen);
  72. void RssLimitCallback();
  73. bool InFuzzingThread() const { return IsMyThread; }
  74. size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
  75. void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
  76. bool DuringInitialCorpusExecution);
  77. void HandleMalloc(size_t Size);
  78. static void MaybeExitGracefully();
  79. std::string WriteToOutputCorpus(const Unit &U);
  80. private:
  81. void AlarmCallback();
  82. void CrashCallback();
  83. void ExitCallback();
  84. void CrashOnOverwrittenData();
  85. void InterruptCallback();
  86. void MutateAndTestOne();
  87. void PurgeAllocator();
  88. void ReportNewCoverage(InputInfo *II, const Unit &U);
  89. void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);
  90. void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
  91. void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0,
  92. size_t Features = 0);
  93. void PrintStatusForNewUnit(const Unit &U, const char *Text);
  94. void CheckExitOnSrcPosOrItem();
  95. static void StaticDeathCallback();
  96. void DumpCurrentUnit(const char *Prefix);
  97. void DeathCallback();
  98. void AllocateCurrentUnitData();
  99. uint8_t *CurrentUnitData = nullptr;
  100. std::atomic<size_t> CurrentUnitSize;
  101. uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
  102. bool GracefulExitRequested = false;
  103. size_t TotalNumberOfRuns = 0;
  104. size_t NumberOfNewUnitsAdded = 0;
  105. size_t LastCorpusUpdateRun = 0;
  106. bool HasMoreMallocsThanFrees = false;
  107. size_t NumberOfLeakDetectionAttempts = 0;
  108. system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now();
  109. UserCallback CB;
  110. InputCorpus &Corpus;
  111. MutationDispatcher &MD;
  112. FuzzingOptions Options;
  113. DataFlowTrace DFT;
  114. system_clock::time_point ProcessStartTime = system_clock::now();
  115. system_clock::time_point UnitStartTime, UnitStopTime;
  116. long TimeOfLongestUnitInSeconds = 0;
  117. long EpochOfLastReadOfOutputCorpus = 0;
  118. size_t MaxInputLen = 0;
  119. size_t MaxMutationLen = 0;
  120. size_t TmpMaxMutationLen = 0;
  121. std::vector<uint32_t> UniqFeatureSetTmp;
  122. // Need to know our own thread.
  123. static thread_local bool IsMyThread;
  124. };
  125. struct ScopedEnableMsanInterceptorChecks {
  126. ScopedEnableMsanInterceptorChecks() {
  127. if (EF->__msan_scoped_enable_interceptor_checks)
  128. EF->__msan_scoped_enable_interceptor_checks();
  129. }
  130. ~ScopedEnableMsanInterceptorChecks() {
  131. if (EF->__msan_scoped_disable_interceptor_checks)
  132. EF->__msan_scoped_disable_interceptor_checks();
  133. }
  134. };
  135. struct ScopedDisableMsanInterceptorChecks {
  136. ScopedDisableMsanInterceptorChecks() {
  137. if (EF->__msan_scoped_disable_interceptor_checks)
  138. EF->__msan_scoped_disable_interceptor_checks();
  139. }
  140. ~ScopedDisableMsanInterceptorChecks() {
  141. if (EF->__msan_scoped_enable_interceptor_checks)
  142. EF->__msan_scoped_enable_interceptor_checks();
  143. }
  144. };
  145. } // namespace fuzzer
  146. #endif // LLVM_FUZZER_INTERNAL_H