// 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.
}
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);
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() { }
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]);
}
TotalNumberOfRuns++;
// TODO(aizatsky): this Reset call seems to be not needed.
- CController->ResetCounters();
+ ResetCounters();
ExecuteCallback(Data, Size);
bool Res = UpdateMaxCoverage();
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<uint8_t[]> 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 {
}
void Fuzzer::ResetCoverage() {
- CController->Reset();
+ ResetEdgeCoverage();
MaxCoverage.Reset();
- CController->Prepare(&MaxCoverage);
+ PrepareCounters(&MaxCoverage);
}
// Experimental search heuristic: drilling.