summaryrefslogtreecommitdiffstats
path: root/patches/source/gegl/gegl-0.2.0-CVE-2012-4433.patch
blob: 965c6fc201a93665b97f7873f22740372be5640f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
From ffa77a246652c7e706d690682fe659f50fbe5656 Mon Sep 17 00:00:00 2001
From: Nils Philippsen <nils@redhat.com>
Date: Mon, 1 Jul 2013 12:03:51 +0200
Subject: [PATCH] patch: CVE-2012-4433

Squashed commit of the following:

commit 2a9071e2dc4cfe1aaa7a726805985281936f9874
Author: Nils Philippsen <nils@redhat.com>
Date:   Tue Oct 16 16:57:37 2012 +0200

    ppm-load: bring comment in line with reality

    (cherry picked from commit 6975a9cfeaf0698b42ac81b1c2f00d13c8755453)

commit 8bb88ebf78e54837322d3be74688f98800e9f33a
Author: Nils Philippsen <nils@redhat.com>
Date:   Tue Oct 16 16:56:40 2012 +0200

    ppm-load: CVE-2012-4433: add plausibility checks for header fields

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

    (cherry picked from commit 4757cdf73d3675478d645a3ec8250ba02168a230)

commit 2b099886969bf055a8635d06a4d89f20fed1ee42
Author: Nils Philippsen <nils@redhat.com>
Date:   Tue Oct 16 16:58:27 2012 +0200

    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.

    (cherry picked from commit 1e92e5235ded0415d555aa86066b8e4041ee5a53)
---
 operations/external/ppm-load.c | 64 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 54 insertions(+), 10 deletions(-)

diff --git a/operations/external/ppm-load.c b/operations/external/ppm-load.c
index efe6d56..e22521c 100644
--- a/operations/external/ppm-load.c
+++ b/operations/external/ppm-load.c
@@ -36,6 +36,7 @@ gegl_chant_file_path (path, _("File"), "", _("Path of file to load."))
 #include "gegl-chant.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 
 typedef enum {
   PIXMAP_ASCII  = 51,
@@ -44,8 +45,8 @@ typedef enum {
 
 typedef struct {
 	map_type   type;
-	gint       width;
-	gint       height;
+	glong      width;
+	glong      height;
         gsize      numsamples; /* width * height * channels */
         gsize      bpc;        /* bytes per channel */
 	guchar    *data;
@@ -61,7 +62,7 @@ ppm_load_read_header(FILE       *fp,
     gchar  header[MAX_CHARS_IN_ROW];
     gint   maxval;
 
-    /* Check the PPM file Type P2 or P5 */
+    /* Check the PPM file Type P3 or P6 */
     fgets (header,MAX_CHARS_IN_ROW,fp);
 
     if (header[0] != ASCII_P ||
@@ -82,12 +83,33 @@ ppm_load_read_header(FILE       *fp,
       }
 
     /* Get Width and Height */
-    img->width  = strtol (header,&ptr,0);
-    img->height = atoi (ptr);
-    img->numsamples = img->width * img->height * CHANNEL_COUNT;
+    errno = 0;
+    img->width  = strtol (header,&ptr,10);
+    if (errno)
+      {
+        g_warning ("Error reading width: %s", strerror(errno));
+        return FALSE;
+      }
+    else if (img->width < 0)
+      {
+        g_warning ("Error: width is negative");
+        return FALSE;
+      }
+
+    img->height = strtol (ptr,&ptr,10);
+    if (errno)
+      {
+        g_warning ("Error reading height: %s", strerror(errno));
+        return FALSE;
+      }
+    else if (img->width < 0)
+      {
+        g_warning ("Error: height is negative");
+        return FALSE;
+      }
 
     fgets (header,MAX_CHARS_IN_ROW,fp);
-    maxval = strtol (header,&ptr,0);
+    maxval = strtol (header,&ptr,10);
 
     if ((maxval != 255) && (maxval != 65535))
       {
@@ -109,6 +131,16 @@ ppm_load_read_header(FILE       *fp,
       g_warning ("%s: Programmer stupidity error", G_STRLOC);
     }
 
+    /* Later on, img->numsamples is multiplied with img->bpc to allocate
+     * memory. Ensure it doesn't overflow. */
+    if (!img->width || !img->height ||
+        G_MAXSIZE / img->width / img->height / CHANNEL_COUNT < img->bpc)
+      {
+        g_warning ("Illegal width/height: %ld/%ld", img->width, img->height);
+        return FALSE;
+      }
+    img->numsamples = img->width * img->height * CHANNEL_COUNT;
+
     return TRUE;
 }
 
@@ -229,12 +261,24 @@ process (GeglOperation       *operation,
   if (!ppm_load_read_header (fp, &img))
     goto out;
 
-  rect.height = img.height;
-  rect.width = img.width;
-
   /* 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_malloc (img.numsamples * img.bpc);
 
+  /* No-op without g_try_malloc(), see above. */
+  if (! img.data)
+    {
+      g_warning ("Couldn't allocate %" G_GSIZE_FORMAT " bytes, giving up.", ((gsize)img.numsamples * img.bpc));
+      goto out;
+    }
+
+  rect.height = img.height;
+  rect.width = img.width;
+
   switch (img.bpc)
     {
     case 1:
-- 
1.8.3.1