fuzz: Add support for custom crossover functions
libfuzzer supports a "custom crossover function". Libfuzzer often tries to blend two inputs to create a new interesting input. Sometimes, we have a better idea about how to blend inputs together. This change allows fuzzers to specify a custom function for blending two inputs together. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Message-Id: <20201023150746.107063-8-alxndr@bu.edu> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
a3c20e91de
commit
f81cb729be
@ -118,6 +118,19 @@ static FuzzTarget *fuzz_get_target(char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Sometimes called by libfuzzer to mutate two inputs into one */
|
||||||
|
size_t LLVMFuzzerCustomCrossOver(const uint8_t *data1, size_t size1,
|
||||||
|
const uint8_t *data2, size_t size2,
|
||||||
|
uint8_t *out, size_t max_out_size,
|
||||||
|
unsigned int seed)
|
||||||
|
{
|
||||||
|
if (fuzz_target->crossover) {
|
||||||
|
return fuzz_target->crossover(data1, size1, data2, size2, out,
|
||||||
|
max_out_size, seed);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Executed for each fuzzing-input */
|
/* Executed for each fuzzing-input */
|
||||||
int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size)
|
int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +77,29 @@ typedef struct FuzzTarget {
|
|||||||
*/
|
*/
|
||||||
void(*fuzz)(QTestState *, const unsigned char *, size_t);
|
void(*fuzz)(QTestState *, const unsigned char *, size_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The fuzzer can specify a "Custom Crossover" function for combining two
|
||||||
|
* inputs from the corpus. This function is sometimes called by libfuzzer
|
||||||
|
* when mutating inputs.
|
||||||
|
*
|
||||||
|
* data1: location of first input
|
||||||
|
* size1: length of first input
|
||||||
|
* data1: location of second input
|
||||||
|
* size1: length of second input
|
||||||
|
* out: where to place the resulting, mutated input
|
||||||
|
* max_out_size: the maximum length of the input that can be placed in out
|
||||||
|
* seed: the seed that should be used to make mutations deterministic, when
|
||||||
|
* needed
|
||||||
|
*
|
||||||
|
* See libfuzzer's LLVMFuzzerCustomCrossOver API for more info.
|
||||||
|
*
|
||||||
|
* Can be NULL
|
||||||
|
*/
|
||||||
|
size_t(*crossover)(const uint8_t *data1, size_t size1,
|
||||||
|
const uint8_t *data2, size_t size2,
|
||||||
|
uint8_t *out, size_t max_out_size,
|
||||||
|
unsigned int seed);
|
||||||
|
|
||||||
} FuzzTarget;
|
} FuzzTarget;
|
||||||
|
|
||||||
void flush_events(QTestState *);
|
void flush_events(QTestState *);
|
||||||
@ -91,6 +114,10 @@ void fuzz_qtest_set_serialize(bool option);
|
|||||||
*/
|
*/
|
||||||
void fuzz_add_target(const FuzzTarget *target);
|
void fuzz_add_target(const FuzzTarget *target);
|
||||||
|
|
||||||
|
size_t LLVMFuzzerCustomCrossOver(const uint8_t *data1, size_t size1,
|
||||||
|
const uint8_t *data2, size_t size2,
|
||||||
|
uint8_t *out, size_t max_out_size,
|
||||||
|
unsigned int seed);
|
||||||
int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
|
int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
|
||||||
int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp);
|
int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user