File gegl-ppm-segfault.patch of Package gegl

From 021add95ac3bcd7f60932c63c7c1ed5cec765c4d Mon Sep 17 00:00:00 2001
From: Nils Philippsen <nils@redhat.com>
Date: Tue, 16 Oct 2012 16:58:27 +0200
Subject: [PATCH 1/3] ppm-load: CVE-2012-4433: don't overflow memory
 allocation

Carefully selected width/height values could cause the size of a later
allocation to overflow, resulting in a buffer much too small to store
the data which would then written beyond its end.

From 147388a43d1a67000a409163098abec30a4194c0 Mon Sep 17 00:00:00 2001
From: Nils Philippsen <nils@redhat.com>
Date: Tue, 16 Oct 2012 16:56:40 +0200
Subject: [PATCH 2/3] ppm-load: CVE-2012-4433: add plausibility checks for
 header fields

Refuse values that are non-decimal, negative or overflow the target
type.

From 7085d5362b131726bdd8fa3e5bf30217849046e7 Mon Sep 17 00:00:00 2001
From: Nils Philippsen <nils@redhat.com>
Date: Tue, 16 Oct 2012 16:57:37 +0200
Subject: [PATCH 3/3] ppm-load: bring comment in line with reality

Index: gegl-0.1.2/operations/external/ppm-load.c
===================================================================
--- gegl-0.1.2.orig/operations/external/ppm-load.c
+++ gegl-0.1.2/operations/external/ppm-load.c
@@ -36,6 +36,7 @@ gegl_chant_file_path (path, _("File"), "
 #include "gegl-chant.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 
 typedef enum {
   PIXMAP_ASCII  = 51,
@@ -44,9 +45,9 @@ typedef enum {
 
 typedef struct {
 	map_type   type;
-	gint       width;
-	gint       height;
-        gint       size;
+	glong      width;
+	glong      height;
+        glong      size;
 	gint       maxval;
 	guchar    *data;
 } pnm_struct;
@@ -67,7 +68,10 @@ ppm_load_read_header(FILE       *fp,
     gchar *retval;
     gchar  header[MAX_CHARS_IN_ROW];
 
-    /* Check the PPM file Type P2 or P5 */
+    /* Maxval is not used, but value 0 indicates header error. */
+    img->maxval = 0;
+
+    /* Check the PPM file Type P2 or P6 */
     retval = fgets (header,MAX_CHARS_IN_ROW,fp);
 
     if (header[0] != ASCII_P ||
@@ -87,14 +91,45 @@ ppm_load_read_header(FILE       *fp,
       }
 
     /* Get Width and Height */
-    img->width  = strtol (header,&ptr,0);
-    img->height = atoi (ptr);
+    errno = 0;
+    img->width  = strtol (header,&ptr,10);
+    if (errno)
+      {
+        g_warning ("Error reading width: %s", strerror(errno));
+        return;
+      }
+    else if (img->width < 0)
+      {
+        g_warning ("Error: width is negative");
+        return;
+      }
+
+    img->height = strtol (ptr,&ptr,10);
+    if (errno)
+      {
+        g_warning ("Error reading height: %s", strerror(errno));
+        return;
+      }
+    else if (img->width < 0)
+      {
+        g_warning ("Error: height is negative");
+        return;
+      }
 
     img->size = img->width * img->height * sizeof (guchar) * CHANNEL_COUNT;
 
+    /* Ensure it doesn't overflow. */
+    if (!img->width || !img->height ||
+        G_MAXSIZE / img->width / img->height / CHANNEL_COUNT < 1)
+      {
+        g_warning ("Illegal width/height: %ld/%ld", img->width, img->height);
+        return;
+      }
+
     retval = fgets (header,100,fp);
+
     /* Maxval is not used */
-    img->maxval = (int) strtol (header,&ptr,0);
+    img->maxval = (int) strtol (header,&ptr,10);
   }
 
 void
@@ -166,12 +201,30 @@ process (GeglOperation       *operation,
     }
 
   ppm_load_read_header (fp, &img);
-  rect.height = img.height;
-  rect.width = img.width;
+  if (img.maxval == 0)
+    return FALSE;
+
+   /* Allocating Array Size */
 
-  /* Allocating Array Size */
+  /* Should use g_try_malloc(), but this causes crashes elsewhere because the
+   * error signalled by returning FALSE isn't properly acted upon. Therefore
+   * g_malloc() is used here which aborts if the requested memory size can't be
+   * allocated causing a controlled crash. */
   img.data = (guchar*) g_malloc0 (img.size);
 
+  /* No-op without g_try_malloc(), see above. */
+  if (! img.data)
+    {
+      g_warning ("Couldn't allocate %" G_GSIZE_FORMAT " bytes, giving up.", ((gsize)img.size));
+      /* goto out; */
+      if (stdin != fp)
+	fclose (fp);
+      return FALSE;
+    }
+
+  rect.height = img.height;
+  rect.width = img.width;
+
   gegl_buffer_get (output, 1.0, &rect, babl_format ("R'G'B' u8"), img.data,
           GEGL_AUTO_ROWSTRIDE);
 
openSUSE Build Service is sponsored by