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));
+}
pgpBxOdDbtJS3.pgp
Description: PGP signature

