changeset 11205:f5d50932acc0 libavcodec

Add some AAC buffer overread checks.
author alexc
date Thu, 18 Feb 2010 23:06:56 +0000
parents ba1c541f7e8a
children cb29d50bf6d4
files aac.c
diffstat 1 files changed, 26 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/aac.c	Thu Feb 18 18:23:48 2010 +0000
+++ b/aac.c	Thu Feb 18 23:06:56 2010 +0000
@@ -107,6 +107,8 @@
 
 static uint32_t cbrt_tab[1<<13];
 
+static const char overread_err[] = "Input buffer exhausted before END element found\n";
+
 static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
 {
     if (ac->tag_che_map[type][elem_id]) {
@@ -278,6 +280,7 @@
                       GetBitContext *gb)
 {
     int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc, sampling_index;
+    int comment_len;
 
     skip_bits(gb, 2);  // object_type
 
@@ -312,7 +315,12 @@
     align_get_bits(gb);
 
     /* comment field, first byte is length */
-    skip_bits_long(gb, 8 * get_bits(gb, 8));
+    comment_len = get_bits(gb, 8) * 8;
+    if (get_bits_left(gb) < comment_len) {
+        av_log(ac->avccontext, AV_LOG_ERROR, overread_err);
+        return -1;
+    }
+    skip_bits_long(gb, comment_len);
     return 0;
 }
 
@@ -574,7 +582,7 @@
 /**
  * Skip data_stream_element; reference: table 4.10.
  */
-static void skip_data_stream_element(GetBitContext *gb)
+static int skip_data_stream_element(AACContext *ac, GetBitContext *gb)
 {
     int byte_align = get_bits1(gb);
     int count = get_bits(gb, 8);
@@ -582,7 +590,13 @@
         count += get_bits(gb, 8);
     if (byte_align)
         align_get_bits(gb);
+
+    if (get_bits_left(gb) < 8 * count) {
+        av_log(ac->avccontext, AV_LOG_ERROR, overread_err);
+        return -1;
+    }
     skip_bits_long(gb, 8 * count);
+    return 0;
 }
 
 static int decode_prediction(AACContext *ac, IndividualChannelStream *ics,
@@ -1972,8 +1986,7 @@
             break;
 
         case TYPE_DSE:
-            skip_data_stream_element(&gb);
-            err = 0;
+            err = skip_data_stream_element(ac, &gb);
             break;
 
         case TYPE_PCE: {
@@ -1992,6 +2005,10 @@
         case TYPE_FIL:
             if (elem_id == 15)
                 elem_id += get_bits(&gb, 8) - 1;
+            if (get_bits_left(&gb) < 8 * elem_id) {
+                    av_log(avccontext, AV_LOG_ERROR, overread_err);
+                    return -1;
+            }
             while (elem_id > 0)
                 elem_id -= decode_extension_payload(ac, &gb, elem_id);
             err = 0; /* FIXME */
@@ -2004,6 +2021,11 @@
 
         if (err)
             return err;
+
+        if (get_bits_left(&gb) < 3) {
+            av_log(avccontext, AV_LOG_ERROR, overread_err);
+            return -1;
+        }
     }
 
     spectral_to_sample(ac);