Mercurial > hg > xemacs-beta
changeset 4646:6c6bfdb80a0c
Prevent integer overflow and subsequent crashes when attempting to load large
images. See <870180fe0907011540m7509f371h97d336477145166a@mail.gmail.com> in
xemacs-patches.
author | Jerry James <james@xemacs.org> |
---|---|
date | Wed, 01 Jul 2009 16:42:11 -0600 |
parents | f2a991ff6db0 |
children | e4ed58cb0e5b |
files | src/ChangeLog src/glyphs-eimage.c |
diffstat | 2 files changed, 28 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Mon Jun 29 08:20:47 2009 -0600 +++ b/src/ChangeLog Wed Jul 01 16:42:11 2009 -0600 @@ -1,3 +1,11 @@ +2009-06-09 Jerry James <james@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@xemacs.org> * callint.c (Finteractive): Document that (interactive) must
--- a/src/glyphs-eimage.c Mon Jun 29 08:20:47 2009 -0600 +++ b/src/glyphs-eimage.c Wed Jul 01 16:42:11 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;