CVE-2016-5689: NULL Pointer Dereference (CWE-476)
value: The DCM reader in ImageMagick before 6.9.4-5 and 7.x before 7.0.1-7 allows remote attackers to have unspecified impact by leveraging lack of NULL pointer checks.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 9.8
Published: 2016-12-13T15:59Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: Other
Files changed: ChangeLog, coders/dcm.c
Commit date: 2016-05-30 07:51:39 -0400
Commit message: Add additional checks to DCM reader to prevent data-driven faults (bug report from Hanno Böck

Diff: diff --git a/ChangeLog b/ChangeLog
index 70f2d014da..de0b1fa589 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,10 +3,12 @@
     https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=29754).
   * Fix stroke offset problem for -annotate (reference
     https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=29626).
   * Don't interpret -fx option arguments (reference
     https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=29774);
+  * Add additional checks to DCM reader to prevent data-driven faults (bug
+    report from Hanno Böck).
 
 2016-05-21  7.0.1-6 Cristy  <quetzlzacatenango@image...>
   * Release ImageMagick version 7.0.1-6, GIT revision 18241:d4f277c:20160521.
 
 2016-05-20  7.0.1-6 Cristy  <quetzlzacatenango@image...>
diff --git a/coders/dcm.c b/coders/dcm.c
index f86e573265..26125f778b 100644
--- a/coders/dcm.c
+++ b/coders/dcm.c
@@ -3214,10 +3214,12 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
           case 0x0004:
           {
             /*
               Photometric interpretation.
             */
+            if (data == (unsigned char *) NULL)
+              break;
             for (i=0; i < (ssize_t) MagickMin(length,MagickPathExtent-1); i++)
               photometric[i]=(char) data[i];
             photometric[i]='\0';
             polarity=LocaleCompare(photometric,"MONOCHROME1 ") == 0 ?
               MagickTrue : MagickFalse;
@@ -3235,10 +3237,12 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
           case 0x0008:
           {
             /*
               Number of frames.
             */
+            if (data == (unsigned char *) NULL)
+              break;
             number_scenes=StringToUnsignedLong((char *) data);
             break;
           }
           case 0x0010:
           {
@@ -3672,11 +3676,11 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
       length=(size_t) (GetQuantumRange(depth)+1);
       scale=(Quantum *) AcquireQuantumMemory(length,sizeof(*scale));
       if (scale == (Quantum *) NULL)
         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
       range=GetQuantumRange(depth);
-      for (i=0; i < (ssize_t) (GetQuantumRange(depth)+1); i++)
+      for (i=0; i <= (ssize_t) GetQuantumRange(depth); i++)
         scale[i]=ScaleAnyToQuantum((size_t) i,range);
     }
   if (image->compression == RLECompression)
     {
       size_t
@@ -3963,13 +3967,16 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 pixel.red&=mask;
                 pixel.green&=mask;
                 pixel.blue&=mask;
                 if (scale != (Quantum *) NULL)
                   {
-                    pixel.red=scale[pixel.red];
-                    pixel.green=scale[pixel.green];
-                    pixel.blue=scale[pixel.blue];
+                    if (pixel.red <= GetQuantumRange(depth))
+                      pixel.red=scale[pixel.red];
+                    if (pixel.green <= GetQuantumRange(depth))
+                      pixel.green=scale[pixel.green];
+                    if (pixel.blue <= GetQuantumRange(depth))
+                      pixel.blue=scale[pixel.blue];
                   }
               }
             SetPixelRed(image,(Quantum) pixel.red,q);
             SetPixelGreen(image,(Quantum) pixel.green,q);
             SetPixelBlue(image,(Quantum) pixel.blue,q);

Vulnerable code:       for (i=0; i < (ssize_t) (GetQuantumRange(depth)+1); i++)
                    pixel.red=scale[pixel.red];
                    pixel.green=scale[pixel.green];
                    pixel.blue=scale[pixel.blue];
Fixed code:   * Add additional checks to DCM reader to prevent data-driven faults (bug
    report from Hanno Böck).
            if (data == (unsigned char *) NULL)
              break;
            if (data == (unsigned char *) NULL)
              break;
      for (i=0; i <= (ssize_t) GetQuantumRange(depth); i++)
                    if (pixel.red <= GetQuantumRange(depth))
                      pixel.red=scale[pixel.red];
                    if (pixel.green <= GetQuantumRange(depth))
                      pixel.green=scale[pixel.green];
                    if (pixel.blue <= GetQuantumRange(depth))
                      pixel.blue=scale[pixel.blue];