CVE-2018-16642 (C, published 2018-09-06T22:29Z)
Description: value: The function InsertRow in coders/cut.c in ImageMagick 7.0.7-37 allows remote attackers to cause a denial of service via a crafted image file due to an out-of-bounds write.
Severity: MEDIUM (CVSS v3 base score: 6.5)
Weakness: CWE-787 \u2014 Out-of-bounds Write
The product writes data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/ImageMagick/ImageMagick
Files changed:
coders/cut.c
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1162


Vulnerable code:
static void InsertRow(Image *image,ssize_t depth,unsigned char *p,ssize_t y,
  ExceptionInfo *exception)
  size_t bit; ssize_t x;
  register Quantum *q;
  Quantum index;
  index=0;
  switch (depth)
  {
        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (Quantum *) NULL)
          break;
            index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
            for (bit=0; bit < (image->columns % 8); bit++)
              {
                index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
                SetPixelIndex(image,index,q);
                q+=GetPixelChannels(image);
              }
        (void) SyncAuthenticPixels(image,exception);
        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (Quantum *) NULL)
          break;
        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
          index=ConstrainColormapIndex(image,(*p >> 6) & 0x3,exception);
          SetPixelIndex(image,index,q);
          q+=GetPixelChannels(image);
          index=ConstrainColormapIndex(image,(*p >> 4) & 0x3,exception);
          SetPixelIndex(image,index,q);
          q+=GetPixelChannels(image);
          index=ConstrainColormapIndex(image,(*p >> 2) & 0x3,exception);
          SetPixelIndex(image,index,q);
          q+=GetPixelChannels(image);
          index=ConstrainColormapIndex(image,(*p) & 0x3,exception);
          SetPixelIndex(image,index,q);
          q+=GetPixelChannels(image);
          p++;
        if ((image->columns % 4) != 0)
            if ((image->columns % 4) >= 1)

                if ((image->columns % 4) >= 2)

        (void) SyncAuthenticPixels(image,exception);
        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (Quantum *) NULL)
          break;
        {
            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
            index=ConstrainColormapIndex(image,(*p) & 0xf,exception);
            q+=GetPixelChannels(image);
            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
            q+=GetPixelChannels(image);
        (void) SyncAuthenticPixels(image,exception);
        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
        if (q == (Quantum *) NULL)
          break;
          index=ConstrainColormapIndex(image,*p,exception);
          SetPixelIndex(image,index,q);
          p++;
        (void) SyncAuthenticPixels(image,exception);
        break;
      }

Fixed code:
static MagickBooleanType InsertRow(Image *image,ssize_t bpp,unsigned char *p,
  ssize_t y,ExceptionInfo *exception)
  int
    bit;
  Quantum
    index;

  register Quantum
    *q;

  ssize_t
    x;

  q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
  if (q == (Quantum *) NULL)
    return(MagickFalse);
  switch (bpp)
    {
            index=((*p) & (0x80 >> bit) ? 0x01 : 0x00);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            for (bit=0; bit < (ssize_t) (image->columns % 8); bit++)
            {
              index=((*p) & (0x80 >> bit) ? 0x01 : 0x00);
              SetPixelIndex(image,index,q);
              if (index < image->colors)
                SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
              q+=GetPixelChannels(image);
            }
        for (x=0; x < ((ssize_t) image->columns-3); x+=4)
            index=ConstrainColormapIndex(image,(*p >> 6) & 0x3,exception);
            SetPixelIndex(image,index,q);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            q+=GetPixelChannels(image);
            index=ConstrainColormapIndex(image,(*p >> 4) & 0x3,exception);
            SetPixelIndex(image,index,q);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            q+=GetPixelChannels(image);
            index=ConstrainColormapIndex(image,(*p >> 2) & 0x3,exception);
            SetPixelIndex(image,index,q);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            q+=GetPixelChannels(image);
            index=ConstrainColormapIndex(image,(*p) & 0x3,exception);
            SetPixelIndex(image,index,q);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            q+=GetPixelChannels(image);
            p++;
       if ((image->columns % 4) != 0)
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            if ((image->columns % 4) > 1)
                if (index < image->colors)
                  SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
                if ((image->columns % 4) > 2)
                    if (index < image->colors)
                      SetPixelViaPixelInfo(image,image->colormap+(ssize_t)
                        index,q);
          {
            index=ConstrainColormapIndex(image,(*p >> 4) & 0x0f,exception);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            index=ConstrainColormapIndex(image,(*p) & 0x0f,exception);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            q+=GetPixelChannels(image);
            index=ConstrainColormapIndex(image,(*p >> 4) & 0x0f,exception);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            q+=GetPixelChannels(image);
          {
            index=ConstrainColormapIndex(image,*p,exception);
            SetPixelIndex(image,index,q);
            if (index < image->colors)
              SetPixelViaPixelInfo(image,image->colormap+(ssize_t) index,q);
            p++;
            q+=GetPixelChannels(image);
          }
      }
      break;

    case 24:     /*  Convert DirectColor scanline.  */
      for (x=0; x < (ssize_t) image->columns; x++)
          SetPixelRed(image,ScaleCharToQuantum(*p++),q);
          SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
          SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
      break;
  if (!SyncAuthenticPixels(image,exception))
    return(MagickFalse);
  return(MagickTrue);