[FFmpeg-cvslog] dsicinav: Check for overread in RLE decode.

Michael Niedermayer git at videolan.org
Mon Apr 16 17:02:53 CEST 2012


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Mon Apr 16 16:44:12 2012 +0200| [47f0beadba9003391d8bfef59b15aa21a5b2d293] | committer: Michael Niedermayer

dsicinav: Check for overread in RLE decode.

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=47f0beadba9003391d8bfef59b15aa21a5b2d293
---

 libavcodec/dsicinav.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index 6d18f9a..cd36564 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -179,24 +179,29 @@ static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char
     return 0;
 }
 
-static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
+static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
 {
     int len, code;
     unsigned char *dst_end = dst + dst_size;
     const unsigned char *src_end = src + src_size;
 
-    while (src < src_end && dst < dst_end) {
+    while (src + 1 < src_end && dst < dst_end) {
         code = *src++;
         if (code & 0x80) {
             len = code - 0x7F;
             memset(dst, *src++, FFMIN(len, dst_end - dst));
         } else {
             len = code + 1;
+            if (len > src_end-src) {
+                av_log(0, AV_LOG_ERROR, "RLE overread\n");
+                return AVERROR_INVALIDDATA;
+            }
             memcpy(dst, src, FFMIN(len, dst_end - dst));
             src += len;
         }
         dst += len;
     }
+    return 0;
 }
 
 static int cinvideo_decode_frame(AVCodecContext *avctx,



More information about the ffmpeg-cvslog mailing list