xref: /freebsd/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerMutate.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- FuzzerMutate.h - Internal header for the Fuzzer ----------*- C++ -* ===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric // fuzzer::MutationDispatcher
9*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10*0b57cec5SDimitry Andric 
11*0b57cec5SDimitry Andric #ifndef LLVM_FUZZER_MUTATE_H
12*0b57cec5SDimitry Andric #define LLVM_FUZZER_MUTATE_H
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric #include "FuzzerDefs.h"
15*0b57cec5SDimitry Andric #include "FuzzerDictionary.h"
16*0b57cec5SDimitry Andric #include "FuzzerOptions.h"
17*0b57cec5SDimitry Andric #include "FuzzerRandom.h"
18*0b57cec5SDimitry Andric 
19*0b57cec5SDimitry Andric namespace fuzzer {
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric class MutationDispatcher {
22*0b57cec5SDimitry Andric public:
23*0b57cec5SDimitry Andric   MutationDispatcher(Random &Rand, const FuzzingOptions &Options);
24*0b57cec5SDimitry Andric   ~MutationDispatcher() {}
25*0b57cec5SDimitry Andric   /// Indicate that we are about to start a new sequence of mutations.
26*0b57cec5SDimitry Andric   void StartMutationSequence();
27*0b57cec5SDimitry Andric   /// Print the current sequence of mutations.
28*0b57cec5SDimitry Andric   void PrintMutationSequence();
29*0b57cec5SDimitry Andric   /// Indicate that the current sequence of mutations was successful.
30*0b57cec5SDimitry Andric   void RecordSuccessfulMutationSequence();
31*0b57cec5SDimitry Andric   /// Mutates data by invoking user-provided mutator.
32*0b57cec5SDimitry Andric   size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
33*0b57cec5SDimitry Andric   /// Mutates data by invoking user-provided crossover.
34*0b57cec5SDimitry Andric   size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
35*0b57cec5SDimitry Andric   /// Mutates data by shuffling bytes.
36*0b57cec5SDimitry Andric   size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
37*0b57cec5SDimitry Andric   /// Mutates data by erasing bytes.
38*0b57cec5SDimitry Andric   size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize);
39*0b57cec5SDimitry Andric   /// Mutates data by inserting a byte.
40*0b57cec5SDimitry Andric   size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);
41*0b57cec5SDimitry Andric   /// Mutates data by inserting several repeated bytes.
42*0b57cec5SDimitry Andric   size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize);
43*0b57cec5SDimitry Andric   /// Mutates data by chanding one byte.
44*0b57cec5SDimitry Andric   size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);
45*0b57cec5SDimitry Andric   /// Mutates data by chanding one bit.
46*0b57cec5SDimitry Andric   size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);
47*0b57cec5SDimitry Andric   /// Mutates data by copying/inserting a part of data into a different place.
48*0b57cec5SDimitry Andric   size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize);
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric   /// Mutates data by adding a word from the manual dictionary.
51*0b57cec5SDimitry Andric   size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,
52*0b57cec5SDimitry Andric                                             size_t MaxSize);
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric   /// Mutates data by adding a word from the TORC.
55*0b57cec5SDimitry Andric   size_t Mutate_AddWordFromTORC(uint8_t *Data, size_t Size, size_t MaxSize);
56*0b57cec5SDimitry Andric 
57*0b57cec5SDimitry Andric   /// Mutates data by adding a word from the persistent automatic dictionary.
58*0b57cec5SDimitry Andric   size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,
59*0b57cec5SDimitry Andric                                                     size_t MaxSize);
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric   /// Tries to find an ASCII integer in Data, changes it to another ASCII int.
62*0b57cec5SDimitry Andric   size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);
63*0b57cec5SDimitry Andric   /// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.
64*0b57cec5SDimitry Andric   size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);
65*0b57cec5SDimitry Andric 
66*0b57cec5SDimitry Andric   /// CrossOver Data with CrossOverWith.
67*0b57cec5SDimitry Andric   size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
68*0b57cec5SDimitry Andric 
69*0b57cec5SDimitry Andric   /// Applies one of the configured mutations.
70*0b57cec5SDimitry Andric   /// Returns the new size of data which could be up to MaxSize.
71*0b57cec5SDimitry Andric   size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
72*0b57cec5SDimitry Andric 
73*0b57cec5SDimitry Andric   /// Applies one of the configured mutations to the bytes of Data
74*0b57cec5SDimitry Andric   /// that have '1' in Mask.
75*0b57cec5SDimitry Andric   /// Mask.size() should be >= Size.
76*0b57cec5SDimitry Andric   size_t MutateWithMask(uint8_t *Data, size_t Size, size_t MaxSize,
77*0b57cec5SDimitry Andric                         const Vector<uint8_t> &Mask);
78*0b57cec5SDimitry Andric 
79*0b57cec5SDimitry Andric   /// Applies one of the default mutations. Provided as a service
80*0b57cec5SDimitry Andric   /// to mutation authors.
81*0b57cec5SDimitry Andric   size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric   /// Creates a cross-over of two pieces of Data, returns its size.
84*0b57cec5SDimitry Andric   size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
85*0b57cec5SDimitry Andric                    size_t Size2, uint8_t *Out, size_t MaxOutSize);
86*0b57cec5SDimitry Andric 
87*0b57cec5SDimitry Andric   void AddWordToManualDictionary(const Word &W);
88*0b57cec5SDimitry Andric 
89*0b57cec5SDimitry Andric   void PrintRecommendedDictionary();
90*0b57cec5SDimitry Andric 
91*0b57cec5SDimitry Andric   void SetCrossOverWith(const Unit *U) { CrossOverWith = U; }
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   Random &GetRand() { return Rand; }
94*0b57cec5SDimitry Andric 
95*0b57cec5SDimitry Andric  private:
96*0b57cec5SDimitry Andric   struct Mutator {
97*0b57cec5SDimitry Andric     size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
98*0b57cec5SDimitry Andric     const char *Name;
99*0b57cec5SDimitry Andric   };
100*0b57cec5SDimitry Andric 
101*0b57cec5SDimitry Andric   size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
102*0b57cec5SDimitry Andric                                size_t MaxSize);
103*0b57cec5SDimitry Andric   size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
104*0b57cec5SDimitry Andric                     Vector<Mutator> &Mutators);
105*0b57cec5SDimitry Andric 
106*0b57cec5SDimitry Andric   size_t InsertPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
107*0b57cec5SDimitry Andric                       size_t ToSize, size_t MaxToSize);
108*0b57cec5SDimitry Andric   size_t CopyPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
109*0b57cec5SDimitry Andric                     size_t ToSize);
110*0b57cec5SDimitry Andric   size_t ApplyDictionaryEntry(uint8_t *Data, size_t Size, size_t MaxSize,
111*0b57cec5SDimitry Andric                               DictionaryEntry &DE);
112*0b57cec5SDimitry Andric 
113*0b57cec5SDimitry Andric   template <class T>
114*0b57cec5SDimitry Andric   DictionaryEntry MakeDictionaryEntryFromCMP(T Arg1, T Arg2,
115*0b57cec5SDimitry Andric                                              const uint8_t *Data, size_t Size);
116*0b57cec5SDimitry Andric   DictionaryEntry MakeDictionaryEntryFromCMP(const Word &Arg1, const Word &Arg2,
117*0b57cec5SDimitry Andric                                              const uint8_t *Data, size_t Size);
118*0b57cec5SDimitry Andric   DictionaryEntry MakeDictionaryEntryFromCMP(const void *Arg1, const void *Arg2,
119*0b57cec5SDimitry Andric                                              const void *Arg1Mutation,
120*0b57cec5SDimitry Andric                                              const void *Arg2Mutation,
121*0b57cec5SDimitry Andric                                              size_t ArgSize,
122*0b57cec5SDimitry Andric                                              const uint8_t *Data, size_t Size);
123*0b57cec5SDimitry Andric 
124*0b57cec5SDimitry Andric   Random &Rand;
125*0b57cec5SDimitry Andric   const FuzzingOptions Options;
126*0b57cec5SDimitry Andric 
127*0b57cec5SDimitry Andric   // Dictionary provided by the user via -dict=DICT_FILE.
128*0b57cec5SDimitry Andric   Dictionary ManualDictionary;
129*0b57cec5SDimitry Andric   // Temporary dictionary modified by the fuzzer itself,
130*0b57cec5SDimitry Andric   // recreated periodically.
131*0b57cec5SDimitry Andric   Dictionary TempAutoDictionary;
132*0b57cec5SDimitry Andric   // Persistent dictionary modified by the fuzzer, consists of
133*0b57cec5SDimitry Andric   // entries that led to successful discoveries in the past mutations.
134*0b57cec5SDimitry Andric   Dictionary PersistentAutoDictionary;
135*0b57cec5SDimitry Andric 
136*0b57cec5SDimitry Andric   Vector<DictionaryEntry *> CurrentDictionaryEntrySequence;
137*0b57cec5SDimitry Andric 
138*0b57cec5SDimitry Andric   static const size_t kCmpDictionaryEntriesDequeSize = 16;
139*0b57cec5SDimitry Andric   DictionaryEntry CmpDictionaryEntriesDeque[kCmpDictionaryEntriesDequeSize];
140*0b57cec5SDimitry Andric   size_t CmpDictionaryEntriesDequeIdx = 0;
141*0b57cec5SDimitry Andric 
142*0b57cec5SDimitry Andric   const Unit *CrossOverWith = nullptr;
143*0b57cec5SDimitry Andric   Vector<uint8_t> MutateInPlaceHere;
144*0b57cec5SDimitry Andric   Vector<uint8_t> MutateWithMaskTemp;
145*0b57cec5SDimitry Andric   // CustomCrossOver needs its own buffer as a custom implementation may call
146*0b57cec5SDimitry Andric   // LLVMFuzzerMutate, which in turn may resize MutateInPlaceHere.
147*0b57cec5SDimitry Andric   Vector<uint8_t> CustomCrossOverInPlaceHere;
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric   Vector<Mutator> Mutators;
150*0b57cec5SDimitry Andric   Vector<Mutator> DefaultMutators;
151*0b57cec5SDimitry Andric   Vector<Mutator> CurrentMutatorSequence;
152*0b57cec5SDimitry Andric };
153*0b57cec5SDimitry Andric 
154*0b57cec5SDimitry Andric }  // namespace fuzzer
155*0b57cec5SDimitry Andric 
156*0b57cec5SDimitry Andric #endif  // LLVM_FUZZER_MUTATE_H
157