APPROVE COMMIT 21.5
This patch has been committed. When trying to open very large image
files (or image files with header files that claim the image is very
large), we multiply length times width to get the number of pixels in
the image (and possibly multiply that number if a pixel occupies more
than 1 byte). The multiplication can overflow, resulting in passing
negative or insufficiently positive size values to malloc. This patch
checks whether the multiplication will overflow. If so, XEmacs
refuses to attempt to load the image.
diff -r f2a991ff6db0 src/ChangeLog
--- a/src/ChangeLog Mon Jun 29 08:20:47 2009 -0600
+++ b/src/ChangeLog Wed Jul 01 15:42:54 2009 -0600
@@ -1,3 +1,11 @@
+2009-06-09 Jerry James <james(a)xemacs.org>
+
+ * glyphs-eimage.c (jpeg_instantiate):
+ (gif_instantiate):
+ (png_instantiate):
+ (tiff_instantiate): Check for integer overflow before allocating
+ memory for an image.
+
2009-06-20 Stephen Turnbull <stephen(a)xemacs.org>
* callint.c (Finteractive): Document that (interactive) must
diff -r f2a991ff6db0 src/glyphs-eimage.c
--- a/src/glyphs-eimage.c Mon Jun 29 08:20:47 2009 -0600
+++ b/src/glyphs-eimage.c Wed Jul 01 15:42:54 2009 -0600
@@ -409,6 +409,7 @@
*/
{
+ UINT_64_BIT pixels_sq;
int jpeg_gray = 0; /* if we're dealing with a grayscale */
/* Step 4: set parameters for decompression. */
@@ -431,7 +432,10 @@
jpeg_start_decompress (&cinfo);
/* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
-
+ pixels_sq =
+ (UINT_64_BIT) cinfo.output_width * (UINT_64_BIT) cinfo.output_height;
+ if (pixels_sq > ((size_t) -1) / 3)
+ signal_image_error ("JPEG image too large to instantiate",
instantiator);
unwind.eimage =
xnew_binbytes (cinfo.output_width * cinfo.output_height * 3);
if (!unwind.eimage)
@@ -677,6 +681,7 @@
{
ColorMapObject *cmo = unwind.giffile->SColorMap;
int i, j, row, pass, interlace, slice;
+ UINT_64_BIT pixels_sq;
Binbyte *eip;
/* interlaced gifs have rows in this order:
0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
@@ -685,6 +690,9 @@
height = unwind.giffile->SHeight;
width = unwind.giffile->SWidth;
+ pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height;
+ if (pixels_sq > ((size_t) -1) / (3 * unwind.giffile->ImageCount))
+ signal_image_error ("GIF image too large to instantiate", instantiator);
unwind.eimage =
xnew_binbytes (width * height * 3 * unwind.giffile->ImageCount);
if (!unwind.eimage)
@@ -948,11 +956,15 @@
{
int y;
Binbyte **row_pointers;
+ UINT_64_BIT pixels_sq;
height = info_ptr->height;
width = info_ptr->width;
+ pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height;
+ if (pixels_sq > ((size_t) -1) / 3)
+ signal_image_error ("PNG image too large to instantiate", instantiator);
/* Wow, allocate all the memory. Truly, exciting. */
- unwind.eimage = xnew_array_and_zero (Binbyte, width * height * 3);
+ unwind.eimage = xnew_array_and_zero (Binbyte, (size_t) (pixels_sq * 3));
/* libpng expects that the image buffer passed in contains a
picture to draw on top of if the png has any transparencies.
This could be a good place to pass that in... */
@@ -1299,6 +1311,7 @@
uint32 *raster;
Binbyte *ep;
+ UINT_64_BIT pixels_sq;
assert (!NILP (data));
@@ -1321,12 +1334,15 @@
TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
- unwind.eimage = xnew_binbytes (width * height * 3);
+ pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height;
+ if (pixels_sq >= 1 << 29)
+ signal_image_error ("TIFF image too large to instantiate",
instantiator);
+ unwind.eimage = xnew_binbytes (pixels_sq * 3);
/* #### This is little more than proof-of-concept/function testing.
It needs to be reimplemented via scanline reads for both memory
compactness. */
- raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
+ raster = (uint32*) _TIFFmalloc ((tsize_t) (pixels_sq * sizeof (uint32)));
if (raster != NULL)
{
int i, j;
--
Jerry James
http://www.jamezone.org/
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://calypso.tux.org/cgi-bin/mailman/listinfo/xemacs-patches