CVE-2021-20224 (published 2022-08-25T20:15Z)

An integer overflow issue was discovered in ImageMagick's ExportIndexQuantum() function in MagickCore/quantum-export.c. Function calls to GetPixelIndex() could result in values outside the range of representable for the 'unsigned char'. When ImageMagick processes a crafted pdf file, this could lead to an undefined behaviour or a crash.

CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-190
cwe_name: Integer Overflow or Wraparound
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.
extended_description: 
            
            
            
            
         
         

Fix information:
repo_url: https://github.com/ImageMagick/ImageMagick
commit_details: repo_url: https://github.com/ImageMagick/ImageMagick
author: ruc_zhangxiaohui
author_date: 2021-01-07 07:15:12+08:00
msg: outside the range of representable values of type 'unsigned char' (#3083)

Co-authored-by: Zhang Xiaohui <ruc_zhangxiaohui@163.com>
repository: repo_url: https://github.com/ImageMagick/ImageMagick
repo_name: ImageMagick/ImageMagick
description: 🧙‍♂️ ImageMagick 7
repo_language: C
owner: ImageMagick
file_changes: filename: quantum-export.c
change_type: ModificationType.MODIFY
diff: @@ -2530,28 +2530,28 @@ static void ExportIndexQuantum(const Image *image,QuantumInfo *quantum_info,
 
       for (x=((ssize_t) number_pixels-7); x > 0; x-=8)
       {
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q=((pixel & 0x01) << 7);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0x01) << 6);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0x01) << 5);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0x01) << 4);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0x01) << 3);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0x01) << 2);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0x01) << 1);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0x01) << 0);
         p+=GetPixelChannels(image);
         q++;
@@ -2561,7 +2561,7 @@ static void ExportIndexQuantum(const Image *image,QuantumInfo *quantum_info,
           *q='\0';
           for (bit=7; bit >= (ssize_t) (8-(number_pixels % 8)); bit--)
           {
-            pixel=(unsigned char) GetPixelIndex(image,p);
+            pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
             *q|=((pixel & 0x01) << (unsigned char) bit);
             p+=GetPixelChannels(image);
           }
@@ -2576,17 +2576,17 @@ static void ExportIndexQuantum(const Image *image,QuantumInfo *quantum_info,
 
       for (x=0; x < (ssize_t) (number_pixels-1) ; x+=2)
       {
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q=((pixel & 0xf) << 4);
         p+=GetPixelChannels(image);
-        pixel=(unsigned char) GetPixelIndex(image,p);
+        pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
         *q|=((pixel & 0xf) << 0);
         p+=GetPixelChannels(image);
         q++;
       }
       if ((number_pixels % 2) != 0)
         {
-          pixel=(unsigned char) GetPixelIndex(image,p);
+          pixel=(unsigned char) ((ssize_t) GetPixelIndex(image,p));
           *q=((pixel & 0xf) << 4);
           p+=GetPixelChannels(image);
           q++;
@@ -2597,7 +2597,7 @@ static void ExportIndexQuantum(const Image *image,QuantumInfo *quantum_info,
     {
       for (x=0; x < (ssize_t) number_pixels; x++)
       {
-        q=PopCharPixel((unsigned char) GetPixelIndex(image,p),q);
+        q=PopCharPixel((unsigned char) ((ssize_t) GetPixelIndex(image,p)),q);
         p+=GetPixelChannels(image);
         q+=quantum_info->pad;
       }

programming_language: Objective-C
repo_url: https://github.com/ImageMagick/ImageMagick6
commit_details: repo_url: https://github.com/ImageMagick/ImageMagick6
author: Cristy
author_date: 2021-01-06 18:34:31-05:00
msg: https://github.com/ImageMagick/ImageMagick/pull/3083
repository: repo_url: https://github.com/ImageMagick/ImageMagick6
repo_name: ImageMagick/ImageMagick6
description: 🧙‍♂️ ImageMagick 6
repo_language: C
owner: ImageMagick
file_changes: filename: quantum-export.c
change_type: ModificationType.MODIFY
diff: @@ -2516,21 +2516,21 @@ static void ExportIndexQuantum(const Image *image,QuantumInfo *quantum_info,
 
       for (x=((ssize_t) number_pixels-7); x > 0; x-=8)
       {
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q=((pixel & 0x01) << 7);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 6);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 5);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 4);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 3);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 2);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 1);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 0);
         q++;
       }
