Vulnerability: The ReadRLEImage function in coders/rle.c in ImageMagick allows remote attackers to cause a denial of service (out-of-bounds read) via vectors related to the number of pixels.
Vulnerability ID: CVE-2016-7515
CWE: CWE-125
Severity score: 2.9
Project: https://github.com/ImageMagick/ImageMagick
Published: 2017-04-19
File: coders/rle.c
Commit message: Fixed check for the number of pixels that will be allocated.
Commit author: dirk

Vulnerable version (before fix):
 static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)     map_length,     number_colormaps,     number_planes,     one,     offset,     pixel_info_length; static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)     if (image->alpha_trait != UndefinedPixelTrait)       number_planes++;     number_pixels=(MagickSizeType) image->columns*image->rows;     if ((number_pixels*number_planes) != (size_t) (number_pixels*number_planes))       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");     pixel_info_length=image->columns*image->rows*MagickMax(number_planes,4);     pixel_info=AcquireVirtualMemory(pixel_info_length,sizeof(*pixels));     if (pixel_info == (MemoryInfo *) NULL)       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");

Fixed version (after fix):
 static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)     map_length,     number_colormaps,     number_planes,     number_planes_filled,     one,     offset,     pixel_info_length; static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)     if (image->alpha_trait != UndefinedPixelTrait)       number_planes++;     number_pixels=(MagickSizeType) image->columns*image->rows;     number_planes_filled=(number_planes % 2 == 0) ? number_planes :       number_planes+1;     if ((number_pixels*number_planes_filled) != (size_t) (number_pixels*          number_planes_filled))       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");     pixel_info_length=image->columns*image->rows*number_planes_filled;     pixel_info=AcquireVirtualMemory(pixel_info_length,sizeof(*pixels));     if (pixel_info == (MemoryInfo *) NULL)       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");

Patch:
patch: @@ -173,6 +173,7 @@ static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
     map_length,
     number_colormaps,
     number_planes,
+    number_planes_filled,
     one,
     offset,
     pixel_info_length;
@@ -308,9 +309,12 @@ static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
     if (image->alpha_trait != UndefinedPixelTrait)
       number_planes++;
     number_pixels=(MagickSizeType) image->columns*image->rows;
-    if ((number_pixels*number_planes) != (size_t) (number_pixels*number_planes))
+    number_planes_filled=(number_planes % 2 == 0) ? number_planes :
+      number_planes+1;
+    if ((number_pixels*number_planes_filled) != (size_t) (number_pixels*
+         number_planes_filled))
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-    pixel_info_length=image->columns*image->rows*MagickMax(number_planes,4);
+    pixel_info_length=image->columns*image->rows*number_planes_filled;
     pixel_info=AcquireVirtualMemory(pixel_info_length,sizeof(*pixels));
     if (pixel_info == (MemoryInfo *) NULL)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
path: coders/rle.c