--- coders/bmp.c.cve-2007-1667_1797 2007-02-13 13:19:04.000000000 -0700 +++ coders/bmp.c 2007-07-13 14:32:59.000000000 -0600 @@ -863,7 +863,8 @@ static Image *ReadBMPImage(const ImageIn packet_size=3; else packet_size=4; - (void) SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET); + if (SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET) == -1) + ThrowReaderException(CorruptImageError,"ImproperImageHeader") count=ReadBlob(image,packet_size*image->colors,bmp_colormap); if (count != (ssize_t) (packet_size*image->colors)) ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile"); @@ -884,7 +885,8 @@ static Image *ReadBMPImage(const ImageIn /* Read image data. */ - (void) SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET); + if (SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET) == -1) + ThrowReaderException(CorruptImageError,"ImproperImageHeader") if (bmp_info.compression == BI_RLE4) bmp_info.bits_per_pixel<<=1; bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32); @@ -1304,7 +1306,8 @@ static Image *ReadBMPImage(const ImageIn break; *magick='\0'; if (bmp_info.ba_offset != 0) - (void) SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET); + if (SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET) == -1) + ThrowReaderException(CorruptImageError,"ImproperImageHeader") count=ReadBlob(image,2,magick); if ((count == 2) && (IsBMP(magick,2) != MagickFalse)) { --- coders/cin.c.cve-2007-1667_1797 2006-11-04 12:09:28.000000000 -0700 +++ coders/cin.c 2007-07-13 14:32:59.000000000 -0600 @@ -301,7 +301,8 @@ static Image *ReadCINImage(const ImageIn (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); --- coders/dcm.c.cve-2007-1667_1797 2007-02-12 18:56:02.000000000 -0700 +++ coders/dcm.c 2007-07-13 14:32:59.000000000 -0600 @@ -2914,6 +2914,9 @@ static Image *ReadDCMImage(const ImageIn else if ((quantum != 0) && (length != 0)) { + /* new check for CVE-2007-1797 */ + if (length > ((~0UL)/quantum)) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); data=(unsigned char *) AcquireMagickMemory((size_t) quantum*(length+1)); if (data == (unsigned char *) NULL) --- coders/icon.c.cve-2007-1667_1797 2007-01-14 09:26:23.000000000 -0700 +++ coders/icon.c 2007-07-13 15:07:08.000000000 -0600 @@ -246,13 +246,16 @@ static Image *ReadICONImage(const ImageI /* 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=(unsigned char) ReadBlobLSBLong(image); icon_info.height=(unsigned char) ReadBlobLSBLong(image)/2; 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); @@ -279,7 +282,7 @@ static Image *ReadICONImage(const ImageI (void) LogMagickEvent(CoderEvent,GetMagickModule()," bpp = %d", icon_info.bits_per_pixel); } - 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; --- coders/pcx.c.cve-2007-1667_1797 2007-02-12 18:56:02.000000000 -0700 +++ coders/pcx.c 2007-07-13 15:09:06.000000000 -0600 @@ -296,7 +296,9 @@ static Image *ReadPCXImage(const ImageIn } } 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++) @@ -335,7 +337,11 @@ static Image *ReadPCXImage(const ImageIn 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)) @@ -362,7 +368,7 @@ static Image *ReadPCXImage(const ImageIn pcx_pixels=(unsigned char *) AcquireMagickMemory(pcx_packets* sizeof(*pcx_pixels)); scanline=(unsigned char *) AcquireMagickMemory(MagickMax(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"); @@ -620,7 +626,9 @@ static Image *ReadPCXImage(const ImageIn 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)) { --- coders/pict.c.cve-2007-1667_1797 2007-02-16 20:22:07.000000000 -0700 +++ coders/pict.c 2007-07-13 15:10:26.000000000 -0600 @@ -82,6 +82,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) \ @@ -90,6 +94,9 @@ rectangle.left=(short) ReadBlobMSBShort(image); \ rectangle.bottom=(short) ReadBlobMSBShort(image); \ rectangle.right=(short) ReadBlobMSBShort(image); \ + if (rectangle.top > rectangle.bottom || \ + rectangle.left > rectangle.right) \ + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \ } typedef struct _PICTCode --- coders/png.c.cve-2007-1667_1797 2007-02-21 11:47:14.000000000 -0700 +++ coders/png.c 2007-07-13 14:32:59.000000000 -0600 @@ -4729,6 +4729,8 @@ static Image *ReadMNGImage(const ImageIn continue; } #ifdef MNG_INSERT_LAYERS + if (length < 8) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); image_width=(unsigned long) mng_get_long(p); image_height=(unsigned long) mng_get_long(&p[4]); #endif --- coders/pnm.c.cve-2007-1667_1797 2007-02-19 13:23:06.000000000 -0700 +++ coders/pnm.c 2007-07-13 14:32:59.000000000 -0600 @@ -209,6 +209,19 @@ static unsigned long PNMInteger(Image *i return(value); } +#define ValidateScalingIndex(image, index, max) \ + do { \ + if (index < 0 || index > max) \ + ThrowReaderException(CorruptImageError,"CorruptImage"); \ + } 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) \ @@ -475,6 +488,7 @@ static Image *ReadPNMImage(const ImageIn 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; @@ -520,6 +534,7 @@ static Image *ReadPNMImage(const ImageIn 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]; @@ -688,6 +703,7 @@ static Image *ReadPNMImage(const ImageIn 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]; @@ -705,6 +721,7 @@ static Image *ReadPNMImage(const ImageIn 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]; --- coders/sun.c.cve-2007-1667_1797 2007-02-19 13:23:06.000000000 -0700 +++ coders/sun.c 2007-07-13 14:32:59.000000000 -0600 @@ -304,6 +304,8 @@ static Image *ReadSUNImage(const ImageIn 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) { @@ -463,72 +465,85 @@ static Image *ReadSUNImage(const ImageIn } 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) && + 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; + 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) + if (status == MagickFalse) break; } - } + } + } else - 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++) + 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++) { - 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) && + 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) + if (status == MagickFalse) break; } - } + } + } if (image->storage_class == PseudoClass) (void) SyncImage(image); sun_pixels=(unsigned char *) RelinquishMagickMemory(sun_pixels); --- coders/xwd.c.cve-2007-1667_1797 2007-01-10 12:25:02.000000000 -0700 +++ coders/xwd.c 2007-07-13 14:32:59.000000000 -0600 @@ -235,6 +235,10 @@ static Image *ReadXWDImage(const ImageIn if (header.header_size < sz_XWDheader) ThrowReaderException(CorruptImageError,"CorruptImage"); length=(size_t) header.header_size-sz_XWDheader; + /* new check for CVE-2007-1797 */ + if (length > ((~0UL)/sizeof(*comment))) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); + comment=(char *) AcquireMagickMemory(length+MaxTextExtent); if (comment == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); @@ -266,6 +270,13 @@ static Image *ReadXWDImage(const ImageIn 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"); x_status=XInitImage(ximage); if (x_status == 0) ThrowReaderException(CorruptImageError,"UnableToReadImageHeader"); @@ -278,6 +289,10 @@ static Image *ReadXWDImage(const ImageIn 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)); if (colors == (XColor *) NULL) @@ -310,11 +325,23 @@ static Image *ReadXWDImage(const ImageIn /* 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=(size_t) ximage->bytes_per_line*ximage->height; + if (OVERFLOW(length, (size_t) 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 *) AcquireMagickMemory(length); + } +#undef OVERFLOW + } if (ximage->data == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,length,(unsigned char *) ximage->data); --- magick/studio.h~ 2007-07-13 16:09:47.000000000 -0600 +++ magick/studio.h 2007-07-13 16:09:47.000000000 -0600 @@ -370,6 +370,8 @@ extern size_t Magick defines. */ #define Swap(x,y) ((x)^=(y), (y)^=(x), (x)^=(y)) +#define Max(x,y) (((x) > (y)) ? (x) : (y)) +#define Min(x,y) (((x) < (y)) ? (x) : (y)) #if defined(__cplusplus) || defined(c_plusplus) }