summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Fuzzer
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-12-27 23:24:55 +0000
committerKostya Serebryany <kcc@google.com>2016-12-27 23:24:55 +0000
commit2a8440df70fd59fb6c30444f74864a459bd18869 (patch)
tree2069f8ad740fabcdf0225051c6f35a6ffd5cdc8b /llvm/lib/Fuzzer
parentaa54e501058361bef34613c6b3f1905ca48f741b (diff)
downloadbcm5719-llvm-2a8440df70fd59fb6c30444f74864a459bd18869.tar.gz
bcm5719-llvm-2a8440df70fd59fb6c30444f74864a459bd18869.zip
[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)
llvm-svn: 290637
Diffstat (limited to 'llvm/lib/Fuzzer')
-rw-r--r--llvm/lib/Fuzzer/FuzzerCorpus.h6
-rw-r--r--llvm/lib/Fuzzer/FuzzerDriver.cpp3
-rw-r--r--llvm/lib/Fuzzer/FuzzerFlags.def1
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp23
-rw-r--r--llvm/lib/Fuzzer/FuzzerOptions.h1
5 files changed, 32 insertions, 2 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerCorpus.h b/llvm/lib/Fuzzer/FuzzerCorpus.h
index 663c5854b4c..42b3d2482fa 100644
--- a/llvm/lib/Fuzzer/FuzzerCorpus.h
+++ b/llvm/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/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp
index f45ed043751..e6c9764f113 100644
--- a/llvm/lib/Fuzzer/FuzzerDriver.cpp
+++ b/llvm/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/llvm/lib/Fuzzer/FuzzerFlags.def b/llvm/lib/Fuzzer/FuzzerFlags.def
index 25ef1741a9d..08eaad9856b 100644
--- a/llvm/lib/Fuzzer/FuzzerFlags.def
+++ b/llvm/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/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp
index 73e058ff34a..8c8afeab8b5 100644
--- a/llvm/lib/Fuzzer/FuzzerLoop.cpp
+++ b/llvm/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/llvm/lib/Fuzzer/FuzzerOptions.h b/llvm/lib/Fuzzer/FuzzerOptions.h
index 34e93fc34ac..cb702d28520 100644
--- a/llvm/lib/Fuzzer/FuzzerOptions.h
+++ b/llvm/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;
OpenPOWER on IntegriCloud