Gentoo Archives: gentoo-commits

From: "Pacho Ramos (pacho)" <pacho@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in dev-dotnet/libgdiplus/files: libgdiplus-2.6.7-fix-overflows.patch
Date: Tue, 07 Sep 2010 21:57:06
Message-Id: 20100907215703.5D7C220051@flycatcher.gentoo.org
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