diff options
author | Nick Terrell <terrelln@fb.com> | 2019-07-13 02:27:00 (GMT) |
---|---|---|
committer | Nick Terrell <terrelln@fb.com> | 2019-07-15 19:22:04 (GMT) |
commit | 3c40db8d258716b9efcfb46fa6dc29de6e43e616 (patch) | |
tree | 7fd1d48f6195dfde2c6475fe035a0061b948e9c3 /ossfuzz/decompress_fuzzer.c | |
parent | 725cb0aafdf78b550c52618fe5cea1fadd278881 (diff) | |
download | lz4-3c40db8d258716b9efcfb46fa6dc29de6e43e616.zip lz4-3c40db8d258716b9efcfb46fa6dc29de6e43e616.tar.gz lz4-3c40db8d258716b9efcfb46fa6dc29de6e43e616.tar.bz2 |
[ossfuzz] Improve the fuzzers
* Run more decompression variants
* Round trip the compression fuzzer and do partial decompression as well
* Add a compression fuzzer that compresses into a smaller output buffer
and test the destSize variant
These fuzzers caught 2 bugs that were fixed in the previous commit.
* Input buffer over-read in partial decompress
* Partial decompress fails if output size is 0
Diffstat (limited to 'ossfuzz/decompress_fuzzer.c')
-rw-r--r-- | ossfuzz/decompress_fuzzer.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/ossfuzz/decompress_fuzzer.c b/ossfuzz/decompress_fuzzer.c index e6e14c4..0267c93 100644 --- a/ossfuzz/decompress_fuzzer.c +++ b/ossfuzz/decompress_fuzzer.c @@ -1,28 +1,58 @@ +/** + * This fuzz target attempts to decompress the fuzzed data with the simple + * decompression function to ensure the decompressor never crashes. + */ + #include <stddef.h> #include <stdint.h> #include <stdlib.h> -#include "lz4.h" +#include <string.h> -#define CHECK(COND) if (!(COND)) { abort(); } +#include "fuzz_helpers.h" +#include "lz4.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - // TODO: Size input buffer pseudo-randomly based on seed extracted from input - size_t const buffer_size = 10 * 1024 * 1024; - char *const dest_buffer = (char *)malloc(buffer_size); - CHECK(dest_buffer != NULL); + uint32_t seed = FUZZ_seed(&data, &size); + size_t const dstCapacity = FUZZ_rand32(&seed, 0, 4 * size); + size_t const smallDictSize = size + 1; + size_t const largeDictSize = 64 * 1024 - 1; + size_t const dictSize = MAX(smallDictSize, largeDictSize); + char* const dst = (char*)malloc(dstCapacity); + char* const dict = (char*)malloc(dictSize + size); + char* const largeDict = dict; + char* const dataAfterDict = dict + dictSize; + char* const smallDict = dataAfterDict - smallDictSize; - // Allocation succeeded, try decompressing the incoming data. - int result = LZ4_decompress_safe((const char*)data, - dest_buffer, - size, - buffer_size); + FUZZ_ASSERT(dst); + FUZZ_ASSERT(dict); - // Ignore the result of decompression. - (void)result; + /* Prepare the dictionary. The data doesn't matter for decompression. */ + memset(dict, 0, dictSize); + memcpy(dataAfterDict, data, size); - free(dest_buffer); + /* Decompress using each possible dictionary configuration. */ + /* No dictionary. */ + LZ4_decompress_safe_usingDict((char const*)data, dst, size, + dstCapacity, NULL, 0); + /* Small external dictonary. */ + LZ4_decompress_safe_usingDict((char const*)data, dst, size, + dstCapacity, smallDict, smallDictSize); + /* Large external dictionary. */ + LZ4_decompress_safe_usingDict((char const*)data, dst, size, + dstCapacity, largeDict, largeDictSize); + /* Small prefix. */ + LZ4_decompress_safe_usingDict((char const*)dataAfterDict, dst, size, + dstCapacity, smallDict, smallDictSize); + /* Large prefix. */ + LZ4_decompress_safe_usingDict((char const*)data, dst, size, + dstCapacity, largeDict, largeDictSize); + /* Partial decompression. */ + LZ4_decompress_safe_partial((char const*)data, dst, size, + dstCapacity, dstCapacity); + free(dst); + free(dict); - return 0; + return 0; } |