mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[libFuzzer] reimplement experimental_len_control=1: bump the temporary max_len every time we failed to find new coverage during the last 1000 runs and 1 second. Also fix FileToVector to not load unfinished files
llvm-svn: 308811
This commit is contained in:
parent
087c99eed3
commit
2634a37d75
@ -564,8 +564,6 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||||||
Options.Verbosity = Flags.verbosity;
|
Options.Verbosity = Flags.verbosity;
|
||||||
Options.MaxLen = Flags.max_len;
|
Options.MaxLen = Flags.max_len;
|
||||||
Options.ExperimentalLenControl = Flags.experimental_len_control;
|
Options.ExperimentalLenControl = Flags.experimental_len_control;
|
||||||
if (Flags.experimental_len_control && Flags.max_len == kMinDefaultLen)
|
|
||||||
Options.MaxLen = 1 << 20;
|
|
||||||
Options.UnitTimeoutSec = Flags.timeout;
|
Options.UnitTimeoutSec = Flags.timeout;
|
||||||
Options.ErrorExitCode = Flags.error_exitcode;
|
Options.ErrorExitCode = Flags.error_exitcode;
|
||||||
Options.TimeoutExitCode = Flags.timeout_exitcode;
|
Options.TimeoutExitCode = Flags.timeout_exitcode;
|
||||||
|
@ -38,7 +38,9 @@ Unit FileToVector(const std::string &Path, size_t MaxSize, bool ExitOnError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
T.seekg(0, T.end);
|
T.seekg(0, T.end);
|
||||||
size_t FileLen = T.tellg();
|
auto EndPos = T.tellg();
|
||||||
|
if (EndPos < 0) return {};
|
||||||
|
size_t FileLen = EndPos;
|
||||||
if (MaxSize)
|
if (MaxSize)
|
||||||
FileLen = std::min(FileLen, MaxSize);
|
FileLen = std::min(FileLen, MaxSize);
|
||||||
|
|
||||||
|
@ -118,6 +118,10 @@ private:
|
|||||||
size_t TotalNumberOfRuns = 0;
|
size_t TotalNumberOfRuns = 0;
|
||||||
size_t NumberOfNewUnitsAdded = 0;
|
size_t NumberOfNewUnitsAdded = 0;
|
||||||
|
|
||||||
|
size_t LastCorpusUpdateRun = 0;
|
||||||
|
system_clock::time_point LastCorpusUpdateTime = system_clock::now();
|
||||||
|
|
||||||
|
|
||||||
bool HasMoreMallocsThanFrees = false;
|
bool HasMoreMallocsThanFrees = false;
|
||||||
size_t NumberOfLeakDetectionAttempts = 0;
|
size_t NumberOfLeakDetectionAttempts = 0;
|
||||||
|
|
||||||
@ -133,6 +137,7 @@ private:
|
|||||||
|
|
||||||
size_t MaxInputLen = 0;
|
size_t MaxInputLen = 0;
|
||||||
size_t MaxMutationLen = 0;
|
size_t MaxMutationLen = 0;
|
||||||
|
size_t TmpMaxMutationLen = 0;
|
||||||
|
|
||||||
std::vector<uint32_t> UniqFeatureSetTmp;
|
std::vector<uint32_t> UniqFeatureSetTmp;
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
|
|||||||
if (!Options.OutputCorpus.empty() && Options.ReloadIntervalSec)
|
if (!Options.OutputCorpus.empty() && Options.ReloadIntervalSec)
|
||||||
EpochOfLastReadOfOutputCorpus = GetEpoch(Options.OutputCorpus);
|
EpochOfLastReadOfOutputCorpus = GetEpoch(Options.OutputCorpus);
|
||||||
MaxInputLen = MaxMutationLen = Options.MaxLen;
|
MaxInputLen = MaxMutationLen = Options.MaxLen;
|
||||||
|
TmpMaxMutationLen = Max(size_t(4), Corpus.MaxInputSize());
|
||||||
AllocateCurrentUnitData();
|
AllocateCurrentUnitData();
|
||||||
CurrentUnitSize = 0;
|
CurrentUnitSize = 0;
|
||||||
memset(BaseSha1, 0, sizeof(BaseSha1));
|
memset(BaseSha1, 0, sizeof(BaseSha1));
|
||||||
@ -511,7 +512,7 @@ void Fuzzer::WriteToOutputCorpus(const Unit &U) {
|
|||||||
std::string Path = DirPlusFile(Options.OutputCorpus, Hash(U));
|
std::string Path = DirPlusFile(Options.OutputCorpus, Hash(U));
|
||||||
WriteToFile(U, Path);
|
WriteToFile(U, Path);
|
||||||
if (Options.Verbosity >= 2)
|
if (Options.Verbosity >= 2)
|
||||||
Printf("Written to %s\n", Path.c_str());
|
Printf("Written %zd bytes to %s\n", U.size(), Path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
|
void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
|
||||||
@ -532,7 +533,7 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U, const char *Text) {
|
|||||||
return;
|
return;
|
||||||
PrintStats(Text, "");
|
PrintStats(Text, "");
|
||||||
if (Options.Verbosity) {
|
if (Options.Verbosity) {
|
||||||
Printf(" L: %zd ", U.size());
|
Printf(" L: %zd/%zd ", U.size(), Corpus.MaxInputSize());
|
||||||
MD.PrintMutationSequence();
|
MD.PrintMutationSequence();
|
||||||
Printf("\n");
|
Printf("\n");
|
||||||
}
|
}
|
||||||
@ -547,6 +548,8 @@ void Fuzzer::ReportNewCoverage(InputInfo *II, const Unit &U) {
|
|||||||
NumberOfNewUnitsAdded++;
|
NumberOfNewUnitsAdded++;
|
||||||
TPC.PrintNewPCs();
|
TPC.PrintNewPCs();
|
||||||
CheckExitOnSrcPosOrItem(); // Check only after the unit is saved to corpus.
|
CheckExitOnSrcPosOrItem(); // Check only after the unit is saved to corpus.
|
||||||
|
LastCorpusUpdateRun = TotalNumberOfRuns;
|
||||||
|
LastCorpusUpdateTime = system_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tries detecting a memory leak on the particular input that we have just
|
// Tries detecting a memory leak on the particular input that we have just
|
||||||
@ -588,19 +591,6 @@ void Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ComputeMutationLen(size_t MaxInputSize, size_t MaxMutationLen,
|
|
||||||
Random &Rand) {
|
|
||||||
assert(MaxInputSize <= MaxMutationLen);
|
|
||||||
if (MaxInputSize == MaxMutationLen) return MaxMutationLen;
|
|
||||||
size_t Result = MaxInputSize;
|
|
||||||
size_t R = Rand.Rand();
|
|
||||||
if ((R % (1U << 7)) == 0)
|
|
||||||
Result++;
|
|
||||||
if ((R % (1U << 15)) == 0)
|
|
||||||
Result += 10 + Result / 2;
|
|
||||||
return Min(Result, MaxMutationLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fuzzer::MutateAndTestOne() {
|
void Fuzzer::MutateAndTestOne() {
|
||||||
MD.StartMutationSequence();
|
MD.StartMutationSequence();
|
||||||
|
|
||||||
@ -615,10 +605,8 @@ void Fuzzer::MutateAndTestOne() {
|
|||||||
assert(MaxMutationLen > 0);
|
assert(MaxMutationLen > 0);
|
||||||
|
|
||||||
size_t CurrentMaxMutationLen =
|
size_t CurrentMaxMutationLen =
|
||||||
Options.ExperimentalLenControl
|
Min(MaxMutationLen, Max(U.size(), TmpMaxMutationLen));
|
||||||
? ComputeMutationLen(Corpus.MaxInputSize(), MaxMutationLen,
|
assert(CurrentMaxMutationLen > 0);
|
||||||
MD.GetRand())
|
|
||||||
: MaxMutationLen;
|
|
||||||
|
|
||||||
for (int i = 0; i < Options.MutateDepth; i++) {
|
for (int i = 0; i < Options.MutateDepth; i++) {
|
||||||
if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
|
if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
|
||||||
@ -652,6 +640,25 @@ void Fuzzer::Loop() {
|
|||||||
if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
|
if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
|
||||||
break;
|
break;
|
||||||
if (TimedOut()) break;
|
if (TimedOut()) break;
|
||||||
|
|
||||||
|
// Update TmpMaxMutationLen
|
||||||
|
if (Options.ExperimentalLenControl) {
|
||||||
|
if (TmpMaxMutationLen < MaxMutationLen &&
|
||||||
|
(TotalNumberOfRuns - LastCorpusUpdateRun > 1000 &&
|
||||||
|
duration_cast<seconds>(Now - LastCorpusUpdateTime).count() >= 1)) {
|
||||||
|
LastCorpusUpdateRun = TotalNumberOfRuns;
|
||||||
|
LastCorpusUpdateTime = Now;
|
||||||
|
TmpMaxMutationLen =
|
||||||
|
Min(MaxMutationLen,
|
||||||
|
TmpMaxMutationLen + Max(size_t(4), TmpMaxMutationLen / 8));
|
||||||
|
if (TmpMaxMutationLen <= MaxMutationLen)
|
||||||
|
Printf("#%zd\tTEMP_MAX_LEN: %zd\n", TotalNumberOfRuns,
|
||||||
|
TmpMaxMutationLen);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TmpMaxMutationLen = MaxMutationLen;
|
||||||
|
}
|
||||||
|
|
||||||
// Perform several mutations and runs.
|
// Perform several mutations and runs.
|
||||||
MutateAndTestOne();
|
MutateAndTestOne();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user