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));
+}

Attachment: pgpBxOdDbtJS3.pgp
Description: PGP signature

Reply via email to