void Fuzzer::MutateAndTestOne() { MD.StartMutationSequence(); auto &U = ChooseUnitToMutate(); MutateInPlaceHere.resize(Options.MaxLen); size_t Size = U.size(); assert(Size <= Options.MaxLen && "Oversized Unit"); memcpy(MutateInPlaceHere.data(), U.data(), Size); for (int i = 0; i < Options.MutateDepth; i++) { size_t NewSize = 0; if (LLVMFuzzerCustomMutator) NewSize = LLVMFuzzerCustomMutator(MutateInPlaceHere.data(), Size, Options.MaxLen, MD.GetRand().Rand()); else NewSize = MD.Mutate(MutateInPlaceHere.data(), Size, Options.MaxLen); assert(NewSize > 0 && "Mutator returned empty unit"); assert(NewSize <= Options.MaxLen && "Mutator return overisized unit"); Size = NewSize; if (i == 0) StartTraceRecording(); RunOneAndUpdateCorpus(MutateInPlaceHere.data(), Size); StopTraceRecording(); TryDetectingAMemoryLeak(MutateInPlaceHere.data(), Size); } }
// Experimental search heuristic: drilling. // - Read, shuffle, execute and minimize the corpus. // - Choose one random unit. // - Reset the coverage. // - Start fuzzing as if the chosen unit was the only element of the corpus. // - When done, reset the coverage again. // - Merge the newly created corpus into the original one. void Fuzzer::Drill() { // The corpus is already read, shuffled, and minimized. assert(!Corpus.empty()); Options.PrintNEW = false; // Don't print NEW status lines when drilling. Unit U = ChooseUnitToMutate(); CHECK_WEAK_API_FUNCTION(__sanitizer_reset_coverage); __sanitizer_reset_coverage(); std::vector<Unit> SavedCorpus; SavedCorpus.swap(Corpus); Corpus.push_back(U); assert(Corpus.size() == 1); RunOne(U); PrintStats("DRILL "); std::string SavedOutputCorpusPath; // Don't write new units while drilling. SavedOutputCorpusPath.swap(Options.OutputCorpus); Loop(); __sanitizer_reset_coverage(); PrintStats("REINIT"); SavedOutputCorpusPath.swap(Options.OutputCorpus); for (auto &U : SavedCorpus) { CurrentUnit = U; RunOne(U); } PrintStats("MERGE "); Options.PrintNEW = true; size_t NumMerged = 0; for (auto &U : Corpus) { CurrentUnit = U; if (RunOne(U)) { PrintStatusForNewUnit(U); NumMerged++; WriteToOutputCorpus(U); } } PrintStats("MERGED"); if (NumMerged && Options.Verbosity) Printf("Drilling discovered %zd new units\n", NumMerged); }
void Fuzzer::MutateAndTestOne() { auto &U = CurrentUnit; USF.StartMutationSequence(); U = ChooseUnitToMutate(); for (int i = 0; i < Options.MutateDepth; i++) { size_t Size = U.size(); U.resize(Options.MaxLen); size_t NewSize = USF.Mutate(U.data(), Size, U.size()); assert(NewSize > 0 && "Mutator returned empty unit"); assert(NewSize <= (size_t)Options.MaxLen && "Mutator return overisized unit"); U.resize(NewSize); if (i == 0) StartTraceRecording(); RunOneAndUpdateCorpus(U); StopTraceRecording(); } }