@@ -2539,7 +2539,7 @@ static void ExportIndexQuantum(const Image *image,QuantumInfo *quantum_info,
           *q='\0';
           for (bit=7; bit >= (ssize_t) (8-(number_pixels % 8)); bit--)
           {
-            pixel=(unsigned char) *indexes++;
+            pixel=(unsigned char) ((ssize_t) *indexes++);
             *q|=((pixel & 0x01) << (unsigned char) bit);
           }
           q++;
@@ -2553,15 +2553,15 @@ static void ExportIndexQuantum(const Image *image,QuantumInfo *quantum_info,
 
       for (x=0; x < (ssize_t) (number_pixels-1) ; x+=2)
       {
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q=((pixel & 0xf) << 4);
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0xf) << 0);
         q++;
       }
       if ((number_pixels % 2) != 0)
         {
-          pixel=(unsigned char) *indexes++;
+          pixel=(unsigned char) ((ssize_t) *indexes++);
           *q=((pixel & 0xf) << 4);
           q++;
         }
@@ -2669,25 +2669,25 @@ static void ExportIndexAlphaQuantum(const Image *image,
 
       for (x=((ssize_t) number_pixels-3); x > 0; x-=4)
       {
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q=((pixel & 0x01) << 7);
         pixel=(unsigned char) (GetPixelOpacity(p) == (Quantum)
           TransparentOpacity ? 1 : 0);
         *q|=((pixel & 0x01) << 6);
         p++;
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 5);
         pixel=(unsigned char) (GetPixelOpacity(p) == (Quantum)
           TransparentOpacity ? 1 : 0);
         *q|=((pixel & 0x01) << 4);
         p++;
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 3);
         pixel=(unsigned char) (GetPixelOpacity(p) == (Quantum)
           TransparentOpacity ? 1 : 0);
         *q|=((pixel & 0x01) << 2);
         p++;
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q|=((pixel & 0x01) << 1);
         pixel=(unsigned char) (GetPixelOpacity(p) == (Quantum)
           TransparentOpacity ? 1 : 0);
