[libfuzzer] moving is_ascii handler inside mutation dispatcher.
Summary: It also fixes a bug, when first random might not be ascii. Differential Revision: http://reviews.llvm.org/D21573 llvm-svn: 273611
This commit is contained in:
parent
f2898d73a5
commit
f0b3e85f4e
|
@ -297,7 +297,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||
|
||||
const size_t kMaxSaneLen = 1 << 20;
|
||||
const size_t kMinDefaultLen = 64;
|
||||
Fuzzer::FuzzingOptions Options;
|
||||
FuzzingOptions Options;
|
||||
Options.Verbosity = Flags.verbosity;
|
||||
Options.MaxLen = Flags.max_len;
|
||||
Options.UnitTimeoutSec = Flags.timeout;
|
||||
|
@ -347,7 +347,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||
Printf("INFO: Seed: %u\n", Seed);
|
||||
|
||||
Random Rand(Seed);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, Options);
|
||||
Fuzzer F(Callback, MD, Options);
|
||||
|
||||
for (auto &U: Dictionary)
|
||||
|
|
|
@ -203,9 +203,43 @@ private:
|
|||
size_t Size = 0;
|
||||
};
|
||||
|
||||
struct FuzzingOptions {
|
||||
int Verbosity = 1;
|
||||
size_t MaxLen = 0;
|
||||
int UnitTimeoutSec = 300;
|
||||
int TimeoutExitCode = 77;
|
||||
int ErrorExitCode = 77;
|
||||
int MaxTotalTimeSec = 0;
|
||||
int RssLimitMb = 0;
|
||||
bool DoCrossOver = true;
|
||||
int MutateDepth = 5;
|
||||
bool UseCounters = false;
|
||||
bool UseIndirCalls = true;
|
||||
bool UseTraces = false;
|
||||
bool UseMemcmp = true;
|
||||
bool UseFullCoverageSet = false;
|
||||
bool Reload = true;
|
||||
bool ShuffleAtStartUp = true;
|
||||
bool PreferSmall = true;
|
||||
size_t MaxNumberOfRuns = ULONG_MAX;
|
||||
int ReportSlowUnits = 10;
|
||||
bool OnlyASCII = false;
|
||||
std::string OutputCorpus;
|
||||
std::string ArtifactPrefix = "./";
|
||||
std::string ExactArtifactPath;
|
||||
bool SaveArtifacts = true;
|
||||
bool PrintNEW = true; // Print a status line when new units are found;
|
||||
bool OutputCSV = false;
|
||||
bool PrintNewCovPcs = false;
|
||||
bool PrintFinalStats = false;
|
||||
bool DetectLeaks = true;
|
||||
bool TruncateUnits = false;
|
||||
bool PruneCorpus = true;
|
||||
};
|
||||
|
||||
class MutationDispatcher {
|
||||
public:
|
||||
MutationDispatcher(Random &Rand);
|
||||
MutationDispatcher(Random &Rand, const FuzzingOptions &Options);
|
||||
~MutationDispatcher() {}
|
||||
/// Indicate that we are about to start a new sequence of mutations.
|
||||
void StartMutationSequence();
|
||||
|
@ -280,6 +314,8 @@ private:
|
|||
const std::vector<Mutator> &Mutators);
|
||||
|
||||
Random &Rand;
|
||||
const FuzzingOptions Options;
|
||||
|
||||
// Dictionary provided by the user via -dict=DICT_FILE.
|
||||
Dictionary ManualDictionary;
|
||||
// Temporary dictionary modified by the fuzzer itself,
|
||||
|
@ -299,39 +335,6 @@ private:
|
|||
|
||||
class Fuzzer {
|
||||
public:
|
||||
struct FuzzingOptions {
|
||||
int Verbosity = 1;
|
||||
size_t MaxLen = 0;
|
||||
int UnitTimeoutSec = 300;
|
||||
int TimeoutExitCode = 77;
|
||||
int ErrorExitCode = 77;
|
||||
int MaxTotalTimeSec = 0;
|
||||
int RssLimitMb = 0;
|
||||
bool DoCrossOver = true;
|
||||
int MutateDepth = 5;
|
||||
bool UseCounters = false;
|
||||
bool UseIndirCalls = true;
|
||||
bool UseTraces = false;
|
||||
bool UseMemcmp = true;
|
||||
bool UseFullCoverageSet = false;
|
||||
bool Reload = true;
|
||||
bool ShuffleAtStartUp = true;
|
||||
bool PreferSmall = true;
|
||||
size_t MaxNumberOfRuns = ULONG_MAX;
|
||||
int ReportSlowUnits = 10;
|
||||
bool OnlyASCII = false;
|
||||
std::string OutputCorpus;
|
||||
std::string ArtifactPrefix = "./";
|
||||
std::string ExactArtifactPath;
|
||||
bool SaveArtifacts = true;
|
||||
bool PrintNEW = true; // Print a status line when new units are found;
|
||||
bool OutputCSV = false;
|
||||
bool PrintNewCovPcs = false;
|
||||
bool PrintFinalStats = false;
|
||||
bool DetectLeaks = true;
|
||||
bool TruncateUnits = false;
|
||||
bool PruneCorpus = true;
|
||||
};
|
||||
|
||||
// Aggregates all available coverage measurements.
|
||||
struct Coverage {
|
||||
|
|
|
@ -60,14 +60,13 @@ struct CoverageController {
|
|||
PcMapResetCurrent();
|
||||
}
|
||||
|
||||
static void ResetCounters(const Fuzzer::FuzzingOptions &Options) {
|
||||
static void ResetCounters(const FuzzingOptions &Options) {
|
||||
if (Options.UseCounters) {
|
||||
EF->__sanitizer_update_counter_bitset_and_clear_counters(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void Prepare(const Fuzzer::FuzzingOptions &Options,
|
||||
Fuzzer::Coverage *C) {
|
||||
static void Prepare(const FuzzingOptions &Options, Fuzzer::Coverage *C) {
|
||||
if (Options.UseCounters) {
|
||||
size_t NumCounters = EF->__sanitizer_get_number_of_counters();
|
||||
C->CounterBitmap.resize(NumCounters);
|
||||
|
@ -76,8 +75,7 @@ struct CoverageController {
|
|||
|
||||
// Records data to a maximum coverage tracker. Returns true if additional
|
||||
// coverage was discovered.
|
||||
static bool RecordMax(const Fuzzer::FuzzingOptions &Options,
|
||||
Fuzzer::Coverage *C) {
|
||||
static bool RecordMax(const FuzzingOptions &Options, Fuzzer::Coverage *C) {
|
||||
bool Res = false;
|
||||
|
||||
uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();
|
||||
|
@ -675,8 +673,6 @@ void Fuzzer::MutateAndTestOne() {
|
|||
assert(NewSize <= Options.MaxLen &&
|
||||
"Mutator return overisized unit");
|
||||
Size = NewSize;
|
||||
if (Options.OnlyASCII)
|
||||
ToASCII(CurrentUnitData, Size);
|
||||
if (i == 0)
|
||||
StartTraceRecording();
|
||||
RunOneAndUpdateCorpus(CurrentUnitData, Size);
|
||||
|
|
|
@ -18,7 +18,9 @@ namespace fuzzer {
|
|||
|
||||
const size_t Dictionary::kMaxDictSize;
|
||||
|
||||
MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) {
|
||||
MutationDispatcher::MutationDispatcher(Random &Rand,
|
||||
const FuzzingOptions &Options)
|
||||
: Rand(Rand), Options(Options) {
|
||||
DefaultMutators.insert(
|
||||
DefaultMutators.begin(),
|
||||
{
|
||||
|
@ -285,6 +287,8 @@ size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
|
|||
if (Size == 0) {
|
||||
for (size_t i = 0; i < MaxSize; i++)
|
||||
Data[i] = RandCh(Rand);
|
||||
if (Options.OnlyASCII)
|
||||
ToASCII(Data, MaxSize);
|
||||
return MaxSize;
|
||||
}
|
||||
assert(Size > 0);
|
||||
|
@ -295,6 +299,8 @@ size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
|
|||
auto M = Mutators[Rand(Mutators.size())];
|
||||
size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
|
||||
if (NewSize) {
|
||||
if (Options.OnlyASCII)
|
||||
ToASCII(Data, NewSize);
|
||||
CurrentMutatorSequence.push_back(M);
|
||||
return NewSize;
|
||||
}
|
||||
|
|
|
@ -173,8 +173,8 @@ static bool RecordingTraces = false;
|
|||
static bool RecordingMemcmp = false;
|
||||
|
||||
class TraceState {
|
||||
public:
|
||||
TraceState(MutationDispatcher &MD, const Fuzzer::FuzzingOptions &Options,
|
||||
public:
|
||||
TraceState(MutationDispatcher &MD, const FuzzingOptions &Options,
|
||||
const Fuzzer *F)
|
||||
: MD(MD), Options(Options), F(F) {}
|
||||
|
||||
|
@ -209,7 +209,8 @@ class TraceState {
|
|||
}
|
||||
|
||||
void StopTraceRecording() {
|
||||
if (!RecordingTraces && !RecordingMemcmp) return;
|
||||
if (!RecordingTraces && !RecordingMemcmp)
|
||||
return;
|
||||
RecordingTraces = false;
|
||||
RecordingMemcmp = false;
|
||||
for (size_t i = 0; i < NumMutations; i++) {
|
||||
|
@ -287,7 +288,7 @@ class TraceState {
|
|||
LabelRange LabelRanges[1 << (sizeof(dfsan_label) * 8)];
|
||||
size_t LastDfsanLabel = 0;
|
||||
MutationDispatcher &MD;
|
||||
const Fuzzer::FuzzingOptions &Options;
|
||||
const FuzzingOptions Options;
|
||||
const Fuzzer *F;
|
||||
std::map<Word, size_t> AutoDictUnitCounts;
|
||||
size_t AutoDictAdds = 0;
|
||||
|
|
|
@ -22,7 +22,7 @@ TEST(Fuzzer, CrossOver) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
Unit A({0, 1, 2}), B({5, 6, 7});
|
||||
Unit C;
|
||||
Unit Expected[] = {
|
||||
|
@ -100,7 +100,7 @@ void TestEraseByte(Mutator M, int NumIter) {
|
|||
uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
|
||||
uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
int FoundMask = 0;
|
||||
for (int i = 0; i < NumIter; i++) {
|
||||
uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
|
@ -128,7 +128,7 @@ void TestInsertByte(Mutator M, int NumIter) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
int FoundMask = 0;
|
||||
uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
|
||||
uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
|
||||
|
@ -164,7 +164,7 @@ void TestChangeByte(Mutator M, int NumIter) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
int FoundMask = 0;
|
||||
uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
|
@ -200,7 +200,7 @@ void TestChangeBit(Mutator M, int NumIter) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
int FoundMask = 0;
|
||||
uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
|
@ -236,7 +236,7 @@ void TestShuffleBytes(Mutator M, int NumIter) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
int FoundMask = 0;
|
||||
uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
|
||||
uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
|
||||
|
@ -266,7 +266,7 @@ void TestAddWordFromDictionary(Mutator M, int NumIter) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
|
||||
uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
|
||||
MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
|
||||
|
@ -308,7 +308,7 @@ void TestAddWordFromDictionaryWithHint(Mutator M, int NumIter) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
uint8_t W[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0xEE, 0xEF};
|
||||
size_t PosHint = 7777;
|
||||
MD.AddWordToAutoDictionary(Word(W, sizeof(W)), PosHint);
|
||||
|
@ -337,7 +337,7 @@ void TestChangeASCIIInteger(Mutator M, int NumIter) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
|
||||
uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
|
||||
uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
|
||||
|
@ -431,9 +431,8 @@ TEST(Corpus, Distribution) {
|
|||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand);
|
||||
Fuzzer::FuzzingOptions Options;
|
||||
Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, Options);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
Fuzzer Fuzz(LLVMFuzzerTestOneInput, MD, {});
|
||||
size_t N = 10;
|
||||
size_t TriesPerUnit = 1<<20;
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
|
|
Loading…
Reference in New Issue