CVE-2015-8900: Loop with Unreachable Exit Condition ('Infinite Loop') (CWE-835)
value: The ReadHDRImage function in coders/hdr.c in ImageMagick 6.x and 7.x allows remote attackers to cause a denial of service (infinite loop) via a crafted HDR file.
CWE description: The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.
CVSS v3 base score: 5.5
Published: 2017-02-27T22:59Z
Repository: https://github.com/ImageMagick/ImageMagick
Language: C
Files changed: coders/hdr.c
Commit date: 2015-01-25 07:27:09 +0000
Commit message: Fixed infinite loop and added checks for the sscanf result.

Diff: diff --git a/coders/hdr.c b/coders/hdr.c
index ccea76391..cd07f22e7 100644
--- a/coders/hdr.c
+++ b/coders/hdr.c
@@ -272,11 +272,11 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
           if (LocaleCompare(keyword,"Y") == 0)
             value_expected=MagickTrue;
           if (value_expected == MagickFalse)
             continue;
           p=value;
-          while ((c != '\n') && (c != '\0'))
+          while ((c != '\n') && (c != '\0') && (c != EOF))
           {
             if ((size_t) (p-value) < (MaxTextExtent-1))
               *p++=c;
             c=ReadBlobByte(image);
           }
@@ -317,22 +317,24 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 {
                   float
                     chromaticity[6],
                     white_point[2];
 
-                  (void) sscanf(value,"%g %g %g %g %g %g %g %g",
-                    &chromaticity[0],&chromaticity[1],&chromaticity[2],
-                    &chromaticity[3],&chromaticity[4],&chromaticity[5],
-                    &white_point[0],&white_point[1]);
-                  image->chromaticity.red_primary.x=chromaticity[0];
-                  image->chromaticity.red_primary.y=chromaticity[1];
-                  image->chromaticity.green_primary.x=chromaticity[2];
-                  image->chromaticity.green_primary.y=chromaticity[3];
-                  image->chromaticity.blue_primary.x=chromaticity[4];
-                  image->chromaticity.blue_primary.y=chromaticity[5];
-                  image->chromaticity.white_point.x=white_point[0],
-                  image->chromaticity.white_point.y=white_point[1];
+                  if (sscanf(value,"%g %g %g %g %g %g %g %g",&chromaticity[0],
+                      &chromaticity[1],&chromaticity[2],&chromaticity[3],
+                      &chromaticity[4],&chromaticity[5],&white_point[0],
+                      &white_point[1]) == 8)
+                    {
+                      image->chromaticity.red_primary.x=chromaticity[0];
+                      image->chromaticity.red_primary.y=chromaticity[1];
+                      image->chromaticity.green_primary.x=chromaticity[2];
+                      image->chromaticity.green_primary.y=chromaticity[3];
+                      image->chromaticity.blue_primary.x=chromaticity[4];
+                      image->chromaticity.blue_primary.y=chromaticity[5];
+                      image->chromaticity.white_point.x=white_point[0],
+                      image->chromaticity.white_point.y=white_point[1];
+                    }
                   break;
                 }
               (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
               (void) SetImageProperty(image,tag,value,exception);
               break;
@@ -347,13 +349,15 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 {
                   int
                     height,
                     width;
 
-                  (void) sscanf(value,"%d +X %d",&height,&width);
-                  image->columns=(size_t) width;
-                  image->rows=(size_t) height;
+                  if (sscanf(value,"%d +X %d",&height,&width) == 2)
+                    {
+                      image->columns=(size_t) width;
+                      image->rows=(size_t) height;
+                    }
                   break;
                 }
               (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
               (void) SetImageProperty(image,tag,value,exception);
               break;

Vulnerable code:           while ((c != '\n') && (c != '\0'))
                  (void) sscanf(value,"%g %g %g %g %g %g %g %g",
                    &chromaticity[0],&chromaticity[1],&chromaticity[2],
                    &chromaticity[3],&chromaticity[4],&chromaticity[5],
                    &white_point[0],&white_point[1]);
                  image->chromaticity.red_primary.x=chromaticity[0];
                  image->chromaticity.red_primary.y=chromaticity[1];
                  image->chromaticity.green_primary.x=chromaticity[2];
                  image->chromaticity.green_primary.y=chromaticity[3];
                  image->chromaticity.blue_primary.x=chromaticity[4];
                  image->chromaticity.blue_primary.y=chromaticity[5];
                  image->chromaticity.white_point.x=white_point[0],
                  image->chromaticity.white_point.y=white_point[1];
                  (void) sscanf(value,"%d +X %d",&height,&width);
                  image->columns=(size_t) width;
                  image->rows=(size_t) height;
Fixed code:           while ((c != '\n') && (c != '\0') && (c != EOF))
                  if (sscanf(value,"%g %g %g %g %g %g %g %g",&chromaticity[0],
                      &chromaticity[1],&chromaticity[2],&chromaticity[3],
                      &chromaticity[4],&chromaticity[5],&white_point[0],
                      &white_point[1]) == 8)
                    {
                      image->chromaticity.red_primary.x=chromaticity[0];
                      image->chromaticity.red_primary.y=chromaticity[1];
                      image->chromaticity.green_primary.x=chromaticity[2];
                      image->chromaticity.green_primary.y=chromaticity[3];
                      image->chromaticity.blue_primary.x=chromaticity[4];
                      image->chromaticity.blue_primary.y=chromaticity[5];
                      image->chromaticity.white_point.x=white_point[0],
                      image->chromaticity.white_point.y=white_point[1];
                    }
                  if (sscanf(value,"%d +X %d",&height,&width) == 2)
                    {
                      image->columns=(size_t) width;
                      image->rows=(size_t) height;
                    }