@@ -2700,7 +2700,7 @@ static void ExportIndexAlphaQuantum(const Image *image,
           *q='\0';
           for (bit=3; bit >= (ssize_t) (4-(number_pixels % 4)); bit-=2)
           {
-            pixel=(unsigned char) *indexes++;
+            pixel=(unsigned char) ((ssize_t) *indexes++);
             *q|=((pixel & 0x01) << (unsigned char) (bit+4));
             pixel=(unsigned char) (GetPixelOpacity(p) == (Quantum)
               TransparentOpacity ? 1 : 0);
@@ -2718,10 +2718,10 @@ static void ExportIndexAlphaQuantum(const Image *image,
 
       for (x=0; x < (ssize_t) number_pixels ; x++)
       {
-        pixel=(unsigned char) *indexes++;
+        pixel=(unsigned char) ((ssize_t) *indexes++);
         *q=((pixel & 0xf) << 4);
-        pixel=(unsigned char) (16*QuantumScale*((Quantum) (QuantumRange-
-          GetPixelOpacity(p)))+0.5);
+        pixel=(unsigned char) ((ssize_t) (16*QuantumScale*((Quantum)
+          (QuantumRange-GetPixelOpacity(p)))+0.5));
         *q|=((pixel & 0xf) << 0);
         p++;
         q++;
@@ -2752,7 +2752,8 @@ static void ExportIndexAlphaQuantum(const Image *image,
         {
           for (x=0; x < (ssize_t) number_pixels; x++)
           {
-            q=PopShortPixel(quantum_info->endian,(unsigned short) GetPixelIndex(indexes+x),q);
+            q=PopShortPixel(quantum_info->endian,(unsigned short)
+              ((ssize_t) GetPixelIndex(indexes+x)),q);
             pixel=SinglePrecisionToHalf(QuantumScale*GetPixelAlpha(p));
             q=PopShortPixel(quantum_info->endian,pixel,q);
             p++;
@@ -2762,7 +2763,8 @@ static void ExportIndexAlphaQuantum(const Image *image,
         }
       for (x=0; x < (ssize_t) number_pixels; x++)
       {
-        q=PopShortPixel(quantum_info->endian,(unsigned short) GetPixelIndex(indexes+x),q);
+        q=PopShortPixel(quantum_info->endian,(unsigned short)
+          ((ssize_t) GetPixelIndex(indexes+x)),q);
         pixel=ScaleQuantumToShort((Quantum) (QuantumRange-GetPixelOpacity(p)));
         q=PopShortPixel(quantum_info->endian,pixel,q);
         p++;
@@ -2792,7 +2794,8 @@ static void ExportIndexAlphaQuantum(const Image *image,
         }
       for (x=0; x < (ssize_t) number_pixels; x++)
       {
-        q=PopLongPixel(quantum_info->endian,(unsigned int) GetPixelIndex(indexes+x),q);
+        q=PopLongPixel(quantum_info->endian,(unsigned int)
+          GetPixelIndex(indexes+x),q);
         pixel=ScaleQuantumToLong((Quantum) (QuantumRange-GetPixelOpacity(p)));
         q=PopLongPixel(quantum_info->endian,pixel,q);
         p++;
@@ -2827,10 +2830,9 @@ static void ExportIndexAlphaQuantum(const Image *image,
       range=GetQuantumRange(quantum_info->depth);
       for (x=0; x < (ssize_t) number_pixels; x++)
       {
-        q=PopQuantumPixel(quantum_info,
-          GetPixelIndex(indexes+x),q);
-        q=PopQuantumPixel(quantum_info,
-          ScaleQuantumToAny((Quantum) (GetPixelAlpha(p)),range),q);
+        q=PopQuantumPixel(quantum_info,GetPixelIndex(indexes+x),q);
+        q=PopQuantumPixel(quantum_info,ScaleQuantumToAny((Quantum)
+          (GetPixelAlpha(p)),range),q);
         p++;
         q+=quantum_info->pad;
       }
@@ -3035,8 +3037,8 @@ static void ExportRedQuantum(QuantumInfo *quantum_info,
       range=GetQuantumRange(quantum_info->depth);
       for (x=0; x < (ssize_t) number_pixels; x++)
       {
-        q=PopQuantumPixel(quantum_info,
-          ScaleQuantumToAny(GetPixelRed(p),range),q);
+        q=PopQuantumPixel(quantum_info,ScaleQuantumToAny(GetPixelRed(p),range),
+          q);
         p++;
         q+=quantum_info->pad;
       }
@@ -3150,7 +3152,8 @@ static void ExportRGBQuantum(QuantumInfo *quantum_info,
                 break;
               }
             }
-            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),q);
+            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),
+              q);
             switch ((x+1) % 3)
             {
               default:
@@ -3171,7 +3174,8 @@ static void ExportRGBQuantum(QuantumInfo *quantum_info,
                 break;
               }
             }
-            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),q);
+            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),
+              q);
             q+=quantum_info->pad;
           }
           for (bit=0; bit < (ssize_t) (3*number_pixels % 2); bit++)
@@ -3196,7 +3200,8 @@ static void ExportRGBQuantum(QuantumInfo *quantum_info,
                 break;
               }
             }
-            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),q);
+            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),
+              q);
             q+=quantum_info->pad;
           }
           if (bit != 0)

programming_language: C