xorl %eax, %eax

GIMP BMP ReadImage() Integer Overflow

with 2 comments

This vulnerability was discovered by Secunia Research as you can read in the original advisory, and it affects GIMP 2.6.7 and probably earlier releases too. The susceptible code is located in plug-ins/file-bmp/bmp-read.c like this…

static gint32
ReadImage (FILE                  *fd,
           gint                   width,
           gint                   height,
           guchar                 cmap[256][3],
           gint                   ncols,
           gint                   bpp,
           gint                   compression,
           gint                   rowbytes,
           gboolean               grey,
           const Bitmap_Channel  *masks,
           GError               **error)
{
      ...
  GimpDrawable      *drawable;
  guchar            *dest, *temp, *buffer;
      ...
  if ((width < 0) || (width > GIMP_MAX_IMAGE_SIZE))
      ...
  if ((height < 0) || (height > GIMP_MAX_IMAGE_SIZE))
      ...
  image = gimp_image_new (width, height, base_type);
      ...
  gimp_image_add_layer (image, layer, 0);
  drawable = gimp_drawable_get (layer);

  /* use g_malloc0 to initialize the dest buffer so that unspecified
     pixels in RLE bitmaps show up as the zeroth element in the palette.
  */
  dest      = g_malloc0 (drawable->width * drawable->height * channels);
      ...
  g_free (dest);

  return image;
}

This function is used to read a BMP file as it’s implied by its name. As you can see, both width and height of the BMP image cannot exceed the GIMP_MAX_IMAGE_SIZE limit which as we can read from libgimpbase/gimplimits.h is:

/*  pixel sizes
 */
#define GIMP_MIN_IMAGE_SIZE  1
#define GIMP_MAX_IMAGE_SIZE  262144    /*  2^18  */

This is nonetheless, a huge value. The next call to gimp_image_new() will initialize an image with those values assuming that they’re not negative and up to 262144 (GIMP_MAX_IMAGE_SIZE). Then, gimp_drawable_get() will return a pointer to a ‘GimpDrawable’ structure and use g_malloc0() to allocate the exact size using:

width * height * channels

It’s not hard to spot that this calculation can overflow in case of width and height set to a large value. This can lead to allocation of a small size where the subsequent operations on that pointer will eventually result in heap memory corruption.
For example, if both values are set to the maximum allowed limit, and the image uses three channels, the result will be:

262144 * 262144 * 3 = 0x3000000000

which could definitely not fit in a 32-bit long signed integer. I didn’t found any official bug-report or patch from the GIMP project so I assume that this is not patched yet.

Written by xorl

November 12, 2009 at 21:43

Posted in bugs

2 Responses

Subscribe to comments with RSS.

  1. There is a patch in the GIT repository:
    http://git.gnome.org/cgit/gimp/tree/plug-ins/file-bmp/bmp-read.c
    the fix starts at line 451:
    /* protect against integer overflows caused by malicious BMPs */

    Cheers

    stefan

    November 13, 2009 at 07:00

  2. Thanks stefan for the info! I didn’t notice it :)

    xorl

    November 13, 2009 at 23:36


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