// Experimental. // Fuly reset the current coverage state, run a single unit, // compute a hash function from the full coverage set, // return non-zero if the hash value is new. // This produces tons of new units and as is it's only suitable for small tests, // e.g. test/FullCoverageSetTest.cpp. FIXME: make it scale. size_t Fuzzer::RunOneMaximizeFullCoverageSet(const Unit &U) { __sanitizer_reset_coverage(); ExecuteCallback(U); uintptr_t *PCs; uintptr_t NumPCs =__sanitizer_get_coverage_guards(&PCs); if (FullCoverageSets.insert(HashOfArrayOfPCs(PCs, NumPCs)).second) return FullCoverageSets.size(); return 0; }
// Fuly reset the current coverage state, run a single unit, // compute a hash function from the full coverage set, // return non-zero if the hash value is new. // This produces tons of new units and as is it's only suitable for small tests, // e.g. test/FullCoverageSetTest.cpp. FIXME: make it scale. size_t Fuzzer::RunOneMaximizeFullCoverageSet(const Unit &U) { __sanitizer_reset_coverage(); TestOneInput(U.data(), U.size()); uintptr_t *PCs; uintptr_t NumPCs =__sanitizer_get_coverage_guards(&PCs); if (FullCoverageSets.insert(HashOfArrayOfPCs(PCs, NumPCs)).second) return FullCoverageSets.size(); return 0; }
// Experimental search heuristic: drilling. // - Read, shuffle, execute and minimize the corpus. // - Choose one random unit. // - Reset the coverage. // - Start fuzzing as if the chosen unit was the only element of the corpus. // - When done, reset the coverage again. // - Merge the newly created corpus into the original one. void Fuzzer::Drill() { // The corpus is already read, shuffled, and minimized. assert(!Corpus.empty()); Options.PrintNEW = false; // Don't print NEW status lines when drilling. Unit U = ChooseUnitToMutate(); CHECK_WEAK_API_FUNCTION(__sanitizer_reset_coverage); __sanitizer_reset_coverage(); std::vector<Unit> SavedCorpus; SavedCorpus.swap(Corpus); Corpus.push_back(U); assert(Corpus.size() == 1); RunOne(U); PrintStats("DRILL "); std::string SavedOutputCorpusPath; // Don't write new units while drilling. SavedOutputCorpusPath.swap(Options.OutputCorpus); Loop(); __sanitizer_reset_coverage(); PrintStats("REINIT"); SavedOutputCorpusPath.swap(Options.OutputCorpus); for (auto &U : SavedCorpus) { CurrentUnit = U; RunOne(U); } PrintStats("MERGE "); Options.PrintNEW = true; size_t NumMerged = 0; for (auto &U : Corpus) { CurrentUnit = U; if (RunOne(U)) { PrintStatusForNewUnit(U); NumMerged++; WriteToOutputCorpus(U); } } PrintStats("MERGED"); if (NumMerged && Options.Verbosity) Printf("Drilling discovered %zd new units\n", NumMerged); }
// Experimental. Does not yet scale. // Fuly reset the current coverage state, run a single unit, // collect all coverage pairs and return non-zero if a new pair is observed. size_t Fuzzer::RunOneMaximizeCoveragePairs(const Unit &U) { __sanitizer_reset_coverage(); ExecuteCallback(U); uintptr_t *PCs; uintptr_t NumPCs = __sanitizer_get_coverage_guards(&PCs); bool HasNewPairs = false; for (uintptr_t i = 0; i < NumPCs; i++) { if (!PCs[i]) continue; for (uintptr_t j = 0; j < NumPCs; j++) { if (!PCs[j]) continue; uint64_t Pair = (i << 32) | j; HasNewPairs |= CoveragePairs.insert(Pair).second; } } if (HasNewPairs) return CoveragePairs.size(); return 0; }
static void Reset() { CHECK_WEAK_API_FUNCTION(__sanitizer_reset_coverage); __sanitizer_reset_coverage(); PcMapResetCurrent(); }