Index: lib/Fuzzer/FuzzerDriver.cpp =================================================================== --- lib/Fuzzer/FuzzerDriver.cpp +++ lib/Fuzzer/FuzzerDriver.cpp @@ -297,7 +297,7 @@ 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 @@ 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) Index: lib/Fuzzer/FuzzerInternal.h =================================================================== --- lib/Fuzzer/FuzzerInternal.h +++ lib/Fuzzer/FuzzerInternal.h @@ -203,9 +203,43 @@ 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 @@ 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 @@ 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 { Index: lib/Fuzzer/FuzzerLoop.cpp =================================================================== --- lib/Fuzzer/FuzzerLoop.cpp +++ lib/Fuzzer/FuzzerLoop.cpp @@ -60,14 +60,13 @@ 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 @@ // 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(); @@ -547,6 +545,7 @@ MD.PrintMutationSequence(); Printf("\n"); } + // PrintASCII(U, "\n"); } void Fuzzer::ReportNewCoverage(const Unit &U) { @@ -675,8 +674,6 @@ assert(NewSize <= Options.MaxLen && "Mutator return overisized unit"); Size = NewSize; - if (Options.OnlyASCII) - ToASCII(CurrentUnitData, Size); if (i == 0) StartTraceRecording(); RunOneAndUpdateCorpus(CurrentUnitData, Size); Index: lib/Fuzzer/FuzzerMutate.cpp =================================================================== --- lib/Fuzzer/FuzzerMutate.cpp +++ lib/Fuzzer/FuzzerMutate.cpp @@ -18,7 +18,9 @@ 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 @@ 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 @@ 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; } Index: lib/Fuzzer/FuzzerTraceState.cpp =================================================================== --- lib/Fuzzer/FuzzerTraceState.cpp +++ lib/Fuzzer/FuzzerTraceState.cpp @@ -173,8 +173,8 @@ 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 @@ } 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 @@ 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; Index: lib/Fuzzer/test/FuzzerUnittest.cpp =================================================================== --- lib/Fuzzer/test/FuzzerUnittest.cpp +++ lib/Fuzzer/test/FuzzerUnittest.cpp @@ -22,7 +22,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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++) {