[libFuzzer] provide a plain C interface for custom mutators (experimental)
llvm-svn: 260794
This commit is contained in:
parent
94d1855e08
commit
22cc5e2375
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -16,6 +16,7 @@ set(Tests
|
|||
BufferOverflowOnInput
|
||||
CallerCalleeTest
|
||||
CounterTest
|
||||
CustomMutatorTest
|
||||
FourIndependentBranchesTest
|
||||
FullCoverageSetTest
|
||||
InitializeTest
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue