[FFmpeg-cvslog] avcodec/ac3dec: Keep track of band structure

Michael Niedermayer git at videolan.org
Sat May 13 22:38:15 EEST 2017


ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Sat May 13 19:28:01 2017 +0200| [9351a156de724edb69ba6e1f05884fe806a13a21] | committer: Michael Niedermayer

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 <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9351a156de724edb69ba6e1f05884fe806a13a21
---

 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 7e2cbce90b..ffea9d335c 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -761,30 +761,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.
@@ -863,7 +864,8 @@ static inline int spx_strategy(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));
     return 0;
 }
 
@@ -1000,7 +1002,8 @@ static inline int coupling_strategy(AC3DecodeContext *s, int blk,
         decode_band_structure(bc, 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 bac661c167..aa4cf04f8a 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -128,6 +128,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)
@@ -144,6 +145,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)



More information about the ffmpeg-cvslog mailing list