forked from OSchip/llvm-project
[libFuzzer] add -exit_on_src_pos to test libFuzzer itself, add a test script for RE2 that uses this flag
llvm-svn: 282458
This commit is contained in:
parent
bde62d78e9
commit
5ff481fd9e
|
@ -79,6 +79,7 @@ void PrintASCII(const uint8_t *Data, size_t Size, const char *PrintAfter = "");
|
|||
void PrintASCII(const Unit &U, const char *PrintAfter = "");
|
||||
|
||||
void PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC);
|
||||
std::string DescribePC(const char *SymbolizedFMT, uintptr_t PC);
|
||||
std::string Hash(const Unit &U);
|
||||
void SetTimer(int Seconds);
|
||||
void SetSigSegvHandler();
|
||||
|
|
|
@ -428,6 +428,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||
Options.PrintCorpusStats = Flags.print_corpus_stats;
|
||||
Options.PrintCoverage = Flags.print_coverage;
|
||||
Options.PruneCorpus = Flags.prune_corpus;
|
||||
if (Flags.exit_on_src_pos)
|
||||
Options.ExitOnSrcPos = Flags.exit_on_src_pos;
|
||||
|
||||
unsigned Seed = Flags.seed;
|
||||
// Initialize Seed.
|
||||
|
|
|
@ -94,6 +94,9 @@ FUZZER_FLAG_INT(rss_limit_mb, 2048, "If non-zero, the fuzzer will exit upon"
|
|||
"reaching this limit of RSS memory usage.")
|
||||
FUZZER_FLAG_INT(prune_corpus, 1, "Prune corpus items without new coverage when "
|
||||
"loading corpus.")
|
||||
FUZZER_FLAG_STRING(exit_on_src_pos, "Exit if a newly found PC originates"
|
||||
" from the given source location. Example: -exit_on_src_pos=foo.cc:123. "
|
||||
"Used primarily for testing libFuzzer itself.")
|
||||
|
||||
FUZZER_DEPRECATED_FLAG(exit_on_first)
|
||||
FUZZER_DEPRECATED_FLAG(save_minimized_corpus)
|
||||
|
|
|
@ -116,6 +116,7 @@ private:
|
|||
void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
|
||||
bool DuringInitialCorpusExecution);
|
||||
void AddToCorpusAndMaybeRerun(const Unit &U);
|
||||
void CheckExitOnSrcPos();
|
||||
|
||||
bool UpdateMaxCoverage();
|
||||
|
||||
|
|
|
@ -374,7 +374,24 @@ void Fuzzer::SetMaxMutationLen(size_t MaxMutationLen) {
|
|||
this->MaxMutationLen = MaxMutationLen;
|
||||
}
|
||||
|
||||
void Fuzzer::CheckExitOnSrcPos() {
|
||||
if (!Options.ExitOnSrcPos.empty()) {
|
||||
uintptr_t *PCIDs;
|
||||
if (size_t NumNewPCIDs = TPC.GetNewPCIDs(&PCIDs)) {
|
||||
for (size_t i = 0; i < NumNewPCIDs; i++) {
|
||||
std::string Descr = DescribePC("%L", TPC.GetPCbyPCID(PCIDs[i]));
|
||||
if (Descr.find(Options.ExitOnSrcPos) != std::string::npos) {
|
||||
Printf("INFO: found line matching '%s', exiting.\n",
|
||||
Options.ExitOnSrcPos.c_str());
|
||||
_Exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Fuzzer::AddToCorpusAndMaybeRerun(const Unit &U) {
|
||||
CheckExitOnSrcPos();
|
||||
Corpus.AddToCorpus(U);
|
||||
if (TPC.GetTotalPCCoverage()) {
|
||||
TPC.ResetMaps();
|
||||
|
|
|
@ -40,6 +40,7 @@ struct FuzzingOptions {
|
|||
std::string OutputCorpus;
|
||||
std::string ArtifactPrefix = "./";
|
||||
std::string ExactArtifactPath;
|
||||
std::string ExitOnSrcPos;
|
||||
bool SaveArtifacts = true;
|
||||
bool PrintNEW = true; // Print a status line when new units are found;
|
||||
bool OutputCSV = false;
|
||||
|
|
|
@ -70,7 +70,7 @@ void TracePC::ResetGuards() {
|
|||
|
||||
void TracePC::FinalizeTrace() {
|
||||
if (TotalPCCoverage) {
|
||||
for (size_t Idx = 1, N = Min(kNumCounters, NumGuards); Idx < N;
|
||||
for (size_t Idx = 1, N = Min(kNumCounters, NumGuards + 1); Idx < N;
|
||||
Idx++) {
|
||||
uint8_t Counter = Counters[Idx];
|
||||
if (!Counter) continue;
|
||||
|
@ -96,7 +96,7 @@ void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) {
|
|||
|
||||
void TracePC::PrintCoverage() {
|
||||
Printf("COVERAGE:\n");
|
||||
for (size_t i = 0; i < Min(NumGuards, kNumPCs); i++) {
|
||||
for (size_t i = 0; i < Min(NumGuards + 1, kNumPCs); i++) {
|
||||
if (PCs[i])
|
||||
PrintPC("COVERED: %p %F %L\n", "COVERED: %p\n", PCs[i]);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ class TracePC {
|
|||
return Min(kMaxNewPCIDs, NumNewPCIDs);
|
||||
}
|
||||
|
||||
void ResetNewPCIDs() { NumNewPCIDs = 0; }
|
||||
uintptr_t GetPCbyPCID(uintptr_t PCID) { return PCs[PCID]; }
|
||||
|
||||
void ResetMaps() {
|
||||
|
@ -64,7 +63,7 @@ private:
|
|||
bool UseValueProfile = false;
|
||||
size_t TotalPCCoverage = 0;
|
||||
|
||||
static const size_t kMaxNewPCIDs = 64;
|
||||
static const size_t kMaxNewPCIDs = 1024;
|
||||
uintptr_t NewPCIDs[kMaxNewPCIDs];
|
||||
size_t NumNewPCIDs = 0;
|
||||
void AddNewPCID(uintptr_t PCID) {
|
||||
|
|
|
@ -290,16 +290,20 @@ size_t GetPeakRSSMb() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::string DescribePC(const char *SymbolizedFMT, uintptr_t PC) {
|
||||
if (!EF->__sanitizer_symbolize_pc) return "<can not symbolize>";
|
||||
char PcDescr[1024];
|
||||
EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PC),
|
||||
SymbolizedFMT, PcDescr, sizeof(PcDescr));
|
||||
PcDescr[sizeof(PcDescr) - 1] = 0; // Just in case.
|
||||
return PcDescr;
|
||||
}
|
||||
|
||||
void PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC) {
|
||||
if (EF->__sanitizer_symbolize_pc) {
|
||||
char PcDescr[1024];
|
||||
EF->__sanitizer_symbolize_pc(reinterpret_cast<void*>(PC),
|
||||
SymbolizedFMT, PcDescr, sizeof(PcDescr));
|
||||
PcDescr[sizeof(PcDescr) - 1] = 0; // Just in case.
|
||||
Printf("%s", PcDescr);
|
||||
} else {
|
||||
if (EF->__sanitizer_symbolize_pc)
|
||||
Printf("%s", DescribePC(SymbolizedFMT, PC).c_str());
|
||||
else
|
||||
Printf(FallbackFMT, PC);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fuzzer
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
set -x
|
||||
SCRIPT_DIR=$(dirname $0)
|
||||
EXECUTABLE_NAME_BASE=$(basename $SCRIPT_DIR)
|
||||
CORPUS=CORPUS-$EXECUTABLE_NAME_BASE
|
||||
JOBS=8
|
||||
rm -rf $CORPUS
|
||||
mkdir $CORPUS
|
||||
[ -e $EXECUTABLE_NAME_BASE ] && ./$EXECUTABLE_NAME_BASE -exit_on_src_pos=re2/dfa.cc:474 -exit_on_src_pos=re2/dfa.cc:474 -runs=1000000 -jobs=$JOBS $CORPUS
|
||||
grep "INFO: found line matching 're2/dfa.cc:474', exiting." fuzz-0.log
|
|
@ -21,7 +21,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||
int Z = Ids[(unsigned char)'Z'];
|
||||
if (F >= 0 && U > F && Z > U) {
|
||||
Sink++;
|
||||
// printf("IDS: %d %d %d\n", F, U, Z);
|
||||
// fprintf(stderr, "IDS: %d %d %d\n", F, U, Z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -53,3 +53,7 @@ RUN: not LLVMFuzzer-DSOTest 2>&1 | FileCheck %s --check-prefix=DSO
|
|||
DSO: INFO: Loaded 3 modules
|
||||
DSO: BINGO
|
||||
|
||||
RUN: LLVMFuzzer-SimpleTest-TracePC -exit_on_src_pos=SimpleTest.cpp:17 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
|
||||
RUN: LLVMFuzzer-MinimizeCorpusTest-TracePC -exit_on_src_pos=MinimizeCorpusTest.cpp:23 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
|
||||
EXIT_ON_SRC_POS: INFO: found line matching '{{.*}}', exiting.
|
||||
|
||||
|
|
Loading…
Reference in New Issue