CVE-2015-8897: Out-of-bounds Read (CWE-125)
value: The SpliceImage function in MagickCore/transform.c in ImageMagick before 6.9.2-4 allows remote attackers to cause a denial of service (application crash) via a crafted png file.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2017-03-15T19:59Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: C
Files changed: MagickCore/transform.c
Commit date: 2015-10-09 10:07:51 +0200
Commit message: Fixed out of bounds error in SpliceImage.

Diff: diff --git a/MagickCore/transform.c b/MagickCore/transform.c
index 2e9040b30..c3967242d 100644
--- a/MagickCore/transform.c
+++ b/MagickCore/transform.c
@@ -1720,10 +1720,11 @@ MagickExport Image *SpliceImage(const Image *image,
 
   RectangleInfo
     splice_geometry;
 
   ssize_t
+    columns,
     y;
 
   /*
     Allocate splice image.
   */
@@ -1808,10 +1809,11 @@ MagickExport Image *SpliceImage(const Image *image,
   /*
     Splice image.
   */
   status=MagickTrue;
   progress=0;
+  columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
   image_view=AcquireVirtualCacheView(image,exception);
   splice_view=AcquireAuthenticCacheView(splice_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(progress,status) \
     magick_threads(image,splice_image,1,1)
@@ -1827,19 +1829,20 @@ MagickExport Image *SpliceImage(const Image *image,
     register Quantum
       *restrict q;
 
     if (status == MagickFalse)
       continue;
-    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
+    p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
+      exception);
     q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
       exception);
     if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
       {
         status=MagickFalse;
         continue;
       }
-    for (x=0; x < splice_geometry.x; x++)
+    for (x=0; x < columns; x++)
     {
       register ssize_t
         i;
 
       if (GetPixelReadMask(image,p) == 0)
@@ -1929,22 +1932,22 @@ MagickExport Image *SpliceImage(const Image *image,
     register Quantum
       *restrict q;
 
     if (status == MagickFalse)
       continue;
-    p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
-      image->columns,1,exception);
-    if ((y < 0) || (y >= (ssize_t) splice_image->rows))
+    if ((y < 0) || (y >= (ssize_t)splice_image->rows))
       continue;
+    p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
+      splice_image->columns,1,exception);
     q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
       exception);
     if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
       {
         status=MagickFalse;
         continue;
       }
-    for (x=0; x < splice_geometry.x; x++)
+    for (x=0; x < columns; x++)
     {
       register ssize_t
         i;
 
       if (GetPixelReadMask(image,q) == 0)

Vulnerable code:     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
    for (x=0; x < splice_geometry.x; x++)
    p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
      image->columns,1,exception);
    if ((y < 0) || (y >= (ssize_t) splice_image->rows))
    for (x=0; x < splice_geometry.x; x++)
Fixed code:     columns,
  columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
    p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
      exception);
    for (x=0; x < columns; x++)
    if ((y < 0) || (y >= (ssize_t)splice_image->rows))
    p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
      splice_image->columns,1,exception);
    for (x=0; x < columns; x++)