diff options
| author | Kostya Serebryany <kcc@google.com> | 2016-02-13 02:29:38 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2016-02-13 02:29:38 +0000 |
| commit | 22cc5e2375b896b3a99945c9d6c64b9dc2a2f246 (patch) | |
| tree | 598e5116e24a3c93db0240b6aac306676276bd53 /llvm | |
| parent | 94d1855e08122fadf06e21dfd2c346912469371a (diff) | |
| download | bcm5719-llvm-22cc5e2375b896b3a99945c9d6c64b9dc2a2f246.tar.gz bcm5719-llvm-22cc5e2375b896b3a99945c9d6c64b9dc2a2f246.zip | |
[libFuzzer] provide a plain C interface for custom mutators (experimental)
llvm-svn: 260794
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerInterface.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerInterface.h | 18 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerLoop.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/CustomMutatorTest.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/Fuzzer/test/fuzzer.test | 4 |
6 files changed, 65 insertions, 2 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerInterface.cpp b/llvm/lib/Fuzzer/FuzzerInterface.cpp index 149ec66e5d5..c5aa841c89b 100644 --- a/llvm/lib/Fuzzer/FuzzerInterface.cpp +++ b/llvm/lib/Fuzzer/FuzzerInterface.cpp @@ -58,6 +58,10 @@ size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, return MD.Mutate(Data, Size, MaxSize); } - +size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) { + FuzzerRandom_mt19937 R(Seed); + MutationDispatcher MD(R); + return MD.Mutate(Data, Size, MaxSize); +} } // namespace fuzzer. diff --git a/llvm/lib/Fuzzer/FuzzerInterface.h b/llvm/lib/Fuzzer/FuzzerInterface.h index 64b8f868f65..663cd5e7fdb 100644 --- a/llvm/lib/Fuzzer/FuzzerInterface.h +++ b/llvm/lib/Fuzzer/FuzzerInterface.h @@ -22,6 +22,22 @@ #include <vector> #include <string> +// Plain C interface. Should be sufficient for most uses. +extern "C" { +// The target function, mandatory. +// Must return 0. +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); +// The initialization function, optional. +int LLVMFuzzerInitialize(int *argc, char ***argv); +// Custom mutator, optional. +// Mutates raw data in [Data, Data+Size] inplace. +// Returns the new size, which is not greater than MaxSize. +// Given the same Seed produces the same mutation. +size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize, + unsigned int Seed); + +} // extern "C" + namespace fuzzer { /// Returns an int 0. Values other than zero are reserved for future. @@ -93,6 +109,8 @@ class FuzzerRandom_mt19937 : public FuzzerRandomBase { size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, FuzzerRandomBase &Rand); +size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed); + class MutationDispatcher; /** An abstract class that allows to use user-supplied mutators with libFuzzer. diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 7dc48e63641..db542b26511 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -35,6 +35,10 @@ __attribute__((weak)) uintptr_t __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset); __attribute__((weak)) uintptr_t __sanitizer_get_coverage_pc_buffer(uintptr_t **data); + +__attribute__((weak)) size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, + size_t MaxSize, + unsigned int Seed); } namespace fuzzer { @@ -407,7 +411,12 @@ void Fuzzer::MutateAndTestOne() { for (int i = 0; i < Options.MutateDepth; i++) { size_t Size = U.size(); U.resize(Options.MaxLen); - size_t NewSize = USF.Mutate(U.data(), Size, U.size()); + size_t NewSize = 0; + if (LLVMFuzzerCustomMutator) + NewSize = LLVMFuzzerCustomMutator(U.data(), Size, U.size(), + USF.GetRand().Rand()); + else + NewSize = USF.Mutate(U.data(), Size, U.size()); assert(NewSize > 0 && "Mutator returned empty unit"); assert(NewSize <= (size_t)Options.MaxLen && "Mutator return overisized unit"); diff --git a/llvm/lib/Fuzzer/test/CMakeLists.txt b/llvm/lib/Fuzzer/test/CMakeLists.txt index 1443dc58eef..f7ed87e251f 100644 --- a/llvm/lib/Fuzzer/test/CMakeLists.txt +++ b/llvm/lib/Fuzzer/test/CMakeLists.txt @@ -16,6 +16,7 @@ set(Tests BufferOverflowOnInput CallerCalleeTest CounterTest + CustomMutatorTest FourIndependentBranchesTest FullCoverageSetTest InitializeTest diff --git a/llvm/lib/Fuzzer/test/CustomMutatorTest.cpp b/llvm/lib/Fuzzer/test/CustomMutatorTest.cpp new file mode 100644 index 00000000000..84077d7368d --- /dev/null +++ b/llvm/lib/Fuzzer/test/CustomMutatorTest.cpp @@ -0,0 +1,27 @@ +// Simple test for a cutom mutator. +#include <assert.h> +#include <cstdint> +#include <cstdlib> +#include <cstddef> +#include <iostream> + +#include "FuzzerInterface.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + assert(Data); + if (Size > 0 && Data[0] == 'F') { + std::cout << "BINGO; Found the target, exiting\n"; + exit(1); + } + return 0; +} + +extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, + size_t MaxSize, unsigned int Seed) { + static bool Printed; + if (!Printed) { + std::cerr << "In LLVMFuzzerCustomMutator\n"; + Printed = true; + } + return fuzzer::Mutate(Data, Size, MaxSize, Seed); +} diff --git a/llvm/lib/Fuzzer/test/fuzzer.test b/llvm/lib/Fuzzer/test/fuzzer.test index aadff795ed4..4638b97ed6b 100644 --- a/llvm/lib/Fuzzer/test/fuzzer.test +++ b/llvm/lib/Fuzzer/test/fuzzer.test @@ -66,3 +66,7 @@ RUN: LLVMFuzzer-NthRunCrashTest %t/NthRunCrashTest.in RUN: LLVMFuzzer-NthRunCrashTest %t/NthRunCrashTest.in -runs=10 RUN: not LLVMFuzzer-NthRunCrashTest %t/NthRunCrashTest.in -runs=10000 2>&1 | FileCheck %s RUN: rm %t/NthRunCrashTest.in + +RUN: not LLVMFuzzer-CustomMutatorTest 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomMutator +LLVMFuzzerCustomMutator: In LLVMFuzzerCustomMutator +LLVMFuzzerCustomMutator: BINGO |

