[FFmpeg-cvslog] Additional checks to prevent overread.

Vitaliy E Sugrobov git at videolan.org
Fri Nov 30 15:59:47 CET 2012


ffmpeg | branch: master | Vitaliy E Sugrobov <vsugrob at hotmail.com> | Fri Nov 30 12:58:54 2012 +0400| [de0cb7f070dc941ea2d3f8a99dad497c852b4e35] | committer: Paul B Mahol

Additional checks to prevent overread.

Check for availability of some required amount of bytes in buffer before
reading further.

Signed-off-by: Vitaliy E Sugrobov <vsugrob at hotmail.com>

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

 libavcodec/gifdec.c |   24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 887a253..2213733 100755
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -146,6 +146,10 @@ static int gif_read_image(GifState *s)
     int ret;
     uint8_t *idx;
 
+    /* At least 9 bytes of Image Descriptor. */
+    if (s->bytestream_end < s->bytestream + 9)
+        return AVERROR_INVALIDDATA;
+
     left = bytestream_get_le16(&s->bytestream);
     top = bytestream_get_le16(&s->bytestream);
     width = bytestream_get_le16(&s->bytestream);
@@ -222,6 +226,10 @@ static int gif_read_image(GifState *s)
         }
     }
 
+    /* Expect at least 2 bytes: 1 for lzw code size and 1 for block size. */
+    if (s->bytestream_end < s->bytestream + 2)
+        return AVERROR_INVALIDDATA;
+
     /* now get the image data */
     code_size = bytestream_get_byte(&s->bytestream);
     if ((ret = ff_lzw_decode_init(s->lzw, code_size, s->bytestream,
@@ -296,7 +304,11 @@ static int gif_read_extension(GifState *s)
 {
     int ext_code, ext_len, i, gce_flags, gce_transparent_index;
 
-    /* extension */
+    /* There must be at least 2 bytes:
+     * 1 for extension label and 1 for extension length. */
+    if (s->bytestream_end < s->bytestream + 2)
+        return AVERROR_INVALIDDATA;
+
     ext_code = bytestream_get_byte(&s->bytestream);
     ext_len = bytestream_get_byte(&s->bytestream);
 
@@ -306,6 +318,12 @@ static int gif_read_extension(GifState *s)
     case GIF_GCE_EXT_LABEL:
         if (ext_len != 4)
             goto discard_ext;
+
+        /* We need at least 5 bytes more: 4 is for extension body
+         * and 1 for next block size. */
+        if (s->bytestream_end < s->bytestream + 5)
+            return AVERROR_INVALIDDATA;
+
         s->transparent_color_index = -1;
         gce_flags = bytestream_get_byte(&s->bytestream);
         bytestream_get_le16(&s->bytestream);    // delay during which the frame is shown
@@ -332,6 +350,10 @@ static int gif_read_extension(GifState *s)
     /* NOTE: many extension blocks can come after */
  discard_ext:
     while (ext_len != 0) {
+        /* There must be at least ext_len bytes and 1 for next block size byte. */
+        if (s->bytestream_end < s->bytestream + ext_len + 1)
+            return AVERROR_INVALIDDATA;
+
         for (i = 0; i < ext_len; i++)
             bytestream_get_byte(&s->bytestream);
         ext_len = bytestream_get_byte(&s->bytestream);



More information about the ffmpeg-cvslog mailing list