Vulnerability: coders/psd.c in ImageMagick allows remote attackers to cause a denial of service (out-of-bounds read) via a crafted PSD file.
Vulnerability ID: CVE-2016-7532
CWE: CWE-125
Severity score: 2.9
Project: https://github.com/ImageMagick/ImageMagick
Published: 2017-04-20
File: coders/psd.c
Commit message: Added check for out of bounds read (https://github.com/ImageMagick/ImageMagick/issues/108).
Commit author: dirk

Vulnerable version (before fix):
 static void RemoveResolutionFromResourceBlock(StringInfo *bim_profile)     register unsigned char       *q;      q=(unsigned char *) p;     if (LocaleNCompare((const char *) p,"8BIM",4) != 0)       break;     p=PushLongPixel(MSBEndian,p,&long_sans);     p=PushShortPixel(MSBEndian,p,&id);     p=PushShortPixel(MSBEndian,p,&short_sans);     p=PushLongPixel(MSBEndian,p,&count);     if ((id == 0x000003ed) && (PSDQuantum(count) < (ssize_t) (length-12)))       {         (void) CopyMagickMemory(q,q+PSDQuantum(count)+12,length-           (PSDQuantum(count)+12)-(q-datum));         SetStringInfoLength(bim_profile,length-(PSDQuantum(count)+12));         break;       }     p+=count; static void RemoveResolutionFromResourceBlock(StringInfo *bim_profile)   } }  static MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image,   ExceptionInfo *exception) {   const char     *property;

Fixed version (after fix):
 static void RemoveResolutionFromResourceBlock(StringInfo *bim_profile)     register unsigned char       *q;      ssize_t       cnt;      q=(unsigned char *) p;     if (LocaleNCompare((const char *) p,"8BIM",4) != 0)       return;     p=PushLongPixel(MSBEndian,p,&long_sans);     p=PushShortPixel(MSBEndian,p,&id);     p=PushShortPixel(MSBEndian,p,&short_sans);     p=PushLongPixel(MSBEndian,p,&count);     cnt=PSDQuantum(count);     if (cnt < 0)       return;     if ((id == 0x000003ed) && (cnt < (ssize_t) (length-12)))       {         (void) CopyMagickMemory(q,q+cnt+12,length-(cnt+12)-(q-datum));         SetStringInfoLength(bim_profile,length-(cnt+12));         break;       }     p+=count; static void RemoveResolutionFromResourceBlock(StringInfo *bim_profile)   } }  static MagickBooleanType WritePSDImage(const ImageInfo *image_info,   Image *image,ExceptionInfo *exception) {   const char     *property;

Patch:
patch: @@ -2605,18 +2605,23 @@ static void RemoveResolutionFromResourceBlock(StringInfo *bim_profile)
     register unsigned char
       *q;
 
+    ssize_t
+      cnt;
+
     q=(unsigned char *) p;
     if (LocaleNCompare((const char *) p,"8BIM",4) != 0)
-      break;
+      return;
     p=PushLongPixel(MSBEndian,p,&long_sans);
     p=PushShortPixel(MSBEndian,p,&id);
     p=PushShortPixel(MSBEndian,p,&short_sans);
     p=PushLongPixel(MSBEndian,p,&count);
-    if ((id == 0x000003ed) && (PSDQuantum(count) < (ssize_t) (length-12)))
+    cnt=PSDQuantum(count);
+    if (cnt < 0)
+      return;
+    if ((id == 0x000003ed) && (cnt < (ssize_t) (length-12)))
       {
-        (void) CopyMagickMemory(q,q+PSDQuantum(count)+12,length-
-          (PSDQuantum(count)+12)-(q-datum));
-        SetStringInfoLength(bim_profile,length-(PSDQuantum(count)+12));
+        (void) CopyMagickMemory(q,q+cnt+12,length-(cnt+12)-(q-datum));
+        SetStringInfoLength(bim_profile,length-(cnt+12));
         break;
       }
     p+=count;
@@ -2625,8 +2630,8 @@ static void RemoveResolutionFromResourceBlock(StringInfo *bim_profile)
   }
 }
 
-static MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image,
-  ExceptionInfo *exception)
+static MagickBooleanType WritePSDImage(const ImageInfo *image_info,
+  Image *image,ExceptionInfo *exception)
 {
   const char
     *property;
path: coders/psd.c