1 |
pacho 10/09/07 21:57:03 |
2 |
|
3 |
Added: libgdiplus-2.6.7-fix-overflows.patch |
4 |
Log: |
5 |
Fix Multiple Integer Overflow Vulnerabilities (CVE-2010-1526) (bug #334101) applying upstream patch also used in Fedora. |
6 |
(Portage version: 2.1.8.3/cvs/Linux x86_64) |
7 |
|
8 |
Revision Changes Path |
9 |
1.1 dev-dotnet/libgdiplus/files/libgdiplus-2.6.7-fix-overflows.patch |
10 |
|
11 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-dotnet/libgdiplus/files/libgdiplus-2.6.7-fix-overflows.patch?rev=1.1&view=markup |
12 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-dotnet/libgdiplus/files/libgdiplus-2.6.7-fix-overflows.patch?rev=1.1&content-type=text/plain |
13 |
|
14 |
Index: libgdiplus-2.6.7-fix-overflows.patch |
15 |
=================================================================== |
16 |
From 6779fbf994d5270720ccb1687ba8b004e20a1821 Mon Sep 17 00:00:00 2001 |
17 |
From: Sebastien Pouliot <sebastien@××××××.com> |
18 |
Date: Mon, 16 Aug 2010 16:48:02 -0400 |
19 |
Subject: [PATCH] Fix integer overflows when loading images, see bnc #630756 |
20 |
|
21 |
* src/bmpcodec.c: |
22 |
* src/jpgcodec.c: |
23 |
* src/tifcodec.c: |
24 |
Ensure no integer overflow can occur when computing the |
25 |
stride or the total pixel size (in bytes) used to load |
26 |
pictures in memory. Fix bug #630756 |
27 |
--- |
28 |
src/bmpcodec.c | 32 +++++++++++++++++++++++--------- |
29 |
src/jpegcodec.c | 25 +++++++++++++++++++------ |
30 |
src/tiffcodec.c | 23 ++++++++++++++++++----- |
31 |
3 files changed, 60 insertions(+), 20 deletions(-) |
32 |
|
33 |
diff --git a/src/bmpcodec.c b/src/bmpcodec.c |
34 |
index 7f02561..5547262 100644 |
35 |
--- a/src/bmpcodec.c |
36 |
+++ b/src/bmpcodec.c |
37 |
@@ -781,7 +781,6 @@ gdip_read_bmp_image (void *pointer, GpImage **image, ImageSource source) |
38 |
int colours; |
39 |
BOOL os2format = FALSE; |
40 |
BOOL upsidedown = TRUE; |
41 |
- int size; |
42 |
int size_read; |
43 |
BYTE *data_read = NULL; |
44 |
int line; |
45 |
@@ -793,6 +792,7 @@ gdip_read_bmp_image (void *pointer, GpImage **image, ImageSource source) |
46 |
ARGB green_mask = 0; |
47 |
ARGB blue_mask = 0; |
48 |
int red_shift = 0; |
49 |
+ unsigned long long int size; |
50 |
|
51 |
status = gdip_read_BITMAPINFOHEADER (pointer, &bmi, source, &os2format, &upsidedown); |
52 |
if (status != Ok) |
53 |
@@ -860,23 +860,30 @@ gdip_read_bmp_image (void *pointer, GpImage **image, ImageSource source) |
54 |
result->active_bitmap->width = bmi.biWidth; |
55 |
result->active_bitmap->height = bmi.biHeight; |
56 |
|
57 |
+ /* biWidth and biHeight are LONG (32 bits signed integer) */ |
58 |
+ size = bmi.biWidth; |
59 |
+ |
60 |
switch (result->active_bitmap->pixel_format) { |
61 |
case PixelFormat1bppIndexed: |
62 |
- result->active_bitmap->stride = (result->active_bitmap->width + 7) / 8; |
63 |
+ result->active_bitmap->stride = (size + 7) / 8; |
64 |
break; |
65 |
case PixelFormat4bppIndexed: |
66 |
- result->active_bitmap->stride = (result->active_bitmap->width + 1) / 2; |
67 |
+ result->active_bitmap->stride = (size + 1) / 2; |
68 |
break; |
69 |
case PixelFormat8bppIndexed: |
70 |
- result->active_bitmap->stride = result->active_bitmap->width; |
71 |
- break; |
72 |
- case PixelFormat24bppRGB: |
73 |
- result->active_bitmap->stride = result->active_bitmap->width * 4; |
74 |
+ result->active_bitmap->stride = size; |
75 |
break; |
76 |
default: |
77 |
/* For other types, we assume 32 bit and translate into 32 bit from source format */ |
78 |
result->active_bitmap->pixel_format = PixelFormat32bppRGB; |
79 |
- result->active_bitmap->stride = result->active_bitmap->width * 4; |
80 |
+ /* fall-thru */ |
81 |
+ case PixelFormat24bppRGB: |
82 |
+ /* stride is a (signed) _int_ and once multiplied by 4 it should hold a value that can be allocated by GdipAlloc |
83 |
+ * this effectively limits 'width' to 536870911 pixels */ |
84 |
+ size *= 4; |
85 |
+ if (size > G_MAXINT32) |
86 |
+ goto error; |
87 |
+ result->active_bitmap->stride = size; |
88 |
break; |
89 |
} |
90 |
|
91 |
@@ -922,7 +929,14 @@ gdip_read_bmp_image (void *pointer, GpImage **image, ImageSource source) |
92 |
data_read = NULL; |
93 |
} |
94 |
|
95 |
- pixels = GdipAlloc (result->active_bitmap->stride * result->active_bitmap->height); |
96 |
+ size = result->active_bitmap->stride; |
97 |
+ /* ensure total 'size' does not overflow an integer and fits inside our 2GB limit */ |
98 |
+ size *= result->active_bitmap->height; |
99 |
+ if (size > G_MAXINT32) { |
100 |
+ status = OutOfMemory; |
101 |
+ goto error; |
102 |
+ } |
103 |
+ pixels = GdipAlloc (size); |
104 |
if (pixels == NULL) { |
105 |
status = OutOfMemory; |
106 |
goto error; |
107 |
diff --git a/src/jpegcodec.c b/src/jpegcodec.c |
108 |
index 55df776..e330efb 100644 |
109 |
--- a/src/jpegcodec.c |
110 |
+++ b/src/jpegcodec.c |
111 |
@@ -282,6 +282,7 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr *src, GpImage **image) |
112 |
BYTE *lines[4] = {NULL, NULL, NULL, NULL}; |
113 |
GpStatus status; |
114 |
int stride; |
115 |
+ unsigned long long int size; |
116 |
|
117 |
destbuf = NULL; |
118 |
result = NULL; |
119 |
@@ -323,20 +324,21 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr *src, GpImage **image) |
120 |
|
121 |
if (cinfo.num_components == 1) { |
122 |
result->cairo_format = CAIRO_FORMAT_A8; |
123 |
- result->active_bitmap->stride = cinfo.image_width; |
124 |
result->active_bitmap->pixel_format = PixelFormat8bppIndexed; |
125 |
+ size = 1; |
126 |
} else if (cinfo.num_components == 3) { |
127 |
/* libjpeg gives us RGB for many formats and |
128 |
* we convert to RGB format when needed. JPEG |
129 |
* does not support alpha (transparency). */ |
130 |
result->cairo_format = CAIRO_FORMAT_ARGB32; |
131 |
- result->active_bitmap->stride = 4 * cinfo.image_width; |
132 |
result->active_bitmap->pixel_format = PixelFormat24bppRGB; |
133 |
+ size = 4; |
134 |
} else if (cinfo.num_components == 4) { |
135 |
result->cairo_format = CAIRO_FORMAT_ARGB32; |
136 |
- result->active_bitmap->stride = 4 * cinfo.image_width; |
137 |
result->active_bitmap->pixel_format = PixelFormat32bppRGB; |
138 |
- } |
139 |
+ size = 4; |
140 |
+ } else |
141 |
+ goto error; |
142 |
|
143 |
switch (cinfo.jpeg_color_space) { |
144 |
case JCS_GRAYSCALE: |
145 |
@@ -360,7 +362,12 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr *src, GpImage **image) |
146 |
break; |
147 |
} |
148 |
|
149 |
- stride = result->active_bitmap->stride; |
150 |
+ size *= cinfo.image_width; |
151 |
+ /* stride is a (signed) _int_ and once multiplied by 4 it should hold a value that can be allocated by GdipAlloc |
152 |
+ * this effectively limits 'width' to 536870911 pixels */ |
153 |
+ if (size > G_MAXINT32) |
154 |
+ goto error; |
155 |
+ stride = result->active_bitmap->stride = size; |
156 |
|
157 |
/* Request cairo-compat output */ |
158 |
/* libjpeg can do only following conversions, |
159 |
@@ -397,7 +404,13 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr *src, GpImage **image) |
160 |
|
161 |
jpeg_start_decompress (&cinfo); |
162 |
|
163 |
- destbuf = GdipAlloc (stride * cinfo.output_height); |
164 |
+ /* ensure total 'size' does not overflow an integer and fits inside our 2GB limit */ |
165 |
+ size *= cinfo.output_height; |
166 |
+ if (size > G_MAXINT32) { |
167 |
+ status = OutOfMemory; |
168 |
+ goto error; |
169 |
+ } |
170 |
+ destbuf = GdipAlloc (size); |
171 |
if (destbuf == NULL) { |
172 |
status = OutOfMemory; |
173 |
goto error; |
174 |
diff --git a/src/tiffcodec.c b/src/tiffcodec.c |
175 |
index 9e9504f..cf4cf3b 100644 |
176 |
--- a/src/tiffcodec.c |
177 |
+++ b/src/tiffcodec.c |
178 |
@@ -1104,6 +1104,8 @@ gdip_load_tiff_image (TIFF *tiff, GpImage **image) |
179 |
frame = gdip_frame_add(result, &gdip_image_frameDimension_page_guid); |
180 |
|
181 |
for (page = 0; page < num_of_pages; page++) { |
182 |
+ unsigned long long int size; |
183 |
+ |
184 |
bitmap_data = gdip_frame_add_bitmapdata(frame); |
185 |
if (bitmap_data == NULL) { |
186 |
goto error; |
187 |
@@ -1139,14 +1141,25 @@ gdip_load_tiff_image (TIFF *tiff, GpImage **image) |
188 |
bitmap_data->image_flags |= ImageFlagsHasRealDPI; |
189 |
} |
190 |
|
191 |
- bitmap_data->stride = tiff_image.width * 4; |
192 |
+ /* width and height are uint32, but TIFF uses 32 bits offsets (so it's real size limit is 4GB), |
193 |
+ * however libtiff uses signed int (int32 not uint32) as offsets so we limit ourselves to 2GB */ |
194 |
+ size = tiff_image.width; |
195 |
+ /* stride is a (signed) _int_ and once multiplied by 4 it should hold a value that can be allocated by GdipAlloc |
196 |
+ * this effectively limits 'width' to 536870911 pixels */ |
197 |
+ size *= sizeof (guint32); |
198 |
+ if (size > G_MAXINT32) |
199 |
+ goto error; |
200 |
+ bitmap_data->stride = size; |
201 |
bitmap_data->width = tiff_image.width; |
202 |
bitmap_data->height = tiff_image.height; |
203 |
bitmap_data->reserved = GBD_OWN_SCAN0; |
204 |
bitmap_data->image_flags |= ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly; |
205 |
|
206 |
- num_of_pixels = tiff_image.width * tiff_image.height; |
207 |
- pixbuf = GdipAlloc(num_of_pixels * sizeof(guint32)); |
208 |
+ /* ensure total 'size' does not overflow an integer and fits inside our 2GB limit */ |
209 |
+ size *= tiff_image.height; |
210 |
+ if (size > G_MAXINT32) |
211 |
+ goto error; |
212 |
+ pixbuf = GdipAlloc (size); |
213 |
if (pixbuf == NULL) { |
214 |
goto error; |
215 |
} |
216 |
@@ -1168,9 +1181,9 @@ gdip_load_tiff_image (TIFF *tiff, GpImage **image) |
217 |
memcpy(pixbuf + (bitmap_data->stride * (tiff_image.height - i - 1)), pixbuf_row, bitmap_data->stride); |
218 |
} |
219 |
|
220 |
- /* Now flip from ARGB to ABGR */ |
221 |
+ /* Now flip from ARGB to ABGR processing one pixel (4 bytes) at the time */ |
222 |
pixbuf_ptr = (guint32 *)pixbuf; |
223 |
- for (i = 0; i < num_of_pixels; i++) { |
224 |
+ for (i = 0; i < (size >> 2); i++) { |
225 |
*pixbuf_ptr = (*pixbuf_ptr & 0xff000000) | |
226 |
((*pixbuf_ptr & 0x00ff0000) >> 16) | |
227 |
(*pixbuf_ptr & 0x0000ff00) | |
228 |
-- |
229 |
1.7.2.1 |