void Fuzzer::MutateAndTestOne(Unit *U) { for (int i = 0; i < Options.MutateDepth; i++) { StartTraceRecording(); 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); RunOneAndUpdateCorpus(*U); size_t NumTraceBasedMutations = StopTraceRecording(); size_t TBMWidth = std::min((size_t)Options.TBMWidth, NumTraceBasedMutations); size_t TBMDepth = std::min((size_t)Options.TBMDepth, NumTraceBasedMutations); Unit BackUp = *U; for (size_t w = 0; w < TBMWidth; w++) { *U = BackUp; for (size_t d = 0; d < TBMDepth; d++) { TotalNumberOfExecutedTraceBasedMutations++; ApplyTraceBasedMutation(USF.GetRand()(NumTraceBasedMutations), U); RunOneAndUpdateCorpus(*U); } } } }
void Fuzzer::MutateAndTestOne(Unit *U) { for (int i = 0; i < Options.MutateDepth; i++) { StartTraceRecording(); Mutate(U, Options.MaxLen); RunOneAndUpdateCorpus(*U); size_t NumTraceBasedMutations = StopTraceRecording(); for (size_t j = 0; j < NumTraceBasedMutations; j++) { ApplyTraceBasedMutation(j, U); RunOneAndUpdateCorpus(*U); } } }
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); } }
// Tries detecting a memory leak on the particular input that we have just // executed before calling this function. void Fuzzer::TryDetectingAMemoryLeak(uint8_t *Data, size_t Size) { if (!HasMoreMallocsThanFrees) return; // mallocs==frees, a leak is unlikely. if (!Options.DetectLeaks) return; if (!&__lsan_enable || !&__lsan_disable || !__lsan_do_recoverable_leak_check) return; // No lsan. // Run the target once again, but with lsan disabled so that if there is // a real leak we do not report it twice. __lsan_disable(); RunOneAndUpdateCorpus(Data, Size); __lsan_enable(); if (!HasMoreMallocsThanFrees) return; // a leak is unlikely. if (NumberOfLeakDetectionAttempts++ > 1000) { Options.DetectLeaks = false; Printf("INFO: libFuzzer disabled leak detection after every mutation.\n" " Most likely the target function accumulates allocated\n" " memory in a global state w/o actually leaking it.\n" " If LeakSanitizer is enabled in this process it will still\n" " run on the process shutdown.\n"); return; } // Now perform the actual lsan pass. This is expensive and we must ensure // we don't call it too often. if (__lsan_do_recoverable_leak_check()) { // Leak is found, report it. CurrentUnitData = Data; CurrentUnitSize = Size; DumpCurrentUnit("leak-"); PrintFinalStats(); _Exit(Options.ErrorExitCode); // not exit() to disable lsan further on. } }
void Fuzzer::MutateAndTestOne(Unit *U) { for (int i = 0; i < Options.MutateDepth; i++) { StartTraceRecording(); 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); RunOneAndUpdateCorpus(*U); size_t NumTraceBasedMutations = StopTraceRecording(); for (size_t j = 0; j < NumTraceBasedMutations; j++) { ApplyTraceBasedMutation(j, U); RunOneAndUpdateCorpus(*U); } } }
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(); } }