CVE-2016-5691: Improper Input Validation (CWE-20)
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 validation of (1) pixel.red, (2) pixel.green, and (3) pixel.blue.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
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];