forked from OSchip/llvm-project
[libFuzzer] when there is a leak in the existing corpus report the reproducer properly
llvm-svn: 270905
This commit is contained in:
parent
e19b95d879
commit
4b92326b17
|
@ -415,8 +415,8 @@ private:
|
|||
void PrintStats(const char *Where, const char *End = "\n");
|
||||
void PrintStatusForNewUnit(const Unit &U);
|
||||
void ShuffleCorpus(UnitVector *V);
|
||||
void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size);
|
||||
void CheckForMemoryLeaks();
|
||||
void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
|
||||
bool DuringInitialCorpusExecution);
|
||||
|
||||
// Updates the probability distribution for the units in the corpus.
|
||||
// Must be called whenever the corpus or unit weights are changed.
|
||||
|
|
|
@ -409,13 +409,14 @@ void Fuzzer::ShuffleAndMinimize() {
|
|||
if (Options.Verbosity >= 2)
|
||||
Printf("NEW0: %zd L %zd\n", MaxCoverage.BlockCoverage, U.size());
|
||||
}
|
||||
TryDetectingAMemoryLeak(U.data(), U.size(),
|
||||
/*DuringInitialCorpusExecution*/ true);
|
||||
}
|
||||
Corpus = NewCorpus;
|
||||
UpdateCorpusDistribution();
|
||||
for (auto &X : Corpus)
|
||||
UnitHashesAddedToCorpus.insert(Hash(X));
|
||||
PrintStats("INITED");
|
||||
CheckForMemoryLeaks();
|
||||
}
|
||||
|
||||
bool Fuzzer::UpdateMaxCoverage() {
|
||||
|
@ -639,26 +640,10 @@ void Fuzzer::Merge(const std::vector<std::string> &Corpora) {
|
|||
Printf("=== Merge: written %zd units\n", Res.size());
|
||||
}
|
||||
|
||||
// Tries to call lsan, and if there are leaks exits. We call this right after
|
||||
// the initial corpus was read because if there are leaky inputs in the corpus
|
||||
// further fuzzing will likely hit OOMs.
|
||||
void Fuzzer::CheckForMemoryLeaks() {
|
||||
if (!Options.DetectLeaks) return;
|
||||
if (!__lsan_do_recoverable_leak_check)
|
||||
return;
|
||||
if (__lsan_do_recoverable_leak_check()) {
|
||||
Printf("==%d== ERROR: libFuzzer: initial corpus triggers memory leaks.\n"
|
||||
"Exiting now. Use -detect_leaks=0 to disable leak detection here.\n"
|
||||
"LeakSanitizer will still check for leaks at the process exit.\n",
|
||||
GetPid());
|
||||
PrintFinalStats();
|
||||
_Exit(Options.ErrorExitCode);
|
||||
}
|
||||
}
|
||||
|
||||
// Tries detecting a memory leak on the particular input that we have just
|
||||
// executed before calling this function.
|
||||
void Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size) {
|
||||
void Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
|
||||
bool DuringInitialCorpusExecution) {
|
||||
if (!HasMoreMallocsThanFrees) return; // mallocs==frees, a leak is unlikely.
|
||||
if (!Options.DetectLeaks) return;
|
||||
if (!&__lsan_enable || !&__lsan_disable || !__lsan_do_recoverable_leak_check)
|
||||
|
@ -681,6 +666,9 @@ void Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size) {
|
|||
// 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.
|
||||
if (DuringInitialCorpusExecution)
|
||||
Printf("\nINFO: a leak has been found in the initial corpus.\n\n");
|
||||
Printf("INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.\n\n");
|
||||
CurrentUnitData = Data;
|
||||
CurrentUnitSize = Size;
|
||||
DumpCurrentUnit("leak-");
|
||||
|
@ -715,7 +703,8 @@ void Fuzzer::MutateAndTestOne() {
|
|||
StartTraceRecording();
|
||||
RunOneAndUpdateCorpus(MutateInPlaceHere.data(), Size);
|
||||
StopTraceRecording();
|
||||
TryDetectingAMemoryLeak(MutateInPlaceHere.data(), Size);
|
||||
TryDetectingAMemoryLeak(MutateInPlaceHere.data(), Size,
|
||||
/*DuringInitialCorpusExecution*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LEAK_DURING-NOT: DEATH:
|
|||
|
||||
RUN: not LLVMFuzzer-LeakTest -runs=0 -detect_leaks=1 %S 2>&1 | FileCheck %s --check-prefix=LEAK_IN_CORPUS
|
||||
LEAK_IN_CORPUS: ERROR: LeakSanitizer: detected memory leaks
|
||||
LEAK_IN_CORPUS: ERROR: libFuzzer: initial corpus triggers memory leaks.
|
||||
LEAK_IN_CORPUS: INFO: a leak has been found in the initial corpus.
|
||||
|
||||
|
||||
RUN: not LLVMFuzzer-LeakTest -runs=100000 -detect_leaks=0 2>&1 | FileCheck %s --check-prefix=LEAK_AFTER
|
||||
|
|
Loading…
Reference in New Issue