[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:
Mike Aizatsky 2016-06-23 20:44:48 +00:00
parent f2898d73a5
commit f0b3e85f4e
6 changed files with 65 additions and 60 deletions

View File

@ -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)

View File

@ -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 {

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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++) {