Skip to content

Commit 70fd3e4

Browse files
committedJun 3, 2016
[libfuzzer] hiding custom mutator handling in MutationDispatcher.
Summary: Refactoring, no functional changes. Differential Revision: http://reviews.llvm.org/D20975 llvm-svn: 271740
1 parent c0308c4 commit 70fd3e4

File tree

3 files changed

+60
-29
lines changed

3 files changed

+60
-29
lines changed
 

Diff for: ‎llvm/lib/Fuzzer/FuzzerInternal.h

+16-4
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,16 @@ class Dictionary {
205205

206206
class MutationDispatcher {
207207
public:
208-
MutationDispatcher(Random &Rand) : Rand(Rand) {}
208+
MutationDispatcher(Random &Rand);
209209
~MutationDispatcher() {}
210210
/// Indicate that we are about to start a new sequence of mutations.
211211
void StartMutationSequence();
212212
/// Print the current sequence of mutations.
213213
void PrintMutationSequence();
214214
/// Indicate that the current sequence of mutations was successfull.
215215
void RecordSuccessfulMutationSequence();
216+
/// Mutates data by invoking user-provided mutator.
217+
size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
216218
/// Mutates data by shuffling bytes.
217219
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
218220
/// Mutates data by erasing a byte.
@@ -242,9 +244,12 @@ class MutationDispatcher {
242244
/// CrossOver Data with some other element of the corpus.
243245
size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
244246

245-
/// Applies one of the above mutations.
247+
/// Applies one of the configured mutations.
246248
/// Returns the new size of data which could be up to MaxSize.
247249
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
250+
/// Applies one of the default mutations. Provided as a service
251+
/// to mutation authors.
252+
size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
248253

249254
/// Creates a cross-over of two pieces of Data, returns its size.
250255
size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
@@ -269,6 +274,11 @@ class MutationDispatcher {
269274

270275
size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
271276
size_t MaxSize);
277+
size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
278+
const std::vector<Mutator> &Mutators);
279+
280+
// Interface to functions that may or may not be available.
281+
const ExternalFunctions EF;
272282

273283
Random &Rand;
274284
// Dictionary provided by the user via -dict=DICT_FILE.
@@ -284,7 +294,8 @@ class MutationDispatcher {
284294
const std::vector<Unit> *Corpus = nullptr;
285295
std::vector<uint8_t> MutateInPlaceHere;
286296

287-
static Mutator Mutators[];
297+
std::vector<Mutator> Mutators;
298+
std::vector<Mutator> DefaultMutators;
288299
};
289300

290301
class Fuzzer {
@@ -471,7 +482,8 @@ class Fuzzer {
471482
static thread_local bool IsMyThread;
472483

473484
// Interface to functions that may or may not be available.
474-
ExternalFunctions EF;
485+
// For future use, currently not used.
486+
const ExternalFunctions EF;
475487
};
476488

477489
}; // namespace fuzzer

Diff for: ‎llvm/lib/Fuzzer/FuzzerLoop.cpp

+2-6
Original file line numberDiff line numberDiff line change
@@ -692,11 +692,7 @@ void Fuzzer::MutateAndTestOne() {
692692

693693
for (int i = 0; i < Options.MutateDepth; i++) {
694694
size_t NewSize = 0;
695-
if (EF.LLVMFuzzerCustomMutator)
696-
NewSize = EF.LLVMFuzzerCustomMutator(CurrentUnitData, Size,
697-
Options.MaxLen, MD.GetRand().Rand());
698-
else
699-
NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
695+
NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
700696
assert(NewSize > 0 && "Mutator returned empty unit");
701697
assert(NewSize <= Options.MaxLen &&
702698
"Mutator return overisized unit");
@@ -816,6 +812,6 @@ extern "C" {
816812

817813
size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
818814
assert(fuzzer::F);
819-
return fuzzer::F->GetMD().Mutate(Data, Size, MaxSize);
815+
return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
820816
}
821817
} // extern "C"

Diff for: ‎llvm/lib/Fuzzer/FuzzerMutate.cpp

+42-19
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,30 @@ namespace fuzzer {
1818

1919
const size_t Dictionary::kMaxDictSize;
2020

21-
MutationDispatcher::Mutator MutationDispatcher::Mutators[] = {
22-
{&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
23-
{&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
24-
{&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
25-
{&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
26-
{&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
27-
{&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
28-
{&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
29-
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
30-
"AddFromManualDict"},
31-
{&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
32-
"AddFromTempAutoDict"},
33-
{&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
34-
"AddFromPersAutoDict"},
35-
};
21+
MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) {
22+
DefaultMutators.insert(
23+
DefaultMutators.begin(),
24+
{
25+
{&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
26+
{&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
27+
{&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
28+
{&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
29+
{&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
30+
{&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
31+
{&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
32+
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
33+
"AddFromManualDict"},
34+
{&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
35+
"AddFromTempAutoDict"},
36+
{&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
37+
"AddFromPersAutoDict"},
38+
});
39+
40+
if (EF.LLVMFuzzerCustomMutator)
41+
Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
42+
else
43+
Mutators = DefaultMutators;
44+
}
3645

3746
static char FlipRandomBit(char X, Random &Rand) {
3847
int Bit = Rand(8);
@@ -52,6 +61,11 @@ static char RandCh(Random &Rand) {
5261
return Special[Rand(sizeof(Special) - 1)];
5362
}
5463

64+
size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
65+
size_t MaxSize) {
66+
return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
67+
}
68+
5569
size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
5670
size_t MaxSize) {
5771
assert(Size);
@@ -230,8 +244,19 @@ void MutationDispatcher::PrintMutationSequence() {
230244
}
231245
}
232246

233-
// Mutates Data in place, returns new size.
234247
size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
248+
return MutateImpl(Data, Size, MaxSize, Mutators);
249+
}
250+
251+
size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
252+
size_t MaxSize) {
253+
return MutateImpl(Data, Size, MaxSize, DefaultMutators);
254+
}
255+
256+
// Mutates Data in place, returns new size.
257+
size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
258+
size_t MaxSize,
259+
const std::vector<Mutator> &Mutators) {
235260
assert(MaxSize > 0);
236261
assert(Size <= MaxSize);
237262
if (Size == 0) {
@@ -244,9 +269,7 @@ size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
244269
// in which case they will return 0.
245270
// Try several times before returning un-mutated data.
246271
for (int Iter = 0; Iter < 10; Iter++) {
247-
size_t NumMutators = sizeof(Mutators) / sizeof(Mutators[0]);
248-
size_t MutatorIdx = Rand(NumMutators);
249-
auto M = Mutators[MutatorIdx];
272+
auto M = Mutators[Rand(Mutators.size())];
250273
size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
251274
if (NewSize) {
252275
CurrentMutatorSequence.push_back(M);

0 commit comments

Comments
 (0)
Please sign in to comment.