CVE-2015-8958: Out-of-bounds Read (CWE-125)
value: coders/sun.c in ImageMagick before 6.9.0-4 Beta allows remote attackers to cause a denial of service (out-of-bounds read and application crash) via a crafted SUN file.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 6.5
Published: 2017-04-20T18:59Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: C
Files changed: coders/sun.c
Commit date: 2015-01-13 02:23:43 +0000
Diff: diff --git a/coders/sun.c b/coders/sun.c
index 728bffa4d..04915bc3d 100644
--- a/coders/sun.c
+++ b/coders/sun.c
@@ -253,10 +253,11 @@ static Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
     *p;
 
   size_t
     bytes_per_line,
     extent,
+    height,
     length;
 
   ssize_t
     count,
     y;
@@ -418,37 +419,27 @@ static Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
     if (sun_data == (unsigned char *) NULL)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     count=(ssize_t) ReadBlob(image,sun_info.length,sun_data);
     if (count != (ssize_t) sun_info.length)
       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
-    sun_pixels=sun_data;
-    bytes_per_line=0;
+    height=sun_info.height;
+    if ((height == 0) || (sun_info.width == 0) || (sun_info.depth == 0) ||
+        ((bytes_per_line/sun_info.depth) != sun_info.width))
+      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+    bytes_per_line+=15;
+    bytes_per_line<<=1;
+    if ((bytes_per_line >> 1) != (sun_info.width*sun_info.depth+15))
+      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+    bytes_per_line>>=4;
+    sun_pixels=(unsigned char *) AcquireQuantumMemory(height,
+      bytes_per_line*sizeof(*sun_pixels));
+    if (sun_pixels == (unsigned char *) NULL)
+      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     if (sun_info.type == RT_ENCODED)
-      {
-        size_t
-          height;
-
-        /*
-          Read run-length encoded raster pixels.
-        */
-        height=sun_info.height;
-        if ((height == 0) || (sun_info.width == 0) || (sun_info.depth == 0) ||
-            ((bytes_per_line/sun_info.depth) != sun_info.width))
-          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-        bytes_per_line+=15;
-        bytes_per_line<<=1;
-        if ((bytes_per_line >> 1) != (sun_info.width*sun_info.depth+15))
-          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-        bytes_per_line>>=4;
-        sun_pixels=(unsigned char *) AcquireQuantumMemory(height,
-          bytes_per_line*sizeof(*sun_pixels));
-        if (sun_pixels == (unsigned char *) NULL)
-          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-        (void) DecodeImage(sun_data,sun_info.length,sun_pixels,bytes_per_line*
-          height);
-        sun_data=(unsigned char *) RelinquishMagickMemory(sun_data);
-      }
+      (void) DecodeImage(sun_data,sun_info.length,sun_pixels,bytes_per_line*
+        height);
+    sun_data=(unsigned char *) RelinquishMagickMemory(sun_data);
     /*
       Convert SUN raster image to pixel packets.
     */
     p=sun_pixels;
     if (sun_info.depth == 1)

Vulnerable code:     sun_pixels=sun_data;
    bytes_per_line=0;
      {
        size_t
          height;

        /*
          Read run-length encoded raster pixels.
        */
        height=sun_info.height;
        if ((height == 0) || (sun_info.width == 0) || (sun_info.depth == 0) ||
            ((bytes_per_line/sun_info.depth) != sun_info.width))
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        bytes_per_line+=15;
        bytes_per_line<<=1;
        if ((bytes_per_line >> 1) != (sun_info.width*sun_info.depth+15))
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        bytes_per_line>>=4;
        sun_pixels=(unsigned char *) AcquireQuantumMemory(height,
          bytes_per_line*sizeof(*sun_pixels));
        if (sun_pixels == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
        (void) DecodeImage(sun_data,sun_info.length,sun_pixels,bytes_per_line*
          height);
        sun_data=(unsigned char *) RelinquishMagickMemory(sun_data);
      }
Fixed code:     height,
    height=sun_info.height;
    if ((height == 0) || (sun_info.width == 0) || (sun_info.depth == 0) ||
        ((bytes_per_line/sun_info.depth) != sun_info.width))
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    bytes_per_line+=15;
    bytes_per_line<<=1;
    if ((bytes_per_line >> 1) != (sun_info.width*sun_info.depth+15))
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    bytes_per_line>>=4;
    sun_pixels=(unsigned char *) AcquireQuantumMemory(height,
      bytes_per_line*sizeof(*sun_pixels));
    if (sun_pixels == (unsigned char *) NULL)
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
      (void) DecodeImage(sun_data,sun_info.length,sun_pixels,bytes_per_line*
        height);
    sun_data=(unsigned char *) RelinquishMagickMemory(sun_data);