Skip to content

Potential Memory Leak in WriteDIBImage in coders/dib.c #1453

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 WriteDIBImage in coders/dib.c

Steps to Reproduce

The critical code snippets are:
https://github.com/ImageMagick/ImageMagick/blob/master/coders/dib.c#L1330

if (dib_info.bits_per_pixel == 8)       //line 1330
    if (image_info->compression != NoCompression)     //line 1331
      {
        size_t
          length;

        /*
          Convert run-length encoded raster pixels.
        */
        length=2UL*(bytes_per_line+2UL)+2UL;
        dib_data=(unsigned char *) AcquireQuantumMemory(length,     // line 1340
          (image->rows+2UL)*sizeof(*dib_data));
        if (dib_data == (unsigned char *) NULL)
          {
            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
          }
        dib_info.image_size=(unsigned int) EncodeImage(image,bytes_per_line,
          pixels,dib_data);
        pixels=(unsigned char *) RelinquishMagickMemory(pixels);
        pixels=dib_data;                                 // line 1350
        dib_info.compression = BI_RLE8;
      }

and
https://github.com/ImageMagick/ImageMagick/blob/master/coders/dib.c#L1367

if (image->storage_class == PseudoClass)     //line 1367
    {
      if (dib_info.bits_per_pixel <= 8)              //line 1369
        {
          unsigned char
            *dib_colormap;

          /*
            Dump colormap to file.
          */
          dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
            (1UL << dib_info.bits_per_pixel),4*sizeof(*dib_colormap));
          if (dib_colormap == (unsigned char *) NULL)     // line 1379
            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");      // line 1380
          q=dib_colormap;

According to the code in function WriteDIBImage before line 1330, when image->storage_class is not DirectClass (i.e. storage class is PseudoClass) and image_info->depth<=8, dib_info.bits_per_pixel can be equal to 8 (at line 1151-1155), as a result, dib_info.compression will be BI_RGB (at line 1164-1165). So the 4 conditions at line 1330, 1331, 1367 and 1369 can be satisfied at the same time in some setting.

When the 4 conditions are satisfied and dib_data is successfully allocated at line 1340, dib_data will be assigned to pixels at line 1350. However, when the allocation at line 1377 fails, the function don't free dib_data memory as done at line 1410 before returning with exception at line 1378. As a result, a memory leak will happen.

The size of leaked memory is 4*((image->columnsdib_info.bits_per_pixel+31)/32)(image->rows+2UL)*sizeof(*dib_data) = (image->columns + 4) * (image->rows + 2) * sizeof(*dib_data), which may be a large value. (ps. dib_info.bits_per_pixel is 8)

Patch Suggestion:

          dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)  // line 1377
            (1UL << dib_info.bits_per_pixel),4*sizeof(*dib_colormap));
          if (dib_colormap == (unsigned char *) NULL)
          {
            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
          }
          q=dib_colormap;

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