CVE-2022-32545: Integer Overflow or Wraparound (CWE-190)
value: A vulnerability was found in ImageMagick, causing an outside the range of representable values of type 'unsigned char' at coders/psd.c, when crafted or untrusted input is processed. This leads to a negative impact to application availability or other problems related to undefined behavior.
CWE description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
CVSS v3 base score: 7.8
Published: 2022-06-16T18:15Z
Repository: https://github.com/ImageMagick/ImageMagick6
Language: C
Files changed: coders/emf.c, coders/psd.c, magick/widget.c, wand/animate.c, wand/display.c
Commit date: 2022-03-19 07:01:57 -0400
Commit message: Pull request: https://github.com/ImageMagick/ImageMagick/pull/4963

Diff: diff --git a/coders/emf.c b/coders/emf.c
index 39c0ac726b6..efc92c303f9 100644
--- a/coders/emf.c
+++ b/coders/emf.c
@@ -409,11 +409,12 @@ static HENHMETAFILE ReadEnhMetaFile(const char *path,ssize_t *width,
       CloseHandle(hFile);
       return((HENHMETAFILE) NULL);
     }
   ReadFile(hFile,pBits,dwSize,&dwSize,NULL);
   CloseHandle(hFile);
-  if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l)
+  if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l ||
+      (((PAPMHEADER) pBits)->wInch == 0))
     {
       pBits=(BYTE *) DestroyString((char *) pBits);
       return((HENHMETAFILE) NULL);
     }
   /*
diff --git a/coders/psd.c b/coders/psd.c
index 19d36f0a0e0..eedcf3782d8 100644
--- a/coders/psd.c
+++ b/coders/psd.c
@@ -1046,12 +1046,13 @@ static MagickBooleanType ReadPSDChannelPixels(Image *image,
         number_bits=(ssize_t) image->columns-x;
         if (number_bits > 8)
           number_bits=8;
         for (bit=0; bit < number_bits; bit++)
         {
-          SetPSDPixel(image,channels,type,packet_size,(((unsigned char) pixel)
-            & (0x01 << (7-bit))) != 0 ? 0 : QuantumRange,q++,indexes,x++);
+          SetPSDPixel(image,channels,type,packet_size,
+            (((unsigned char) ((ssize_t) pixel)) & (0x01 << (7-bit))) != 0 ? 0 :
+            QuantumRange,q++,indexes,x++);
         }
         if (x != (ssize_t) image->columns)
           x--;
         continue;
       }
diff --git a/magick/widget.c b/magick/widget.c
index 96fb7cd8dfd..dea54667d55 100644
--- a/magick/widget.c
+++ b/magick/widget.c
@@ -7859,10 +7859,12 @@ MagickExport int XMenuWidget(Display *display,XWindows *windows,
             *item='\0';
             state|=ExitState;
             break;
           }
         state&=(~InactiveWidgetState);
+        if (selection_info.height == 0)
+          break;
         id=(event.xbutton.y-top_offset)/(int) selection_info.height;
         selection_info.id=id;
         if ((id < 0) || (id >= (int) number_selections))
           break;
         /*
@@ -7912,10 +7914,12 @@ MagickExport int XMenuWidget(Display *display,XWindows *windows,
         if (event.xcrossing.window != windows->widget.id)
           break;
         if (event.xcrossing.state == 0)
           break;
         state&=(~InactiveWidgetState);
+        if (selection_info.height == 0)
+          break;
         id=((event.xcrossing.y-top_offset)/(int) selection_info.height);
         if ((selection_info.id >= 0) &&
             (selection_info.id < (int) number_selections))
           {
             /*
@@ -7998,10 +8002,12 @@ MagickExport int XMenuWidget(Display *display,XWindows *windows,
             }
         if (event.xmotion.window != windows->widget.id)
           break;
         if (state & InactiveWidgetState)
           break;
+        if (selection_info.height == 0)
+          break;
         id=(event.xmotion.y-top_offset)/(int) selection_info.height;
         if ((selection_info.id >= 0) &&
             (selection_info.id < (int) number_selections))
           {
             /*
diff --git a/wand/animate.c b/wand/animate.c
index 0f704361082..adc84d86790 100644
--- a/wand/animate.c
+++ b/wand/animate.c
@@ -1141,11 +1141,14 @@ WandExport MagickBooleanType AnimateImageCommand(ImageInfo *image_info,
           {
             i++;
             if (i == (ssize_t) argc)
               ThrowAnimateException(OptionError,"MissingArgument",option);
             if (XRemoteCommand(display,resource_info.window_id,argv[i]) != 0)
-              return(MagickFalse);
+              {
+                DestroyAnimate();
+                return(MagickFalse);
+              }
             i--;
             break;
           }
         if (LocaleCompare("repage",option+1) == 0)
           {
diff --git a/wand/display.c b/wand/display.c
index b7b9ed932d7..27abafa1b5c 100644
--- a/wand/display.c
+++ b/wand/display.c
@@ -1489,11 +1489,14 @@ WandExport MagickBooleanType DisplayImageCommand(ImageInfo *image_info,
           {
             i++;
             if (i == (ssize_t) argc)
               ThrowDisplayException(OptionError,"MissingArgument",option);
             if (XRemoteCommand(display,resource_info.window_id,argv[i]) != 0)
-              return(MagickFalse);
+              {
+                DestroyDisplay();
+                return(MagickFalse);
+              }
             i--;
             break;
           }
         if (LocaleCompare("repage",option+1) == 0)
           {

Vulnerable code:   if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l)
          SetPSDPixel(image,channels,type,packet_size,(((unsigned char) pixel)
            & (0x01 << (7-bit))) != 0 ? 0 : QuantumRange,q++,indexes,x++);
              return(MagickFalse);
              return(MagickFalse);
Fixed code:   if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l ||
      (((PAPMHEADER) pBits)->wInch == 0))
          SetPSDPixel(image,channels,type,packet_size,
            (((unsigned char) ((ssize_t) pixel)) & (0x01 << (7-bit))) != 0 ? 0 :
            QuantumRange,q++,indexes,x++);
        if (selection_info.height == 0)
          break;
        if (selection_info.height == 0)
          break;
        if (selection_info.height == 0)
          break;
              {
                DestroyAnimate();
                return(MagickFalse);
              }
              {
                DestroyDisplay();
                return(MagickFalse);
              }