diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-03-04 08:14:07 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-03-04 08:14:07 +0100 |
commit | 37fca5daa0bed1fdb651dfc1c38a3b47f79c58a5 (patch) | |
tree | 8e244b55bf59d93cca39b1b58fa1eb21dba073d5 | |
parent | 999d38f3a94eb963c073512e5dad7940456eb634 (diff) | |
download | ffmpeg-37fca5daa0bed1fdb651dfc1c38a3b47f79c58a5.tar.gz |
mmvideo: fix overreads of the input buffer.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/mmvideo.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index ff7d100792..5afe5eb648 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -123,11 +123,18 @@ static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const */ static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) { - const int data_ptr = 2 + AV_RL16(&buf[0]); + int data_ptr; int d, r, y; + + if(buf_size < 2) { + av_log(s->avctx, AV_LOG_ERROR, "1 or less byte inter frame\n"); + return; + } + + data_ptr = 2 + AV_RL16(&buf[0]); d = data_ptr; r = 2; y = 0; - while(r < data_ptr) { + while(r + 1 < data_ptr) { int i, j; int length = buf[r] & 0x7f; int x = buf[r+1] + ((buf[r] & 0x80) << 1); @@ -138,14 +145,19 @@ static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const continue; } - if (y + half_vert >= s->avctx->height) + if (y + half_vert >= s->avctx->height || r+length > buf_size) return; for(i=0; i<length; i++) { for(j=0; j<8; j++) { int replace = (buf[r+i] >> (7-j)) & 1; if (replace) { - int color = buf[d]; + int color; + if (d >= buf_size) { + av_log(s->avctx, AV_LOG_ERROR, "overread buf\n"); + return; + } + color = buf[d]; s->frame.data[0][y*s->frame.linesize[0] + x] = color; if (half_horiz) s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color; |