[FFmpeg-cvslog] vcr1: add sanity checks

Anton Khirnov git at videolan.org
Mon Nov 4 19:16:43 CET 2013


ffmpeg | branch: release/0.10 | Anton Khirnov <anton at khirnov.net> | Sat Aug 24 21:30:46 2013 +0200| [be8b796f559cece8a0312749e470d47b1653fa23] | committer: Luca Barbato

vcr1: add sanity checks

Fixes invalid reads with corrupted files.

Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable at libav.org
(cherry picked from commit 8aba7968dd604aae91ee42cbce0be3dad7dceb30)
Signed-off-by: Luca Barbato <lu_zero at gentoo.org>

Conflicts:
	libavcodec/vcr1.c

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=be8b796f559cece8a0312749e470d47b1653fa23
---

 libavcodec/vcr1.c |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index e50e092..e9fedbd 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -64,9 +64,13 @@ static int decode_frame(AVCodecContext *avctx,
     p->pict_type= AV_PICTURE_TYPE_I;
     p->key_frame= 1;
 
+    if (buf_size < 32)
+        goto packet_small;
+
     for(i=0; i<16; i++){
         a->delta[i]= *(bytestream++);
         bytestream++;
+        buf_size--;
     }
 
     for(y=0; y<avctx->height; y++){
@@ -77,8 +81,12 @@ static int decode_frame(AVCodecContext *avctx,
             uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ];
             uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ];
 
+            if (buf_size < 4 + avctx->width)
+                goto packet_small;
+
             for(i=0; i<4; i++)
                 a->offset[i]= *(bytestream++);
+            buf_size -= 4;
 
             offset= a->offset[0] - a->delta[ bytestream[2]&0xF ];
             for(x=0; x<avctx->width; x+=4){
@@ -92,8 +100,12 @@ static int decode_frame(AVCodecContext *avctx,
                 *(cr++) = bytestream[1];
 
                 bytestream+= 4;
+                buf_size  -= 4;
             }
         }else{
+            if (buf_size < avctx->width / 2)
+                goto packet_small;
+
             offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ];
 
             for(x=0; x<avctx->width; x+=8){
@@ -107,6 +119,7 @@ static int decode_frame(AVCodecContext *avctx,
                 luma[7]=( offset += a->delta[ bytestream[1]>>4  ]);
                 luma += 8;
                 bytestream+= 4;
+                buf_size  -= 4;
             }
         }
     }
@@ -115,6 +128,9 @@ static int decode_frame(AVCodecContext *avctx,
     *data_size = sizeof(AVPicture);
 
     return buf_size;
+packet_small:
+    av_log(avctx, AV_LOG_ERROR, "Input packet too small.\n");
+    return AVERROR_INVALIDDATA;
 }
 
 #if CONFIG_VCR1_ENCODER
@@ -151,6 +167,11 @@ static av_cold int decode_init(AVCodecContext *avctx){
 
     avctx->pix_fmt= PIX_FMT_YUV410P;
 
+    if (avctx->width & 7) {
+        av_log(avctx, AV_LOG_ERROR, "Width %d is not divisble by 8.\n", avctx->width);
+        return AVERROR_INVALIDDATA;
+    }
+
     return 0;
 }
 



More information about the ffmpeg-cvslog mailing list