Skip to content

memory leak in DecodeImage in coders/pcd.c different from #1193 and #811 #1450

Closed
@twelveand0

Description

@twelveand0

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am using the latest version of ImageMagick
  • I have searched open and closed issues to ensure it has not already been reported

Description

memory leak in DecodeImage in coders/pcd.c, which is different from #1193 and #811

Steps to Reproduce

The critical code snippet is:
https://github.com/ImageMagick/ImageMagick/blob/master/coders/pcd.c#L198

for (i=0; i < (image->columns > 1536 ? 3 : 1); i++)
  {
    PCDGetBits(8);
    length=(sum & 0xff)+1;
    pcd_table[i]=(PCDTable *) AcquireQuantumMemory(length,  //line 202
      sizeof(*pcd_table[i]));
    if (pcd_table[i] == (PCDTable *) NULL)              //line 204
      {
        buffer=(unsigned char *) RelinquishMagickMemory(buffer); 
        ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",  //line 207
          image->filename);
      }
    r=pcd_table[i];
    for (j=0; j < (ssize_t) length; j++)
    {
      PCDGetBits(8);
      r->length=(unsigned int) (sum & 0xff)+1;
      if (r->length > 16)                                       //line 215
        {
          buffer=(unsigned char *) RelinquishMagickMemory(buffer);
          return(MagickFalse);                            //line 218
        }
      PCDGetBits(16);
      r->sequence=(unsigned int) (sum & 0xffff) << 16;
      PCDGetBits(8);
      r->key=(unsigned char) (sum & 0xff);
      r->mask=(~((1U << (32-r->length))-1));
      r++;
    }
    pcd_length[i]=(size_t) length;
  }

pcd_table[i] is allocated at line 202, however, pcd_table[0~i] are forgot to be freed when exception happens at line 204 or function returns at line 215. pcd_table is a local array variable and it isn't passed to the caller function when DecodeImage returns with MagickFalse at line 207 and 218. As a result, the allocated memory pcd_table[0~(i-1)] (or pcd_table[0~i] when returned at line 218) will not be freed and memory leak happens.

The max size of leaked memory is 3*(0xff+1)*sizeof(*pcd_table[0])

The patch suggestion:

if (pcd_table[i] == (PCDTable *) NULL)    //line 204
      {
        buffer=(unsigned char *) RelinquishMagickMemory(buffer);
        for (k=0; k < i; k++)
          pcd_table[k] = (PCDTable *)RelinquishMagickMemory(pcd_table[k]);
        ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
          image->filename);
      }

if (r->length > 16)
        {
          buffer=(unsigned char *) RelinquishMagickMemory(buffer);
          for (k=0; k <= i; k++)
            pcd_table[k] = (PCDTable *)RelinquishMagickMemory(pcd_table[k]);
          return(MagickFalse);
        }

System Configuration

  • ImageMagick version: ImageMagick-4f0ea40e2a090e245f31d1f05247520d6e7eb4ca
  • Environment (Operating system, version and so on): Ubuntu 16.04
  • Additional information:

Credit to Bingchang Liu at VARAS of IIE

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions