From ea5478cd34b2c48e5d75b468578744dd397a0f99 Mon Sep 17 00:00:00 2001 From: Max Moroz Date: Mon, 23 Jul 2018 14:20:52 +0000 Subject: [libFuzzer] Handle unstable edges by using minimum hit counts Summary: Created unstable_handle flag that takes 1 or 2, depending on the handling type. Modified RunOne to accommodate the following heuristic: Use the first CollectFeatures to count how many features there are. If no new features, CollectFeatures like before. If there is new feature, we run CB 2 more times, Check which edges are unstable per input and we store the least amount of hit counts for each edge. Apply these hit counts back to inline8bitcounters so that CollectFeatures can work as intended. Modified UnstableCounters to 8int_t and created a bitset UnstableSet to tell which edges are unstable. Patch by Kyungtak Woo (@kevinwkt). Reviewers: Dor1s, metzman, morehouse Reviewed By: Dor1s, morehouse Subscribers: delcypher, #sanitizers, llvm-commits, kcc Differential Revision: https://reviews.llvm.org/D49525 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@337696 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/fuzzer/FuzzerLoop.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'lib/fuzzer/FuzzerLoop.cpp') diff --git a/lib/fuzzer/FuzzerLoop.cpp b/lib/fuzzer/FuzzerLoop.cpp index ffcd3419c..e63ee7361 100644 --- a/lib/fuzzer/FuzzerLoop.cpp +++ b/lib/fuzzer/FuzzerLoop.cpp @@ -465,11 +465,15 @@ void Fuzzer::CheckForUnstableCounters(const uint8_t *Data, size_t Size) { // First Rerun CBSetupAndRun(); - TPC.UpdateUnstableCounters(); + TPC.UpdateUnstableCounters(Options.HandleUnstable); // Second Rerun CBSetupAndRun(); - TPC.UpdateUnstableCounters(); + TPC.UpdateUnstableCounters(Options.HandleUnstable); + + // Move minimum hit counts back to ModuleInline8bitCounters + if (Options.HandleUnstable) + TPC.ApplyUnstableCounters(); } bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, @@ -482,6 +486,17 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, UniqFeatureSetTmp.clear(); size_t FoundUniqFeaturesOfII = 0; size_t NumUpdatesBefore = Corpus.NumFeatureUpdates(); + bool NewFeaturesUnstable = false; + + if (Options.HandleUnstable || Options.PrintUnstableStats) { + TPC.CollectFeatures([&](size_t Feature) { + if (Corpus.IsFeatureNew(Feature, Size, Options.Shrink)) + NewFeaturesUnstable = true; + }); + if (NewFeaturesUnstable) + CheckForUnstableCounters(Data, Size); + } + TPC.CollectFeatures([&](size_t Feature) { if (Corpus.AddFeature(Feature, Size, Options.Shrink)) UniqFeatureSetTmp.push_back(Feature); @@ -490,16 +505,12 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, II->UniqFeatureSet.end(), Feature)) FoundUniqFeaturesOfII++; }); + if (FoundUniqFeatures) *FoundUniqFeatures = FoundUniqFeaturesOfII; PrintPulseAndReportSlowInput(Data, Size); size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore; - // If print_unstable_stats, execute the same input two more times to detect - // unstable edges. - if (NumNewFeatures && Options.PrintUnstableStats) - CheckForUnstableCounters(Data, Size); - if (NumNewFeatures) { TPC.UpdateObservedPCs(); Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile, -- cgit v1.2.3