From: "Ronald S. Bultje" <[email protected]>

Check that the mode is valid before using it as an index into tables.
Also provide a size parameter to ff_amr_bit_reorder() to prevent
overreads.

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: [email protected]
---
 libavcodec/amr.h      |    9 +++++----
 libavcodec/amrnbdec.c |    6 +++++-
 libavcodec/amrwbdec.c |    2 +-
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/libavcodec/amr.h b/libavcodec/amr.h
index ae6e4d1..bdc9e92 100644
--- a/libavcodec/amr.h
+++ b/libavcodec/amr.h
@@ -47,7 +47,7 @@
  * @param ord_table the reordering table as above
  */
 static inline void ff_amr_bit_reorder(uint16_t *out, int size,
-                                      const uint8_t *data,
+                                      const uint8_t *data, int data_size,
                                       const R_TABLE_TYPE *ord_table)
 {
     int field_size;
@@ -57,9 +57,10 @@ static inline void ff_amr_bit_reorder(uint16_t *out, int 
size,
         int field = 0;
         int field_offset = *ord_table++;
         while (field_size--) {
-           int bit = *ord_table++;
-           field <<= 1;
-           field |= data[bit >> 3] >> (bit & 7) & 1;
+            int bit = *ord_table++;
+            field <<= 1;
+            if ((bit >> 3) < data_size)
+                field |= data[bit >> 3] >> (bit & 7) & 1;
         }
         out[field_offset] = field;
     }
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index fff0e72..e4e070a3 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -201,7 +201,7 @@ static enum Mode unpack_bitstream(AMRContext *p, const 
uint8_t *buf,
     skip_bits(&gb, 2);                        // two padding bits
 
     if (mode < MODE_DTX)
-        ff_amr_bit_reorder((uint16_t *) &p->frame, sizeof(AMRNBFrame), buf + 1,
+        ff_amr_bit_reorder((uint16_t *) &p->frame, sizeof(AMRNBFrame), buf + 
1, buf_size - 1,
                            amr_unpacking_bitmaps_per_mode[mode]);
 
     return mode;
@@ -950,6 +950,10 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void 
*data,
     if (p->cur_frame_mode == MODE_DTX) {
         av_log_missing_feature(avctx, "dtx mode", 1);
         return -1;
+    } else if (p->cur_frame_mode >= N_MODES) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Corrupt bitstream\n");
+        return AVERROR_INVALIDDATA;
     }
 
     if (p->cur_frame_mode == MODE_12k2) {
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 6ea5d22..4393350 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -1114,7 +1114,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void 
*data,
         return -1;
 
     ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame),
-        buf + header_size, amr_bit_orderings_by_mode[ctx->fr_cur_mode]);
+        buf + header_size, buf_size - header_size, 
amr_bit_orderings_by_mode[ctx->fr_cur_mode]);
 
     /* Decode the quantized ISF vector */
     if (ctx->fr_cur_mode == MODE_6k60) {
-- 
1.7.7.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to