Version in base suite: 6.2.4.5.dfsg1-0.14 Version in overlay suite: (not present) Base version: imagemagick_6.2.4.5.dfsg1-0.14 Target version: imagemagick_6.2.4.5.dfsg1-0.15+etch1 Base file: /org/ftp.debian.org/ftp/pool/main/i/imagemagick/imagemagick_6.2.4.5.dfsg1-0.14.dsc Target file: /org/ftp.debian.org/queue/o-p-u-new/imagemagick_6.2.4.5.dfsg1-0.15+etch1.dsc coders/cin.c | 3 - coders/dcm.c | 16 +++--- coders/dib.c | 22 +++++--- coders/icon.c | 8 +-- coders/pcx.c | 14 +++-- coders/pict.c | 7 ++ coders/png.c | 2 coders/pnm.c | 17 ++++++ coders/sun.c | 143 ++++++++++++++++++++++++++++++------------------------- coders/xbm.c | 21 ++++---- coders/xcf.c | 26 ++++++++-- coders/xwd.c | 51 +++++++++++++++---- debian/changelog | 30 +++++++++++ magick/blob.c | 8 ++- magick/image.c | 16 +++--- magick/memory.c | 86 +++++++++++++++++++++++++++++++++ magick/memory_.h | 4 + magick/methods.h | 2 magick/xwindow.c | 24 +++++---- 19 files changed, 372 insertions(+), 128 deletions(-) diff -Nru imagemagick-6.2.4.5.dfsg1/coders/cin.c imagemagick-6.2.4.5.dfsg1/coders/cin.c --- imagemagick-6.2.4.5.dfsg1/coders/cin.c 2005-08-12 18:02:43.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/cin.c 2009-07-27 14:32:18.000000000 +0000 @@ -229,7 +229,8 @@ (void) ReadBlobByte(image); image->columns=ReadBlobLong(image); image->rows=ReadBlobLong(image); - (void) SeekBlob(image,(MagickOffsetType) headersize,SEEK_SET); + if (SeekBlob(image,(MagickOffsetType) headersize,SEEK_SET) == -1) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if (image_info->ping) { CloseBlob(image); diff -Nru imagemagick-6.2.4.5.dfsg1/coders/dcm.c imagemagick-6.2.4.5.dfsg1/coders/dcm.c --- imagemagick-6.2.4.5.dfsg1/coders/dcm.c 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/dcm.c 2009-07-27 14:32:18.000000000 +0000 @@ -2899,8 +2899,12 @@ else if ((quantum != 0) && (length != 0)) { - data=(unsigned char *) - AcquireMagickMemory((size_t) quantum*(length+1)); + /* new check for CVE-2007-1797 */ + if (length > ((~0UL)/quantum)) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + data=(unsigned char *) NULL; + if (~length >= 1) + data=(unsigned char *) AcquireQuantumMemory(length+1,quantum*sizeof(*data)); if (data == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError, "MemoryAllocationFailed"); @@ -3039,8 +3043,7 @@ break; colors=(unsigned long) (length/bytes_per_pixel); datum=(long) colors; - graymap=(unsigned short *) - AcquireMagickMemory((size_t) colors*sizeof(*graymap)); + graymap=(unsigned short *) AcquireQuantumMemory((size_t) colors,sizeof(*graymap)); if (graymap == (unsigned short *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (i=0; i < (long) colors; i++) @@ -3205,8 +3208,9 @@ /* Compute pixel scaling table. */ - scale=(Quantum *) - AcquireMagickMemory((size_t) (max_value+1)*sizeof(*scale)); + scale=(Quantum *) NULL; + if (max_value < max_value+1) + scale=(Quantum *) AcquireQuantumMemory(max_value+1,sizeof(*scale)); if (scale == (Quantum *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (i=0; i <= (long) max_value; i++) diff -Nru imagemagick-6.2.4.5.dfsg1/coders/dib.c imagemagick-6.2.4.5.dfsg1/coders/dib.c --- imagemagick-6.2.4.5.dfsg1/coders/dib.c 2005-05-09 02:02:56.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/dib.c 2009-07-27 14:32:18.000000000 +0000 @@ -532,8 +532,8 @@ dib_info.blue_mask=ReadBlobLSBShort(image); } image->matte=dib_info.bits_per_pixel == 32 ? MagickTrue : MagickFalse; - image->columns=dib_info.width; - image->rows=AbsoluteValue(dib_info.height); + image->columns=(unsigned long) AbsoluteValue(dib_info.width); + image->rows=(unsigned long) AbsoluteValue(dib_info.height); image->depth=8; if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16)) { @@ -571,7 +571,9 @@ */ if (AllocateImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); - dib_colormap=(unsigned char *) AcquireMagickMemory(4*image->colors); + length=(size_t) image->colors; + dib_colormap=(unsigned char *) AcquireQuantumMemory(length, + 4*sizeof(*dib_colormap)); if (dib_colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); packet_size=4; @@ -596,8 +598,8 @@ dib_info.bits_per_pixel<<=1; bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32); length=bytes_per_line*image->rows; - pixels=(unsigned char *) AcquireMagickMemory((size_t) - Max(bytes_per_line,image->columns+256)*image->rows*sizeof(*pixels)); + pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows, + Max(bytes_per_line,image->columns+256)*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if ((dib_info.compression == 0) || (dib_info.compression == 3)) @@ -1048,7 +1050,8 @@ /* Convert MIFF to DIB raster pixels. */ - pixels=(unsigned char *) AcquireMagickMemory(dib_info.image_size); + pixels=(unsigned char *) AcquireQuantumMemory(dib_info.image_size, + sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(pixels,0,dib_info.image_size); @@ -1179,7 +1182,8 @@ Convert run-length encoded raster pixels. */ length=2*(bytes_per_line+2)*(image->rows+2)+2; - dib_data=(unsigned char *) AcquireMagickMemory(length); + dib_data=(unsigned char *) AcquireQuantumMemory(length, + sizeof(*dib_data)); if (pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); @@ -1212,8 +1216,8 @@ /* Dump colormap to file. */ - dib_colormap=(unsigned char *) - AcquireMagickMemory((size_t) (4*(1 << dib_info.bits_per_pixel))); + dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t) + (1UL << dib_info.bits_per_pixel),4*sizeof(dib_colormap)); if (dib_colormap == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); q=dib_colormap; diff -Nru imagemagick-6.2.4.5.dfsg1/coders/icon.c imagemagick-6.2.4.5.dfsg1/coders/icon.c --- imagemagick-6.2.4.5.dfsg1/coders/icon.c 2005-05-09 02:02:56.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/icon.c 2009-07-27 14:32:18.000000000 +0000 @@ -241,13 +241,15 @@ /* Verify Icon identifier. */ - (void) SeekBlob(image,(MagickOffsetType) icon_file.directory[i].offset, - SEEK_SET); + if (SeekBlob(image,(MagickOffsetType) icon_file.directory[i].offset,SEEK_SET) == -1) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); icon_info.size=ReadBlobLSBLong(image); icon_info.width=ReadBlobLSBLong(image); icon_info.height=ReadBlobLSBLong(image); icon_info.planes=ReadBlobLSBShort(image); icon_info.bits_per_pixel=ReadBlobLSBShort(image); + if (icon_info.bits_per_pixel > 32) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); icon_info.compression=ReadBlobLSBLong(image); icon_info.image_size=ReadBlobLSBLong(image); icon_info.x_pixels=ReadBlobLSBLong(image); @@ -258,7 +260,7 @@ image->columns=icon_info.width; image->rows=icon_info.height; image->depth=8; - if ((icon_info.number_colors != 0) || (icon_info.bits_per_pixel < 16)) + if ((icon_info.number_colors != 0) || (icon_info.bits_per_pixel <= 16)) { image->storage_class=PseudoClass; image->colors=icon_info.number_colors; diff -Nru imagemagick-6.2.4.5.dfsg1/coders/pcx.c imagemagick-6.2.4.5.dfsg1/coders/pcx.c --- imagemagick-6.2.4.5.dfsg1/coders/pcx.c 2005-06-22 16:19:09.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/pcx.c 2009-07-27 14:32:18.000000000 +0000 @@ -288,7 +288,8 @@ } } if (page_table != (MagickOffsetType *) NULL) - (void) SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET); + if (SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET) == -1) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); pcx_colormap=(unsigned char *) NULL; count=ReadBlob(image,1,&pcx_info.identifier); for (id=1; id < 1024; id++) @@ -327,7 +328,11 @@ if ((pcx_info.bits_per_pixel != 8) || (pcx_info.planes == 1)) if ((pcx_info.version == 3) || (pcx_info.version == 5) || ((pcx_info.bits_per_pixel*pcx_info.planes) == 1)) - image->colors=1 << (pcx_info.bits_per_pixel*pcx_info.planes); + { + image->colors=1 << (pcx_info.bits_per_pixel*pcx_info.planes); + if (image->colors > 256) + image->colors = 256; + } if (AllocateImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1)) @@ -354,7 +359,7 @@ pcx_pixels=(unsigned char *) AcquireMagickMemory(pcx_packets*sizeof(*pcx_pixels)); scanline=(unsigned char *) AcquireMagickMemory(Max(image->columns, - pcx_info.bytes_per_line)*pcx_info.planes*sizeof(*scanline)); + pcx_info.bytes_per_line)*Max(pcx_info.planes,8)*sizeof(*scanline)); if ((pcx_pixels == (unsigned char *) NULL) || (scanline == (unsigned char *) NULL)) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); @@ -612,7 +617,8 @@ break; if (page_table[id] == 0) break; - (void) SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET); + if (SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET) == -1) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); count=ReadBlob(image,1,&pcx_info.identifier); if ((count != 0) && (pcx_info.identifier == 0x0a)) { diff -Nru imagemagick-6.2.4.5.dfsg1/coders/pict.c imagemagick-6.2.4.5.dfsg1/coders/pict.c --- imagemagick-6.2.4.5.dfsg1/coders/pict.c 2005-08-31 00:11:11.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/pict.c 2009-07-27 14:32:18.000000000 +0000 @@ -78,6 +78,10 @@ pixmap.plane_bytes=ReadBlobMSBLong(image); \ pixmap.table=ReadBlobMSBLong(image); \ pixmap.reserved=ReadBlobMSBLong(image); \ + if (pixmap.bits_per_pixel <= 0 || pixmap.bits_per_pixel > 32 || \ + pixmap.component_count <= 0 || pixmap.component_count > 4 || \ + pixmap.component_size <= 0) \ + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \ } #define ReadRectangle(rectangle) \ @@ -86,6 +90,9 @@ rectangle.left=ReadBlobMSBShort(image); \ rectangle.bottom=ReadBlobMSBShort(image); \ rectangle.right=ReadBlobMSBShort(image); \ + if (rectangle.top > rectangle.bottom || \ + rectangle.left > rectangle.right) \ + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \ } typedef struct _PICTCode diff -Nru imagemagick-6.2.4.5.dfsg1/coders/png.c imagemagick-6.2.4.5.dfsg1/coders/png.c --- imagemagick-6.2.4.5.dfsg1/coders/png.c 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/png.c 2009-07-27 14:32:18.000000000 +0000 @@ -4638,6 +4638,8 @@ continue; } #ifdef MNG_INSERT_LAYERS + if (length < 8) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); image_width=mng_get_long(p); image_height=mng_get_long(&p[4]); #endif diff -Nru imagemagick-6.2.4.5.dfsg1/coders/pnm.c imagemagick-6.2.4.5.dfsg1/coders/pnm.c --- imagemagick-6.2.4.5.dfsg1/coders/pnm.c 2005-07-13 23:09:58.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/pnm.c 2009-07-27 14:32:18.000000000 +0000 @@ -215,6 +215,19 @@ return(value); } +#define ValidateScalingIndex(image, index, max) \ + do { \ + if (index < 0 || index > max) \ + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \ + } while (0) + +#define ValidateScalingPixel(image, pixel, max) \ + do { \ + ValidateScalingIndex(image, pixel.red, max); \ + ValidateScalingIndex(image, pixel.green, max); \ + ValidateScalingIndex(image, pixel.blue, max); \ + } while (0) + static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception) { #define PushCharPixel(pixel,p) \ @@ -420,6 +433,7 @@ for (x=0; x < (long) image->columns; x++) { intensity=PNMInteger(image,10); + ValidateScalingIndex(image, intensity, max_value); if (scale != (Quantum *) NULL) intensity=scale[intensity]; index=(IndexPacket) intensity; @@ -462,6 +476,7 @@ pixel.red=PNMInteger(image,10); pixel.green=PNMInteger(image,10); pixel.blue=PNMInteger(image,10); + ValidateScalingPixel(image, pixel, max_value); if (scale != (Quantum *) NULL) { pixel.red=scale[pixel.red]; @@ -624,6 +639,7 @@ PushCharPixel(pixel.red,p); PushCharPixel(pixel.green,p); PushCharPixel(pixel.blue,p); + ValidateScalingPixel(image, pixel, max_value); if (scale != (Quantum *) NULL) { pixel.red=scale[pixel.red]; @@ -641,6 +657,7 @@ PushShortPixel(pixel.red,p); PushShortPixel(pixel.green,p); PushShortPixel(pixel.blue,p); + ValidateScalingPixel(image, pixel, max_value); if (scale != (Quantum *) NULL) { pixel.red=scale[pixel.red]; diff -Nru imagemagick-6.2.4.5.dfsg1/coders/sun.c imagemagick-6.2.4.5.dfsg1/coders/sun.c --- imagemagick-6.2.4.5.dfsg1/coders/sun.c 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/sun.c 2009-07-27 14:32:18.000000000 +0000 @@ -303,6 +303,8 @@ sun_info.maplength=ReadBlobMSBLong(image); image->columns= sun_info.width; image->rows= sun_info.height; + if (sun_info.depth == 0 || sun_info.depth > 32) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); image->depth=sun_info.depth <= 8 ? 8UL : QuantumDepth; if (sun_info.depth < 24) { @@ -461,72 +463,85 @@ } else if (image->storage_class == PseudoClass) - for (y=0; y < (long) image->rows; y++) { - q=SetImagePixels(image,0,y,image->columns,1); - if (q == (PixelPacket *) NULL) - break; - indexes=GetIndexes(image); - for (x=0; x < (long) image->columns; x++) - indexes[x]=(*p++); - if ((image->columns % 2) != 0) - p++; - if (SyncImagePixels(image) == MagickFalse) - break; - if (image->previous == (Image *) NULL) - if ((image->progress_monitor != (MagickProgressMonitor) NULL) && - (QuantumTick(y,image->rows) != MagickFalse)) - { - status=image->progress_monitor(LoadImageTag,y,image->rows, - image->client_data); - if (status == MagickFalse) - break; - } - } - else + unsigned long n = image->rows*(image->columns+image->columns%2); + if ((sun_info.type == RT_ENCODED && n > bytes_per_line*image->rows) || + (sun_info.type != RT_ENCODED && n > sun_info.length)) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); for (y=0; y < (long) image->rows; y++) - { - q=SetImagePixels(image,0,y,image->columns,1); - if (q == (PixelPacket *) NULL) - break; - for (x=0; x < (long) image->columns; x++) - { - if (image->matte != MagickFalse) - q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++)); - if (sun_info.type == RT_STANDARD) - { - q->blue=ScaleCharToQuantum(*p++); - q->green=ScaleCharToQuantum(*p++); - q->red=ScaleCharToQuantum(*p++); - } - else - { - q->red=ScaleCharToQuantum(*p++); - q->green=ScaleCharToQuantum(*p++); - q->blue=ScaleCharToQuantum(*p++); - } - if (image->colors != 0) - { - q->red=image->colormap[q->red].red; - q->green=image->colormap[q->green].green; - q->blue=image->colormap[q->blue].blue; - } - q++; - } - if ((image->columns % 2) != 0) - p++; - if (SyncImagePixels(image) == MagickFalse) - break; - if (image->previous == (Image *) NULL) - if ((image->progress_monitor != (MagickProgressMonitor) NULL) && - (QuantumTick(y,image->rows) != MagickFalse)) - { - status=image->progress_monitor(LoadImageTag,y,image->rows, - image->client_data); - if (status == MagickFalse) - break; - } - } + { + q=SetImagePixels(image,0,y,image->columns,1); + if (q == (PixelPacket *) NULL) + break; + indexes=GetIndexes(image); + for (x=0; x < (long) image->columns; x++) + indexes[x]=(*p++); + if ((image->columns % 2) != 0) + p++; + if (SyncImagePixels(image) == MagickFalse) + break; + if (image->previous == (Image *) NULL) + if ((image->progress_monitor != (MagickProgressMonitor) NULL) && + (QuantumTick(y,image->rows) != MagickFalse)) + { + status=image->progress_monitor(LoadImageTag,y,image->rows, + image->client_data); + if (status == MagickFalse) + break; + } + } + } + else + { + unsigned long n = image->columns*((image->matte) ? 4 : 3); + n = image->rows*(n+image->columns%2); + if ((sun_info.type == RT_ENCODED && n > bytes_per_line*image->rows) || + (sun_info.type != RT_ENCODED && n > sun_info.length)) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + for (y=0; y < (long) image->rows; y++) + { + q=SetImagePixels(image,0,y,image->columns,1); + if (q == (PixelPacket *) NULL) + break; + for (x=0; x < (long) image->columns; x++) + { + if (image->matte != MagickFalse) + q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++)); + if (sun_info.type == RT_STANDARD) + { + q->blue=ScaleCharToQuantum(*p++); + q->green=ScaleCharToQuantum(*p++); + q->red=ScaleCharToQuantum(*p++); + } + else + { + q->red=ScaleCharToQuantum(*p++); + q->green=ScaleCharToQuantum(*p++); + q->blue=ScaleCharToQuantum(*p++); + } + if (image->colors != 0) + { + q->red=image->colormap[q->red].red; + q->green=image->colormap[q->green].green; + q->blue=image->colormap[q->blue].blue; + } + q++; + } + if ((image->columns % 2) != 0) + p++; + if (SyncImagePixels(image) == MagickFalse) + break; + if (image->previous == (Image *) NULL) + if ((image->progress_monitor != (MagickProgressMonitor) NULL) && + (QuantumTick(y,image->rows) != MagickFalse)) + { + status=image->progress_monitor(LoadImageTag,y,image->rows, + image->client_data); + if (status == MagickFalse) + break; + } + } + } if (image->storage_class == PseudoClass) (void) SyncImage(image); sun_pixels=(unsigned char *) RelinquishMagickMemory(sun_pixels); diff -Nru imagemagick-6.2.4.5.dfsg1/coders/xbm.c imagemagick-6.2.4.5.dfsg1/coders/xbm.c --- imagemagick-6.2.4.5.dfsg1/coders/xbm.c 2005-08-12 16:27:48.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/xbm.c 2009-07-27 14:32:18.000000000 +0000 @@ -187,6 +187,8 @@ short int hex_digits[256]; + size_t length; + unsigned char *data; @@ -263,15 +265,6 @@ */ if (AllocateImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); - padding=0; - if (((image->columns % 16) != 0) && - ((image->columns % 16) < 9) && (version == 10)) - padding=1; - bytes_per_line=(image->columns+7)/8+padding; - data=(unsigned char *) - AcquireMagickMemory((size_t) bytes_per_line*image->rows); - if (data == (unsigned char *) NULL) - ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); /* Initialize colormap. */ @@ -320,6 +313,16 @@ /* Read hex image data. */ + padding=0; + if (((image->columns % 16) != 0) && + ((image->columns % 16) < 9) && (version == 10)) + padding=1; + bytes_per_line=(image->columns+7)/8+padding; + length=(size_t) image->rows; + data=(unsigned char *) AcquireQuantumMemory(length,bytes_per_line* + sizeof(*data)); + if (data == (unsigned char *) NULL) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); p=data; if (version == 10) for (i=0; i < (long) (bytes_per_line*image->rows); (i+=2)) diff -Nru imagemagick-6.2.4.5.dfsg1/coders/xcf.c imagemagick-6.2.4.5.dfsg1/coders/xcf.c --- imagemagick-6.2.4.5.dfsg1/coders/xcf.c 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/xcf.c 2009-07-27 14:32:55.000000000 +0000 @@ -305,10 +305,14 @@ XCFPixelPacket *xcfdata, *xcfodata; unsigned char *graydata; - xcfdata = xcfodata = (XCFPixelPacket *) AcquireMagickMemory(data_length); + xcfdata = xcfodata = (XCFPixelPacket *) AcquireQuantumMemory(data_length, + sizeof(*xcfdata)); graydata = (unsigned char *)xcfdata; /* used by gray and indexed */ nmemb_read_successfully = ReadBlob(image, data_length, (unsigned char *) xcfdata); + if (nmemb_read_successfully > (ssize_t) (tile_image->columns*tile_image->rows)) + ThrowBinaryException(CorruptImageError,"NotEnoughPixelData",image->filename); + q=SetImagePixels(tile_image,0,0,tile_image->columns,tile_image->rows); /* we have to copy the pixels individually since IM uses a different @@ -352,8 +356,8 @@ bpp = (int) inDocInfo->bpp; - xcfdata = xcfodata = (unsigned char *) - AcquireMagickMemory((size_t) data_length); + xcfdata = xcfodata = (unsigned char *) AcquireQuantumMemory((size_t) + data_length,sizeof(*xcfdata)); nmemb_read_successfully = ReadBlob(image, (size_t) data_length, xcfdata); @@ -553,6 +557,9 @@ offset2 = (MagickOffsetType) (offset + TILE_WIDTH * TILE_WIDTH * 4* 1.5); /* 1.5 is probably more than we need to allow */ + + if (offset2-offset > (MagickOffsetType) (TILE_WIDTH * TILE_WIDTH * 4* 1.5)) + ThrowBinaryException(CorruptImageError,"CorruptImage",image->filename); /* seek to the tile offset */ (void) SeekBlob(image, offset, SEEK_SET); @@ -899,6 +906,9 @@ ssize_t count; + size_t + length; + XCFDocInfo doc_info; @@ -944,6 +954,11 @@ else if ( image_type == GIMP_INDEXED ) ThrowReaderException(CoderError,"ColormapTypeNotSupported"); + if (SetImageExtent(image,0,0) == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } SetImageBackgroundColor(image); /* Read properties. @@ -1149,8 +1164,9 @@ /* allocate our array of layer info blocks */ - layer_info=(XCFLayerInfo *) - AcquireMagickMemory(number_layers*sizeof(XCFLayerInfo)); + length=(size_t) number_layers; + layer_info=(XCFLayerInfo *) AcquireQuantumMemory(length, + sizeof(*layer_info)); if (layer_info == (XCFLayerInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(layer_info,0,number_layers*sizeof(XCFLayerInfo)); diff -Nru imagemagick-6.2.4.5.dfsg1/coders/xwd.c imagemagick-6.2.4.5.dfsg1/coders/xwd.c --- imagemagick-6.2.4.5.dfsg1/coders/xwd.c 2005-08-28 17:15:25.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/coders/xwd.c 2009-07-27 14:32:18.000000000 +0000 @@ -231,7 +231,9 @@ if (header.header_size < sz_XWDheader) ThrowReaderException(CorruptImageError,"CorruptImage"); length=(size_t) header.header_size-sz_XWDheader; - comment=(char *) AcquireMagickMemory(length+MaxTextExtent); + if (length >= ((~0UL)/sizeof(*comment))) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + comment=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*comment)); if (comment == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,length,(unsigned char *) comment); @@ -262,6 +264,13 @@ ximage->red_mask=header.red_mask; ximage->green_mask=header.green_mask; ximage->blue_mask=header.blue_mask; + /* Why those are signed ints is beyond me. */ + if (ximage->depth < 0 || ximage->width < 0 || ximage->height < 0 || + ximage->bitmap_pad < 0 || ximage->bytes_per_line < 0) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + /* Guard against buffer overflow in libX11. */ + if (ximage->bits_per_pixel > 32 || ximage->bitmap_unit > 32) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); status=(MagickBooleanType) XInitImage(ximage); if (status == MagickFalse) ThrowReaderException(CorruptImageError,"UnableToReadImageHeader"); @@ -274,8 +283,12 @@ XWDColor color; + /* new check for CVE-2007-1797 */ + if (length > ((~0UL)/sizeof(*colors))) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + colors=(XColor *) - AcquireMagickMemory((size_t) header.ncolors*sizeof(*colors)); + AcquireQuantumMemory((size_t) header.ncolors,sizeof(*colors)); if (colors == (XColor *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (i=0; i < (long) header.ncolors; i++) @@ -306,11 +319,24 @@ /* Allocate the pixel buffer. */ - if (ximage->format == ZPixmap) - length=(size_t) ximage->bytes_per_line*ximage->height; - else - length=(size_t) ximage->bytes_per_line*ximage->height*ximage->depth; - ximage->data=(char *) AcquireMagickMemory(length); + { +#define OVERFLOW(c,a,b) ((b) != 0 && ((c)/(b) != (a))) + int overflow=0; + length=ximage->bytes_per_line*ximage->height; + if (OVERFLOW(length, ximage->bytes_per_line, ximage->height)) overflow=1; + if (ximage->format != ZPixmap) { + size_t l1=length*ximage->depth; + if (OVERFLOW(l1, length, ximage->depth)) overflow=1; + length=l1; + } + if (overflow) { + ximage->data = (char *) NULL; + } else { + ximage->data=(char *) AcquireQuantumMemory(length,sizeof(*ximage->data)); + } +#undef OVERFLOW + } + if (ximage->data == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,length,(unsigned char *) ximage->data); @@ -326,6 +352,11 @@ image->storage_class=DirectClass; else image->storage_class=PseudoClass; + if (SetImageExtent(image,0,0) == MagickFalse) + { + InheritException(exception,&image->exception); + return(DestroyImageList(image)); + } image->colors=header.ncolors; if (image_info->ping == MagickFalse) switch (image->storage_class) @@ -695,8 +726,8 @@ /* Dump colormap to file. */ - colors=(XColor *) - AcquireMagickMemory((size_t) image->colors*sizeof(*colors)); + colors=(XColor *) AcquireQuantumMemory((size_t) image->colors, + sizeof(*colors)); if (colors == (XColor *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); for (i=0; i < (long) image->colors; i++) @@ -732,7 +763,7 @@ length=3*bytes_per_line; if (image->storage_class == PseudoClass) length=bytes_per_line; - pixels=(unsigned char *) AcquireMagickMemory(length); + pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); ResetMagickMemory(pixels,0,length); diff -Nru imagemagick-6.2.4.5.dfsg1/debian/changelog imagemagick-6.2.4.5.dfsg1/debian/changelog --- imagemagick-6.2.4.5.dfsg1/debian/changelog 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/debian/changelog 2009-07-27 17:13:54.000000000 +0000 @@ -1,3 +1,33 @@ +imagemagick (7:6.2.4.5.dfsg1-0.15+etch1) oldstable-security; urgency=high + + * Non-maintainer upload. + * Fix various crashes on malformed input, including CVE-2007-1797, + CVE-2007-1667, CVE-2008-1096 and CVE-2008-1097. Closes: #418057, #412945 + * Fix multiple vulnerabilities in imagemagick. (It's a port of the diff + between these tags of the SCM: debian_version_6_2_4_5_dfsg1-2 and + debian_version_6_2_4_5_dfsg1-1). Closes: #444267 + + magick/memory.c,magick/memory_.h,magick/methods.h: Add new allocator + wrapper AcquireQuantumMemory() to prevent potential integer overflows. + Backport from upstream version 6.3.5.9. + + magick/image.c: Backport new implementation of SetImageExtent() from + upstream version 6.3.5.9. + + coders/dcm.c,coders/xcf.c: Fix integer overflow in DCM and XCF coders. + (CVE-2007-4985) Backport of upstream patch from version 6.3.5.9. + + coders/dcm.c,coders/dib.c,coders/xbm.c,coders/xcf.c,coders/xwd.c: + Fix multiple integer overflows in DCM, DIB, XBM, XCF, and XWD coders. + (CVE-2007-4986 and CVE-2007-4988) Based on upstream patch from + version 6.3.5.9. + + magick/blob.c: Fix fencepost error in ReadBlobString() + (CVE-2007-4987) Backport of upstream patch from version 6.3.5.9. + + coders/dib.c: Ensure positive value for image rows and columns. + Based on upstream patch from version 6.3.5.9. + + All of the above patches have been derived from backports supplied by + Jonathan Smith. + * Apply upstream patch to fix integer overflow in XMakeImage() + (CVE-2009-1882). Closes: #530838 + + -- Luciano Bello Mon, 27 Jul 2009 12:49:27 -0300 + imagemagick (7:6.2.4.5.dfsg1-0.14) unstable; urgency=high * Non-maintainer upload. diff -Nru imagemagick-6.2.4.5.dfsg1/magick/blob.c imagemagick-6.2.4.5.dfsg1/magick/blob.c --- imagemagick-6.2.4.5.dfsg1/magick/blob.c 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/magick/blob.c 2009-07-27 14:32:18.000000000 +0000 @@ -1432,6 +1432,12 @@ register unsigned char *p; + if ((ssize_t) image->blob->offset >= (ssize_t) image->blob->length) + { + image->blob->eof=MagickTrue; + return 0; + } + p=image->blob->data+image->blob->offset; count=Min((ssize_t) length,(ssize_t) image->blob->length-(ssize_t) image->blob->offset); @@ -2863,7 +2869,7 @@ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); - for (i=0; i < (long) MaxTextExtent; i++) + for (i=0; i < ((long) MaxTextExtent - 1L); i++) { p=ReadInlineBlobStream(image,1,buffer,&count); if (count != 1) diff -Nru imagemagick-6.2.4.5.dfsg1/magick/image.c imagemagick-6.2.4.5.dfsg1/magick/image.c --- imagemagick-6.2.4.5.dfsg1/magick/image.c 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/magick/image.c 2009-07-27 14:32:18.000000000 +0000 @@ -2621,6 +2621,7 @@ return(MagickTrue); } + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @@ -2636,8 +2637,8 @@ % % The format of the SetImageExtent method is: % -% MagickBooleanType SetImageExtent(Image *image,const unsigned long columns, -% const unsigned long rows) +% MagickBooleanType SetImageExtent(Image *image, +% const unsigned long columns,const unsigned long rows) % % A description of each parameter follows: % @@ -2654,12 +2655,15 @@ register PixelPacket *p; - image->columns=columns; - image->rows=rows; - (void) ParseAbsoluteGeometry("0x0+0+0",&image->page); - p=SetImagePixels(image,0,0,1,1); + if ((columns != 0) || (rows != 0)) + { + image->columns=columns; + image->rows=rows; + } + p=SetImagePixels(image,0,0,image->columns,1); return(p == (PixelPacket *) NULL ? MagickFalse : MagickTrue); } + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff -Nru imagemagick-6.2.4.5.dfsg1/magick/memory.c imagemagick-6.2.4.5.dfsg1/magick/memory.c --- imagemagick-6.2.4.5.dfsg1/magick/memory.c 2005-07-28 18:44:45.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/magick/memory.c 2009-07-27 14:32:18.000000000 +0000 @@ -356,6 +356,48 @@ return(memory); } + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% A c q u i r e Q u a n t u m M e m o r y % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% AcquireQuantumMemory() returns a pointer to a block of memory at least +% count * quantum bytes suitably aligned for any use. +% +% The format of the AcquireQuantumMemory method is: +% +% void *AcquireQuantumMemory(const size_t count,const size_t quantum) +% +% A description of each parameter follows: +% +% o count: The number of quantum elements to allocate. +% +% o quantum: The number of bytes in each quantum. +% +*/ +MagickExport void *AcquireQuantumMemory(const size_t count,const size_t quantum) +{ + size_t + size; + + size=count*quantum; + if ((count == 0) || (quantum != (size/count))) + { + errno=ENOMEM; + return((void *) NULL); + } + return(AcquireMagickMemory(size)); +} + + + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @@ -698,3 +740,47 @@ memory=RelinquishMagickMemory(memory); return(block); } + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% R e s i z e Q u a n t u m M e m o r y % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ResizeQuantumMemory() changes the size of the memory and returns a pointer +% to the (possibly moved) block. The contents will be unchanged up to the +% lesser of the new and old sizes. +% +% The format of the ResizeQuantumMemory method is: +% +% void *ResizeQuantumMemory(void *memory,const size_t count, +% const size_t quantum) +% +% A description of each parameter follows: +% +% o memory: A pointer to a memory allocation. +% +% o count: The number of quantum elements to allocate. +% +% o quantum: The number of bytes in each quantum. +% +*/ +MagickExport void *ResizeQuantumMemory(void *memory,const size_t count, + const size_t quantum) +{ + size_t + size; + + size=count*quantum; + if ((count == 0) || (quantum != (size/count))) + { + errno=ENOMEM; + return((void *) NULL); + } + return(ResizeMagickMemory(memory,size)); +} diff -Nru imagemagick-6.2.4.5.dfsg1/magick/memory_.h imagemagick-6.2.4.5.dfsg1/magick/memory_.h --- imagemagick-6.2.4.5.dfsg1/magick/memory_.h 2005-04-20 16:27:36.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/magick/memory_.h 2009-07-27 14:32:18.000000000 +0000 @@ -24,11 +24,13 @@ extern MagickExport void *AcquireMagickMemory(const size_t), + *AcquireQuantumMemory(const size_t,const size_t), *CopyMagickMemory(void *,const void *,const size_t), DestroyMagickMemory(void), *RelinquishMagickMemory(void *), *ResetMagickMemory(void *,int,const size_t), - *ResizeMagickMemory(void *,const size_t); + *ResizeMagickMemory(void *,const size_t), + *ResizeQuantumMemory(void *,const size_t,const size_t); #if defined(__cplusplus) || defined(c_plusplus) } diff -Nru imagemagick-6.2.4.5.dfsg1/magick/methods.h imagemagick-6.2.4.5.dfsg1/magick/methods.h --- imagemagick-6.2.4.5.dfsg1/magick/methods.h 2009-08-10 17:31:37.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/magick/methods.h 2009-07-27 14:32:18.000000000 +0000 @@ -44,6 +44,7 @@ #define AcquireMagickResource PrependMagickMethod(AcquireMagickResource) #define AcquireMemory PrependMagickMethod(AcquireMemory) #define AcquireOnePixel PrependMagickMethod(AcquireOnePixel) +#define AcquireQuantumMemory PrependMagickMethod(AcquireQuantumMemory) #define AcquireSemaphoreInfo PrependMagickMethod(AcquireSemaphoreInfo) #define AcquireStringInfo PrependMagickMethod(AcquireStringInfo) #define AcquireString PrependMagickMethod(AcquireString) @@ -692,6 +693,7 @@ #define ResetTimer PrependMagickMethod(ResetTimer) #define ResizeImage PrependMagickMethod(ResizeImage) #define ResizeMagickMemory PrependMagickMethod(ResizeMagickMemory) +#define ResizeQuantumMemory PrependMagickMethod(ResizeQuantumMemory) #define ReverseImageList PrependMagickMethod(ReverseImageList) #define RGBTransformImage PrependMagickMethod(RGBTransformImage) #define RollImage PrependMagickMethod(RollImage) diff -Nru imagemagick-6.2.4.5.dfsg1/magick/xwindow.c imagemagick-6.2.4.5.dfsg1/magick/xwindow.c --- imagemagick-6.2.4.5.dfsg1/magick/xwindow.c 2005-08-30 23:55:19.000000000 +0000 +++ imagemagick-6.2.4.5.dfsg1/magick/xwindow.c 2009-07-27 16:38:13.000000000 +0000 @@ -5371,6 +5371,9 @@ const XResourceInfo *resource_info,XWindowInfo *window,Image *image, unsigned int width,unsigned int height) { +#define CheckOverflowException(length,width,height) \ + (((height) != 0) && ((length)/((size_t) height) != ((size_t) width))) + int depth, format; @@ -5524,9 +5527,11 @@ (char *) NULL,&segment_info[1],width,height); if (ximage == (XImage *) NULL) window->shared_memory=MagickFalse; + length=(size_t) ximage->bytes_per_line*ximage->height; + if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height)) + window->shared_memory=MagickFalse; if (window->shared_memory != MagickFalse) - segment_info[1].shmid=shmget(IPC_PRIVATE,(unsigned int) - (ximage->bytes_per_line*ximage->height),IPC_CREAT | 0777); + segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777); if (window->shared_memory != MagickFalse) segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0); if (segment_info[1].shmid < 0) @@ -5629,11 +5634,12 @@ } if (window->shared_memory == MagickFalse) { - if (ximage->format == XYBitmap) - length=(size_t) ximage->bytes_per_line*ximage->height*ximage->depth; + if (ximage->format != XYBitmap) + ximage->data=(char *) AcquireQuantumMemory((size_t) + ximage->bytes_per_line,(size_t) ximage->height); else - length=(size_t) ximage->bytes_per_line*ximage->height; - ximage->data=(char *) malloc(length); + ximage->data=(char *) AcquireQuantumMemory((size_t) + ximage->bytes_per_line*ximage->depth,(size_t) ximage->height); } if (ximage->data == (char *) NULL) { @@ -5711,9 +5717,9 @@ /* Allocate matte image pixel data. */ - length=(size_t) matte_image->bytes_per_line* - matte_image->height*matte_image->depth; - matte_image->data=(char *) malloc(length); + matte_image->data=(char *) AcquireQuantumMemory((size_t) + matte_image->bytes_per_line*matte_image->depth, + (size_t) matte_image->height); if (matte_image->data == (char *) NULL) { XDestroyImage(matte_image);