1 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 2 // See https://llvm.org/LICENSE.txt for license information. 3 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 4 5 // Avoid ODR violations (LibFuzzer is built without ASan and this test is built 6 // with ASan) involving C++ standard library types when using libcxx. 7 #define _LIBCPP_HAS_NO_ASAN 8 9 // Do not attempt to use LLVM ostream etc from gtest. 10 #define GTEST_NO_LLVM_SUPPORT 1 11 12 #include "FuzzerCorpus.h" 13 #include "FuzzerDictionary.h" 14 #include "FuzzerInternal.h" 15 #include "FuzzerMerge.h" 16 #include "FuzzerMutate.h" 17 #include "FuzzerRandom.h" 18 #include "FuzzerTracePC.h" 19 #include "gtest/gtest.h" 20 #include <memory> 21 #include <set> 22 #include <sstream> 23 24 using namespace fuzzer; 25 26 // For now, have LLVMFuzzerTestOneInput just to make it link. 27 // Later we may want to make unittests that actually call LLVMFuzzerTestOneInput. 28 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { 29 abort(); 30 } 31 32 TEST(Fuzzer, Basename) { 33 EXPECT_EQ(Basename("foo/bar"), "bar"); 34 EXPECT_EQ(Basename("bar"), "bar"); 35 EXPECT_EQ(Basename("/bar"), "bar"); 36 EXPECT_EQ(Basename("foo/x"), "x"); 37 EXPECT_EQ(Basename("foo/"), ""); 38 #if LIBFUZZER_WINDOWS 39 EXPECT_EQ(Basename("foo\\bar"), "bar"); 40 EXPECT_EQ(Basename("foo\\bar/baz"), "baz"); 41 EXPECT_EQ(Basename("\\bar"), "bar"); 42 EXPECT_EQ(Basename("foo\\x"), "x"); 43 EXPECT_EQ(Basename("foo\\"), ""); 44 #endif 45 } 46 47 TEST(Fuzzer, CrossOver) { 48 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 49 fuzzer::EF = t.get(); 50 Random Rand(0); 51 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 52 Unit A({0, 1, 2}), B({5, 6, 7}); 53 Unit C; 54 Unit Expected[] = { 55 { 0 }, 56 { 0, 1 }, 57 { 0, 5 }, 58 { 0, 1, 2 }, 59 { 0, 1, 5 }, 60 { 0, 5, 1 }, 61 { 0, 5, 6 }, 62 { 0, 1, 2, 5 }, 63 { 0, 1, 5, 2 }, 64 { 0, 1, 5, 6 }, 65 { 0, 5, 1, 2 }, 66 { 0, 5, 1, 6 }, 67 { 0, 5, 6, 1 }, 68 { 0, 5, 6, 7 }, 69 { 0, 1, 2, 5, 6 }, 70 { 0, 1, 5, 2, 6 }, 71 { 0, 1, 5, 6, 2 }, 72 { 0, 1, 5, 6, 7 }, 73 { 0, 5, 1, 2, 6 }, 74 { 0, 5, 1, 6, 2 }, 75 { 0, 5, 1, 6, 7 }, 76 { 0, 5, 6, 1, 2 }, 77 { 0, 5, 6, 1, 7 }, 78 { 0, 5, 6, 7, 1 }, 79 { 0, 1, 2, 5, 6, 7 }, 80 { 0, 1, 5, 2, 6, 7 }, 81 { 0, 1, 5, 6, 2, 7 }, 82 { 0, 1, 5, 6, 7, 2 }, 83 { 0, 5, 1, 2, 6, 7 }, 84 { 0, 5, 1, 6, 2, 7 }, 85 { 0, 5, 1, 6, 7, 2 }, 86 { 0, 5, 6, 1, 2, 7 }, 87 { 0, 5, 6, 1, 7, 2 }, 88 { 0, 5, 6, 7, 1, 2 } 89 }; 90 for (size_t Len = 1; Len < 8; Len++) { 91 Set<Unit> FoundUnits, ExpectedUnitsWitThisLength; 92 for (int Iter = 0; Iter < 3000; Iter++) { 93 C.resize(Len); 94 size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(), 95 C.data(), C.size()); 96 C.resize(NewSize); 97 FoundUnits.insert(C); 98 } 99 for (const Unit &U : Expected) 100 if (U.size() <= Len) 101 ExpectedUnitsWitThisLength.insert(U); 102 EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits); 103 } 104 } 105 106 TEST(Fuzzer, Hash) { 107 uint8_t A[] = {'a', 'b', 'c'}; 108 fuzzer::Unit U(A, A + sizeof(A)); 109 EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U)); 110 U.push_back('d'); 111 EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U)); 112 } 113 114 typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size, 115 size_t MaxSize); 116 117 void TestEraseBytes(Mutator M, int NumIter) { 118 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 119 fuzzer::EF = t.get(); 120 uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 121 uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 122 uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77}; 123 uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77}; 124 uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77}; 125 uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77}; 126 uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77}; 127 uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 128 129 uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 130 uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; 131 uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77}; 132 133 uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77}; 134 uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44}; 135 uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77}; 136 137 138 Random Rand(0); 139 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 140 int FoundMask = 0; 141 for (int i = 0; i < NumIter; i++) { 142 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 143 size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T)); 144 if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0; 145 if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1; 146 if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2; 147 if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3; 148 if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4; 149 if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5; 150 if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6; 151 if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7; 152 153 if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8; 154 if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9; 155 if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10; 156 157 if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11; 158 if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12; 159 if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13; 160 } 161 EXPECT_EQ(FoundMask, (1 << 14) - 1); 162 } 163 164 TEST(FuzzerMutate, EraseBytes1) { 165 TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200); 166 } 167 TEST(FuzzerMutate, EraseBytes2) { 168 TestEraseBytes(&MutationDispatcher::Mutate, 2000); 169 } 170 171 void TestInsertByte(Mutator M, int NumIter) { 172 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 173 fuzzer::EF = t.get(); 174 Random Rand(0); 175 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 176 int FoundMask = 0; 177 uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 178 uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 179 uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66}; 180 uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66}; 181 uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66}; 182 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66}; 183 uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66}; 184 uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8}; 185 for (int i = 0; i < NumIter; i++) { 186 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 187 size_t NewSize = (*MD.*M)(T, 7, 8); 188 if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0; 189 if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1; 190 if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2; 191 if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3; 192 if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4; 193 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5; 194 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6; 195 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7; 196 } 197 EXPECT_EQ(FoundMask, 255); 198 } 199 200 TEST(FuzzerMutate, InsertByte1) { 201 TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15); 202 } 203 TEST(FuzzerMutate, InsertByte2) { 204 TestInsertByte(&MutationDispatcher::Mutate, 1 << 17); 205 } 206 207 void TestInsertRepeatedBytes(Mutator M, int NumIter) { 208 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 209 fuzzer::EF = t.get(); 210 Random Rand(0); 211 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 212 int FoundMask = 0; 213 uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'}; 214 uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33}; 215 uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33}; 216 uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33}; 217 uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33}; 218 219 uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'}; 220 uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33}; 221 uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33}; 222 uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33}; 223 uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33}; 224 225 for (int i = 0; i < NumIter; i++) { 226 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33}; 227 size_t NewSize = (*MD.*M)(T, 4, 8); 228 if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0; 229 if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1; 230 if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2; 231 if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3; 232 if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4; 233 234 if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5; 235 if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6; 236 if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7; 237 if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8; 238 if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9; 239 240 } 241 EXPECT_EQ(FoundMask, (1 << 10) - 1); 242 } 243 244 TEST(FuzzerMutate, InsertRepeatedBytes1) { 245 TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000); 246 } 247 TEST(FuzzerMutate, InsertRepeatedBytes2) { 248 TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000); 249 } 250 251 void TestChangeByte(Mutator M, int NumIter) { 252 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 253 fuzzer::EF = t.get(); 254 Random Rand(0); 255 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 256 int FoundMask = 0; 257 uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 258 uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 259 uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77}; 260 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77}; 261 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77}; 262 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77}; 263 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77}; 264 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7}; 265 for (int i = 0; i < NumIter; i++) { 266 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 267 size_t NewSize = (*MD.*M)(T, 8, 9); 268 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 269 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 270 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 271 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 272 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4; 273 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 274 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 275 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 276 } 277 EXPECT_EQ(FoundMask, 255); 278 } 279 280 TEST(FuzzerMutate, ChangeByte1) { 281 TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15); 282 } 283 TEST(FuzzerMutate, ChangeByte2) { 284 TestChangeByte(&MutationDispatcher::Mutate, 1 << 17); 285 } 286 287 void TestChangeBit(Mutator M, int NumIter) { 288 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 289 fuzzer::EF = t.get(); 290 Random Rand(0); 291 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 292 int FoundMask = 0; 293 uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 294 uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 295 uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77}; 296 uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77}; 297 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77}; 298 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77}; 299 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77}; 300 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7}; 301 for (int i = 0; i < NumIter; i++) { 302 uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 303 size_t NewSize = (*MD.*M)(T, 8, 9); 304 if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 305 if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 306 if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 307 if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 308 if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4; 309 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 310 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 311 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 312 } 313 EXPECT_EQ(FoundMask, 255); 314 } 315 316 TEST(FuzzerMutate, ChangeBit1) { 317 TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16); 318 } 319 TEST(FuzzerMutate, ChangeBit2) { 320 TestChangeBit(&MutationDispatcher::Mutate, 1 << 18); 321 } 322 323 void TestShuffleBytes(Mutator M, int NumIter) { 324 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 325 fuzzer::EF = t.get(); 326 Random Rand(0); 327 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 328 int FoundMask = 0; 329 uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66}; 330 uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66}; 331 uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66}; 332 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33}; 333 uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66}; 334 for (int i = 0; i < NumIter; i++) { 335 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 336 size_t NewSize = (*MD.*M)(T, 7, 7); 337 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0; 338 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1; 339 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2; 340 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3; 341 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4; 342 } 343 EXPECT_EQ(FoundMask, 31); 344 } 345 346 TEST(FuzzerMutate, ShuffleBytes1) { 347 TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17); 348 } 349 TEST(FuzzerMutate, ShuffleBytes2) { 350 TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20); 351 } 352 353 void TestCopyPart(Mutator M, int NumIter) { 354 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 355 fuzzer::EF = t.get(); 356 Random Rand(0); 357 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 358 int FoundMask = 0; 359 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11}; 360 uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66}; 361 uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66}; 362 uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66}; 363 uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66}; 364 365 for (int i = 0; i < NumIter; i++) { 366 uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 367 size_t NewSize = (*MD.*M)(T, 7, 7); 368 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0; 369 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1; 370 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2; 371 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3; 372 if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4; 373 } 374 375 uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22}; 376 uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44}; 377 uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44}; 378 uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44}; 379 uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44}; 380 381 for (int i = 0; i < NumIter; i++) { 382 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 383 size_t NewSize = (*MD.*M)(T, 5, 8); 384 if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 385 if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 386 if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 387 if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8; 388 if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9; 389 } 390 391 EXPECT_EQ(FoundMask, 1023); 392 } 393 394 TEST(FuzzerMutate, CopyPart1) { 395 TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10); 396 } 397 TEST(FuzzerMutate, CopyPart2) { 398 TestCopyPart(&MutationDispatcher::Mutate, 1 << 13); 399 } 400 TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) { 401 // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an 402 // insert on an input of size `MaxSize`. Performing an insert in this case 403 // will lead to the mutation failing. 404 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 405 fuzzer::EF = t.get(); 406 Random Rand(0); 407 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 408 uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22}; 409 size_t MaxSize = sizeof(Data); 410 for (int count = 0; count < (1 << 18); ++count) { 411 size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize); 412 ASSERT_EQ(NewSize, MaxSize); 413 } 414 } 415 416 void TestAddWordFromDictionary(Mutator M, int NumIter) { 417 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 418 fuzzer::EF = t.get(); 419 Random Rand(0); 420 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 421 uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD}; 422 uint8_t Word2[3] = {0xFF, 0xEE, 0xEF}; 423 MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1))); 424 MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2))); 425 int FoundMask = 0; 426 uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD}; 427 uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22}; 428 uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22}; 429 uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22}; 430 uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF}; 431 uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22}; 432 uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22}; 433 uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22}; 434 for (int i = 0; i < NumIter; i++) { 435 uint8_t T[7] = {0x00, 0x11, 0x22}; 436 size_t NewSize = (*MD.*M)(T, 3, 7); 437 if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0; 438 if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1; 439 if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2; 440 if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3; 441 if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4; 442 if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5; 443 if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6; 444 if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7; 445 } 446 EXPECT_EQ(FoundMask, 255); 447 } 448 449 TEST(FuzzerMutate, AddWordFromDictionary1) { 450 TestAddWordFromDictionary( 451 &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15); 452 } 453 454 TEST(FuzzerMutate, AddWordFromDictionary2) { 455 TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15); 456 } 457 458 void TestChangeASCIIInteger(Mutator M, int NumIter) { 459 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 460 fuzzer::EF = t.get(); 461 Random Rand(0); 462 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 463 464 uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'}; 465 uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'}; 466 uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'}; 467 uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'}; 468 int FoundMask = 0; 469 for (int i = 0; i < NumIter; i++) { 470 uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'}; 471 size_t NewSize = (*MD.*M)(T, 8, 8); 472 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 473 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 474 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 475 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 476 else if (NewSize == 8) FoundMask |= 1 << 4; 477 } 478 EXPECT_EQ(FoundMask, 31); 479 } 480 481 TEST(FuzzerMutate, ChangeASCIIInteger1) { 482 TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger, 483 1 << 15); 484 } 485 486 TEST(FuzzerMutate, ChangeASCIIInteger2) { 487 TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15); 488 } 489 490 void TestChangeBinaryInteger(Mutator M, int NumIter) { 491 std::unique_ptr<ExternalFunctions> t(new ExternalFunctions()); 492 fuzzer::EF = t.get(); 493 Random Rand(0); 494 std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {})); 495 496 uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79}; 497 uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77}; 498 uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 499 uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77}; 500 uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77}; 501 uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88}; 502 uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size 503 uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size) 504 505 int FoundMask = 0; 506 for (int i = 0; i < NumIter; i++) { 507 uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 508 size_t NewSize = (*MD.*M)(T, 8, 8); 509 /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; 510 else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; 511 else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; 512 else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3; 513 else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4; 514 else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5; 515 else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6; 516 else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7; 517 } 518 EXPECT_EQ(FoundMask, 255); 519 } 520 521 TEST(FuzzerMutate, ChangeBinaryInteger1) { 522 TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger, 523 1 << 12); 524 } 525 526 TEST(FuzzerMutate, ChangeBinaryInteger2) { 527 TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15); 528 } 529 530 531 TEST(FuzzerDictionary, ParseOneDictionaryEntry) { 532 Unit U; 533 EXPECT_FALSE(ParseOneDictionaryEntry("", &U)); 534 EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U)); 535 EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U)); 536 EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U)); 537 EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U)); 538 EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U)); 539 EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U)); 540 EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U)); 541 EXPECT_EQ(U, Unit({'a'})); 542 EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U)); 543 EXPECT_EQ(U, Unit({'a', 'b', 'c'})); 544 EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U)); 545 EXPECT_EQ(U, Unit({'a', 'b', 'c'})); 546 EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U)); 547 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U)); 548 EXPECT_EQ(U, Unit({'\\'})); 549 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U)); 550 EXPECT_EQ(U, Unit({0xAB})); 551 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U)); 552 EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE})); 553 EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U)); 554 EXPECT_EQ(U, Unit({'#'})); 555 EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U)); 556 EXPECT_EQ(U, Unit({'"'})); 557 } 558 559 TEST(FuzzerDictionary, ParseDictionaryFile) { 560 Vector<Unit> Units; 561 EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units)); 562 EXPECT_FALSE(ParseDictionaryFile("", &Units)); 563 EXPECT_TRUE(ParseDictionaryFile("\n", &Units)); 564 EXPECT_EQ(Units.size(), 0U); 565 EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units)); 566 EXPECT_EQ(Units.size(), 0U); 567 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units)); 568 EXPECT_EQ(Units.size(), 0U); 569 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units)); 570 EXPECT_EQ(Units.size(), 0U); 571 EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units)); 572 EXPECT_EQ(Units, Vector<Unit>({Unit({'a', 'a'})})); 573 EXPECT_TRUE( 574 ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units)); 575 EXPECT_EQ(Units, 576 Vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})})); 577 } 578 579 TEST(FuzzerUtil, Base64) { 580 EXPECT_EQ("", Base64({})); 581 EXPECT_EQ("YQ==", Base64({'a'})); 582 EXPECT_EQ("eA==", Base64({'x'})); 583 EXPECT_EQ("YWI=", Base64({'a', 'b'})); 584 EXPECT_EQ("eHk=", Base64({'x', 'y'})); 585 EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'})); 586 EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'})); 587 EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'})); 588 EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'})); 589 EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'})); 590 } 591 592 TEST(Corpus, Distribution) { 593 DataFlowTrace DFT; 594 Random Rand(0); 595 struct EntropicOptions Entropic = {false, 0xFF, 100}; 596 std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic)); 597 size_t N = 10; 598 size_t TriesPerUnit = 1<<16; 599 for (size_t i = 0; i < N; i++) 600 C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, /*NumFeatures*/ 1, 601 /*MayDeleteFile*/ false, /*HasFocusFunction*/ false, 602 /*ForceAddToCorpus*/ false, 603 /*TimeOfUnit*/ std::chrono::microseconds(0), 604 /*FeatureSet*/ {}, DFT, 605 /*BaseII*/ nullptr); 606 607 Vector<size_t> Hist(N); 608 for (size_t i = 0; i < N * TriesPerUnit; i++) { 609 Hist[C->ChooseUnitIdxToMutate(Rand)]++; 610 } 611 for (size_t i = 0; i < N; i++) { 612 // A weak sanity check that every unit gets invoked. 613 EXPECT_GT(Hist[i], TriesPerUnit / N / 3); 614 } 615 } 616 617 TEST(Merge, Bad) { 618 const char *kInvalidInputs[] = { 619 "", 620 "x", 621 "3\nx", 622 "2\n3", 623 "2\n2", 624 "2\n2\nA\n", 625 "2\n2\nA\nB\nC\n", 626 "0\n0\n", 627 "1\n1\nA\nFT 0", 628 "1\n1\nA\nSTARTED 1", 629 }; 630 Merger M; 631 for (auto S : kInvalidInputs) { 632 // fprintf(stderr, "TESTING:\n%s\n", S); 633 EXPECT_FALSE(M.Parse(S, false)); 634 } 635 } 636 637 void EQ(const Vector<uint32_t> &A, const Vector<uint32_t> &B) { 638 EXPECT_EQ(A, B); 639 } 640 641 void EQ(const Vector<std::string> &A, const Vector<std::string> &B) { 642 Set<std::string> a(A.begin(), A.end()); 643 Set<std::string> b(B.begin(), B.end()); 644 EXPECT_EQ(a, b); 645 } 646 647 static void Merge(const std::string &Input, 648 const Vector<std::string> Result, 649 size_t NumNewFeatures) { 650 Merger M; 651 Vector<std::string> NewFiles; 652 Set<uint32_t> NewFeatures, NewCov; 653 EXPECT_TRUE(M.Parse(Input, true)); 654 EXPECT_EQ(NumNewFeatures, M.Merge({}, &NewFeatures, {}, &NewCov, &NewFiles)); 655 EQ(NewFiles, Result); 656 } 657 658 TEST(Merge, Good) { 659 Merger M; 660 661 EXPECT_TRUE(M.Parse("1\n0\nAA\n", false)); 662 EXPECT_EQ(M.Files.size(), 1U); 663 EXPECT_EQ(M.NumFilesInFirstCorpus, 0U); 664 EXPECT_EQ(M.Files[0].Name, "AA"); 665 EXPECT_TRUE(M.LastFailure.empty()); 666 EXPECT_EQ(M.FirstNotProcessedFile, 0U); 667 668 EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false)); 669 EXPECT_EQ(M.Files.size(), 2U); 670 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U); 671 EXPECT_EQ(M.Files[0].Name, "AA"); 672 EXPECT_EQ(M.Files[1].Name, "BB"); 673 EXPECT_EQ(M.LastFailure, "AA"); 674 EXPECT_EQ(M.FirstNotProcessedFile, 1U); 675 676 EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n" 677 "STARTED 0 1000\n" 678 "FT 0 1 2 3\n" 679 "STARTED 1 1001\n" 680 "FT 1 4 5 6 \n" 681 "STARTED 2 1002\n" 682 "", true)); 683 EXPECT_EQ(M.Files.size(), 3U); 684 EXPECT_EQ(M.NumFilesInFirstCorpus, 1U); 685 EXPECT_EQ(M.Files[0].Name, "AA"); 686 EXPECT_EQ(M.Files[0].Size, 1000U); 687 EXPECT_EQ(M.Files[1].Name, "BB"); 688 EXPECT_EQ(M.Files[1].Size, 1001U); 689 EXPECT_EQ(M.Files[2].Name, "C"); 690 EXPECT_EQ(M.Files[2].Size, 1002U); 691 EXPECT_EQ(M.LastFailure, "C"); 692 EXPECT_EQ(M.FirstNotProcessedFile, 3U); 693 EQ(M.Files[0].Features, {1, 2, 3}); 694 EQ(M.Files[1].Features, {4, 5, 6}); 695 696 697 Vector<std::string> NewFiles; 698 Set<uint32_t> NewFeatures, NewCov; 699 700 EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n" 701 "STARTED 0 1000\nFT 0 1 2 3\n" 702 "STARTED 1 1001\nFT 1 4 5 6 \n" 703 "STARTED 2 1002\nFT 2 6 1 3 \n" 704 "", true)); 705 EXPECT_EQ(M.Files.size(), 3U); 706 EXPECT_EQ(M.NumFilesInFirstCorpus, 2U); 707 EXPECT_TRUE(M.LastFailure.empty()); 708 EXPECT_EQ(M.FirstNotProcessedFile, 3U); 709 EQ(M.Files[0].Features, {1, 2, 3}); 710 EQ(M.Files[1].Features, {4, 5, 6}); 711 EQ(M.Files[2].Features, {1, 3, 6}); 712 EXPECT_EQ(0U, M.Merge({}, &NewFeatures, {}, &NewCov, &NewFiles)); 713 EQ(NewFiles, {}); 714 715 EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n" 716 "STARTED 0 1000\nFT 0 1 2 3\n" 717 "STARTED 1 1001\nFT 1 4 5 6 \n" 718 "STARTED 2 1002\nFT 2 6 1 3\n" 719 "", true)); 720 EQ(M.Files[0].Features, {1, 2, 3}); 721 EQ(M.Files[1].Features, {4, 5, 6}); 722 EQ(M.Files[2].Features, {1, 3, 6}); 723 EXPECT_EQ(3U, M.Merge({}, &NewFeatures, {}, &NewCov, &NewFiles)); 724 EQ(NewFiles, {"B"}); 725 726 // Same as the above, but with InitialFeatures. 727 EXPECT_TRUE(M.Parse("2\n0\nB\nC\n" 728 "STARTED 0 1001\nFT 0 4 5 6 \n" 729 "STARTED 1 1002\nFT 1 6 1 3\n" 730 "", true)); 731 EQ(M.Files[0].Features, {4, 5, 6}); 732 EQ(M.Files[1].Features, {1, 3, 6}); 733 Set<uint32_t> InitialFeatures; 734 InitialFeatures.insert(1); 735 InitialFeatures.insert(2); 736 InitialFeatures.insert(3); 737 EXPECT_EQ(3U, M.Merge(InitialFeatures, &NewFeatures, {}, &NewCov, &NewFiles)); 738 EQ(NewFiles, {"B"}); 739 } 740 741 TEST(Merge, Merge) { 742 743 Merge("3\n1\nA\nB\nC\n" 744 "STARTED 0 1000\nFT 0 1 2 3\n" 745 "STARTED 1 1001\nFT 1 4 5 6 \n" 746 "STARTED 2 1002\nFT 2 6 1 3 \n", 747 {"B"}, 3); 748 749 Merge("3\n0\nA\nB\nC\n" 750 "STARTED 0 2000\nFT 0 1 2 3\n" 751 "STARTED 1 1001\nFT 1 4 5 6 \n" 752 "STARTED 2 1002\nFT 2 6 1 3 \n", 753 {"A", "B", "C"}, 6); 754 755 Merge("4\n0\nA\nB\nC\nD\n" 756 "STARTED 0 2000\nFT 0 1 2 3\n" 757 "STARTED 1 1101\nFT 1 4 5 6 \n" 758 "STARTED 2 1102\nFT 2 6 1 3 100 \n" 759 "STARTED 3 1000\nFT 3 1 \n", 760 {"A", "B", "C", "D"}, 7); 761 762 Merge("4\n1\nA\nB\nC\nD\n" 763 "STARTED 0 2000\nFT 0 4 5 6 7 8\n" 764 "STARTED 1 1100\nFT 1 1 2 3 \n" 765 "STARTED 2 1100\nFT 2 2 3 \n" 766 "STARTED 3 1000\nFT 3 1 \n", 767 {"B", "D"}, 3); 768 } 769 770 TEST(DFT, BlockCoverage) { 771 BlockCoverage Cov; 772 // Assuming C0 has 5 instrumented blocks, 773 // C1: 7 blocks, C2: 4, C3: 9, C4 never covered, C5: 15, 774 775 // Add C0 776 EXPECT_TRUE(Cov.AppendCoverage("C0 5\n")); 777 EXPECT_EQ(Cov.GetCounter(0, 0), 1U); 778 EXPECT_EQ(Cov.GetCounter(0, 1), 0U); // not seen this BB yet. 779 EXPECT_EQ(Cov.GetCounter(0, 5), 0U); // BB ID out of bounds. 780 EXPECT_EQ(Cov.GetCounter(1, 0), 0U); // not seen this function yet. 781 782 EXPECT_EQ(Cov.GetNumberOfBlocks(0), 5U); 783 EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 1U); 784 EXPECT_EQ(Cov.GetNumberOfBlocks(1), 0U); 785 786 // Various errors. 787 EXPECT_FALSE(Cov.AppendCoverage("C0\n")); // No total number. 788 EXPECT_FALSE(Cov.AppendCoverage("C0 7\n")); // No total number. 789 EXPECT_FALSE(Cov.AppendCoverage("CZ\n")); // Wrong function number. 790 EXPECT_FALSE(Cov.AppendCoverage("C1 7 7")); // BB ID is too big. 791 EXPECT_FALSE(Cov.AppendCoverage("C1 100 7")); // BB ID is too big. 792 793 // Add C0 more times. 794 EXPECT_TRUE(Cov.AppendCoverage("C0 5\n")); 795 EXPECT_EQ(Cov.GetCounter(0, 0), 2U); 796 EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 5\n")); 797 EXPECT_EQ(Cov.GetCounter(0, 0), 3U); 798 EXPECT_EQ(Cov.GetCounter(0, 1), 1U); 799 EXPECT_EQ(Cov.GetCounter(0, 2), 1U); 800 EXPECT_EQ(Cov.GetCounter(0, 3), 0U); 801 EXPECT_EQ(Cov.GetCounter(0, 4), 0U); 802 EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 3U); 803 EXPECT_TRUE(Cov.AppendCoverage("C0 1 3 4 5\n")); 804 EXPECT_EQ(Cov.GetCounter(0, 0), 4U); 805 EXPECT_EQ(Cov.GetCounter(0, 1), 2U); 806 EXPECT_EQ(Cov.GetCounter(0, 2), 1U); 807 EXPECT_EQ(Cov.GetCounter(0, 3), 1U); 808 EXPECT_EQ(Cov.GetCounter(0, 4), 1U); 809 EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 5U); 810 811 EXPECT_TRUE(Cov.AppendCoverage("C1 7\nC2 4\nC3 9\nC5 15\nC0 5\n")); 812 EXPECT_EQ(Cov.GetCounter(0, 0), 5U); 813 EXPECT_EQ(Cov.GetCounter(1, 0), 1U); 814 EXPECT_EQ(Cov.GetCounter(2, 0), 1U); 815 EXPECT_EQ(Cov.GetCounter(3, 0), 1U); 816 EXPECT_EQ(Cov.GetCounter(4, 0), 0U); 817 EXPECT_EQ(Cov.GetCounter(5, 0), 1U); 818 819 EXPECT_TRUE(Cov.AppendCoverage("C3 4 5 9\nC5 11 12 15")); 820 EXPECT_EQ(Cov.GetCounter(0, 0), 5U); 821 EXPECT_EQ(Cov.GetCounter(1, 0), 1U); 822 EXPECT_EQ(Cov.GetCounter(2, 0), 1U); 823 EXPECT_EQ(Cov.GetCounter(3, 0), 2U); 824 EXPECT_EQ(Cov.GetCounter(3, 4), 1U); 825 EXPECT_EQ(Cov.GetCounter(3, 5), 1U); 826 EXPECT_EQ(Cov.GetCounter(3, 6), 0U); 827 EXPECT_EQ(Cov.GetCounter(4, 0), 0U); 828 EXPECT_EQ(Cov.GetCounter(5, 0), 2U); 829 EXPECT_EQ(Cov.GetCounter(5, 10), 0U); 830 EXPECT_EQ(Cov.GetCounter(5, 11), 1U); 831 EXPECT_EQ(Cov.GetCounter(5, 12), 1U); 832 } 833 834 TEST(DFT, FunctionWeights) { 835 BlockCoverage Cov; 836 // unused function gets zero weight. 837 EXPECT_TRUE(Cov.AppendCoverage("C0 5\n")); 838 auto Weights = Cov.FunctionWeights(2); 839 EXPECT_GT(Weights[0], 0.); 840 EXPECT_EQ(Weights[1], 0.); 841 842 // Less frequently used function gets less weight. 843 Cov.clear(); 844 EXPECT_TRUE(Cov.AppendCoverage("C0 5\nC1 5\nC1 5\n")); 845 Weights = Cov.FunctionWeights(2); 846 EXPECT_GT(Weights[0], Weights[1]); 847 848 // A function with more uncovered blocks gets more weight. 849 Cov.clear(); 850 EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 3 5\nC1 2 4\n")); 851 Weights = Cov.FunctionWeights(2); 852 EXPECT_GT(Weights[1], Weights[0]); 853 854 // A function with DFT gets more weight than the function w/o DFT. 855 Cov.clear(); 856 EXPECT_TRUE(Cov.AppendCoverage("F1 111\nC0 3\nC1 1 2 3\n")); 857 Weights = Cov.FunctionWeights(2); 858 EXPECT_GT(Weights[1], Weights[0]); 859 } 860 861 862 TEST(Fuzzer, ForEachNonZeroByte) { 863 const size_t N = 64; 864 alignas(64) uint8_t Ar[N + 8] = { 865 0, 0, 0, 0, 0, 0, 0, 0, 866 1, 2, 0, 0, 0, 0, 0, 0, 867 0, 0, 3, 0, 4, 0, 0, 0, 868 0, 0, 0, 0, 0, 0, 0, 0, 869 0, 0, 0, 5, 0, 6, 0, 0, 870 0, 0, 0, 0, 0, 0, 7, 0, 871 0, 0, 0, 0, 0, 0, 0, 0, 872 0, 0, 0, 0, 0, 0, 0, 8, 873 9, 9, 9, 9, 9, 9, 9, 9, 874 }; 875 typedef Vector<std::pair<size_t, uint8_t> > Vec; 876 Vec Res, Expected; 877 auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) { 878 Res.push_back({FirstFeature + Idx, V}); 879 }; 880 ForEachNonZeroByte(Ar, Ar + N, 100, CB); 881 Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4}, 882 {135, 5}, {137, 6}, {146, 7}, {163, 8}}; 883 EXPECT_EQ(Res, Expected); 884 885 Res.clear(); 886 ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB); 887 Expected = { {109, 2}, {118, 3}, {120, 4}, 888 {135, 5}, {137, 6}, {146, 7}, {163, 8}}; 889 EXPECT_EQ(Res, Expected); 890 891 Res.clear(); 892 ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB); 893 Expected = { {109, 2}, {118, 3}, {120, 4}, 894 {135, 5}, {137, 6}, {146, 7}}; 895 EXPECT_EQ(Res, Expected); 896 } 897 898 // FuzzerCommand unit tests. The arguments in the two helper methods below must 899 // match. 900 static void makeCommandArgs(Vector<std::string> *ArgsToAdd) { 901 assert(ArgsToAdd); 902 ArgsToAdd->clear(); 903 ArgsToAdd->push_back("foo"); 904 ArgsToAdd->push_back("-bar=baz"); 905 ArgsToAdd->push_back("qux"); 906 ArgsToAdd->push_back(Command::ignoreRemainingArgs()); 907 ArgsToAdd->push_back("quux"); 908 ArgsToAdd->push_back("-grault=garply"); 909 } 910 911 static std::string makeCmdLine(const char *separator, const char *suffix) { 912 std::string CmdLine("foo -bar=baz qux "); 913 if (strlen(separator) != 0) { 914 CmdLine += separator; 915 CmdLine += " "; 916 } 917 CmdLine += Command::ignoreRemainingArgs(); 918 CmdLine += " quux -grault=garply"; 919 if (strlen(suffix) != 0) { 920 CmdLine += " "; 921 CmdLine += suffix; 922 } 923 return CmdLine; 924 } 925 926 TEST(FuzzerCommand, Create) { 927 std::string CmdLine; 928 929 // Default constructor 930 Command DefaultCmd; 931 932 CmdLine = DefaultCmd.toString(); 933 EXPECT_EQ(CmdLine, ""); 934 935 // Explicit constructor 936 Vector<std::string> ArgsToAdd; 937 makeCommandArgs(&ArgsToAdd); 938 Command InitializedCmd(ArgsToAdd); 939 940 CmdLine = InitializedCmd.toString(); 941 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 942 943 // Compare each argument 944 auto InitializedArgs = InitializedCmd.getArguments(); 945 auto i = ArgsToAdd.begin(); 946 auto j = InitializedArgs.begin(); 947 while (i != ArgsToAdd.end() && j != InitializedArgs.end()) { 948 EXPECT_EQ(*i++, *j++); 949 } 950 EXPECT_EQ(i, ArgsToAdd.end()); 951 EXPECT_EQ(j, InitializedArgs.end()); 952 953 // Copy constructor 954 Command CopiedCmd(InitializedCmd); 955 956 CmdLine = CopiedCmd.toString(); 957 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 958 959 // Assignment operator 960 Command AssignedCmd; 961 AssignedCmd = CopiedCmd; 962 963 CmdLine = AssignedCmd.toString(); 964 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 965 } 966 967 TEST(FuzzerCommand, ModifyArguments) { 968 Vector<std::string> ArgsToAdd; 969 makeCommandArgs(&ArgsToAdd); 970 Command Cmd; 971 std::string CmdLine; 972 973 Cmd.addArguments(ArgsToAdd); 974 CmdLine = Cmd.toString(); 975 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 976 977 Cmd.addArgument("waldo"); 978 EXPECT_TRUE(Cmd.hasArgument("waldo")); 979 980 CmdLine = Cmd.toString(); 981 EXPECT_EQ(CmdLine, makeCmdLine("waldo", "")); 982 983 Cmd.removeArgument("waldo"); 984 EXPECT_FALSE(Cmd.hasArgument("waldo")); 985 986 CmdLine = Cmd.toString(); 987 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 988 } 989 990 TEST(FuzzerCommand, ModifyFlags) { 991 Vector<std::string> ArgsToAdd; 992 makeCommandArgs(&ArgsToAdd); 993 Command Cmd(ArgsToAdd); 994 std::string Value, CmdLine; 995 ASSERT_FALSE(Cmd.hasFlag("fred")); 996 997 Value = Cmd.getFlagValue("fred"); 998 EXPECT_EQ(Value, ""); 999 1000 CmdLine = Cmd.toString(); 1001 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1002 1003 Cmd.addFlag("fred", "plugh"); 1004 EXPECT_TRUE(Cmd.hasFlag("fred")); 1005 1006 Value = Cmd.getFlagValue("fred"); 1007 EXPECT_EQ(Value, "plugh"); 1008 1009 CmdLine = Cmd.toString(); 1010 EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", "")); 1011 1012 Cmd.removeFlag("fred"); 1013 EXPECT_FALSE(Cmd.hasFlag("fred")); 1014 1015 Value = Cmd.getFlagValue("fred"); 1016 EXPECT_EQ(Value, ""); 1017 1018 CmdLine = Cmd.toString(); 1019 EXPECT_EQ(CmdLine, makeCmdLine("", "")); 1020 } 1021 1022 TEST(FuzzerCommand, SetOutput) { 1023 Vector<std::string> ArgsToAdd; 1024 makeCommandArgs(&ArgsToAdd); 1025 Command Cmd(ArgsToAdd); 1026 std::string CmdLine; 1027 ASSERT_FALSE(Cmd.hasOutputFile()); 1028 ASSERT_FALSE(Cmd.isOutAndErrCombined()); 1029 1030 Cmd.combineOutAndErr(true); 1031 EXPECT_TRUE(Cmd.isOutAndErrCombined()); 1032 1033 CmdLine = Cmd.toString(); 1034 EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1")); 1035 1036 Cmd.combineOutAndErr(false); 1037 EXPECT_FALSE(Cmd.isOutAndErrCombined()); 1038 1039 Cmd.setOutputFile("xyzzy"); 1040 EXPECT_TRUE(Cmd.hasOutputFile()); 1041 1042 CmdLine = Cmd.toString(); 1043 EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy")); 1044 1045 Cmd.setOutputFile("thud"); 1046 EXPECT_TRUE(Cmd.hasOutputFile()); 1047 1048 CmdLine = Cmd.toString(); 1049 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud")); 1050 1051 Cmd.combineOutAndErr(); 1052 EXPECT_TRUE(Cmd.isOutAndErrCombined()); 1053 1054 CmdLine = Cmd.toString(); 1055 EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1")); 1056 } 1057 1058 TEST(Entropic, UpdateFrequency) { 1059 const size_t One = 1, Two = 2; 1060 const size_t FeatIdx1 = 0, FeatIdx2 = 42, FeatIdx3 = 12, FeatIdx4 = 26; 1061 size_t Index; 1062 // Create input corpus with default entropic configuration 1063 struct EntropicOptions Entropic = {true, 0xFF, 100}; 1064 std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic)); 1065 std::unique_ptr<InputInfo> II(new InputInfo()); 1066 1067 C->AddRareFeature(FeatIdx1); 1068 C->UpdateFeatureFrequency(II.get(), FeatIdx1); 1069 EXPECT_EQ(II->FeatureFreqs.size(), One); 1070 C->AddRareFeature(FeatIdx2); 1071 C->UpdateFeatureFrequency(II.get(), FeatIdx1); 1072 C->UpdateFeatureFrequency(II.get(), FeatIdx2); 1073 EXPECT_EQ(II->FeatureFreqs.size(), Two); 1074 EXPECT_EQ(II->FeatureFreqs[0].second, 2); 1075 EXPECT_EQ(II->FeatureFreqs[1].second, 1); 1076 1077 C->AddRareFeature(FeatIdx3); 1078 C->AddRareFeature(FeatIdx4); 1079 C->UpdateFeatureFrequency(II.get(), FeatIdx3); 1080 C->UpdateFeatureFrequency(II.get(), FeatIdx3); 1081 C->UpdateFeatureFrequency(II.get(), FeatIdx3); 1082 C->UpdateFeatureFrequency(II.get(), FeatIdx4); 1083 1084 for (Index = 1; Index < II->FeatureFreqs.size(); Index++) 1085 EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first); 1086 1087 II->DeleteFeatureFreq(FeatIdx3); 1088 for (Index = 1; Index < II->FeatureFreqs.size(); Index++) 1089 EXPECT_LT(II->FeatureFreqs[Index - 1].first, II->FeatureFreqs[Index].first); 1090 } 1091 1092 double SubAndSquare(double X, double Y) { 1093 double R = X - Y; 1094 R = R * R; 1095 return R; 1096 } 1097 1098 TEST(Entropic, ComputeEnergy) { 1099 const double Precision = 0.01; 1100 struct EntropicOptions Entropic = {true, 0xFF, 100}; 1101 std::unique_ptr<InputCorpus> C(new InputCorpus("", Entropic)); 1102 std::unique_ptr<InputInfo> II(new InputInfo()); 1103 Vector<std::pair<uint32_t, uint16_t>> FeatureFreqs = {{1, 3}, {2, 3}, {3, 3}}; 1104 II->FeatureFreqs = FeatureFreqs; 1105 II->NumExecutedMutations = 0; 1106 II->UpdateEnergy(4, false, std::chrono::microseconds(0)); 1107 EXPECT_LT(SubAndSquare(II->Energy, 1.450805), Precision); 1108 1109 II->NumExecutedMutations = 9; 1110 II->UpdateEnergy(5, false, std::chrono::microseconds(0)); 1111 EXPECT_LT(SubAndSquare(II->Energy, 1.525496), Precision); 1112 1113 II->FeatureFreqs[0].second++; 1114 II->FeatureFreqs.push_back(std::pair<uint32_t, uint16_t>(42, 6)); 1115 II->NumExecutedMutations = 20; 1116 II->UpdateEnergy(10, false, std::chrono::microseconds(0)); 1117 EXPECT_LT(SubAndSquare(II->Energy, 1.792831), Precision); 1118 } 1119 1120 int main(int argc, char **argv) { 1121 testing::InitGoogleTest(&argc, argv); 1122 return RUN_ALL_TESTS(); 1123 } 1124