aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2012-03-13 16:26:44 -0700
committerReinhard Tartler <siretart@tauware.de>2012-03-14 21:33:15 +0100
commit4d343a6f47931a43fe8e4c9288a5068c76b843e0 (patch)
tree604beedcdd9f725643d12ac448dc8371eb625e2c
parenta81a6d9c80448cfbba0d2bcdd681bf971c7055a4 (diff)
downloadffmpeg-4d343a6f47931a43fe8e4c9288a5068c76b843e0.tar.gz
h264: stricter reference limit enforcement.
Progressive images can have only 16 references, error out if there are more, since the data is almost certainly corrupt, and the invalid value will lead to random crashes or invalid writes later on. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit e0febda22d0e0fab094a9c886b0e0f0f662df1ef) Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r--libavcodec/h264.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 95a672b962..e0eb8e119d 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -3020,6 +3020,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h->ref_count[1]= h->pps.ref_count[1];
if(h->slice_type_nos != AV_PICTURE_TYPE_I){
+ int max_refs = s->picture_structure == PICT_FRAME ? 16 : 32;
+
if(h->slice_type_nos == AV_PICTURE_TYPE_B){
h->direct_spatial_mv_pred= get_bits1(&s->gb);
}
@@ -3029,13 +3031,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h->ref_count[0]= get_ue_golomb(&s->gb) + 1;
if(h->slice_type_nos==AV_PICTURE_TYPE_B)
h->ref_count[1]= get_ue_golomb(&s->gb) + 1;
+ }
- if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){
- av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
- h->ref_count[0]= h->ref_count[1]= 1;
- return -1;
- }
+ if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
+ h->ref_count[0] = h->ref_count[1] = 1;
+ return AVERROR_INVALIDDATA;
}
+
if(h->slice_type_nos == AV_PICTURE_TYPE_B)
h->list_count= 2;
else