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