diff --git a/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp index 08a5e19ce75a..ba6edb33f39b 100644 --- a/llvm/lib/Fuzzer/FuzzerDriver.cpp +++ b/llvm/lib/Fuzzer/FuzzerDriver.cpp @@ -297,7 +297,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { const size_t kMaxSaneLen = 1 << 20; const size_t kMinDefaultLen = 64; - Fuzzer::FuzzingOptions Options; + FuzzingOptions Options; Options.Verbosity = Flags.verbosity; Options.MaxLen = Flags.max_len; Options.UnitTimeoutSec = Flags.timeout; @@ -347,7 +347,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { Printf("INFO: Seed: %u\n", Seed); Random Rand(Seed); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, Options); Fuzzer F(Callback, MD, Options); for (auto &U: Dictionary) diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h index 6fb429e705e5..d27ac8684fc0 100644 --- a/llvm/lib/Fuzzer/FuzzerInternal.h +++ b/llvm/lib/Fuzzer/FuzzerInternal.h @@ -203,9 +203,43 @@ private: size_t Size = 0; }; +struct FuzzingOptions { + int Verbosity = 1; + size_t MaxLen = 0; + int UnitTimeoutSec = 300; + int TimeoutExitCode = 77; + int ErrorExitCode = 77; + int MaxTotalTimeSec = 0; + int RssLimitMb = 0; + bool DoCrossOver = true; + int MutateDepth = 5; + bool UseCounters = false; + bool UseIndirCalls = true; + bool UseTraces = false; + bool UseMemcmp = true; + bool UseFullCoverageSet = false; + bool Reload = true; + bool ShuffleAtStartUp = true; + bool PreferSmall = true; + size_t MaxNumberOfRuns = ULONG_MAX; + int ReportSlowUnits = 10; + bool OnlyASCII = false; + std::string OutputCorpus; + std::string ArtifactPrefix = "./"; + std::string ExactArtifactPath; + bool SaveArtifacts = true; + bool PrintNEW = true; // Print a status line when new units are found; + bool OutputCSV = false; + bool PrintNewCovPcs = false; + bool PrintFinalStats = false; + bool DetectLeaks = true; + bool TruncateUnits = false; + bool PruneCorpus = true; +}; + class MutationDispatcher { public: - MutationDispatcher(Random &Rand); + MutationDispatcher(Random &Rand, const FuzzingOptions &Options); ~MutationDispatcher() {} /// Indicate that we are about to start a new sequence of mutations. void StartMutationSequence(); @@ -280,6 +314,8 @@ private: const std::vector &Mutators); Random &Rand; + const FuzzingOptions Options; + // Dictionary provided by the user via -dict=DICT_FILE. Dictionary ManualDictionary; // Temporary dictionary modified by the fuzzer itself, @@ -299,39 +335,6 @@ private: class Fuzzer { public: - struct FuzzingOptions { - int Verbosity = 1; - size_t MaxLen = 0; - int UnitTimeoutSec = 300; - int TimeoutExitCode = 77; - int ErrorExitCode = 77; - int MaxTotalTimeSec = 0; - int RssLimitMb = 0; - bool DoCrossOver = true; - int MutateDepth = 5; - bool UseCounters = false; - bool UseIndirCalls = true; - bool UseTraces = false; - bool UseMemcmp = true; - bool UseFullCoverageSet = false; - bool Reload = true; - bool ShuffleAtStartUp = true; - bool PreferSmall = true; - size_t MaxNumberOfRuns = ULONG_MAX; - int ReportSlowUnits = 10; - bool OnlyASCII = false; - std::string OutputCorpus; - std::string ArtifactPrefix = "./"; - std::string ExactArtifactPath; - bool SaveArtifacts = true; - bool PrintNEW = true; // Print a status line when new units are found; - bool OutputCSV = false; - bool PrintNewCovPcs = false; - bool PrintFinalStats = false; - bool DetectLeaks = true; - bool TruncateUnits = false; - bool PruneCorpus = true; - }; // Aggregates all available coverage measurements. struct Coverage { diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 51cb8703c26d..89db5e0ac0a1 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -60,14 +60,13 @@ struct CoverageController { PcMapResetCurrent(); } - static void ResetCounters(const Fuzzer::FuzzingOptions &Options) { + static void ResetCounters(const FuzzingOptions &Options) { if (Options.UseCounters) { EF->__sanitizer_update_counter_bitset_and_clear_counters(0); } } - static void Prepare(const Fuzzer::FuzzingOptions &Options, - Fuzzer::Coverage *C) { + static void Prepare(const FuzzingOptions &Options, Fuzzer::Coverage *C) { if (Options.UseCounters) { size_t NumCounters = EF->__sanitizer_get_number_of_counters(); C->CounterBitmap.resize(NumCounters); @@ -76,8 +75,7 @@ struct CoverageController { // Records data to a maximum coverage tracker. Returns true if additional // coverage was discovered. - static bool RecordMax(const Fuzzer::FuzzingOptions &Options, - Fuzzer::Coverage *C) { + static bool RecordMax(const FuzzingOptions &Options, Fuzzer::Coverage *C) { bool Res = false; uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage(); @@ -675,8 +673,6 @@ void Fuzzer::MutateAndTestOne() { assert(NewSize <= Options.MaxLen && "Mutator return overisized unit"); Size = NewSize; - if (Options.OnlyASCII) - ToASCII(CurrentUnitData, Size); if (i == 0) StartTraceRecording(); RunOneAndUpdateCorpus(CurrentUnitData, Size); diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp index bd82c0dee590..72b095d651a0 100644 --- a/llvm/lib/Fuzzer/FuzzerMutate.cpp +++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp @@ -18,7 +18,9 @@ namespace fuzzer { const size_t Dictionary::kMaxDictSize; -MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) { +MutationDispatcher::MutationDispatcher(Random &Rand, + const FuzzingOptions &Options) + : Rand(Rand), Options(Options) { DefaultMutators.insert( DefaultMutators.begin(), { @@ -285,6 +287,8 @@ size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size, if (Size == 0) { for (size_t i = 0; i < MaxSize; i++) Data[i] = RandCh(Rand); + if (Options.OnlyASCII) + ToASCII(Data, MaxSize); return MaxSize; } assert(Size > 0); @@ -295,6 +299,8 @@ size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size, auto M = Mutators[Rand(Mutators.size())]; size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize); if (NewSize) { + if (Options.OnlyASCII) + ToASCII(Data, NewSize); CurrentMutatorSequence.push_back(M); return NewSize; } diff --git a/llvm/lib/Fuzzer/FuzzerTraceState.cpp b/llvm/lib/Fuzzer/FuzzerTraceState.cpp index 3ee69e43abaf..cbfa87d21088 100644 --- a/llvm/lib/Fuzzer/FuzzerTraceState.cpp +++ b/llvm/lib/Fuzzer/FuzzerTraceState.cpp @@ -173,8 +173,8 @@ static bool RecordingTraces = false; static bool RecordingMemcmp = false; class TraceState { - public: - TraceState(MutationDispatcher &MD, const Fuzzer::FuzzingOptions &Options, +public: + TraceState(MutationDispatcher &MD, const FuzzingOptions &Options, const Fuzzer *F) : MD(MD), Options(Options), F(F) {} @@ -209,7 +209,8 @@ class TraceState { } void StopTraceRecording() { - if (!RecordingTraces && !RecordingMemcmp) return; + if (!RecordingTraces && !RecordingMemcmp) + return; RecordingTraces = false; RecordingMemcmp = false; for (size_t i = 0; i < NumMutations; i++) { @@ -287,7 +288,7 @@ class TraceState { LabelRange LabelRanges[1 << (sizeof(dfsan_label) * 8)]; size_t LastDfsanLabel = 0; MutationDispatcher &MD; - const Fuzzer::FuzzingOptions &Options; + const FuzzingOptions Options; const Fuzzer *F; std::map AutoDictUnitCounts; size_t AutoDictAdds = 0; diff --git a/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp b/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp index 5b6251b6e96b..3630e39a24ae 100644 --- a/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp +++ b/llvm/lib/Fuzzer/test/FuzzerUnittest.cpp @@ -22,7 +22,7 @@ TEST(Fuzzer, CrossOver) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); Unit A({0, 1, 2}), B({5, 6, 7}); Unit C; Unit Expected[] = { @@ -100,7 +100,7 @@ void TestEraseByte(Mutator M, int NumIter) { uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77}; uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); int FoundMask = 0; for (int i = 0; i < NumIter; i++) { uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; @@ -128,7 +128,7 @@ void TestInsertByte(Mutator M, int NumIter) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); int FoundMask = 0; uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; @@ -164,7 +164,7 @@ void TestChangeByte(Mutator M, int NumIter) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); int FoundMask = 0; uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; @@ -200,7 +200,7 @@ void TestChangeBit(Mutator M, int NumIter) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); int FoundMask = 0; uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; @@ -236,7 +236,7 @@ void TestShuffleBytes(Mutator M, int NumIter) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); int FoundMask = 0; uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66}; uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66}; @@ -266,7 +266,7 @@ void TestAddWordFromDictionary(Mutator M, int NumIter) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD}; uint8_t Word2[3] = {0xFF, 0xEE, 0xEF}; MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1))); @@ -308,7 +308,7 @@ void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF}; size_t PosHint = 7777; MD.AddWordToAutoDictionary(Word(W, sizeof(W)), PosHint); @@ -337,7 +337,7 @@ void TestChangeASCIIInteger(Mutator M, int NumIter) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); + MutationDispatcher MD(Rand, {}); uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'}; uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'}; @@ -431,9 +431,8 @@ TEST(Corpus, Distribution) { std::unique_ptr t(new ExternalFunctions()); fuzzer::EF = t.get(); Random Rand(0); - MutationDispatcher MD(Rand); - Fuzzer::FuzzingOptions Options; - Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, Options); + MutationDispatcher MD(Rand, {}); + Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, {}); size_t N = 10; size_t TriesPerUnit = 1<<20; for (size_t i = 0; i < N; i++) {