xorl %eax, %eax

CVE-2009-2294: Dillo PNG Integer Overflow

leave a comment »

Dillo is an open source web browser. This vulnerability was reported by Tielei Wang and it affects Dillo up to 2.1 release. Here is the vulnerable routine from 2.1 release.

static void
Png_datainfo_callback(png_structp png_ptr, png_infop info_ptr)
{
   DilloPng *png;
   int color_type;
   int bit_depth;
   int interlace_type;
   uint_t i;
   double gamma;

   _MSG("Png_datainfo_callback:\n");
        ...
   /* check max image size */
   if (abs(png->width*png->height) > IMAGE_MAX_W * IMAGE_MAX_H) {
      MSG("Png_datainfo_callback: suspicious image size request %ldx%ld\n",
          png->width, png->height);
      Png_error_handling(png_ptr, "Aborting...");
      return; /* not reached */
   }
       ...
   png->image_data = (uchar_t *) dMalloc(png->rowbytes * png->height);
   png->row_pointers = (uchar_t **) dMalloc(png->height * sizeof(uchar_t *));

   for (i = 0; i < png->height; i++)
      png->row_pointers[i] = png->image_data + (i * png->rowbytes);

   png->linebuf = dMalloc(3 * png->width);
       ...
}

This code is located at src/png.c. As you can see, the maximum image size is checked in the above if statement. It basically performs the following calculations in the absolute values of each variable: width * height > (max_width * max_height)
However, this multiplication on the user controlled arguments can easily overflow and wrap around. Consequently, this will result in a small integer which would definitely be smaller than max_width * max_height. The subsequent calls to dMalloc() and their equivalent copy operations would result in heap corruption.
To fix this, they applied the following patch:

    /* check max image size */
-   if (abs(png->width*png->height) > IMAGE_MAX_W * IMAGE_MAX_H) {
+   if (png->width <= 0 || png->height <= 0 ||
+       png->width > IMAGE_MAX_AREA / png->height) {
       MSG("Png_datainfo_callback: suspicious image size request %ldx%ld\n",
           png->width, png->height);

This way, neither height nor width can contain a negative value which can result in an integer overflow and width is also checked against the maximum area divided by the requested height. By constructing a PNG with large values in width and height you can trigger a remote heap memory corruption.

Written by xorl

July 7, 2009 at 13:57

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s