From 1bec35e33757fc38261b0acfa3c032e720d2baf0 Mon Sep 17 00:00:00 2001 From: Martijn van Beurden Date: Mon, 4 Apr 2022 20:13:44 +0200 Subject: Add residual limit checking This patch adds a (fast) check in the bitreader to detect overflow of the residual --- src/libFLAC/bitreader.c | 12 ++++++++++-- src/libFLAC/stream_decoder.c | 13 +++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/libFLAC/bitreader.c b/src/libFLAC/bitreader.c index aec255bf..1b6e63f6 100644 --- a/src/libFLAC/bitreader.c +++ b/src/libFLAC/bitreader.c @@ -804,6 +804,7 @@ FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, uint32_t *va } #endif +#if 0 /* unused */ FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint32_t parameter) { FLAC__uint32 lsbs = 0, msbs = 0; @@ -830,6 +831,7 @@ FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint3 return true; } +#endif /* this is by far the most heavily used reader call. it ain't pretty but it's fast */ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter) @@ -837,7 +839,7 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[ /* try and get br->consumed_words and br->consumed_bits into register; * must remember to flush them back to *br before calling other * bitreader functions that use them, and before returning */ - uint32_t cwords, words, lsbs, msbs, x, y; + uint32_t cwords, words, lsbs, msbs, x, y, limit; uint32_t ucbits; /* keep track of the number of unconsumed bits in word */ brword b; int *val, *end; @@ -849,6 +851,8 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[ FLAC__ASSERT(parameter < 32); /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ + limit = UINT32_MAX >> parameter; /* Maximal msbs that can occur with residual bounded to int32_t */ + val = vals; end = vals + nvals; @@ -857,7 +861,8 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[ /* read the unary MSBs and end bit */ if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) return false; - + /* Checking limit here would be overzealous: coding UINT32_MAX + * with parameter == 0 would take 4GiB */ *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1); } @@ -898,6 +903,9 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[ ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD; msbs = x; + if(x > limit) + return false; + /* read the binary LSBs */ x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit uint32_t */ if(parameter <= ucbits) { diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 2213cfee..fb1042a3 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -2899,8 +2899,17 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_ if(rice_parameter < pesc) { partitioned_rice_contents->raw_bits[partition] = 0; u = (partition == 0) ? partition_samples - predictor_order : partition_samples; - if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) - return false; /* read_callback_ sets the state for us */ + if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)){ + if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) { + /* no error was set, read_callback_ didn't set it, so + * invalid rice symbol was found */ + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + else + return false; /* read_callback_ sets the state for us */ + } sample += u; } else { -- cgit v1.2.1