Update fuzzer sources

This commit is contained in:
Nick Terrell 2017-09-12 20:20:27 -07:00
parent f1571dad8f
commit 677c2cbf89
6 changed files with 43 additions and 18 deletions

View File

@ -12,15 +12,17 @@
* Fuzz targets have some common parameters passed as macros during compilation. * Fuzz targets have some common parameters passed as macros during compilation.
* Check the documentation for each individual fuzzer for more parameters. * Check the documentation for each individual fuzzer for more parameters.
* *
* @param STATEFULL_FUZZING: * @param STATEFUL_FUZZING:
* Define this to reuse state between fuzzer runs. This can be useful to * Define this to reuse state between fuzzer runs. This can be useful to
* test code paths which are only executed when contexts are reused. * test code paths which are only executed when contexts are reused.
* WARNING: Makes reproducing crashes much harder. * WARNING: Makes reproducing crashes much harder.
* Default: Not defined. * Default: Not defined.
* @param FUZZ_RNG_SEED_SIZE: * @param FUZZ_RNG_SEED_SIZE:
* The number of bytes of the source to look at when constructing a seed * The number of bytes of the source to look at when constructing a seed
* for the deterministic RNG. * for the deterministic RNG. These bytes are discarded before passing
* Default: 128. * the data to zstd functions. Every fuzzer initializes the RNG exactly
* once before doing anything else, even if it is unused.
* Default: 4.
* @param ZSTD_DEBUG: * @param ZSTD_DEBUG:
* This is a parameter for the zstd library. Defining `ZSTD_DEBUG=1` * This is a parameter for the zstd library. Defining `ZSTD_DEBUG=1`
* enables assert() statements in the zstd library. Higher levels enable * enables assert() statements in the zstd library. Higher levels enable
@ -41,12 +43,20 @@
#define FUZZ_H #define FUZZ_H
#ifndef FUZZ_RNG_SEED_SIZE #ifndef FUZZ_RNG_SEED_SIZE
# define FUZZ_RNG_SEED_SIZE 128 # define FUZZ_RNG_SEED_SIZE 4
#endif #endif
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -19,6 +19,10 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
@ -48,11 +52,13 @@
/** /**
* Determininistically constructs a seed based on the fuzz input. * Determininistically constructs a seed based on the fuzz input.
* Only looks at the first FUZZ_RNG_SEED_SIZE bytes of the input. * Consumes up to the first FUZZ_RNG_SEED_SIZE bytes of the input.
*/ */
FUZZ_STATIC uint32_t FUZZ_seed(const uint8_t *src, size_t size) { FUZZ_STATIC uint32_t FUZZ_seed(uint8_t const **src, size_t* size) {
size_t const toHash = MIN(FUZZ_RNG_SEED_SIZE, size); size_t const toHash = MIN(FUZZ_RNG_SEED_SIZE, *size);
return XXH32(src, toHash, 0); return XXH32(*src, toHash, 0);
*size -= toHash;
*src += toHash;
} }
#define FUZZ_rotl32(x, r) (((x) << (r)) | ((x) >> (32 - (r)))) #define FUZZ_rotl32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
@ -67,4 +73,8 @@ FUZZ_STATIC uint32_t FUZZ_rand(uint32_t *state) {
return rand32 >> 5; return rand32 >> 5;
} }
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -24,7 +24,10 @@ static size_t bufSize = 0;
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{ {
size_t const neededBufSize = MAX(20 * size, (size_t)256 << 10); size_t neededBufSize;
FUZZ_seed(&src, &size);
neededBufSize = MAX(20 * size, (size_t)256 << 10);
/* Allocate all buffers and contexts if not already allocated */ /* Allocate all buffers and contexts if not already allocated */
if (neededBufSize > bufSize) { if (neededBufSize > bufSize) {
@ -39,7 +42,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
} }
ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, src, size); ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, src, size);
#ifndef STATEFULL_FUZZING #ifndef STATEFUL_FUZZING
ZSTD_freeDCtx(dctx); dctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL;
#endif #endif
return 0; return 0;

View File

@ -44,9 +44,10 @@ static size_t roundTripTest(void *result, size_t resultCapacity,
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{ {
size_t const neededBufSize = ZSTD_compressBound(size); size_t neededBufSize;
seed = FUZZ_seed(src, size); seed = FUZZ_seed(&src, &size);
neededBufSize = ZSTD_compressBound(size);
/* Allocate all buffers and contexts if not already allocated */ /* Allocate all buffers and contexts if not already allocated */
if (neededBufSize > bufSize) { if (neededBufSize > bufSize) {
@ -73,7 +74,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size"); FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size");
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!"); FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
} }
#ifndef STATEFULL_FUZZING #ifndef STATEFUL_FUZZING
ZSTD_freeCCtx(cctx); cctx = NULL; ZSTD_freeCCtx(cctx); cctx = NULL;
ZSTD_freeDCtx(dctx); dctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL;
#endif #endif

View File

@ -51,7 +51,7 @@ static ZSTD_inBuffer makeInBuffer(const uint8_t **src, size_t *size)
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{ {
seed = FUZZ_seed(src, size); seed = FUZZ_seed(&src, &size);
/* Allocate all buffers and contexts if not already allocated */ /* Allocate all buffers and contexts if not already allocated */
if (!buf) { if (!buf) {
@ -78,7 +78,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
} }
error: error:
#ifndef STATEFULL_FUZZING #ifndef STATEFUL_FUZZING
ZSTD_freeDStream(dstream); dstream = NULL; ZSTD_freeDStream(dstream); dstream = NULL;
#endif #endif
return 0; return 0;

View File

@ -114,9 +114,10 @@ static size_t compress(uint8_t *dst, size_t capacity,
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{ {
size_t const neededBufSize = ZSTD_compressBound(size) * 2; size_t neededBufSize;
seed = FUZZ_seed(src, size); seed = FUZZ_seed(&src, &size);
neededBufSize = ZSTD_compressBound(size) * 2;
/* Allocate all buffers and contexts if not already allocated */ /* Allocate all buffers and contexts if not already allocated */
if (neededBufSize > bufSize) { if (neededBufSize > bufSize) {
@ -145,7 +146,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!"); FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!");
} }
#ifndef STATEFULL_FUZZING #ifndef STATEFUL_FUZZING
ZSTD_freeCStream(cstream); cstream = NULL; ZSTD_freeCStream(cstream); cstream = NULL;
ZSTD_freeDCtx(dctx); dctx = NULL; ZSTD_freeDCtx(dctx); dctx = NULL;
#endif #endif