xorl %eax, %eax

CVE-2009-3909: GIMP PSD Heap Based Buffer Overflow

leave a comment »

This vulnerability was discovered by Secunia Research and it affects GIMP 2.6.7 and probably earlier releases too. The buggy code resides in the plug-in that is responsible for loading PSD image files. Here is this code as seen in plug-ins/file-psd/psd-load.c.

static gint
read_channel_data (PSDchannel     *channel,
                   const guint16   bps,
                   const guint16   compression,
                   const guint16  *rle_pack_len,
                   FILE           *f,
                   GError        **error)
{
  gchar    *raw_data;
  gchar    *src;
  gchar    *dst;
  guint32   readline_len;
  gint      i;
   ...
  IFDBG(3) g_debug ("raw data size %d x %d = %d", readline_len,
                    channel->rows, readline_len * channel->rows);
  raw_data = g_malloc (readline_len * channel->rows);
  switch (compression)
    {
      case PSD_COMP_RAW:
   ...
            memcpy (raw_data + i * readline_len, dst, readline_len);
            g_free (dst);
          }
        break;
    }
   ...
  return 1;
}

The above routine is used to read the channel information of the PSD file. However, the size calculation for the length of each line, represented by ‘readline_len’ mupliplied by the number of rows (through ‘channel->rows’ variable), can result in an integer overflow and allocation of an incorrect size of heap space using g_malloc(). The subsequent operations will eventually result in heap memory corruption.
This was fixed using the patch below.

  IFDBG(3) g_debug ("raw data size %d x %d = %d", readline_len,
                    channel->rows, readline_len * channel->rows);;
+
+ /* sanity check, int overflow check (avoid divisions by zero) */
+ if ((channel->rows == 0) || (channel->columns == 0) ||
+     (channel->rows > G_MAXINT32 / channel->columns / MAX (bps >> 3, 1)))
+   {
+     g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                  _("Unsupported or invalid channel size"));
+     return -1;
+   }
+
  raw_data = g_malloc (readline_len * channel->rows);

Where they check the channel size before proceeding with the actual allocation. For completeness, here is the definition of the ‘PSDchannel’ type as seen in plug-ins/file-psd/psd.h:

/* PSD Channel data structure */
typedef struct
{
  gint16        id;                     /* Channel ID */
  gchar        *name;                   /* Channel name */
  gchar        *data;                   /* Channel image data */
  guint32       rows;                   /* Channel rows */
  guint32       columns;                /* Channel columns */
} PSDchannel;

Written by xorl

November 20, 2009 at 23: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