diff options
author | Mike Aizatsky <aizatsky@chromium.org> | 2016-05-24 23:14:29 +0000 |
---|---|---|
committer | Mike Aizatsky <aizatsky@chromium.org> | 2016-05-24 23:14:29 +0000 |
commit | af432a45e3218d29ce322ff2a074ad3b230b13f5 (patch) | |
tree | 4c6ded29bf06f8b08ca1a5d9d2af37e402917416 /llvm/lib/Fuzzer/FuzzerLoop.cpp | |
parent | 515c15c2073c62caa1ff8ea8de072a3cf6db590c (diff) | |
download | llvm-af432a45e3218d29ce322ff2a074ad3b230b13f5.zip llvm-af432a45e3218d29ce322ff2a074ad3b230b13f5.tar.gz llvm-af432a45e3218d29ce322ff2a074ad3b230b13f5.tar.bz2 |
[libfuzzer] Trying random unit prefixes during corpus load.
Differential Revision: http://reviews.llvm.org/D20301
llvm-svn: 270632
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerLoop.cpp')
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerLoop.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 0adbc89..ed8a1fb 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -59,6 +59,7 @@ __attribute__((weak)) int __lsan_do_recoverable_leak_check(); namespace fuzzer { static const size_t kMaxUnitSizeToPrint = 256; +static const size_t TruncateMaxRuns = 1000; static void MissingWeakApiFunction(const char *FnName) { Printf("ERROR: %s is not defined. Exiting.\n" @@ -353,12 +354,54 @@ void Fuzzer::ShuffleCorpus(UnitVector *V) { }); } +// Tries random prefixes of corpus items. +// Prefix length is chosen according to exponential distribution +// to sample short lengths much more heavily. +void Fuzzer::TruncateUnits(std::vector<Unit> *NewCorpus) { + size_t MaxCorpusLen = 0; + for (const auto &U : Corpus) + MaxCorpusLen = std::max(MaxCorpusLen, U.size()); + + if (MaxCorpusLen <= 1) + return; + + // 50% of exponential distribution is Log[2]/lambda. + // Choose lambda so that median is MaxCorpusLen / 2. + double Lambda = 2.0 * log(2.0) / static_cast<double>(MaxCorpusLen); + std::exponential_distribution<> Dist(Lambda); + std::vector<double> Sizes; + size_t TruncatePoints = std::max(1ul, TruncateMaxRuns / Corpus.size()); + Sizes.reserve(TruncatePoints); + for (size_t I = 0; I < TruncatePoints; ++I) { + Sizes.push_back(Dist(MD.GetRand().Get_mt19937()) + 1); + } + std::sort(Sizes.begin(), Sizes.end()); + + for (size_t S : Sizes) { + for (const auto &U : Corpus) { + if (S < U.size() && RunOne(U.data(), S)) { + Unit U1(U.begin(), U.begin() + S); + NewCorpus->push_back(U1); + WriteToOutputCorpus(U1); + PrintStatusForNewUnit(U1); + } + } + } + PrintStats("TRUNC "); +} + void Fuzzer::ShuffleAndMinimize() { PrintStats("READ "); std::vector<Unit> NewCorpus; if (Options.ShuffleAtStartUp) ShuffleCorpus(&Corpus); + if (Options.TruncateUnits) { + ResetCoverage(); + TruncateUnits(&NewCorpus); + ResetCoverage(); + } + for (const auto &U : Corpus) { if (RunOne(U)) { NewCorpus.push_back(U); |