CVE-2021-20224 (C, published 2022-08-25T20:15Z)
Description: value: 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.
Severity: nan (CVSS v3 base score: 5.5)
Weakness: CWE-190 \u2014 Integer Overflow or Wraparound
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.
Repository: https://github.com/ImageMagick/ImageMagick6
Files changed:
magick/quantum-export.c
Commit message: https://github.com/ImageMagick/ImageMagick/pull/3083


Vulnerable code:
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
            pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
          pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
            pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) *indexes++;
        pixel=(unsigned char) (16*QuantumScale*((Quantum) (QuantumRange-
          GetPixelOpacity(p)))+0.5);
            q=PopShortPixel(quantum_info->endian,(unsigned short) GetPixelIndex(indexes+x),q);
        q=PopShortPixel(quantum_info->endian,(unsigned short) GetPixelIndex(indexes+x),q);
        q=PopLongPixel(quantum_info->endian,(unsigned int) GetPixelIndex(indexes+x),q);
        q=PopQuantumPixel(quantum_info,
          GetPixelIndex(indexes+x),q);
        q=PopQuantumPixel(quantum_info,
          ScaleQuantumToAny((Quantum) (GetPixelAlpha(p)),range),q);
        q=PopQuantumPixel(quantum_info,
          ScaleQuantumToAny(GetPixelRed(p),range),q);
            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),q);
            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),q);
            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),q);

Fixed code:
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
            pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
          pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
            pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) *indexes++);
        pixel=(unsigned char) ((ssize_t) (16*QuantumScale*((Quantum)
          (QuantumRange-GetPixelOpacity(p)))+0.5));
            q=PopShortPixel(quantum_info->endian,(unsigned short)
              ((ssize_t) GetPixelIndex(indexes+x)),q);
        q=PopShortPixel(quantum_info->endian,(unsigned short)
          ((ssize_t) GetPixelIndex(indexes+x)),q);
        q=PopLongPixel(quantum_info->endian,(unsigned int)
          GetPixelIndex(indexes+x),q);
        q=PopQuantumPixel(quantum_info,GetPixelIndex(indexes+x),q);
        q=PopQuantumPixel(quantum_info,ScaleQuantumToAny((Quantum)
          (GetPixelAlpha(p)),range),q);
        q=PopQuantumPixel(quantum_info,ScaleQuantumToAny(GetPixelRed(p),range),
          q);
            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),
              q);
            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),
              q);
            q=PopShortPixel(quantum_info->endian,(unsigned short) (pixel << 4),
              q);