c35cbad554
Mono libgdiplus Image Processing Integer Overflow Vulnerabilities
74 lines
2.5 KiB
Plaintext
74 lines
2.5 KiB
Plaintext
$OpenBSD: patch-src_jpegcodec_c,v 1.1 2010/08/24 09:49:35 jasper Exp $
|
|
|
|
Security fix for SA40792/CVE-2010-1526:
|
|
Mono libgdiplus Image Processing Integer Overflow Vulnerabilities
|
|
|
|
Patch from upstream git:
|
|
http://github.com/mono/libgdiplus/commit/6779fbf994d5270720ccb1687ba8b004e20a1821
|
|
|
|
--- src/jpegcodec.c.orig Tue Aug 24 11:41:53 2010
|
|
+++ src/jpegcodec.c Tue Aug 24 11:45:59 2010
|
|
@@ -282,6 +282,7 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr
|
|
BYTE *lines[4] = {NULL, NULL, NULL, NULL};
|
|
GpStatus status;
|
|
int stride;
|
|
+ unsigned long long int size;
|
|
|
|
destbuf = NULL;
|
|
result = NULL;
|
|
@@ -323,20 +324,21 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr
|
|
|
|
if (cinfo.num_components == 1) {
|
|
result->cairo_format = CAIRO_FORMAT_A8;
|
|
- result->active_bitmap->stride = cinfo.image_width;
|
|
result->active_bitmap->pixel_format = PixelFormat8bppIndexed;
|
|
+ size = 1;
|
|
} else if (cinfo.num_components == 3) {
|
|
/* libjpeg gives us RGB for many formats and
|
|
* we convert to RGB format when needed. JPEG
|
|
* does not support alpha (transparency). */
|
|
result->cairo_format = CAIRO_FORMAT_ARGB32;
|
|
- result->active_bitmap->stride = 4 * cinfo.image_width;
|
|
result->active_bitmap->pixel_format = PixelFormat24bppRGB;
|
|
+ size = 4;
|
|
} else if (cinfo.num_components == 4) {
|
|
result->cairo_format = CAIRO_FORMAT_ARGB32;
|
|
- result->active_bitmap->stride = 4 * cinfo.image_width;
|
|
result->active_bitmap->pixel_format = PixelFormat32bppRGB;
|
|
- }
|
|
+ size = 4;
|
|
+ } else
|
|
+ goto error;
|
|
|
|
switch (cinfo.jpeg_color_space) {
|
|
case JCS_GRAYSCALE:
|
|
@@ -360,7 +362,12 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr
|
|
break;
|
|
}
|
|
|
|
- stride = result->active_bitmap->stride;
|
|
+ size *= cinfo.image_width;
|
|
+ /* stride is a (signed) _int_ and once multiplied by 4 it should hold a value that can be allocated by GdipAlloc
|
|
+ * this effectively limits 'width' to 536870911 pixels */
|
|
+ if (size > G_MAXINT32)
|
|
+ goto error;
|
|
+ stride = result->active_bitmap->stride = size;
|
|
|
|
/* Request cairo-compat output */
|
|
/* libjpeg can do only following conversions,
|
|
@@ -397,7 +404,13 @@ gdip_load_jpeg_image_internal (struct jpeg_source_mgr
|
|
|
|
jpeg_start_decompress (&cinfo);
|
|
|
|
- destbuf = GdipAlloc (stride * cinfo.output_height);
|
|
+ /* ensure total 'size' does not overflow an integer and fits inside our 2GB limit */
|
|
+ size *= cinfo.output_height;
|
|
+ if (size > G_MAXINT32) {
|
|
+ status = OutOfMemory;
|
|
+ goto error;
|
|
+ }
|
|
+ destbuf = GdipAlloc (size);
|
|
if (destbuf == NULL) {
|
|
status = OutOfMemory;
|
|
goto error;
|