tag 383314 + patch
thanks

On Wed, Aug 16, 2006 at 05:20:01PM +0200, Daniel Kobras wrote:
> On Wed, Aug 16, 2006 at 03:51:15PM +0200, Martin Pitt wrote:
> > http://www.overflow.pl/adv/imsgiheap.txt reported a buffer overflow in
> > the SGI parser (demo exploit linked in the report).
> > 
> > This has been assigned CVE-2006-4144, please mention this number in
> > the changelog when you fix this.
> > 
> > Ubuntu patch:
> > 
> >   http://people.ubuntu.com/patches/imagemagick.CVE-2006-4144.diff
> 
> This patch looks insufficient. In only deals sanitises user input for
> the run-length encoded format, but the overflow as described on the page
> linked above is present in the non-RLE case as well.

I've now had the time to look at it in detail:

- The heap overflow described in CVE-2006-4144 has been fixed for ages.
  It is present in graphicsmagick (forked from imagemagick 5), but not
  in any imagemagick 6.x version we ship.
- The heap overflow triggered by the demo exploit to CVE-2006-4144
  triggers a different vulnerability that was fixed upstream in 6.2.9.
  This is the patch you extracted.
- I've discovered two more heap overflows in sgi.c that apparently have
  gone unnoticed so far: ReadSGIImage() implicitly assumes iris_info.depth
  to be no greater than four. Anything else will trivially overflow the
  irix_pixels array. Also the checks in SGIDecode() for an overflow
  condition come too late, and an overflow up to 126 bytes might already
  have happened.

Hope this clears up the confusion. Here's a proposed fix for the current
version in unstable and testing. I haven't checked yet, but it's
probably applicable to stable as well. The first three hunks are not yet
contained in Ubuntu's security update, either.

Regards,

Daniel.

--- imagemagick-6.2.4.5.dfsg1.orig/coders/sgi.c
+++ imagemagick-6.2.4.5.dfsg1/coders/sgi.c
@@ -171,13 +171,13 @@
   q=pixels;
   if (bytes_per_pixel == 2)
     {
-      for (i=0; i < (long) width; )
+      for ( ; ; )
       {
         pixel=(unsigned long) (*p++) << 8;
         pixel|=(*p++);
         count=(ssize_t) (pixel & 0x7f);
         i+=count;
-        if (count == 0)
+       if (count == 0 || i >= (long) width)
           break;
         if ((pixel & 0x80) != 0)
           for ( ; count != 0; count--)
@@ -200,13 +200,13 @@
       }
       return;
     }
-  for (i=0; i < (long) width; )
+  for ( ; ; )
   {
     pixel=(unsigned long) (*p++);
     count=(ssize_t) (pixel & 0x7f);
-    if (count == 0)
-      break;
     i+=count;
+    if (count == 0 || i >= (long) width)
+      break;
     if ((pixel & 0x80) != 0)
       for ( ; count != 0; count--)
       {
@@ -304,6 +304,8 @@
     image->columns=iris_info.columns;
     image->rows=iris_info.rows;
     image->depth=(unsigned long) (iris_info.depth <= 8 ? 8 : QuantumDepth);
+    if (iris_info.depth > 4 || iris_info.depth == 0)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     if (iris_info.depth < 3)
       {
         image->storage_class=PseudoClass;
@@ -396,7 +398,11 @@
         for (i=0; i < (int) (iris_info.rows*iris_info.depth); i++)
           offsets[i]=(ssize_t) ReadBlobMSBLong(image);
         for (i=0; i < (int) (iris_info.rows*iris_info.depth); i++)
-          runlength[i]=ReadBlobMSBLong(image);
+         {
+            runlength[i]=ReadBlobMSBLong(image);
+            if (runlength[i] > 4*iris_info.columns+10)
+              ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+          }
         /*
           Check data order.
         */

Reply via email to