FuzzerMerge.h 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //===- FuzzerMerge.h - merging corpa ----------------------------*- 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. // Merging Corpora.
  9. //
  10. // The task:
  11. // Take the existing corpus (possibly empty) and merge new inputs into
  12. // it so that only inputs with new coverage ('features') are added.
  13. // The process should tolerate the crashes, OOMs, leaks, etc.
  14. //
  15. // Algorithm:
  16. // The outter process collects the set of files and writes their names
  17. // into a temporary "control" file, then repeatedly launches the inner
  18. // process until all inputs are processed.
  19. // The outer process does not actually execute the target code.
  20. //
  21. // The inner process reads the control file and sees a) list of all the inputs
  22. // and b) the last processed input. Then it starts processing the inputs one
  23. // by one. Before processing every input it writes one line to control file:
  24. // STARTED INPUT_ID INPUT_SIZE
  25. // After processing an input it write another line:
  26. // DONE INPUT_ID Feature1 Feature2 Feature3 ...
  27. // If a crash happens while processing an input the last line in the control
  28. // file will be "STARTED INPUT_ID" and so the next process will know
  29. // where to resume.
  30. //
  31. // Once all inputs are processed by the innner process(es) the outer process
  32. // reads the control files and does the merge based entirely on the contents
  33. // of control file.
  34. // It uses a single pass greedy algorithm choosing first the smallest inputs
  35. // within the same size the inputs that have more new features.
  36. //
  37. //===----------------------------------------------------------------------===//
  38. #ifndef LLVM_FUZZER_MERGE_H
  39. #define LLVM_FUZZER_MERGE_H
  40. #include "FuzzerDefs.h"
  41. #include <istream>
  42. #include <ostream>
  43. #include <set>
  44. #include <vector>
  45. namespace fuzzer {
  46. struct MergeFileInfo {
  47. std::string Name;
  48. size_t Size = 0;
  49. Vector<uint32_t> Features, Cov;
  50. };
  51. struct Merger {
  52. Vector<MergeFileInfo> Files;
  53. size_t NumFilesInFirstCorpus = 0;
  54. size_t FirstNotProcessedFile = 0;
  55. std::string LastFailure;
  56. bool Parse(std::istream &IS, bool ParseCoverage);
  57. bool Parse(const std::string &Str, bool ParseCoverage);
  58. void ParseOrExit(std::istream &IS, bool ParseCoverage);
  59. size_t Merge(const Set<uint32_t> &InitialFeatures, Set<uint32_t> *NewFeatures,
  60. const Set<uint32_t> &InitialCov, Set<uint32_t> *NewCov,
  61. Vector<std::string> *NewFiles);
  62. size_t ApproximateMemoryConsumption() const;
  63. Set<uint32_t> AllFeatures() const;
  64. };
  65. void CrashResistantMerge(const Vector<std::string> &Args,
  66. const Vector<SizedFile> &OldCorpus,
  67. const Vector<SizedFile> &NewCorpus,
  68. Vector<std::string> *NewFiles,
  69. const Set<uint32_t> &InitialFeatures,
  70. Set<uint32_t> *NewFeatures,
  71. const Set<uint32_t> &InitialCov,
  72. Set<uint32_t> *NewCov,
  73. const std::string &CFPath,
  74. bool Verbose);
  75. } // namespace fuzzer
  76. #endif // LLVM_FUZZER_MERGE_H