Package: gdk-pixbuf / 2.31.1-2+deb8u7

CVE-2017-1000422.patch Patch series | download
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
--- a/gdk-pixbuf/io-gif.c
+++ b/gdk-pixbuf/io-gif.c
@@ -817,6 +817,35 @@
                                          context->user_data);
 }
 
+/* Available in glib since 2.48 */
+static inline gboolean _g_uint64_checked_mul (guint64 *dest, guint64 a, guint64 b) {
+  *dest = a * b; return !a || *dest / a == b; }
+
+/* Available in gdk-pixbuf 2.36.8 */
+static gint
+_gdk_pixbuf_calculate_rowstride (GdkColorspace colorspace,
+				gboolean      has_alpha,
+				int           bits_per_sample,
+				int           width,
+				int           height)
+{
+	unsigned int channels;
+
+	g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, -1);
+	g_return_val_if_fail (bits_per_sample == 8, -1);
+	g_return_val_if_fail (width > 0, -1);
+	g_return_val_if_fail (height > 0, -1);
+
+	channels = has_alpha ? 4 : 3;
+
+	/* Overflow? */
+	if (width > (G_MAXINT - 3) / channels)
+		return -1;
+
+	/* Always align rows to 32-bit boundaries */
+	return (width * channels + 3) & ~3;
+}
+
 static int
 gif_get_lzw (GifContext *context)
 {
@@ -850,13 +879,29 @@
                                 pixels[2] = 0;
                                 pixels[3] = 0;
                         }
-                } else
-                        context->frame->pixbuf =
-                                gdk_pixbuf_new (GDK_COLORSPACE_RGB,
-                                                TRUE,
-                                                8,
-                                                context->frame_len,
-                                                context->frame_height);
+                } else {
+                        int rowstride;
+                        guint64 len;
+
+                        rowstride = _gdk_pixbuf_calculate_rowstride (GDK_COLORSPACE_RGB,
+                                                                    TRUE,
+                                                                    8,
+                                                                    context->frame_len,
+                                                                    context->frame_height);
+                        if (rowstride > 0 &&
+                            _g_uint64_checked_mul (&len, rowstride, context->frame_height) &&
+                            len <= G_MAXINT) {
+                                context->frame->pixbuf =
+                                        gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+                                                        TRUE,
+                                                        8,
+                                                        context->frame_len,
+                                                        context->frame_height);
+                        } else {
+                                context->frame->pixbuf = NULL;
+                        }
+                }
+
                 if (!context->frame->pixbuf) {
                         g_free (context->frame);
                         g_set_error_literal (context->error,