CVE-2019-13308 (published 2019-07-05T01:15Z)

ImageMagick 7.0.8-50 Q16 has a heap-based buffer overflow in MagickCore/fourier.c in ComplexImage.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-787
cwe_name: Out-of-bounds Write
description: The product writes data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/ImageMagick/ImageMagick
commit_details: repo_url: https://github.com/ImageMagick/ImageMagick
author: Cristy
author_date: 2019-06-17 08:48:14-04:00
msg: https://github.com/ImageMagick/ImageMagick/issues/1595
repository: repo_url: https://github.com/ImageMagick/ImageMagick
repo_name: ImageMagick/ImageMagick
description: 🧙‍♂️ ImageMagick 7
repo_language: C
owner: ImageMagick
file_changes: filename: fourier.c
change_type: ModificationType.MODIFY
diff: @@ -226,9 +226,9 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
   progress=0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static) shared(progress,status) \
-    magick_number_threads(images,complex_images,images->rows,1L)
+    magick_number_threads(Cr_image,complex_images,Cr_image->rows,1L)
 #endif
-  for (y=0; y < (ssize_t) images->rows; y++)
+  for (y=0; y < (ssize_t) Cr_image->rows; y++)
   {
     register const Quantum
       *magick_restrict Ai,
@@ -245,14 +245,10 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
 
     if (status == MagickFalse)
       continue;
-    Ar=GetCacheViewVirtualPixels(Ar_view,0,y,
-      MagickMax(Ar_image->columns,Cr_image->columns),1,exception);
-    Ai=GetCacheViewVirtualPixels(Ai_view,0,y,
-      MagickMax(Ai_image->columns,Ci_image->columns),1,exception);
-    Br=GetCacheViewVirtualPixels(Br_view,0,y,
-      MagickMax(Br_image->columns,Cr_image->columns),1,exception);
-    Bi=GetCacheViewVirtualPixels(Bi_view,0,y,
-      MagickMax(Bi_image->columns,Ci_image->columns),1,exception);
+    Ar=GetCacheViewVirtualPixels(Ar_view,0,y,Cr_image->columns,1,exception);
+    Ai=GetCacheViewVirtualPixels(Ai_view,0,y,Cr_image->columns,1,exception);
+    Br=GetCacheViewVirtualPixels(Br_view,0,y,Cr_image->columns,1,exception);
+    Bi=GetCacheViewVirtualPixels(Bi_view,0,y,Cr_image->columns,1,exception);
     Cr=QueueCacheViewAuthenticPixels(Cr_view,0,y,Cr_image->columns,1,exception);
     Ci=QueueCacheViewAuthenticPixels(Ci_view,0,y,Ci_image->columns,1,exception);
     if ((Ar == (const Quantum *) NULL) || (Ai == (const Quantum *) NULL) || 
@@ -262,12 +258,12 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
         status=MagickFalse;
         continue;
       }
-    for (x=0; x < (ssize_t) images->columns; x++)
+    for (x=0; x < (ssize_t) Cr_image->columns; x++)
     {
       register ssize_t
         i;
 
-      for (i=0; i < (ssize_t) GetPixelChannels(images); i++)
+      for (i=0; i < (ssize_t) GetPixelChannels(Cr_image); i++)
       {
         switch (op)
         {
@@ -289,21 +285,21 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
             double
               gamma;
 
-            gamma=PerceptibleReciprocal(Br[i]*Br[i]+Bi[i]*Bi[i]+snr);
-            Cr[i]=gamma*(Ar[i]*Br[i]+Ai[i]*Bi[i]);
-            Ci[i]=gamma*(Ai[i]*Br[i]-Ar[i]*Bi[i]);
+            gamma=PerceptibleReciprocal((double) Br[i]*Br[i]+Bi[i]*Bi[i]+snr);
+            Cr[i]=gamma*((double) Ar[i]*Br[i]+(double) Ai[i]*Bi[i]);
+            Ci[i]=gamma*((double) Ai[i]*Br[i]-(double) Ar[i]*Bi[i]);
             break;
           }
           case MagnitudePhaseComplexOperator:
           {
-            Cr[i]=sqrt(Ar[i]*Ar[i]+Ai[i]*Ai[i]);
-            Ci[i]=atan2(Ai[i],Ar[i])/(2.0*MagickPI)+0.5;
+            Cr[i]=sqrt((double) Ar[i]*Ar[i]+(double) Ai[i]*Ai[i]);
+            Ci[i]=atan2((double) Ai[i],(double) Ar[i])/(2.0*MagickPI)+0.5;
             break;
           }
           case MultiplyComplexOperator:
           {
-            Cr[i]=QuantumScale*(Ar[i]*Br[i]-Ai[i]*Bi[i]);
-            Ci[i]=QuantumScale*(Ai[i]*Br[i]+Ar[i]*Bi[i]);
+            Cr[i]=QuantumScale*((double) Ar[i]*Br[i]-(double) Ai[i]*Bi[i]);
+            Ci[i]=QuantumScale*((double) Ai[i]*Br[i]+(double) Ar[i]*Bi[i]);
             break;
           }
           case RealImaginaryComplexOperator:

programming_language: Objective-C
filename: gif.c
change_type: ModificationType.MODIFY
diff: @@ -673,13 +673,15 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
       /*
         Probe hash table.
       */
+      next_pixel=MagickFalse;
+      displacement=1;
       index=(Quantum) ((size_t) GetPixelIndex(image,p) & 0xff);
       p+=GetPixelChannels(image);
       k=(ssize_t) (((size_t) index << (MaxGIFBits-8))+waiting_code);
       if (k >= MaxHashTable)
         k-=MaxHashTable;
-      next_pixel=MagickFalse;
-      displacement=1;
+      if (k < 0)
+        continue;
       if (hash_code[k] > 0)
         {
           if ((hash_prefix[k] == waiting_code) &&

programming_language: C++
repo_url: https://github.com/ImageMagick/ImageMagick6
commit_details: repo_url: https://github.com/ImageMagick/ImageMagick6
author: Cristy
author_date: 2019-06-17 08:48:42-04:00
msg: https://github.com/ImageMagick/ImageMagick/issues/1595
repository: repo_url: https://github.com/ImageMagick/ImageMagick6
repo_name: ImageMagick/ImageMagick6
description: 🧙‍♂️ ImageMagick 6
repo_language: C
owner: ImageMagick
file_changes: filename: gif.c
change_type: ModificationType.MODIFY
diff: @@ -685,13 +685,15 @@ static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
       /*
         Probe hash table.
       */
+      next_pixel=MagickFalse;
+      displacement=1;
       index=(IndexPacket) ((size_t) GetPixelIndex(indexes+x) & 0xff);
       p++;
       k=(ssize_t) (((size_t) index << (MaxGIFBits-8))+waiting_code);
       if (k >= MaxHashTable)
         k-=MaxHashTable;
-      next_pixel=MagickFalse;
-      displacement=1;
+      if (k < 0)
+        continue;
       if (hash_code[k] > 0)
         {
           if ((hash_prefix[k] == waiting_code) &&

programming_language: C
filename: fourier.c
change_type: ModificationType.MODIFY
diff: @@ -226,9 +226,9 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
   progress=0;
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static) shared(progress,status) \
-    magick_number_threads(images,complex_images,images->rows,1L)
+    magick_number_threads(Cr_image,complex_images,Cr_image->rows,1L)
 #endif
-  for (y=0; y < (ssize_t) images->rows; y++)
+  for (y=0; y < (ssize_t) Cr_image->rows; y++)
   {
     register const PixelPacket
       *magick_restrict Ai,
@@ -245,14 +245,10 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
 
     if (status == MagickFalse)
       continue;
-    Ar=GetCacheViewVirtualPixels(Ar_view,0,y,
-      MagickMax(Ar_image->columns,Cr_image->columns),1,exception);
-    Ai=GetCacheViewVirtualPixels(Ai_view,0,y,
-      MagickMax(Ai_image->columns,Ci_image->columns),1,exception);
-    Br=GetCacheViewVirtualPixels(Br_view,0,y,
-      MagickMax(Br_image->columns,Cr_image->columns),1,exception);
-    Bi=GetCacheViewVirtualPixels(Bi_view,0,y,
-      MagickMax(Bi_image->columns,Ci_image->columns),1,exception);
+    Ar=GetCacheViewVirtualPixels(Ar_view,0,y,Cr_image->columns,1,exception);
+    Ai=GetCacheViewVirtualPixels(Ai_view,0,y,Cr_image->columns,1,exception);
+    Br=GetCacheViewVirtualPixels(Br_view,0,y,Cr_image->columns,1,exception);
+    Bi=GetCacheViewVirtualPixels(Bi_view,0,y,Cr_image->columns,1,exception);
     Cr=QueueCacheViewAuthenticPixels(Cr_view,0,y,Cr_image->columns,1,exception);
     Ci=QueueCacheViewAuthenticPixels(Ci_view,0,y,Ci_image->columns,1,exception);
     if ((Ar == (const PixelPacket *) NULL) ||
@@ -264,7 +260,7 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
         status=MagickFalse;
         continue;
       }
-    for (x=0; x < (ssize_t) images->columns; x++)
+    for (x=0; x < (ssize_t) Cr_image->columns; x++)
     {
       switch (op)
       {
@@ -305,55 +301,70 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
             gamma;
 
           gamma=PerceptibleReciprocal(Br->red*Br->red+Bi->red*Bi->red+snr);
-          Cr->red=gamma*(Ar->red*Br->red+Ai->red*Bi->red);
-          Ci->red=gamma*(Ai->red*Br->red-Ar->red*Bi->red);
-          gamma=PerceptibleReciprocal(Br->green*Br->green+Bi->green*Bi->green+
-            snr);
-          Cr->green=gamma*(Ar->green*Br->green+Ai->green*Bi->green);
-          Ci->green=gamma*(Ai->green*Br->green-Ar->green*Bi->green);
-          gamma=PerceptibleReciprocal(Br->blue*Br->blue+Bi->blue*Bi->blue+snr);
-          Cr->blue=gamma*(Ar->blue*Br->blue+Ai->blue*Bi->blue);
-          Ci->blue=gamma*(Ai->blue*Br->blue-Ar->blue*Bi->blue);
+          Cr->red=gamma*((double) Ar->red*Br->red+(double) Ai->red*Bi->red);
+          Ci->red=gamma*((double) Ai->red*Br->red-(double) Ar->red*Bi->red);
+          gamma=PerceptibleReciprocal((double) Br->green*Br->green+(double)
+            Bi->green*Bi->green+snr);
+          Cr->green=gamma*((double) Ar->green*Br->green+(double)
+            Ai->green*Bi->green);
+          Ci->green=gamma*((double) Ai->green*Br->green-(double)
+            Ar->green*Bi->green);
+          gamma=PerceptibleReciprocal((double) Br->blue*Br->blue+(double)
+            Bi->blue*Bi->blue+snr);
+          Cr->blue=gamma*((double) Ar->blue*Br->blue+(double)
+            Ai->blue*Bi->blue);
+          Ci->blue=gamma*((double) Ai->blue*Br->blue-(double)
+             Ar->blue*Bi->blue);
           if (images->matte != MagickFalse)
             {
-              gamma=PerceptibleReciprocal(Br->opacity*Br->opacity+Bi->opacity*
-                Bi->opacity+snr);
-              Cr->opacity=gamma*(Ar->opacity*Br->opacity+Ai->opacity*
-                Bi->opacity);
-              Ci->opacity=gamma*(Ai->opacity*Br->opacity-Ar->opacity*
-                Bi->opacity);
+              gamma=PerceptibleReciprocal((double) Br->opacity*Br->opacity+
+                (double) Bi->opacity*Bi->opacity+snr);
+              Cr->opacity=gamma*((double) Ar->opacity*Br->opacity+(double)
+                Ai->opacity*Bi->opacity);
+              Ci->opacity=gamma*((double) Ai->opacity*Br->opacity-(double)
+                Ar->opacity*Bi->opacity);
             }
           break;
         }
         case MagnitudePhaseComplexOperator:
         {
-          Cr->red=sqrt(Ar->red*Ar->red+Ai->red*Ai->red);
-          Ci->red=atan2(Ai->red,Ar->red)/(2.0*MagickPI)+0.5;
-          Cr->green=sqrt(Ar->green*Ar->green+Ai->green*Ai->green);
-          Ci->green=atan2(Ai->green,Ar->green)/(2.0*MagickPI)+0.5;
-          Cr->blue=sqrt(Ar->blue*Ar->blue+Ai->blue*Ai->blue);
+          Cr->red=sqrt((double) Ar->red*Ar->red+(double) Ai->red*Ai->red);
+          Ci->red=atan2((double) Ai->red,(double) Ar->red)/(2.0*MagickPI)+0.5;
+          Cr->green=sqrt((double) Ar->green*Ar->green+(double)
+            Ai->green*Ai->green);
+          Ci->green=atan2((double) Ai->green,(double) Ar->green)/
+            (2.0*MagickPI)+0.5;
+          Cr->blue=sqrt((double) Ar->blue*Ar->blue+(double) Ai->blue*Ai->blue);
           Ci->blue=atan2(Ai->blue,Ar->blue)/(2.0*MagickPI)+0.5;
           if (images->matte != MagickFalse)
             {
-              Cr->opacity=sqrt(Ar->opacity*Ar->opacity+Ai->opacity*Ai->opacity);
-              Ci->opacity=atan2(Ai->opacity,Ar->opacity)/(2.0*MagickPI)+0.5;
+              Cr->opacity=sqrt((double) Ar->opacity*Ar->opacity+(double)
+                Ai->opacity*Ai->opacity);
+              Ci->opacity=atan2((double) Ai->opacity,(double) Ar->opacity)/
+                (2.0*MagickPI)+0.5;
             }
           break;
         }
         case MultiplyComplexOperator:
         {
-          Cr->red=QuantumScale*(Ar->red*Br->red-Ai->red*Bi->red);
-          Ci->red=QuantumScale*(Ai->red*Br->red+Ar->red*Bi->red);
-          Cr->green=QuantumScale*(Ar->green*Br->green-Ai->green*Bi->green);
-          Ci->green=QuantumScale*(Ai->green*Br->green+Ar->green*Bi->green);
-          Cr->blue=QuantumScale*(Ar->blue*Br->blue-Ai->blue*Bi->blue);
-          Ci->blue=QuantumScale*(Ai->blue*Br->blue+Ar->blue*Bi->blue);
+          Cr->red=QuantumScale*((double) Ar->red*Br->red-(double)
+            Ai->red*Bi->red);
+          Ci->red=QuantumScale*((double) Ai->red*Br->red+(double)
+            Ar->red*Bi->red);
+          Cr->green=QuantumScale*((double) Ar->green*Br->green-(double)
+            Ai->green*Bi->green);
+          Ci->green=QuantumScale*((double) Ai->green*Br->green+(double)
+            Ar->green*Bi->green);
+          Cr->blue=QuantumScale*((double) Ar->blue*Br->blue-(double)
+            Ai->blue*Bi->blue);
+          Ci->blue=QuantumScale*((double) Ai->blue*Br->blue+(double)
+            Ar->blue*Bi->blue);
           if (images->matte != MagickFalse)
             {
-              Cr->opacity=QuantumScale*(Ar->opacity*Br->opacity-Ai->opacity*
-                Bi->opacity);
-              Ci->opacity=QuantumScale*(Ai->opacity*Br->opacity+Ar->opacity*
-                Bi->opacity);
+              Cr->opacity=QuantumScale*((double) Ar->opacity*Br->opacity-
+                (double) Ai->opacity*Bi->opacity);
+              Ci->opacity=QuantumScale*((double) Ai->opacity*Br->opacity+
+                (double) Ar->opacity*Bi->opacity);
             }
           break;
         }
@@ -380,7 +391,7 @@ MagickExport Image *ComplexImages(const Image *images,const ComplexOperator op,
           Ci->green=Ai->green-Bi->green;
           Cr->blue=Ar->blue-Br->blue;
           Ci->blue=Ai->blue-Bi->blue;
-          if (images->matte != MagickFalse)
+          if (Cr_image->matte != MagickFalse)
             {
               Cr->opacity=Ar->opacity-Br->opacity;
               Ci->opacity=Ai->opacity-Bi->opacity;

programming_language: Objective-C