[gdk-pixbuf] pixdata: Avoid copying more data than available



commit 73ce5960de256b03a3a06a9ca679add5a1b7f790
Author: Bastien Nocera <hadess hadess net>
Date:   Fri Dec 16 14:15:42 2016 +0100

    pixdata: Avoid copying more data than available
    
    The problem we were encountering in bug 775693 wasn't that we were
    running past the end of the memory we just allocated, but that the
    length of the data we were given couldn't possibly match the dimensions
    of the image.
    
    This fixes running past the end of the given pixdata when the length is
    provided inside the structure.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=775693

 gdk-pixbuf/gdk-pixdata.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)
---
diff --git a/gdk-pixbuf/gdk-pixdata.c b/gdk-pixbuf/gdk-pixdata.c
index b026f7d..b73e5a4 100644
--- a/gdk-pixbuf/gdk-pixdata.c
+++ b/gdk-pixbuf/gdk-pixdata.c
@@ -409,6 +409,9 @@ gdk_pixdata_from_pixbuf (GdkPixdata      *pixdata,
   return free_me;
 }
 
+/* From glib's gmem.c */
+#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b)))
+
 /**
  * gdk_pixbuf_from_pixdata:
  * @pixdata: a #GdkPixdata to convert into a #GdkPixbuf.
@@ -453,6 +456,26 @@ gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata,
 
   if (encoding == GDK_PIXDATA_ENCODING_RLE)
     copy_pixels = TRUE;
+
+  /* Sanity check the length and dimensions */
+  if (SIZE_OVERFLOWS (pixdata->height, pixdata->rowstride))
+    {
+      g_set_error_literal (error, GDK_PIXBUF_ERROR,
+                           GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                           _("Image pixel data corrupt"));
+      return NULL;
+    }
+
+  if (encoding == GDK_PIXDATA_ENCODING_RAW &&
+      pixdata->length >= 1 &&
+      pixdata->length < pixdata->height * pixdata->rowstride - GDK_PIXDATA_HEADER_LENGTH)
+    {
+      g_set_error_literal (error, GDK_PIXBUF_ERROR,
+                           GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                           _("Image pixel data corrupt"));
+      return NULL;
+    }
+
   if (copy_pixels)
     {
       data = g_try_malloc_n (pixdata->height, pixdata->rowstride);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]