Skip to content

Potential Memory Leak in ReadSIXELImage in coders/sixel.c #1452

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

potential memory leak in ReadSIXELImage in sixel.c

Steps to Reproduce

The first critical code snippet is:
https://github.com/ImageMagick/ImageMagick/blob/master/coders/sixel.c#L539

if (imsx > max_x || imsy > max_y) { // line 539
        dmsx = max_x;
        dmsy = max_y;
        if (SetImageExtent(image,dmsx,dmsy,exception) == MagickFalse)
          {
            imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
            return (MagickFalse);
          }
        if ((dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx , dmsy)) == NULL) { //line 547
            imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
            return (MagickFalse);
        }
        for (y = 0; y < dmsy; ++y) {
            (void) memcpy(dmbuf + dmsx * y, imbuf + imsx * y, dmsx);
        }
        imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
        imsx = dmsx;
        imsy = dmsy;
        imbuf = dmbuf;  //line 557
    }

    *pixels = imbuf;  //line 560
    *pwidth = imsx;
    *pheight = imsy;
    *ncolors = max_color_index + 1;
    *palette = (unsigned char *) AcquireQuantumMemory(*ncolors,4); // line 564
    if (*palette == (unsigned char *) NULL)
      return(MagickFalse);     // line 566

When condition at line 539 is satisfied and dmbuf is successfully allocated at line 547, the value of dmbuf is assigned to imbuf at line 557 and is finally assigned to the pointer parameter pixels at line 560 (i.e. the buf's address is passed outside to the caller function).

Now, when the allocation at line 564 failed, the function will return MagickFalse at line 566.

Next, I searched the whole project code and only found one call to sixel_decode which locates in function ReadSIXELImage in sixel.c at line 1057 as the following. The local variable sixel_pixels holds the value of dmbuf.
https://github.com/ImageMagick/ImageMagick/blob/master/coders/sixel.c#L1057

if (sixel_decode(image,(unsigned char *) sixel_buffer,&sixel_pixels,&image->columns,&image->rows,&sixel_palette,&image->colors,exception) == MagickFalse)  // line 1057
    {
      sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }
  sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
  image->depth=24;
  image->storage_class=PseudoClass;
  status=SetImageExtent(image,image->columns,image->rows,exception);
  if (status == MagickFalse)
    {
      sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);  // line 1068
      sixel_palette=(unsigned char *) RelinquishMagickMemory(sixel_palette);
      return(DestroyImageList(image));
    }

However, when function sixel_decode returned MagickFalse as described above, the memory pointed by sixel_pixels (i.e. the memory allocated at line 547) was not freed as done at line 1068. As a result, a memory leak happens.

Patch Suggestion:

if (sixel_decode(image,(unsigned char *) sixel_buffer,&sixel_pixels,&image->columns,&image->rows,&sixel_palette,&image->colors,exception) == MagickFalse)
    {
      sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
+     sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }

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