Commit message: None
CVE: CVE-2017-5506
CWE: CWE-415
Vulnerability description: Double free vulnerability in magick/profile.c in ImageMagick allows remote attackers to have unspecified impact via a crafted file.

Project: ImageMagick
File: profile.c

static unsigned short **AcquirePixelThreadSet(const size_t columns,
  const size_t channels)
{
  register ssize_t
    i;

  unsigned short
    **pixels;

  size_t
    number_threads;

  number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
  pixels=(unsigned short **) AcquireQuantumMemory(number_threads,
    sizeof(*pixels));
  if (pixels == (unsigned short **) NULL)
    return((unsigned short **) NULL);
  (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels));
  for (i=0; i < (ssize_t) number_threads; i++)
  {
    pixels[i]=(unsigned short *) AcquireQuantumMemory(columns,channels*
      sizeof(**pixels));
    if (pixels[i] == (unsigned short *) NULL)
      return(DestroyPixelThreadSet(pixels));
  }
  return(pixels);
}

Project: ImageMagick
File: profile.c

static cmsHTRANSFORM *DestroyTransformThreadSet(cmsHTRANSFORM *transform)
{
  register ssize_t
    i;

  assert(transform != (cmsHTRANSFORM *) NULL);
  for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
    if (transform[i] != (cmsHTRANSFORM) NULL)
      cmsDeleteTransform(transform[i]);
  transform=(cmsHTRANSFORM *) RelinquishMagickMemory(transform);
  return(transform);
}

Project: ImageMagick
File: profile.c

static inline const unsigned char *ReadResourceShort(const unsigned char *p,
  unsigned short *quantum)
{
  *quantum=(unsigned short) (*p++) << 8;
  *quantum|=(unsigned short) (*p++);
  return(p);
}

Project: ImageMagick

static MagickBooleanType Sync8BimProfile(Image *image,StringInfo *profile)
{
  size_t
    length;

  ssize_t
    count;

  unsigned char
    *p;

  unsigned short
    id;

  length=GetStringInfoLength(profile);
  p=GetStringInfoDatum(profile);
  while (length != 0)
  {
    if (ReadProfileByte(&p,&length) != 0x38)
      continue;
    if (ReadProfileByte(&p,&length) != 0x42)
      continue;
    if (ReadProfileByte(&p,&length) != 0x49)
      continue;
    if (ReadProfileByte(&p,&length) != 0x4D)
      continue;
    if (length < 7)
      return(MagickFalse);
    id=ReadProfileMSBShort(&p,&length);
    count=(ssize_t) ReadProfileByte(&p,&length);
    if ((count > (ssize_t) length) || (count < 0))
      return(MagickFalse);
    p+=count;
    if ((*p & 0x01) == 0)
      (void) ReadProfileByte(&p,&length);
    count=(ssize_t) ReadProfileMSBLong(&p,&length);
    if ((count > (ssize_t) length) || (count < 0))
      return(MagickFalse);
    if ((id == 0x3ED) && (count == 16))
      {
        if (image->units == PixelsPerCentimeterResolution)
          WriteProfileLong(MSBEndian, (unsigned int) (image->x_resolution*2.54*
            65536.0),p);
        else
          WriteProfileLong(MSBEndian, (unsigned int) (image->x_resolution*
            65536.0),p);
        WriteProfileShort(MSBEndian,(unsigned short) image->units,p+4);
        if (image->units == PixelsPerCentimeterResolution)
          WriteProfileLong(MSBEndian, (unsigned int) (image->y_resolution*2.54*
            65536.0),p+8);
        else
          WriteProfileLong(MSBEndian, (unsigned int) (image->y_resolution*
            65536.0),p+8);
        WriteProfileShort(MSBEndian,(unsigned short) image->units,p+12);
      }
    p+=count;
    length-=count;
  }
  return(MagickTrue);
}

Project: ImageMagick
File: profile.c

static inline void WriteProfileLong(const EndianType endian,
  const size_t value,unsigned char *p)
{
  unsigned char
    buffer[4];

  if (endian == LSBEndian)
    {
      buffer[0]=(unsigned char) value;
      buffer[1]=(unsigned char) (value >> 8);
      buffer[2]=(unsigned char) (value >> 16);
      buffer[3]=(unsigned char) (value >> 24);
      (void) CopyMagickMemory(p,buffer,4);
      return;
    }
  buffer[0]=(unsigned char) (value >> 24);
  buffer[1]=(unsigned char) (value >> 16);
  buffer[2]=(unsigned char) (value >> 8);
  buffer[3]=(unsigned char) value;
  (void) CopyMagickMemory(p,buffer,4);
}