summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-02-13 02:29:38 +0000
committerKostya Serebryany <kcc@google.com>2016-02-13 02:29:38 +0000
commit22cc5e2375b896b3a99945c9d6c64b9dc2a2f246 (patch)
tree598e5116e24a3c93db0240b6aac306676276bd53 /llvm
parent94d1855e08122fadf06e21dfd2c346912469371a (diff)
downloadbcm5719-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.cpp6
-rw-r--r--llvm/lib/Fuzzer/FuzzerInterface.h18
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp11
-rw-r--r--llvm/lib/Fuzzer/test/CMakeLists.txt1
-rw-r--r--llvm/lib/Fuzzer/test/CustomMutatorTest.cpp27
-rw-r--r--llvm/lib/Fuzzer/test/fuzzer.test4
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
OpenPOWER on IntegriCloud