FuzzerInternal.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. //===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // Define the main class fuzzer::Fuzzer and most functions.
  10. //===----------------------------------------------------------------------===//
  11. #include <cassert>
  12. #include <climits>
  13. #include <chrono>
  14. #include <cstddef>
  15. #include <cstdlib>
  16. #include <string>
  17. #include <vector>
  18. #include <unordered_set>
  19. #include "FuzzerInterface.h"
  20. namespace fuzzer {
  21. typedef std::vector<uint8_t> Unit;
  22. using namespace std::chrono;
  23. std::string FileToString(const std::string &Path);
  24. Unit FileToVector(const std::string &Path);
  25. void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
  26. long *Epoch);
  27. void WriteToFile(const Unit &U, const std::string &Path);
  28. void CopyFileToErr(const std::string &Path);
  29. // Returns "Dir/FileName" or equivalent for the current OS.
  30. std::string DirPlusFile(const std::string &DirPath,
  31. const std::string &FileName);
  32. size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
  33. size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
  34. size_t Size2, uint8_t *Out, size_t MaxOutSize);
  35. void Printf(const char *Fmt, ...);
  36. void Print(const Unit &U, const char *PrintAfter = "");
  37. void PrintASCII(const Unit &U, const char *PrintAfter = "");
  38. std::string Hash(const Unit &U);
  39. void SetTimer(int Seconds);
  40. void PrintFileAsBase64(const std::string &Path);
  41. void ExecuteCommand(const std::string &Command);
  42. // Private copy of SHA1 implementation.
  43. static const int kSHA1NumBytes = 20;
  44. // Computes SHA1 hash of 'Len' bytes in 'Data', writes kSHA1NumBytes to 'Out'.
  45. void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out);
  46. int NumberOfCpuCores();
  47. class Fuzzer {
  48. public:
  49. struct FuzzingOptions {
  50. int Verbosity = 1;
  51. int MaxLen = 0;
  52. int UnitTimeoutSec = 300;
  53. bool DoCrossOver = true;
  54. int MutateDepth = 5;
  55. bool ExitOnFirst = false;
  56. bool UseCounters = false;
  57. bool UseTraces = false;
  58. bool UseFullCoverageSet = false;
  59. bool Reload = true;
  60. int PreferSmallDuringInitialShuffle = -1;
  61. size_t MaxNumberOfRuns = ULONG_MAX;
  62. int SyncTimeout = 600;
  63. std::string OutputCorpus;
  64. std::string SyncCommand;
  65. std::vector<std::string> Tokens;
  66. };
  67. Fuzzer(UserSuppliedFuzzer &USF, FuzzingOptions Options);
  68. void AddToCorpus(const Unit &U) { Corpus.push_back(U); }
  69. void Loop(size_t NumIterations);
  70. void ShuffleAndMinimize();
  71. void InitializeTraceState();
  72. size_t CorpusSize() const { return Corpus.size(); }
  73. void ReadDir(const std::string &Path, long *Epoch) {
  74. ReadDirToVectorOfUnits(Path.c_str(), &Corpus, Epoch);
  75. }
  76. void RereadOutputCorpus();
  77. // Save the current corpus to OutputCorpus.
  78. void SaveCorpus();
  79. size_t secondsSinceProcessStartUp() {
  80. return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
  81. .count();
  82. }
  83. size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
  84. static void StaticAlarmCallback();
  85. Unit SubstituteTokens(const Unit &U) const;
  86. private:
  87. void AlarmCallback();
  88. void ExecuteCallback(const Unit &U);
  89. void MutateAndTestOne(Unit *U);
  90. void ReportNewCoverage(size_t NewCoverage, const Unit &U);
  91. size_t RunOne(const Unit &U);
  92. void RunOneAndUpdateCorpus(const Unit &U);
  93. size_t RunOneMaximizeTotalCoverage(const Unit &U);
  94. size_t RunOneMaximizeFullCoverageSet(const Unit &U);
  95. size_t RunOneMaximizeCoveragePairs(const Unit &U);
  96. void WriteToOutputCorpus(const Unit &U);
  97. void WriteToCrash(const Unit &U, const char *Prefix);
  98. void PrintStats(const char *Where, size_t Cov, const char *End = "\n");
  99. void PrintUnitInASCIIOrTokens(const Unit &U, const char *PrintAfter = "");
  100. void SyncCorpus();
  101. // Trace-based fuzzing: we run a unit with some kind of tracing
  102. // enabled and record potentially useful mutations. Then
  103. // We apply these mutations one by one to the unit and run it again.
  104. // Start tracing; forget all previously proposed mutations.
  105. void StartTraceRecording();
  106. // Stop tracing and return the number of proposed mutations.
  107. size_t StopTraceRecording();
  108. // Apply Idx-th trace-based mutation to U.
  109. void ApplyTraceBasedMutation(size_t Idx, Unit *U);
  110. void SetDeathCallback();
  111. static void StaticDeathCallback();
  112. void DeathCallback();
  113. Unit CurrentUnit;
  114. size_t TotalNumberOfRuns = 0;
  115. std::vector<Unit> Corpus;
  116. std::unordered_set<std::string> UnitHashesAddedToCorpus;
  117. std::unordered_set<uintptr_t> FullCoverageSets;
  118. // For UseCounters
  119. std::vector<uint8_t> CounterBitmap;
  120. size_t TotalBits() { // Slow. Call it only for printing stats.
  121. size_t Res = 0;
  122. for (auto x : CounterBitmap) Res += __builtin_popcount(x);
  123. return Res;
  124. }
  125. UserSuppliedFuzzer &USF;
  126. FuzzingOptions Options;
  127. system_clock::time_point ProcessStartTime = system_clock::now();
  128. system_clock::time_point LastExternalSync = system_clock::now();
  129. system_clock::time_point UnitStartTime;
  130. long TimeOfLongestUnitInSeconds = 0;
  131. long EpochOfLastReadOfOutputCorpus = 0;
  132. };
  133. class SimpleUserSuppliedFuzzer: public UserSuppliedFuzzer {
  134. public:
  135. SimpleUserSuppliedFuzzer(UserCallback Callback) : Callback(Callback) {}
  136. virtual void TargetFunction(const uint8_t *Data, size_t Size) {
  137. return Callback(Data, Size);
  138. }
  139. private:
  140. UserCallback Callback;
  141. };
  142. }; // namespace fuzzer