summaryrefslogtreecommitdiff
path: root/libraries/libglpng/patches/libglpng-1.45-CVE-2010-1519.patch
blob: bc45ffe48ff0fbd192777b55bbc88c5142df200a (plain)
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
diff -up libglpng-1.45.orig/src/glpng.c.cve libglpng-1.45.orig/src/glpng.c
--- libglpng-1.45.orig/src/glpng.c.cve	2010-09-10 14:13:37.105046660 +0200
+++ libglpng-1.45.orig/src/glpng.c	2010-09-10 14:14:46.158045715 +0200
@@ -28,6 +28,7 @@
 #include <GL/glpng.h>
 #include <GL/gl.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <math.h>
 #include <png.h>
 
@@ -259,9 +260,9 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 	png_structp png;
 	png_infop   info;
 	png_infop   endinfo;
-	png_bytep   data;
-   png_bytep  *row_p;
-   double	fileGamma;
+	png_bytep   data = NULL;
+	png_bytep  *row_p = NULL;
+	double      fileGamma;
 
 	png_uint_32 width, height;
 	int depth, color;
@@ -274,13 +275,19 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 	if (!png_check_sig(header, 8)) return 0;
 
 	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+	if (!png) return 0;
 	info = png_create_info_struct(png);
+	if (!info) return 0;
 	endinfo = png_create_info_struct(png);
+	if (!endinfo) return 0;
 
 	// DH: added following lines
 	if (setjmp(png->jmpbuf))
 	{
+error:
 		png_destroy_read_struct(&png, &info, &endinfo);
+		free(data);
+		free(row_p);
 		return 0;
 	}
 	// ~DH
@@ -303,8 +310,16 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 
 	png_read_update_info(png, info);
 
+	/* HDG: We allocate all the png data in one linear array, thus
+	   height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
+	   This check fixes CVE-2010-1519. */
+	if ((uint64_t)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
+		goto error;
+
 	data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
 	row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
+	if (!data || !row_p)
+		goto error;
 
 	for (i = 0; i < height; i++) {
 		if (StandardOrientation)
@@ -315,6 +330,7 @@ int APIENTRY pngLoadRawF(FILE *fp, pngRa
 
 	png_read_image(png, row_p);
 	free(row_p);
+	row_p = NULL;
 
 	if (color == PNG_COLOR_TYPE_PALETTE) {
 		int cols;
@@ -365,9 +381,10 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 	png_structp png;
 	png_infop   info;
 	png_infop   endinfo;
-	png_bytep   data, data2;
-   png_bytep  *row_p;
-   double	fileGamma;
+	png_bytep   data = NULL;
+	png_bytep   data2 = NULL;
+	png_bytep  *row_p = NULL;
+	double      fileGamma;
 
 	png_uint_32 width, height, rw, rh;
 	int depth, color;
@@ -378,13 +395,20 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 	if (!png_check_sig(header, 8)) return 0;
 
 	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+	if (!png) return 0;
 	info = png_create_info_struct(png);
+	if (!info) return 0;
 	endinfo = png_create_info_struct(png);
+	if (!endinfo) return 0;
 
 	// DH: added following lines
 	if (setjmp(png->jmpbuf))
 	{
+error:
 		png_destroy_read_struct(&png, &info, &endinfo);
+		free(data);
+		free(data2);
+		free(row_p);
 		return 0;
 	}
 	// ~DH
@@ -442,8 +466,16 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 
 	png_read_update_info(png, info);
 
+	/* HDG: We allocate all the png data in one linear array, thus
+	   height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
+	   This check fixes CVE-2010-1519. */
+	if ((uint64_t)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
+		goto error;
+
 	data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
 	row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
+	if (!data || !row_p)
+		goto error;
 
 	for (i = 0; i < height; i++) {
 		if (StandardOrientation)
@@ -454,6 +486,7 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 
 	png_read_image(png, row_p);
 	free(row_p);
+	row_p = NULL;
 
 	rw = SafeSize(width), rh = SafeSize(height);
 
@@ -461,6 +494,8 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 		const int channels = png_get_rowbytes(png, info)/width;
 
 		data2 = (png_bytep) malloc(rw*rh*channels);
+		if (!data2)
+			goto error;
 
  		/* Doesn't work on certain sizes */
 /* 		if (gluScaleImage(glformat, width, height, GL_UNSIGNED_BYTE, data, rw, rh, GL_UNSIGNED_BYTE, data2) != 0)
@@ -471,6 +506,7 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 		width = rw, height = rh;
 		free(data);
 		data = data2;
+		data2 = NULL;
 	}
 
 	{ /* OpenGL stuff */
@@ -540,6 +576,12 @@ int APIENTRY pngLoadF(FILE *fp, int mipm
 			png_bytep p, endp, q;
 			int r, g, b, a;
 
+			/* HDG another potential 32 bit address overflow, the
+			   original png had 3 channels and we are going to
+			   4 channels now! */
+			if ((uint64_t)width * height > (PNG_UINT_32_MAX >> 2))
+				goto error;
+
 			p = data, endp = p+width*height*3;
 			q = data2 = (png_bytep) malloc(sizeof(png_byte)*width*height*4);