From c24bff130d612a8412a31202c8da0467ed7b91aa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 13 May 2017 19:28:01 +0200 Subject: [PATCH] avcodec/ac3dec: Keep track of band structure It is needed in some corner cases that seem not to be forbidden Fixes: out of array index Fixes: 1538/clusterfuzz-testcase-minimized-4696904925446144 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Signed-off-by: Michael Niedermayer (cherry picked from commit 9351a156de724edb69ba6e1f05884fe806a13a21) Signed-off-by: Michael Niedermayer --- libavcodec/ac3dec.c | 27 +++++++++++++++------------ libavcodec/ac3dec.h | 2 ++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index f82f3974ef..3b93c7537d 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -744,30 +744,31 @@ static void ac3_upmix_delay(AC3DecodeContext *s) * @param[in] default_band_struct default band structure table * @param[out] num_bands number of bands (optionally NULL) * @param[out] band_sizes array containing the number of bins in each band (optionally NULL) + * @param[in,out] band_struct current band structure */ static void decode_band_structure(GetBitContext *gbc, int blk, int eac3, int ecpl, int start_subband, int end_subband, const uint8_t *default_band_struct, - int *num_bands, uint8_t *band_sizes) + int *num_bands, uint8_t *band_sizes, + uint8_t *band_struct, int band_struct_size) { int subbnd, bnd, n_subbands, n_bands=0; uint8_t bnd_sz[22]; - uint8_t coded_band_struct[22]; - const uint8_t *band_struct; n_subbands = end_subband - start_subband; + if (!blk) + memcpy(band_struct, default_band_struct, band_struct_size); + + av_assert0(band_struct_size >= start_subband + n_subbands); + + band_struct += start_subband + 1; + /* decode band structure from bitstream or use default */ if (!eac3 || get_bits1(gbc)) { for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) { - coded_band_struct[subbnd] = get_bits1(gbc); + band_struct[subbnd] = get_bits1(gbc); } - band_struct = coded_band_struct; - } else if (!blk) { - band_struct = &default_band_struct[start_subband+1]; - } else { - /* no change in band structure */ - return; } /* calculate number of bands and band sizes based on band structure. @@ -894,7 +895,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) start_subband, end_subband, ff_eac3_default_spx_band_struct, &s->num_spx_bands, - s->spx_band_sizes); + s->spx_band_sizes, + s->spx_band_struct, sizeof(s->spx_band_struct)); } } if (!s->eac3 || !s->spx_in_use) { @@ -1028,7 +1030,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) decode_band_structure(gbc, blk, s->eac3, 0, cpl_start_subband, cpl_end_subband, ff_eac3_default_cpl_band_struct, - &s->num_cpl_bands, s->cpl_band_sizes); + &s->num_cpl_bands, s->cpl_band_sizes, + s->cpl_band_struct, sizeof(s->cpl_band_struct)); } else { /* coupling not in use */ for (ch = 1; ch <= fbw_channels; ch++) { diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index b3498fec96..fe3cf86c43 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -126,6 +126,7 @@ typedef struct AC3DecodeContext { int phase_flags_in_use; ///< phase flags in use (phsflginu) int phase_flags[AC3_MAX_CPL_BANDS]; ///< phase flags (phsflg) int num_cpl_bands; ///< number of coupling bands (ncplbnd) + uint8_t cpl_band_struct[AC3_MAX_CPL_BANDS]; uint8_t cpl_band_sizes[AC3_MAX_CPL_BANDS]; ///< number of coeffs in each coupling band int firstchincpl; ///< first channel in coupling int first_cpl_coords[AC3_MAX_CHANNELS]; ///< first coupling coordinates states (firstcplcos) @@ -142,6 +143,7 @@ typedef struct AC3DecodeContext { int spx_dst_start_freq; ///< spx starting frequency bin for copying (copystartmant) ///< the copy region ends at the start of the spx region. int num_spx_bands; ///< number of spx bands (nspxbnds) + uint8_t spx_band_struct[SPX_MAX_BANDS]; uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each spx band uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos) INTFLOAT spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact)