From 3e0a760af876628a3959b1b167bac88082ca38a4 Mon Sep 17 00:00:00 2001 From: Martijn van Beurden Date: Mon, 2 Dec 2024 12:12:08 +0100 Subject: [PATCH 1/2] Do not shrink decoding buffer when parameters change As files with a changing number of channels or bit depth are rare and difficult the handle anyway, improve fuzzer performance with them by limiting realloction of the decoding buffer --- src/libFLAC/stream_decoder.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 6d71bf36c1..09b6357e05 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -1552,6 +1552,11 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_ decoder->private_->side_subframe = 0; } + /* Only grow per-channel buffers, even if number of channels increases */ + if(decoder->private_->output_capacity > size) { + size = decoder->private_->output_capacity; + } + for(i = 0; i < channels; i++) { /* WATCHOUT: * FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN() From a4b1cb7cded01956e7d15a983145d2d2f2a854d5 Mon Sep 17 00:00:00 2001 From: Martijn van Beurden Date: Mon, 2 Dec 2024 12:14:08 +0100 Subject: [PATCH 2/2] Improve fuzzer_seek performance by imposing limits The max number of errors and number of output bytes are limited --- oss-fuzz/seek.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/oss-fuzz/seek.cc b/oss-fuzz/seek.cc index 019112c0d3..045cc8405c 100644 --- a/oss-fuzz/seek.cc +++ b/oss-fuzz/seek.cc @@ -35,6 +35,8 @@ #include "common.h" int write_abort_check_counter = -1; +int written_uncompressed_bytes = 0; +int errors_received_counter = 0; #if 0 /* set to 1 to debug */ #define FPRINTF_DEBUG_ONLY(...) fprintf(__VA_ARGS__) @@ -46,7 +48,7 @@ int write_abort_check_counter = -1; static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data) { - (void)decoder, (void)frame, (void)buffer, (void)client_data; + (void)decoder, (void)buffer, (void)client_data; if(write_abort_check_counter > 0) { write_abort_check_counter--; if(write_abort_check_counter == 0) @@ -54,12 +56,22 @@ static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder * } else if(write_abort_check_counter == 0) /* This must not happen: write callback called after abort is returned */ abort(); + + written_uncompressed_bytes += frame->header.blocksize * frame->header.channels * frame->header.bits_per_sample / 8; + if(written_uncompressed_bytes > (1 << 24)) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + + + if(errors_received_counter > 10000) + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } static void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus error, void *client_data) { - (void)decoder, (void)error, (void)client_data; + (void)decoder, (void)error, (void)client_data; + errors_received_counter++; } @@ -80,6 +92,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) alloc_check_counter = 0; write_abort_check_counter = -1; + written_uncompressed_bytes = 0; + errors_received_counter = 0; /* allocate the decoder */ if((decoder = FLAC__stream_decoder_new()) == NULL) {