Skip to content

Commit

Permalink
adding a fuzzing tool to make sure brotli files may be decoded
Browse files Browse the repository at this point in the history
  • Loading branch information
danielrh committed Nov 4, 2018
1 parent 1b87a19 commit 905fc5f
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ lto=true

[dependencies]
"alloc-no-stdlib" = {version="2.0"}
"brotli-decompressor" = {version="> 2.0.1, < 2.1.0"}
"brotli-decompressor" = {version="> 2.0.2, < 2.1.0"}
"alloc-stdlib" = {version="~0.2", optional=true}
"packed_simd" = {version="0.3", optional=true}
"sha2" = {version="~0.8", optional=true}
Expand Down
2 changes: 1 addition & 1 deletion c/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ lto=true

[dependencies]
"alloc-no-stdlib" = {version="2.0"}
"brotli-decompressor" = {version="~2.0"}
"brotli-decompressor" = {version="> 2.0.2, < 2.1.0"}
"alloc-stdlib" = {version="~0.2", optional=true}
"packed_simd" = {version="0.3", optional=true}
"sha2" = {version="~0.8", optional=true}
Expand Down
6 changes: 5 additions & 1 deletion c/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
multiexample: multiexample_d decompressor multiexample.c vec_u8.h arg.h custom_alloc.h
multiexample: multiexample_d decompressor multiexample.c vec_u8.h arg.h custom_alloc.h fuzz fuzz_d
gcc -O3 -o multiexample -g multiexample.c -I. target/release/libbrotli.[ds][lyo]*
multiexample_d: decompressor multiexample.c vec_u8.h arg.h custom_alloc.h
gcc -o multiexample_d -g multiexample.c -I. target/debug/libbrotli.[ds][lyo]*
decompressor: decompressor_d decompressor.c target/release/libbrotli.so catbrotli
gcc -O3 -o decompressor -g decompressor.c -I. target/release/libbrotli.[ds][lyo]*
decompressor_d: decompressor.c target/debug/libbrotli.so brotli_tool catbrotli_d
cargo build && gcc -o decompressor_d -g decompressor.c -I. target/debug/libbrotli.[ds][lyo]*
fuzz: fuzz_d fuzz.c target/release/libbrotli.so catbrotli
gcc -O3 -o fuzz -g fuzz.c -I. target/release/libbrotli.[ds][lyo]*
fuzz_d: fuzz.c target/debug/libbrotli.so brotli_tool catbrotli_d
cargo build && gcc -o fuzz_d -g fuzz.c -I. target/debug/libbrotli.[ds][lyo]*

brotli_tool: brotli_tool_d decompressor.c target/release/libbrotli.so
gcc -O3 -o brotli_tool -g brotli.c -I. target/release/libbrotli.[ds][lyo]*
Expand Down
14 changes: 14 additions & 0 deletions c/brotli/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,20 @@ BROTLI_DEC_API BROTLI_BOOL BrotliDecoderIsFinished(
BROTLI_DEC_API BrotliDecoderErrorCode BrotliDecoderGetErrorCode(
const BrotliDecoderState* state);

/**
* Acquires a detailed error code.
*
* Should be used only after ::BrotliDecoderDecompressStream returns
* ::BROTLI_DECODER_RESULT_ERROR.
*
* See also ::BrotliDecoderGetErrorString
*
* @param state decoder instance
* @returns last saved error code as a string, or panic information
*/
BROTLI_DEC_API const char* BrotliDecoderGetErrorString(
const BrotliDecoderState* state);

/**
* Converts error code to a c-string.
*/
Expand Down
60 changes: 60 additions & 0 deletions c/fuzz.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "brotli/decode.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
int custom_alloc_data = 0;
void * custom_alloc(void*opaque, size_t size) {
assert(opaque == &custom_alloc_data);
return malloc(size);
}
void custom_free(void*opaque, void* addr) {
assert(opaque == &custom_alloc_data);
free(addr);
}

int main(int argc, char **argv) {
FILE * fp = argc > 1 ? fopen(argv[1], "rb") : stdin;
BrotliDecoderState * state = BrotliDecoderCreateInstance(custom_alloc, custom_free, &custom_alloc_data);
unsigned char ibuffer[4096];
unsigned char obuffer[4096];
size_t total_out = 0;
BrotliDecoderResult rest;
while(1) {
size_t avail_in = fread(ibuffer, 1, sizeof(ibuffer), fp);
int is_eof = (avail_in == 0);
const unsigned char *i_ptr = &ibuffer[0];
while (1) {
unsigned char *o_ptr = &obuffer[0];
size_t avail_out = sizeof(obuffer);
rest = BrotliDecoderDecompressStream(state, &avail_in, &i_ptr, &avail_out, &o_ptr, &total_out);
if (o_ptr != &obuffer[0]) {
// don't actually write
}
if (rest == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
break;
}
if (rest == BROTLI_DECODER_RESULT_SUCCESS || rest == BROTLI_DECODER_RESULT_ERROR) {
break;
}
}
if (rest == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT && is_eof) {
fprintf(stderr, "Unexpected EOF\n");
break;
}
if (rest == BROTLI_DECODER_RESULT_SUCCESS) {
break;
}
if (rest == BROTLI_DECODER_RESULT_ERROR) {
fprintf(stderr, "Error: %s\n", BrotliDecoderGetErrorString(state));
if (BrotliDecoderGetErrorCode(state) == BROTLI_DECODER_ERROR_UNREACHABLE) {
abort(); // possibly a stack trace
}
break;
}
}
BrotliDecoderDestroyInstance(state);
if (rest == BROTLI_DECODER_RESULT_ERROR) {
fprintf(stderr, "Not a valid brotli file\n");
}
}
2 changes: 1 addition & 1 deletion research/concatenate_some.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def process(work, brotli, cat, prefix):
quality = "-q" + str(insecure_random.randrange(2,12 if len(work) < 8 else 10))
if insecure_random.randrange(0,16) == 0:
quality = '-q9.5'
append = insecure_random.randrange(0,8) == 0
append = insecure_random.randrange(0,2) == 0
frivolous_procs = []
procs = []
print 'processing',work,'at',quality,append
Expand Down
4 changes: 4 additions & 0 deletions src/ffi/decompressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,7 @@ pub unsafe extern fn CBrotliDecoderIsFinished(state_ptr: *const ffi::BrotliDecod
pub unsafe extern fn CBrotliDecoderGetErrorCode(state_ptr: *const ffi::BrotliDecoderState) -> ffi::BrotliDecoderErrorCode {
ffi::BrotliDecoderGetErrorCode(state_ptr)
}
#[no_mangle]
pub unsafe extern fn CBrotliDecoderGetErrorString(state_ptr: *const ffi::BrotliDecoderState) -> *const u8 {
ffi::BrotliDecoderGetErrorString(state_ptr)
}

0 comments on commit 905fc5f

Please sign in to comment.