llvm.org GIT mirror llvm / 664513f
[libfuzzer] hiding custom mutator handling in MutationDispatcher. Summary: Refactoring, no functional changes. Differential Revision: http://reviews.llvm.org/D20975 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271740 91177308-0d34-0410-b5e6-96231b3b80d8 Mike Aizatsky 4 years ago
3 changed file(s) with 60 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
204204
205205 class MutationDispatcher {
206206 public:
207 MutationDispatcher(Random &Rand) : Rand(Rand) {}
207 MutationDispatcher(Random &Rand);
208208 ~MutationDispatcher() {}
209209 /// Indicate that we are about to start a new sequence of mutations.
210210 void StartMutationSequence();
212212 void PrintMutationSequence();
213213 /// Indicate that the current sequence of mutations was successfull.
214214 void RecordSuccessfulMutationSequence();
215 /// Mutates data by invoking user-provided mutator.
216 size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
215217 /// Mutates data by shuffling bytes.
216218 size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
217219 /// Mutates data by erasing a byte.
241243 /// CrossOver Data with some other element of the corpus.
242244 size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
243245
244 /// Applies one of the above mutations.
246 /// Applies one of the configured mutations.
245247 /// Returns the new size of data which could be up to MaxSize.
246248 size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
249 /// Applies one of the default mutations. Provided as a service
250 /// to mutation authors.
251 size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
247252
248253 /// Creates a cross-over of two pieces of Data, returns its size.
249254 size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
268273
269274 size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
270275 size_t MaxSize);
276 size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
277 const std::vector &Mutators);
278
279 // Interface to functions that may or may not be available.
280 const ExternalFunctions EF;
271281
272282 Random &Rand;
273283 // Dictionary provided by the user via -dict=DICT_FILE.
283293 const std::vector *Corpus = nullptr;
284294 std::vector MutateInPlaceHere;
285295
286 static Mutator Mutators[];
296 std::vector Mutators;
297 std::vector DefaultMutators;
287298 };
288299
289300 class Fuzzer {
470481 static thread_local bool IsMyThread;
471482
472483 // Interface to functions that may or may not be available.
473 ExternalFunctions EF;
484 // For future use, currently not used.
485 const ExternalFunctions EF;
474486 };
475487
476488 }; // namespace fuzzer
691691
692692 for (int i = 0; i < Options.MutateDepth; i++) {
693693 size_t NewSize = 0;
694 if (EF.LLVMFuzzerCustomMutator)
695 NewSize = EF.LLVMFuzzerCustomMutator(CurrentUnitData, Size,
696 Options.MaxLen, MD.GetRand().Rand());
697 else
698 NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
694 NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
699695 assert(NewSize > 0 && "Mutator returned empty unit");
700696 assert(NewSize <= Options.MaxLen &&
701697 "Mutator return overisized unit");
815811
816812 size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
817813 assert(fuzzer::F);
818 return fuzzer::F->GetMD().Mutate(Data, Size, MaxSize);
814 return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
819815 }
820816 } // extern "C"
1717
1818 const size_t Dictionary::kMaxDictSize;
1919
20 MutationDispatcher::Mutator MutationDispatcher::Mutators[] = {
21 {&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
22 {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
23 {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
24 {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
25 {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
26 {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
27 {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
28 {&MutationDispatcher::Mutate_AddWordFromManualDictionary,
29 "AddFromManualDict"},
30 {&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
31 "AddFromTempAutoDict"},
32 {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
33 "AddFromPersAutoDict"},
34 };
20 MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) {
21 DefaultMutators.insert(
22 DefaultMutators.begin(),
23 {
24 {&MutationDispatcher::Mutate_EraseByte, "EraseByte"},
25 {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
26 {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
27 {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
28 {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
29 {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
30 {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
31 {&MutationDispatcher::Mutate_AddWordFromManualDictionary,
32 "AddFromManualDict"},
33 {&MutationDispatcher::Mutate_AddWordFromTemporaryAutoDictionary,
34 "AddFromTempAutoDict"},
35 {&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
36 "AddFromPersAutoDict"},
37 });
38
39 if (EF.LLVMFuzzerCustomMutator)
40 Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
41 else
42 Mutators = DefaultMutators;
43 }
3544
3645 static char FlipRandomBit(char X, Random &Rand) {
3746 int Bit = Rand(8);
4958 if (Rand.RandBool()) return Rand(256);
5059 const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~.";
5160 return Special[Rand(sizeof(Special) - 1)];
61 }
62
63 size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
64 size_t MaxSize) {
65 return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
5266 }
5367
5468 size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
229243 }
230244 }
231245
246 size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
247 return MutateImpl(Data, Size, MaxSize, Mutators);
248 }
249
250 size_t MutationDispatcher::DefaultMutate(uint8_t *Data, size_t Size,
251 size_t MaxSize) {
252 return MutateImpl(Data, Size, MaxSize, DefaultMutators);
253 }
254
232255 // Mutates Data in place, returns new size.
233 size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
256 size_t MutationDispatcher::MutateImpl(uint8_t *Data, size_t Size,
257 size_t MaxSize,
258 const std::vector &Mutators) {
234259 assert(MaxSize > 0);
235260 assert(Size <= MaxSize);
236261 if (Size == 0) {
243268 // in which case they will return 0.
244269 // Try several times before returning un-mutated data.
245270 for (int Iter = 0; Iter < 10; Iter++) {
246 size_t NumMutators = sizeof(Mutators) / sizeof(Mutators[0]);
247 size_t MutatorIdx = Rand(NumMutators);
248 auto M = Mutators[MutatorIdx];
271 auto M = Mutators[Rand(Mutators.size())];
249272 size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
250273 if (NewSize) {
251274 CurrentMutatorSequence.push_back(M);