From cf1269a0b2657ed42f3d1632fcf1790fcfb0741b Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Thu, 25 Aug 2016 01:25:03 +0000 Subject: [PATCH] [libFuzzer] simplify the code, NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279697 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Fuzzer/FuzzerInternal.h | 13 ++-- lib/Fuzzer/FuzzerLoop.cpp | 159 ++++++++++++++++++++------------------------ 2 files changed, 81 insertions(+), 91 deletions(-) diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index c7382c9cd6c..4917f125842 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -360,8 +359,6 @@ private: std::vector DefaultMutators; }; -class CoverageController; - class Fuzzer { public: @@ -488,6 +485,11 @@ private: void DumpCurrentUnit(const char *Prefix); void DeathCallback(); + void ResetEdgeCoverage(); + void ResetCounters(); + void PrepareCounters(Fuzzer::Coverage *C); + bool RecordMaxCoverage(Fuzzer::Coverage *C); + void LazyAllocateCurrentUnitData(); uint8_t *CurrentUnitData = nullptr; std::atomic CurrentUnitSize; @@ -513,7 +515,10 @@ private: // Maximum recorded coverage. Coverage MaxCoverage; - std::unique_ptr CController; + + // For -print_new_cov_pcs + uintptr_t* PcBuffer = nullptr; + size_t PcBufferLen = 0; // Need to know our own thread. static thread_local bool IsMyThread; diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index 5d94483b8f9..e992612881a 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -53,102 +53,82 @@ static void MissingExternalApiFunction(const char *FnName) { // Only one Fuzzer per process. static Fuzzer *F; -// Only one CoverageController per process should be created. -class CoverageController { - public: - explicit CoverageController(const FuzzingOptions &Options) - : Options(Options) { - if (Options.PrintNewCovPcs) { - PcBufferLen = 1 << 24; - PcBuffer = new uintptr_t[PcBufferLen]; - EF->__sanitizer_set_coverage_pc_buffer(PcBuffer, PcBufferLen); - } - } - - uintptr_t* pc_buffer() const { return PcBuffer; } +void Fuzzer::ResetEdgeCoverage() { + CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage); + EF->__sanitizer_reset_coverage(); +} - void Reset() { - CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage); - EF->__sanitizer_reset_coverage(); +void Fuzzer::ResetCounters() { + if (Options.UseCounters) { + EF->__sanitizer_update_counter_bitset_and_clear_counters(0); } +} - void ResetCounters() { - if (Options.UseCounters) { - EF->__sanitizer_update_counter_bitset_and_clear_counters(0); - } +void Fuzzer::PrepareCounters(Fuzzer::Coverage *C) { + if (Options.UseCounters) { + size_t NumCounters = EF->__sanitizer_get_number_of_counters(); + C->CounterBitmap.resize(NumCounters); } +} - void Prepare(Fuzzer::Coverage *C) { - if (Options.UseCounters) { - size_t NumCounters = EF->__sanitizer_get_number_of_counters(); - C->CounterBitmap.resize(NumCounters); - } - } +// Records data to a maximum coverage tracker. Returns true if additional +// coverage was discovered. +bool Fuzzer::RecordMaxCoverage(Fuzzer::Coverage *C) { + bool Res = false; - // Records data to a maximum coverage tracker. Returns true if additional - // coverage was discovered. - bool RecordMax(Fuzzer::Coverage *C) { - bool Res = false; + uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage(); + if (NewBlockCoverage > C->BlockCoverage) { + Res = true; + C->BlockCoverage = NewBlockCoverage; + } - uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage(); - if (NewBlockCoverage > C->BlockCoverage) { + if (Options.UseIndirCalls && + EF->__sanitizer_get_total_unique_caller_callee_pairs) { + uint64_t NewCallerCalleeCoverage = + EF->__sanitizer_get_total_unique_caller_callee_pairs(); + if (NewCallerCalleeCoverage > C->CallerCalleeCoverage) { Res = true; - C->BlockCoverage = NewBlockCoverage; + C->CallerCalleeCoverage = NewCallerCalleeCoverage; } + } - if (Options.UseIndirCalls && - EF->__sanitizer_get_total_unique_caller_callee_pairs) { - uint64_t NewCallerCalleeCoverage = - EF->__sanitizer_get_total_unique_caller_callee_pairs(); - if (NewCallerCalleeCoverage > C->CallerCalleeCoverage) { - Res = true; - C->CallerCalleeCoverage = NewCallerCalleeCoverage; - } + if (Options.UseCounters) { + uint64_t CounterDelta = + EF->__sanitizer_update_counter_bitset_and_clear_counters( + C->CounterBitmap.data()); + if (CounterDelta > 0) { + Res = true; + C->CounterBitmapBits += CounterDelta; } + } - if (Options.UseCounters) { - uint64_t CounterDelta = - EF->__sanitizer_update_counter_bitset_and_clear_counters( - C->CounterBitmap.data()); - if (CounterDelta > 0) { - Res = true; - C->CounterBitmapBits += CounterDelta; - } - } + size_t NewPCMapBits = PCMapMergeFromCurrent(C->PCMap); + if (NewPCMapBits > C->PCMapBits) { + Res = true; + C->PCMapBits = NewPCMapBits; + } - size_t NewPCMapBits = PCMapMergeFromCurrent(C->PCMap); - if (NewPCMapBits > C->PCMapBits) { - Res = true; - C->PCMapBits = NewPCMapBits; - } + size_t NewVPMapBits = VPMapMergeFromCurrent(C->VPMap); + if (NewVPMapBits > C->VPMapBits) { + Res = true; + C->VPMapBits = NewVPMapBits; + } - size_t NewVPMapBits = VPMapMergeFromCurrent(C->VPMap); - if (NewVPMapBits > C->VPMapBits) { + if (EF->__sanitizer_get_coverage_pc_buffer_pos) { + uint64_t NewPcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos(); + if (NewPcBufferPos > C->PcBufferPos) { Res = true; - C->VPMapBits = NewVPMapBits; + C->PcBufferPos = NewPcBufferPos; } - if (EF->__sanitizer_get_coverage_pc_buffer_pos) { - uint64_t NewPcBufferPos = EF->__sanitizer_get_coverage_pc_buffer_pos(); - if (NewPcBufferPos > C->PcBufferPos) { - Res = true; - C->PcBufferPos = NewPcBufferPos; - } - - if (PcBufferLen && NewPcBufferPos >= PcBufferLen) { - Printf("ERROR: PC buffer overflow\n"); - _Exit(1); - } + if (PcBufferLen && NewPcBufferPos >= PcBufferLen) { + Printf("ERROR: PC buffer overflow\n"); + _Exit(1); } - - return Res; } - private: - const FuzzingOptions Options; - uintptr_t* PcBuffer = nullptr; - size_t PcBufferLen = 0; -}; + return Res; +} // Leak detection is expensive, so we first check if there were more mallocs // than frees (using the sanitizer malloc hooks) and only then try to call lsan. @@ -173,8 +153,7 @@ void FreeHook(const volatile void *ptr) { } Fuzzer::Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options) - : CB(CB), MD(MD), Options(Options), - CController(new CoverageController(Options)) { + : CB(CB), MD(MD), Options(Options) { SetDeathCallback(); InitializeTraceState(); assert(!F); @@ -183,6 +162,12 @@ Fuzzer::Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options) IsMyThread = true; if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks) EF->__sanitizer_install_malloc_and_free_hooks(MallocHook, FreeHook); + + if (Options.PrintNewCovPcs) { + PcBufferLen = 1 << 24; + PcBuffer = new uintptr_t[PcBufferLen]; + EF->__sanitizer_set_coverage_pc_buffer(PcBuffer, PcBufferLen); + } } Fuzzer::~Fuzzer() { } @@ -457,10 +442,9 @@ void Fuzzer::ShuffleAndMinimize() { bool Fuzzer::UpdateMaxCoverage() { uintptr_t PrevPcBufferPos = MaxCoverage.PcBufferPos; - bool Res = CController->RecordMax(&MaxCoverage); + bool Res = RecordMaxCoverage(&MaxCoverage); if (Options.PrintNewCovPcs && PrevPcBufferPos != MaxCoverage.PcBufferPos) { - uintptr_t* PcBuffer = CController->pc_buffer(); for (size_t I = PrevPcBufferPos; I < MaxCoverage.PcBufferPos; ++I) { Printf("%p\n", PcBuffer[I]); } @@ -473,7 +457,7 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size) { TotalNumberOfRuns++; // TODO(aizatsky): this Reset call seems to be not needed. - CController->ResetCounters(); + ResetCounters(); ExecuteCallback(Data, Size); bool Res = UpdateMaxCoverage(); @@ -511,18 +495,19 @@ void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) { UnitStartTime = system_clock::now(); // We copy the contents of Unit into a separate heap buffer // so that we reliably find buffer overflows in it. - std::unique_ptr DataCopy(new uint8_t[Size]); - memcpy(DataCopy.get(), Data, Size); + uint8_t *DataCopy = new uint8_t[Size]; + memcpy(DataCopy, Data, Size); if (CurrentUnitData && CurrentUnitData != Data) memcpy(CurrentUnitData, Data, Size); - AssignTaintLabels(DataCopy.get(), Size); + AssignTaintLabels(DataCopy, Size); CurrentUnitSize = Size; AllocTracer.Start(); - int Res = CB(DataCopy.get(), Size); + int Res = CB(DataCopy, Size); (void)Res; HasMoreMallocsThanFrees = AllocTracer.Stop(); CurrentUnitSize = 0; assert(Res == 0); + delete[] DataCopy; } std::string Fuzzer::Coverage::DebugString() const { @@ -728,9 +713,9 @@ size_t Fuzzer::ChooseUnitIdxToMutate() { } void Fuzzer::ResetCoverage() { - CController->Reset(); + ResetEdgeCoverage(); MaxCoverage.Reset(); - CController->Prepare(&MaxCoverage); + PrepareCounters(&MaxCoverage); } // Experimental search heuristic: drilling. -- 2.11.0