[FFmpeg-cvslog] avcodec/flashsv: check decode_hybrid() for overread

Michael Niedermayer git at videolan.org
Thu Dec 19 16:49:22 CET 2013


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Thu Dec 19 16:17:21 2013 +0100| [a33c7dd21362a694692d0dc30fdbffae5a5d837e] | committer: Michael Niedermayer

avcodec/flashsv: check decode_hybrid() for overread

Fixes use of uninitialized memory
Fixes: msan_uninit-mem_7f906558274e_268_14_244486_2009_04_28.flv
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

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

 libavcodec/flashsv.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 981d774..8791a2d 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -69,7 +69,7 @@ typedef struct FlashSVContext {
     int             diff_start, diff_height;
 } FlashSVContext;
 
-static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
+static int decode_hybrid(const uint8_t *sptr, const uint8_t *sptr_end, uint8_t *dptr, int dx, int dy,
                          int h, int w, int stride, const uint32_t *pal)
 {
     int x, y;
@@ -78,6 +78,8 @@ static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
     for (y = dx + h; y > dx; y--) {
         uint8_t *dst = dptr + (y * stride) + dy * 3;
         for (x = 0; x < w; x++) {
+            if (sptr >= sptr_end)
+                return AVERROR_INVALIDDATA;
             if (*sptr & 0x80) {
                 /* 15-bit color */
                 unsigned c = AV_RB16(sptr) & ~0x8000;
@@ -232,10 +234,15 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
         }
     } else {
         /* hybrid 15-bit/palette mode */
-        decode_hybrid(s->tmpblock, s->frame->data[0],
+        ret = decode_hybrid(s->tmpblock, s->zstream.next_out,
+                      s->frame->data[0],
                       s->image_height - (y_pos + 1 + s->diff_height),
                       x_pos, s->diff_height, width,
                       s->frame->linesize[0], s->pal);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "decode_hybrid failed\n");
+            return ret;
+        }
     }
     skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
     return 0;



More information about the ffmpeg-cvslog mailing list