blob: 858e61d75fe367f22a55c329983867c0aa329c3c [file] [log] [blame]
George Karpenkov10ab2ac2017-08-21 23:25:50 +00001// This file is distributed under the University of Illinois Open Source
2// License. See LICENSE.TXT for details.
3
4// Avoid ODR violations (LibFuzzer is built without ASan and this test is built
5// with ASan) involving C++ standard library types when using libcxx.
6#define _LIBCPP_HAS_NO_ASAN
7
8// Do not attempt to use LLVM ostream from gtest.
9#define GTEST_NO_LLVM_RAW_OSTREAM 1
10
11#include "FuzzerCorpus.h"
12#include "FuzzerDictionary.h"
13#include "FuzzerInternal.h"
14#include "FuzzerMerge.h"
15#include "FuzzerMutate.h"
16#include "FuzzerRandom.h"
17#include "FuzzerTracePC.h"
18#include "gtest/gtest.h"
19#include <memory>
20#include <set>
21#include <sstream>
22
23using namespace fuzzer;
24
25// For now, have LLVMFuzzerTestOneInput just to make it link.
26// Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
27extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
28 abort();
29}
30
31TEST(Fuzzer, CrossOver) {
32 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
33 fuzzer::EF = t.get();
34 Random Rand(0);
35 MutationDispatcher MD(Rand, {});
36 Unit A({0, 1, 2}), B({5, 6, 7});
37 Unit C;
38 Unit Expected[] = {
39 { 0 },
40 { 0, 1 },
41 { 0, 5 },
42 { 0, 1, 2 },
43 { 0, 1, 5 },
44 { 0, 5, 1 },
45 { 0, 5, 6 },
46 { 0, 1, 2, 5 },
47 { 0, 1, 5, 2 },
48 { 0, 1, 5, 6 },
49 { 0, 5, 1, 2 },
50 { 0, 5, 1, 6 },
51 { 0, 5, 6, 1 },
52 { 0, 5, 6, 7 },
53 { 0, 1, 2, 5, 6 },
54 { 0, 1, 5, 2, 6 },
55 { 0, 1, 5, 6, 2 },
56 { 0, 1, 5, 6, 7 },
57 { 0, 5, 1, 2, 6 },
58 { 0, 5, 1, 6, 2 },
59 { 0, 5, 1, 6, 7 },
60 { 0, 5, 6, 1, 2 },
61 { 0, 5, 6, 1, 7 },
62 { 0, 5, 6, 7, 1 },
63 { 0, 1, 2, 5, 6, 7 },
64 { 0, 1, 5, 2, 6, 7 },
65 { 0, 1, 5, 6, 2, 7 },
66 { 0, 1, 5, 6, 7, 2 },
67 { 0, 5, 1, 2, 6, 7 },
68 { 0, 5, 1, 6, 2, 7 },
69 { 0, 5, 1, 6, 7, 2 },
70 { 0, 5, 6, 1, 2, 7 },
71 { 0, 5, 6, 1, 7, 2 },
72 { 0, 5, 6, 7, 1, 2 }
73 };
74 for (size_t Len = 1; Len < 8; Len++) {
75 std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
76 for (int Iter = 0; Iter < 3000; Iter++) {
77 C.resize(Len);
78 size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(),
79 C.data(), C.size());
80 C.resize(NewSize);
81 FoundUnits.insert(C);
82 }
83 for (const Unit &U : Expected)
84 if (U.size() <= Len)
85 ExpectedUnitsWitThisLength.insert(U);
86 EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
87 }
88}
89
90TEST(Fuzzer, Hash) {
91 uint8_t A[] = {'a', 'b', 'c'};
92 fuzzer::Unit U(A, A + sizeof(A));
93 EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
94 U.push_back('d');
95 EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
96}
97
98typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
99 size_t MaxSize);
100
101void TestEraseBytes(Mutator M, int NumIter) {
102 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
103 fuzzer::EF = t.get();
104 uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
105 uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
106 uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
107 uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
108 uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
109 uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
110 uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
111 uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
112
113 uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
114 uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
115 uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
116
117 uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
118 uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
119 uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
120
121
122 Random Rand(0);
123 MutationDispatcher MD(Rand, {});
124 int FoundMask = 0;
125 for (int i = 0; i < NumIter; i++) {
126 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
127 size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));
128 if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
129 if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
130 if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
131 if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
132 if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
133 if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
134 if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
135 if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
136
137 if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
138 if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
139 if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
140
141 if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
142 if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
143 if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
144 }
145 EXPECT_EQ(FoundMask, (1 << 14) - 1);
146}
147
148TEST(FuzzerMutate, EraseBytes1) {
149 TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
150}
151TEST(FuzzerMutate, EraseBytes2) {
152 TestEraseBytes(&MutationDispatcher::Mutate, 2000);
153}
154
155void TestInsertByte(Mutator M, int NumIter) {
156 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
157 fuzzer::EF = t.get();
158 Random Rand(0);
159 MutationDispatcher MD(Rand, {});
160 int FoundMask = 0;
161 uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
162 uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
163 uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
164 uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
165 uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
166 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
167 uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
168 uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
169 for (int i = 0; i < NumIter; i++) {
170 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
171 size_t NewSize = (MD.*M)(T, 7, 8);
172 if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
173 if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
174 if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
175 if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
176 if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
177 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
178 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
179 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
180 }
181 EXPECT_EQ(FoundMask, 255);
182}
183
184TEST(FuzzerMutate, InsertByte1) {
185 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
186}
187TEST(FuzzerMutate, InsertByte2) {
188 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
189}
190
191void TestInsertRepeatedBytes(Mutator M, int NumIter) {
192 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
193 fuzzer::EF = t.get();
194 Random Rand(0);
195 MutationDispatcher MD(Rand, {});
196 int FoundMask = 0;
197 uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
198 uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
199 uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
200 uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
201 uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
202
203 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
204 uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
205 uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
206 uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
207 uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
208
209 for (int i = 0; i < NumIter; i++) {
210 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
211 size_t NewSize = (MD.*M)(T, 4, 8);
212 if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
213 if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
214 if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
215 if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
216 if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
217
218 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
219 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
220 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
221 if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
222 if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
223
224 }
225 EXPECT_EQ(FoundMask, (1 << 10) - 1);
226}
227
228TEST(FuzzerMutate, InsertRepeatedBytes1) {
229 TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
230}
231TEST(FuzzerMutate, InsertRepeatedBytes2) {
232 TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
233}
234
235void TestChangeByte(Mutator M, int NumIter) {
236 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
237 fuzzer::EF = t.get();
238 Random Rand(0);
239 MutationDispatcher MD(Rand, {});
240 int FoundMask = 0;
241 uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
242 uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
243 uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
244 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
245 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
246 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
247 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
248 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
249 for (int i = 0; i < NumIter; i++) {
250 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
251 size_t NewSize = (MD.*M)(T, 8, 9);
252 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
253 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
254 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
255 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
256 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
257 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
258 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
259 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
260 }
261 EXPECT_EQ(FoundMask, 255);
262}
263
264TEST(FuzzerMutate, ChangeByte1) {
265 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
266}
267TEST(FuzzerMutate, ChangeByte2) {
268 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
269}
270
271void TestChangeBit(Mutator M, int NumIter) {
272 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
273 fuzzer::EF = t.get();
274 Random Rand(0);
275 MutationDispatcher MD(Rand, {});
276 int FoundMask = 0;
277 uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
278 uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
279 uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
280 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
281 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
282 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
283 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
284 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
285 for (int i = 0; i < NumIter; i++) {
286 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
287 size_t NewSize = (MD.*M)(T, 8, 9);
288 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
289 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
290 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
291 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
292 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
293 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
294 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
295 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
296 }
297 EXPECT_EQ(FoundMask, 255);
298}
299
300TEST(FuzzerMutate, ChangeBit1) {
301 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
302}
303TEST(FuzzerMutate, ChangeBit2) {
304 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
305}
306
307void TestShuffleBytes(Mutator M, int NumIter) {
308 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
309 fuzzer::EF = t.get();
310 Random Rand(0);
311 MutationDispatcher MD(Rand, {});
312 int FoundMask = 0;
313 uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
314 uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
315 uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
316 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
317 uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
318 for (int i = 0; i < NumIter; i++) {
319 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
320 size_t NewSize = (MD.*M)(T, 7, 7);
321 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
322 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
323 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
324 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
325 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
326 }
327 EXPECT_EQ(FoundMask, 31);
328}
329
330TEST(FuzzerMutate, ShuffleBytes1) {
331 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 16);
332}
333TEST(FuzzerMutate, ShuffleBytes2) {
334 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
335}
336
337void TestCopyPart(Mutator M, int NumIter) {
338 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
339 fuzzer::EF = t.get();
340 Random Rand(0);
341 MutationDispatcher MD(Rand, {});
342 int FoundMask = 0;
343 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};
344 uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};
345 uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};
346 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};
347 uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};
348
349 for (int i = 0; i < NumIter; i++) {
350 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
351 size_t NewSize = (MD.*M)(T, 7, 7);
352 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
353 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
354 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
355 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
356 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
357 }
358
359 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
360 uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};
361 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};
362 uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};
363 uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};
364
365 for (int i = 0; i < NumIter; i++) {
366 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
367 size_t NewSize = (MD.*M)(T, 5, 8);
368 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
369 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
370 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
371 if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;
372 if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;
373 }
374
375 EXPECT_EQ(FoundMask, 1023);
376}
377
378TEST(FuzzerMutate, CopyPart1) {
379 TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
380}
381TEST(FuzzerMutate, CopyPart2) {
382 TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
383}
384
385void TestAddWordFromDictionary(Mutator M, int NumIter) {
386 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
387 fuzzer::EF = t.get();
388 Random Rand(0);
389 MutationDispatcher MD(Rand, {});
390 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
391 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
392 MD.AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
393 MD.AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
394 int FoundMask = 0;
395 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
396 uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
397 uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
398 uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
399 uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
400 uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
401 uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
402 uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
403 for (int i = 0; i < NumIter; i++) {
404 uint8_t T[7] = {0x00, 0x11, 0x22};
405 size_t NewSize = (MD.*M)(T, 3, 7);
406 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
407 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
408 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
409 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
410 if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
411 if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
412 if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
413 if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
414 }
415 EXPECT_EQ(FoundMask, 255);
416}
417
418TEST(FuzzerMutate, AddWordFromDictionary1) {
419 TestAddWordFromDictionary(
420 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
421}
422
423TEST(FuzzerMutate, AddWordFromDictionary2) {
424 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
425}
426
427void TestChangeASCIIInteger(Mutator M, int NumIter) {
428 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
429 fuzzer::EF = t.get();
430 Random Rand(0);
431 MutationDispatcher MD(Rand, {});
432
433 uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
434 uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
435 uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
436 uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
437 int FoundMask = 0;
438 for (int i = 0; i < NumIter; i++) {
439 uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
440 size_t NewSize = (MD.*M)(T, 8, 8);
441 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
442 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
443 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
444 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
445 else if (NewSize == 8) FoundMask |= 1 << 4;
446 }
447 EXPECT_EQ(FoundMask, 31);
448}
449
450TEST(FuzzerMutate, ChangeASCIIInteger1) {
451 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
452 1 << 15);
453}
454
455TEST(FuzzerMutate, ChangeASCIIInteger2) {
456 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
457}
458
459void TestChangeBinaryInteger(Mutator M, int NumIter) {
460 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
461 fuzzer::EF = t.get();
462 Random Rand(0);
463 MutationDispatcher MD(Rand, {});
464
465 uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
466 uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
467 uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
468 uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
469 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
470 uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
471 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size
472 uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)
473
474 int FoundMask = 0;
475 for (int i = 0; i < NumIter; i++) {
476 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
477 size_t NewSize = (MD.*M)(T, 8, 8);
478 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
479 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
480 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
481 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
482 else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
483 else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
484 else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
485 else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
486 }
487 EXPECT_EQ(FoundMask, 255);
488}
489
490TEST(FuzzerMutate, ChangeBinaryInteger1) {
491 TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
492 1 << 12);
493}
494
495TEST(FuzzerMutate, ChangeBinaryInteger2) {
496 TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
497}
498
499
500TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
501 Unit U;
502 EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
503 EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
504 EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U));
505 EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U));
506 EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U));
507 EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U));
508 EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U));
509 EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
510 EXPECT_EQ(U, Unit({'a'}));
511 EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
512 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
513 EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
514 EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
515 EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
516 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
517 EXPECT_EQ(U, Unit({'\\'}));
518 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
519 EXPECT_EQ(U, Unit({0xAB}));
520 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
521 EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
522 EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
523 EXPECT_EQ(U, Unit({'#'}));
524 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
525 EXPECT_EQ(U, Unit({'"'}));
526}
527
528TEST(FuzzerDictionary, ParseDictionaryFile) {
529 std::vector<Unit> Units;
530 EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
531 EXPECT_FALSE(ParseDictionaryFile("", &Units));
532 EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
533 EXPECT_EQ(Units.size(), 0U);
534 EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
535 EXPECT_EQ(Units.size(), 0U);
536 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
537 EXPECT_EQ(Units.size(), 0U);
538 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
539 EXPECT_EQ(Units.size(), 0U);
540 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units));
541 EXPECT_EQ(Units, std::vector<Unit>({Unit({'a', 'a'})}));
542 EXPECT_TRUE(
543 ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
544 EXPECT_EQ(Units,
545 std::vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
546}
547
548TEST(FuzzerUtil, Base64) {
549 EXPECT_EQ("", Base64({}));
550 EXPECT_EQ("YQ==", Base64({'a'}));
551 EXPECT_EQ("eA==", Base64({'x'}));
552 EXPECT_EQ("YWI=", Base64({'a', 'b'}));
553 EXPECT_EQ("eHk=", Base64({'x', 'y'}));
554 EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
555 EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
556 EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
557 EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
558 EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
559}
560
561TEST(Corpus, Distribution) {
562 Random Rand(0);
563 std::unique_ptr<InputCorpus> C(new InputCorpus(""));
564 size_t N = 10;
565 size_t TriesPerUnit = 1<<16;
566 for (size_t i = 0; i < N; i++)
567 C->AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 1, false, {});
568
569 std::vector<size_t> Hist(N);
570 for (size_t i = 0; i < N * TriesPerUnit; i++) {
571 Hist[C->ChooseUnitIdxToMutate(Rand)]++;
572 }
573 for (size_t i = 0; i < N; i++) {
574 // A weak sanity check that every unit gets invoked.
575 EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
576 }
577}
578
579TEST(Merge, Bad) {
580 const char *kInvalidInputs[] = {
581 "",
582 "x",
583 "3\nx",
584 "2\n3",
585 "2\n2",
586 "2\n2\nA\n",
587 "2\n2\nA\nB\nC\n",
588 "0\n0\n",
589 "1\n1\nA\nDONE 0",
590 "1\n1\nA\nSTARTED 1",
591 };
592 Merger M;
593 for (auto S : kInvalidInputs) {
594 // fprintf(stderr, "TESTING:\n%s\n", S);
595 EXPECT_FALSE(M.Parse(S, false));
596 }
597}
598
599void EQ(const std::vector<uint32_t> &A, const std::vector<uint32_t> &B) {
600 EXPECT_EQ(A, B);
601}
602
603void EQ(const std::vector<std::string> &A, const std::vector<std::string> &B) {
604 std::set<std::string> a(A.begin(), A.end());
605 std::set<std::string> b(B.begin(), B.end());
606 EXPECT_EQ(a, b);
607}
608
609static void Merge(const std::string &Input,
610 const std::vector<std::string> Result,
611 size_t NumNewFeatures) {
612 Merger M;
613 std::vector<std::string> NewFiles;
614 EXPECT_TRUE(M.Parse(Input, true));
615 std::stringstream SS;
616 M.PrintSummary(SS);
617 EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));
618 EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS));
619 EQ(NewFiles, Result);
620}
621
622TEST(Merge, Good) {
623 Merger M;
624
625 EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
626 EXPECT_EQ(M.Files.size(), 1U);
627 EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
628 EXPECT_EQ(M.Files[0].Name, "AA");
629 EXPECT_TRUE(M.LastFailure.empty());
630 EXPECT_EQ(M.FirstNotProcessedFile, 0U);
631
632 EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
633 EXPECT_EQ(M.Files.size(), 2U);
634 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
635 EXPECT_EQ(M.Files[0].Name, "AA");
636 EXPECT_EQ(M.Files[1].Name, "BB");
637 EXPECT_EQ(M.LastFailure, "AA");
638 EXPECT_EQ(M.FirstNotProcessedFile, 1U);
639
640 EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
641 "STARTED 0 1000\n"
642 "DONE 0 1 2 3\n"
643 "STARTED 1 1001\n"
644 "DONE 1 4 5 6 \n"
645 "STARTED 2 1002\n"
646 "", true));
647 EXPECT_EQ(M.Files.size(), 3U);
648 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
649 EXPECT_EQ(M.Files[0].Name, "AA");
650 EXPECT_EQ(M.Files[0].Size, 1000U);
651 EXPECT_EQ(M.Files[1].Name, "BB");
652 EXPECT_EQ(M.Files[1].Size, 1001U);
653 EXPECT_EQ(M.Files[2].Name, "C");
654 EXPECT_EQ(M.Files[2].Size, 1002U);
655 EXPECT_EQ(M.LastFailure, "C");
656 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
657 EQ(M.Files[0].Features, {1, 2, 3});
658 EQ(M.Files[1].Features, {4, 5, 6});
659
660
661 std::vector<std::string> NewFiles;
662
663 EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
664 "STARTED 0 1000\nDONE 0 1 2 3\n"
665 "STARTED 1 1001\nDONE 1 4 5 6 \n"
666 "STARTED 2 1002\nDONE 2 6 1 3 \n"
667 "", true));
668 EXPECT_EQ(M.Files.size(), 3U);
669 EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
670 EXPECT_TRUE(M.LastFailure.empty());
671 EXPECT_EQ(M.FirstNotProcessedFile, 3U);
672 EQ(M.Files[0].Features, {1, 2, 3});
673 EQ(M.Files[1].Features, {4, 5, 6});
674 EQ(M.Files[2].Features, {1, 3, 6});
675 EXPECT_EQ(0U, M.Merge(&NewFiles));
676 EQ(NewFiles, {});
677
678 EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
679 "STARTED 0 1000\nDONE 0 1 2 3\n"
680 "STARTED 1 1001\nDONE 1 4 5 6 \n"
681 "STARTED 2 1002\nDONE 2 6 1 3\n"
682 "", true));
683 EQ(M.Files[0].Features, {1, 2, 3});
684 EQ(M.Files[1].Features, {4, 5, 6});
685 EQ(M.Files[2].Features, {1, 3, 6});
686 EXPECT_EQ(3U, M.Merge(&NewFiles));
687 EQ(NewFiles, {"B"});
688
689 // Same as the above, but with InitialFeatures.
690 EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
691 "STARTED 0 1001\nDONE 0 4 5 6 \n"
692 "STARTED 1 1002\nDONE 1 6 1 3\n"
693 "", true));
694 EQ(M.Files[0].Features, {4, 5, 6});
695 EQ(M.Files[1].Features, {1, 3, 6});
696 EXPECT_EQ(3U, M.Merge({1, 2, 3}, &NewFiles));
697 EQ(NewFiles, {"B"});
698}
699
700TEST(Merge, Merge) {
701
702 Merge("3\n1\nA\nB\nC\n"
703 "STARTED 0 1000\nDONE 0 1 2 3\n"
704 "STARTED 1 1001\nDONE 1 4 5 6 \n"
705 "STARTED 2 1002\nDONE 2 6 1 3 \n",
706 {"B"}, 3);
707
708 Merge("3\n0\nA\nB\nC\n"
709 "STARTED 0 2000\nDONE 0 1 2 3\n"
710 "STARTED 1 1001\nDONE 1 4 5 6 \n"
711 "STARTED 2 1002\nDONE 2 6 1 3 \n",
712 {"A", "B", "C"}, 6);
713
714 Merge("4\n0\nA\nB\nC\nD\n"
715 "STARTED 0 2000\nDONE 0 1 2 3\n"
716 "STARTED 1 1101\nDONE 1 4 5 6 \n"
717 "STARTED 2 1102\nDONE 2 6 1 3 100 \n"
718 "STARTED 3 1000\nDONE 3 1 \n",
719 {"A", "B", "C", "D"}, 7);
720
721 Merge("4\n1\nA\nB\nC\nD\n"
722 "STARTED 0 2000\nDONE 0 4 5 6 7 8\n"
723 "STARTED 1 1100\nDONE 1 1 2 3 \n"
724 "STARTED 2 1100\nDONE 2 2 3 \n"
725 "STARTED 3 1000\nDONE 3 1 \n",
726 {"B", "D"}, 3);
727}
728
729TEST(Fuzzer, ForEachNonZeroByte) {
730 const size_t N = 64;
731 alignas(64) uint8_t Ar[N + 8] = {
732 0, 0, 0, 0, 0, 0, 0, 0,
733 1, 2, 0, 0, 0, 0, 0, 0,
734 0, 0, 3, 0, 4, 0, 0, 0,
735 0, 0, 0, 0, 0, 0, 0, 0,
736 0, 0, 0, 5, 0, 6, 0, 0,
737 0, 0, 0, 0, 0, 0, 7, 0,
738 0, 0, 0, 0, 0, 0, 0, 0,
739 0, 0, 0, 0, 0, 0, 0, 8,
740 9, 9, 9, 9, 9, 9, 9, 9,
741 };
742 typedef std::vector<std::pair<size_t, uint8_t> > Vec;
743 Vec Res, Expected;
744 auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) {
745 Res.push_back({FirstFeature + Idx, V});
746 };
747 ForEachNonZeroByte(Ar, Ar + N, 100, CB);
748 Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
749 {135, 5}, {137, 6}, {146, 7}, {163, 8}};
750 EXPECT_EQ(Res, Expected);
751
752 Res.clear();
753 ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
754 Expected = { {109, 2}, {118, 3}, {120, 4},
755 {135, 5}, {137, 6}, {146, 7}, {163, 8}};
756 EXPECT_EQ(Res, Expected);
757
758 Res.clear();
759 ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
760 Expected = { {109, 2}, {118, 3}, {120, 4},
761 {135, 5}, {137, 6}, {146, 7}};
762 EXPECT_EQ(Res, Expected);
763}
764
765int main(int argc, char **argv) {
766 testing::InitGoogleTest(&argc, argv);
767 return RUN_ALL_TESTS();
768}