[gimp] plug-ins: avoid OOB write on malicious GIH files.



commit 13ed12d2b3b191b577a6b35beeadb4cf2d461236
Author: Tobias Stoeckmann <tobias stoeckmann org>
Date:   Sat Apr 8 21:24:43 2017 +0200

    plug-ins: avoid OOB write on malicious GIH files.
    
    Integer overflows allow out of boundary writes while reading GIH files.
    
    The checks are copied from file-gbr.c. In turn, the necessary gsize
    casts are added in file-gbr.c, too. These are important on 64 bit
    systems. Without these casts, the precision of the calculation is still
    32 bit, allowing overflows.
    
    Signed-off-by: Tobias Stoeckmann <tobias stoeckmann org>

 plug-ins/common/file-gbr.c |    4 ++--
 plug-ins/common/file-gih.c |   15 ++++++++++++---
 2 files changed, 14 insertions(+), 5 deletions(-)
---
diff --git a/plug-ins/common/file-gbr.c b/plug-ins/common/file-gbr.c
index 802d646..66df67b 100644
--- a/plug-ins/common/file-gbr.c
+++ b/plug-ins/common/file-gbr.c
@@ -478,7 +478,7 @@ load_image (GFile   *file,
 
   /* Now there's just raw data left. */
 
-  size = bh.width * bh.height * bh.bytes;
+  size = (gsize) bh.width * bh.height * bh.bytes;
   brush_buf = g_malloc (size);
 
   if (! g_input_stream_read_all (input, brush_buf, size,
@@ -528,7 +528,7 @@ load_image (GFile   *file,
                 gint    i;
 
                 bh.bytes = 4;
-                brush_buf = g_malloc (4 * bh.width * bh.height);
+                brush_buf = g_malloc ((gsize) bh.width * bh.height * 4);
 
                 for (i = 0; i < ph.width * ph.height; i++)
                   {
diff --git a/plug-ins/common/file-gih.c b/plug-ins/common/file-gih.c
index b1b120f..f42e645 100644
--- a/plug-ins/common/file-gih.c
+++ b/plug-ins/common/file-gih.c
@@ -454,7 +454,7 @@ gih_load_one_brush (GInputStream  *input,
   BrushHeader    bh;
   guchar        *brush_buf  = NULL;
   gint32         layer_ID;
-  gint           size;
+  gsize          size;
   GimpImageType  image_type;
   gint           width, height;
   gint           new_width, new_height;
@@ -476,6 +476,15 @@ gih_load_one_brush (GInputStream  *input,
   bh.magic_number = g_ntohl (bh.magic_number);
   bh.spacing      = g_ntohl (bh.spacing);
 
+  /* Sanitize values */
+  if ((bh.width  == 0) || (bh.width  > GIMP_MAX_IMAGE_SIZE) ||
+      (bh.height == 0) || (bh.height > GIMP_MAX_IMAGE_SIZE) ||
+      ((bh.bytes != 1) && (bh.bytes != 4)) ||
+      (G_MAXSIZE / bh.width / bh.height / bh.bytes < 1))
+    {
+      return FALSE;
+    }
+
   if ((bh.magic_number != GBRUSH_MAGIC || bh.version != 2) ||
       bh.header_size <= sizeof (bh))
     {
@@ -501,7 +510,7 @@ gih_load_one_brush (GInputStream  *input,
 
   /* Now there's just raw data left. */
 
-  size = bh.width * bh.height * bh.bytes;
+  size = (gsize) bh.width * bh.height * bh.bytes;
   brush_buf = g_malloc (size);
 
   if (! g_input_stream_read_all (input, brush_buf, size,
@@ -548,7 +557,7 @@ gih_load_one_brush (GInputStream  *input,
               gint    i;
 
               bh.bytes = 4;
-              brush_buf = g_malloc (4 * bh.width * bh.height);
+              brush_buf = g_malloc ((gsize) bh.width * bh.height * 4);
 
               for (i = 0; i < ph.width * ph.height; i++)
                 {


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