libfuzzer
This is modified version of libfuzzer.
API
// Mandatory user-provided target function.
// Executes the code under test with [Data, Data+Size) as the input.
// libFuzzer will invoke this function *many* times with different inputs.
// Must return 0.
typedef int (*TestOneInputCallback)(const uint8_t *Data, size_t Size);
// Optional user-provided initialization function.
// If provided, this function will be called by libFuzzer once at startup.
// It may read and modify argc/argv.
// Must return 0.
typedef int (*InitializeCallback)(int *argc, char ***argv);
// Optional user-provided custom mutator.
// 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.
typedef size_t (*CustomMutatorCallback)(uint8_t *Data, size_t Size,
size_t MaxSize, unsigned int Seed);
// Optional user-provided custom cross-over function.
// Combines pieces of Data1 & Data2 together into Out.
// Returns the new size, which is not greater than MaxOutSize.
// Should produce the same mutation given the same Seed.
typedef size_t (*CustomCrossOverCallback)(const uint8_t *Data1, size_t Size1,
const uint8_t *Data2, size_t Size2,
uint8_t *Out, size_t MaxOutSize,
unsigned int Seed);
// Experimental, may go away in future.
// libFuzzer-provided function to be used inside LLVMFuzzerCustomMutator.
// Mutates raw data in [Data, Data+Size) inplace.
// Returns the new size, which is not greater than MaxSize.
FUZZER_INTERFACE_VISIBILITY size_t
LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
// The main entry of the fuzzer.
FUZZER_INTERFACE_VISIBILITY int
LLVMFuzzerRunDriver(int *argc, char ***argv, TestOneInputCallback UserCb,
InitializeCallback InitCb, CustomMutatorCallback MutCb,
CustomCrossOverCallback CrossCb, uint8_t *Counters,
size_t CountersSize);
With a little hack, this version of libfuzzer exposes the extra counters defined in FuzzerExtraCounters.cpp
, which make it esay to use libfuzzer as a library.
Example
#include "LibFuzzer.h"
#include <stdio.h>
static uint8_t Counters[4096];
int Test(const uint8_t *p, size_t s) {
// Instrument the code manually.
if (s == 0) {
Counters[0]++;
} else if (s == 8) {
Counters[1]++;
} else if (s == 16) {
Counters[2]++;
abort();
} else {
Counters[3]++;
}
Counters[4]++;
return 0;
}
int Init(int *argc, char ***argv) { printf("Initialized!\n"); }
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) {
return LLVMFuzzerMutate(Data, Size, MaxSize);
}
size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
size_t Size2, uint8_t *Out, size_t MaxOutSize,
unsigned int Seed) {
return 0; // Do nothing
}
int main(int argc, char **argv) {
LLVMFuzzerRunDriver(&argc, &argv, Test, Init, Mutate, CrossOver,
(uint8_t *)Counters, 4096);
}