In the current code, the display extension info (if present) is used
to set avctx->width and height. These in turn determine the size of
the allocated picture buffer, so if they're too small the decoder will
write past its end.

I've uploaded a sample illustrating the issue to incoming/VC1_DEI_crash.wmv

This patch fixes the issue by using the DEI data just to set the
aspect ratio (which is more or less its intended purpose).
From 2f48eff9261fed290210bb61cb014828d7f738c5 Mon Sep 17 00:00:00 2001
From: Alberto Delmas <adel...@gmail.com>
Date: Mon, 12 Apr 2010 23:02:37 +0200
Subject: [PATCH] Prevent crash with bogus VC-1 display extension info

---
 libavcodec/vc1.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index b058a38..3609831 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -503,10 +503,10 @@ static int decode_sequence_header_adv(VC1Context *v, 
GetBitContext *gb)
     if(get_bits1(gb)) { //Display Info - decoding is not affected by it
         int w, h, ar = 0;
         av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
-        v->s.avctx->width  = w = get_bits(gb, 14) + 1;
-        v->s.avctx->height = h = get_bits(gb, 14) + 1;
+        w = get_bits(gb, 14) + 1;
+        h = get_bits(gb, 14) + 1;
         av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h);
-        if(get_bits1(gb))
+        if(get_bits1(gb)){
             ar = get_bits(gb, 4);
         if(ar && ar < 14){
             v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar];
@@ -515,6 +515,13 @@ static int decode_sequence_header_adv(VC1Context *v, 
GetBitContext *gb)
             h = get_bits(gb, 8);
             v->s.avctx->sample_aspect_ratio = (AVRational){w, h};
         }
+        }else{
+            av_reduce(&v->s.avctx->sample_aspect_ratio.num,
+                      &v->s.avctx->sample_aspect_ratio.den,
+                      v->s.avctx->height * w,
+                      v->s.avctx->width * h,
+                      1<<30);
+        }
         av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", 
v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den);
 
         if(get_bits1(gb)){ //framerate stuff
-- 
1.7.3.3

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to