Commit c20111dc authored by alexc's avatar alexc

Add some AAC buffer overread checks.


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@21886 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 050ecb86
...@@ -107,6 +107,8 @@ static VLC vlc_spectral[11]; ...@@ -107,6 +107,8 @@ static VLC vlc_spectral[11];
static uint32_t cbrt_tab[1<<13]; 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) static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
{ {
if (ac->tag_che_map[type][elem_id]) { if (ac->tag_che_map[type][elem_id]) {
...@@ -278,6 +280,7 @@ static int decode_pce(AACContext *ac, enum ChannelPosition new_che_pos[4][MAX_EL ...@@ -278,6 +280,7 @@ static int decode_pce(AACContext *ac, enum ChannelPosition new_che_pos[4][MAX_EL
GetBitContext *gb) GetBitContext *gb)
{ {
int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc, sampling_index; 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 skip_bits(gb, 2); // object_type
...@@ -312,7 +315,12 @@ static int decode_pce(AACContext *ac, enum ChannelPosition new_che_pos[4][MAX_EL ...@@ -312,7 +315,12 @@ static int decode_pce(AACContext *ac, enum ChannelPosition new_che_pos[4][MAX_EL
align_get_bits(gb); align_get_bits(gb);
/* comment field, first byte is length */ /* 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; return 0;
} }
...@@ -574,7 +582,7 @@ static av_cold int aac_decode_init(AVCodecContext *avccontext) ...@@ -574,7 +582,7 @@ static av_cold int aac_decode_init(AVCodecContext *avccontext)
/** /**
* Skip data_stream_element; reference: table 4.10. * 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 byte_align = get_bits1(gb);
int count = get_bits(gb, 8); int count = get_bits(gb, 8);
...@@ -582,7 +590,13 @@ static void skip_data_stream_element(GetBitContext *gb) ...@@ -582,7 +590,13 @@ static void skip_data_stream_element(GetBitContext *gb)
count += get_bits(gb, 8); count += get_bits(gb, 8);
if (byte_align) if (byte_align)
align_get_bits(gb); 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); skip_bits_long(gb, 8 * count);
return 0;
} }
static int decode_prediction(AACContext *ac, IndividualChannelStream *ics, static int decode_prediction(AACContext *ac, IndividualChannelStream *ics,
...@@ -1972,8 +1986,7 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data, ...@@ -1972,8 +1986,7 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
break; break;
case TYPE_DSE: case TYPE_DSE:
skip_data_stream_element(&gb); err = skip_data_stream_element(ac, &gb);
err = 0;
break; break;
case TYPE_PCE: { case TYPE_PCE: {
...@@ -1992,6 +2005,10 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data, ...@@ -1992,6 +2005,10 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
case TYPE_FIL: case TYPE_FIL:
if (elem_id == 15) if (elem_id == 15)
elem_id += get_bits(&gb, 8) - 1; 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) while (elem_id > 0)
elem_id -= decode_extension_payload(ac, &gb, elem_id); elem_id -= decode_extension_payload(ac, &gb, elem_id);
err = 0; /* FIXME */ err = 0; /* FIXME */
...@@ -2004,6 +2021,11 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data, ...@@ -2004,6 +2021,11 @@ static int aac_decode_frame(AVCodecContext *avccontext, void *data,
if (err) if (err)
return err; return err;
if (get_bits_left(&gb) < 3) {
av_log(avccontext, AV_LOG_ERROR, overread_err);
return -1;
}
} }
spectral_to_sample(ac); spectral_to_sample(ac);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment