Hi, I intend to NMU this bug on behalf of the testing security team. I ported the patches to 6.2.4.5. The attached patch fixes the 4 CVE ids.
It will be also archived on: http://people.debian.org/~nion/nmu-diff/imagemagick-6.2.4.5.dfsg1-1_6.2.4.5.dfsg1-1.1.patch Kind regards Nico -- Nico Golde - http://ngolde.de - [EMAIL PROTECTED] - GPG: 0x73647CFF For security reasons, all text in this mail is double-rot13 encrypted.
diff -u 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 +++ imagemagick-6.2.4.5.dfsg1/coders/xwd.c @@ -99,6 +99,10 @@ % % */ + +#define CheckOverflowException(length,width,height) \ + (((height) != 0) && ((length)/((size_t) height) != ((size_t) width))) + static MagickBooleanType IsXWD(const unsigned char *magick,const size_t length) { if (length < 8) @@ -233,7 +237,7 @@ length=(size_t) header.header_size-sz_XWDheader; if (length > ((~0UL)/sizeof(*comment))) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); - comment=(char *) AcquireMagickMemory((length+1)*sizeof(*comment)); + comment=(char *) AcquireQuantumMemory(length+1,sizeof(*comment)); if (comment == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,length,(unsigned char *) comment); @@ -286,7 +290,8 @@ length=(size_t) header.ncolors; if (length > ((~0UL)/sizeof(*colors))) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); - colors=(XColor *) AcquireMagickMemory(length*sizeof(*colors)); + colors=(XColor *) AcquireQuantumMemory(length,sizeof(*colors)); + if (colors == (XColor *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (i=0; i < (long) header.ncolors; i++) @@ -328,7 +333,7 @@ if (MAGICK_OVERFLOW(length,tmp,ximage->depth)) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } - ximage->data=(char *) AcquireMagickMemory(length); + ximage->data=(char *) AcquireQuantumMemory(length,sizeof(*ximage->data)); if (ximage->data == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,length,(unsigned char *) ximage->data); @@ -344,6 +349,12 @@ 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) @@ -713,8 +724,7 @@ /* 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++) @@ -750,7 +760,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 -u 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 +++ imagemagick-6.2.4.5.dfsg1/coders/xcf.c @@ -305,7 +305,7 @@ 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); @@ -352,8 +352,7 @@ 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); @@ -1149,8 +1148,8 @@ /* allocate our array of layer info blocks */ - layer_info=(XCFLayerInfo *) - AcquireMagickMemory(number_layers*sizeof(XCFLayerInfo)); + layer_info=(XCFLayerInfo *) AcquireQuantumMemory((size_t) number_layers, sizeof(*layer_info)); + if (layer_info == (XCFLayerInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(layer_info,0,number_layers*sizeof(XCFLayerInfo)); diff -u 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 +++ imagemagick-6.2.4.5.dfsg1/coders/dcm.c @@ -3050,8 +3050,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++) @@ -3216,8 +3215,7 @@ /* Compute pixel scaling table. */ - scale=(Quantum *) - AcquireMagickMemory((size_t) (max_value+1)*sizeof(*scale)); + scale=(Quantum *) AcquireQuantumMemory(length,sizeof(*scale)); if (scale == (Quantum *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (i=0; i <= (long) max_value; i++) diff -u 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 +++ imagemagick-6.2.4.5.dfsg1/magick/image.c @@ -2620,7 +2620,8 @@ return(MagickFalse); 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: % @@ -2651,16 +2652,18 @@ MagickExport MagickBooleanType SetImageExtent(Image *image, const unsigned long columns,const unsigned long rows) { - register PixelPacket + PixelPacket *p; - image->columns=columns; - image->rows=rows; - (void) ParseAbsoluteGeometry("0x0+0+0",&image->page); - p=SetImagePixels(image,0,0,1,1); - return(p == (PixelPacket *) NULL ? MagickFalse : MagickTrue); + if ((columns != 0) || (rows != 0)) + { + image->columns=columns; + image->rows=rows; + } + p=SetImagePixels(image,0,0,image->columns,1); + return(p != (PixelPacket *) NULL ? MagickTrue : MagickFalse); } - + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % diff -u 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 +++ imagemagick-6.2.4.5.dfsg1/magick/blob.c @@ -2863,7 +2863,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 -u imagemagick-6.2.4.5.dfsg1/debian/changelog imagemagick-6.2.4.5.dfsg1/debian/changelog --- imagemagick-6.2.4.5.dfsg1/debian/changelog +++ imagemagick-6.2.4.5.dfsg1/debian/changelog @@ -1,3 +1,16 @@ +imagemagick (7:6.2.4.5.dfsg1-1.1) unstable; urgency=high + + * Non-maintainer upload by testing security team. + * Ported Jonathan Smith' patches to 6.2.4.5 to fix infinite loop + via crafted image (CVE-2007-4985), sign extension error in + ReadDIBImage function which could allow arbitrary code execution + (CVE-2007-4988), off-by-one programming error in ReadBlobString + which could lead to code execution (CVE-2007-4987) and multiple + integer overflow via crafted image files which could lead to a + heap overflow (CVE-2007-4986) (Closes: #444267). + + -- Nico Golde <[EMAIL PROTECTED]> Sun, 30 Sep 2007 00:20:38 +0200 + imagemagick (7:6.2.4.5.dfsg1-1) unstable; urgency=high * New maintainers. only in patch2: unchanged: --- imagemagick-6.2.4.5.dfsg1.orig/coders/xbm.c +++ imagemagick-6.2.4.5.dfsg1/coders/xbm.c @@ -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,17 @@ /* 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)) only in patch2: unchanged: --- imagemagick-6.2.4.5.dfsg1.orig/coders/dib.c +++ imagemagick-6.2.4.5.dfsg1/coders/dib.c @@ -442,6 +442,21 @@ % % */ + +static inline long MagickAbsoluteValue(const long x) +{ + if (x < 0) + return(-x); + return(x); +} + +static inline size_t MagickMax(const size_t x,const size_t y) +{ + if (x > y) + return(x); + return(y); +} + static Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception) { DIBInfo @@ -532,7 +547,7 @@ dib_info.blue_mask=ReadBlobLSBShort(image); } image->matte=dib_info.bits_per_pixel == 32 ? MagickTrue : MagickFalse; - image->columns=dib_info.width; + image->columns=(unsigned long) MagickAbsoluteValue(dib_info.width); image->rows=AbsoluteValue(dib_info.height); image->depth=8; if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16)) @@ -569,9 +584,12 @@ /* Read DIB raster colormap. */ + if ((4*image->colors) < image->colors) + ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 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 +614,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, + MagickMax(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 +1066,7 @@ /* 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 +1197,7 @@ 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); @@ -1233,6 +1251,7 @@ } (void) WriteBlob(image,4*(1 << dib_info.bits_per_pixel),dib_colormap); dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap); + dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)(1UL << dib_info.bits_per_pixel),4*sizeof(dib_colormap)); } (void) WriteBlob(image,dib_info.image_size,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); only in patch2: unchanged: --- imagemagick-6.2.4.5.dfsg1.orig/magick/memory.c +++ imagemagick-6.2.4.5.dfsg1/magick/memory.c @@ -355,6 +355,46 @@ #endif 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 +738,48 @@ 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)); +}
pgpVeqzzl5Ofa.pgp
Description: PGP signature