[Pkg-gmagick-im-team] Bug#870107: memory exhaustion in ReadOneJNGImage in png.c

Bastien ROUCARIES roucaries.bastien at gmail.com
Sat Jul 29 20:38:12 UTC 2017


Source: imagemagick
Version: 8:6.9.7.4+dfsg-13
Severity: important
Tags: security upstream
X-Debbugs-CC: team at security.debian.org
control: found -1 8:6.8.9.9-5+deb8u8
control: found -1 8:6.8.9.9-5+deb8u9
control: found -1 8:6.7.7.10-5+deb7u14
control: found -1 8:6.7.7.10-5+deb9u1
forwarded: https://github.com/ImageMagick/ImageMagick/issues/549


When identify JNG file that contains chunk data, imagemagick will
allocate memory to store the chunk data in function ReadOneJNGImage

Here is the critical code:

    if (length != 0)
      {
        chunk=(unsigned char *)
AcquireQuantumMemory(length,sizeof(*chunk));   //length can be
controlled

        if (chunk == (unsigned char *) NULL)
          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");

        for (i=0; i < (ssize_t) length; i++)
        {
          int
            c;

          c=ReadBlobByte(image);
          if (c == EOF)
            break;
          chunk[i]=(unsigned char) c;
        }

        p=chunk;
      }

length can be controlled as follow:

    length=ReadBlobMSBLong(image);   //length is from file data
    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);

    if (logging != MagickFalse)
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
        type[0],type[1],type[2],type[3],(double) length);

    if (length > PNG_UINT_31_MAX || count == 0)
      ThrowReaderException(CorruptImageError,"CorruptImage");

So the only limitation is it must smaller than PNG_UINT_31_MAX, it is
still very large.

Also when chunk type is JDAT, it will write chunk data to file as follow:

    if (memcmp(type,mng_JDAT,4) == 0)
      {
        /* Copy chunk to color_image->blob */

        if (logging != MagickFalse)
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "    Copying JDAT chunk data to color_blob.");

        if (length != 0)
          {
            (void) WriteBlob(color_image,length,chunk);
//write very large chunk data to file
            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
          }

        continue;
      }

So a crafted jng file can cause memory exhausted and large I/O.

testcase:
https://github.com/jgj212/poc/blob/master/mem-jng

Credit: ADLab of Venustech



More information about the Pkg-gmagick-im-team mailing list