From: Kostya Serebryany Date: Tue, 27 Dec 2016 23:24:55 +0000 (+0000) Subject: [libFuzzer] add an experimental flag -experimental_len_control=1 that sets max_len... X-Git-Tag: android-x86-7.1-r4~22696 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=d31ce373a9d586c3f88f9c7b3b00970b8fb67dc3;p=android-x86%2Fexternal-llvm.git [libFuzzer] add an experimental flag -experimental_len_control=1 that sets max_len to 1M and tries to increases the actual max sizes of mutations very gradually (second attempt) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290637 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Fuzzer/FuzzerCorpus.h b/lib/Fuzzer/FuzzerCorpus.h index 663c5854b4c..42b3d2482fa 100644 --- a/lib/Fuzzer/FuzzerCorpus.h +++ b/lib/Fuzzer/FuzzerCorpus.h @@ -59,6 +59,12 @@ class InputCorpus { Res += !II->U.empty(); return Res; } + size_t MaxInputSize() const { + size_t Res = 0; + for (auto II : Inputs) + Res = std::max(Res, II->U.size()); + return Res; + } bool empty() const { return Inputs.empty(); } const Unit &operator[] (size_t Idx) const { return Inputs[Idx]->U; } void AddToCorpus(const Unit &U, size_t NumFeatures, bool MayDeleteFile = false) { diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index f45ed043751..e6c9764f113 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -390,6 +390,9 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { FuzzingOptions Options; Options.Verbosity = Flags.verbosity; Options.MaxLen = Flags.max_len; + Options.ExperimentalLenControl = Flags.experimental_len_control; + if (Flags.experimental_len_control && Flags.max_len == 64) + Options.MaxLen = 1 << 20; Options.UnitTimeoutSec = Flags.timeout; Options.ErrorExitCode = Flags.error_exitcode; Options.TimeoutExitCode = Flags.timeout_exitcode; diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def index 25ef1741a9d..08eaad9856b 100644 --- a/lib/Fuzzer/FuzzerFlags.def +++ b/lib/Fuzzer/FuzzerFlags.def @@ -17,6 +17,7 @@ FUZZER_FLAG_INT(runs, -1, FUZZER_FLAG_INT(max_len, 0, "Maximum length of the test input. " "If 0, libFuzzer tries to guess a good value based on the corpus " "and reports it. ") +FUZZER_FLAG_INT(experimental_len_control, 0, "experimental flag") FUZZER_FLAG_INT(cross_over, 1, "If 1, cross over inputs.") FUZZER_FLAG_INT(mutate_depth, 5, "Apply this number of consecutive mutations to each input.") diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index 73e058ff34a..8c8afeab8b5 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -702,6 +702,19 @@ 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() { MD.StartMutationSequence(); @@ -715,13 +728,19 @@ void Fuzzer::MutateAndTestOne() { assert(MaxMutationLen > 0); + size_t CurrentMaxMutationLen = + Options.ExperimentalLenControl + ? ComputeMutationLen(Corpus.MaxInputSize(), MaxMutationLen, + MD.GetRand()) + : MaxMutationLen; + for (int i = 0; i < Options.MutateDepth; i++) { if (TotalNumberOfRuns >= Options.MaxNumberOfRuns) break; size_t NewSize = 0; - NewSize = MD.Mutate(CurrentUnitData, Size, MaxMutationLen); + NewSize = MD.Mutate(CurrentUnitData, Size, CurrentMaxMutationLen); assert(NewSize > 0 && "Mutator returned empty unit"); - assert(NewSize <= MaxMutationLen && "Mutator return overisized unit"); + assert(NewSize <= CurrentMaxMutationLen && "Mutator return overisized unit"); Size = NewSize; if (i == 0) StartTraceRecording(); diff --git a/lib/Fuzzer/FuzzerOptions.h b/lib/Fuzzer/FuzzerOptions.h index 34e93fc34ac..cb702d28520 100644 --- a/lib/Fuzzer/FuzzerOptions.h +++ b/lib/Fuzzer/FuzzerOptions.h @@ -19,6 +19,7 @@ namespace fuzzer { struct FuzzingOptions { int Verbosity = 1; size_t MaxLen = 0; + bool ExperimentalLenControl = false; int UnitTimeoutSec = 300; int TimeoutExitCode = 77; int ErrorExitCode = 77;