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);
|