[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