Commit 9cc8d78f authored by Simon Budig's avatar Simon Budig
Browse files

Harden the PSD plugin against integer overflows.

Issues discovered by Stefan Cornelius, Secunia Research, advisory SA37232
and CVE identifier CVE-2009-3909. Fixes bug #600741.
parent bc7519d1
......@@ -303,6 +303,15 @@ read_header_block (PSDimage *img_a,
return -1;
}
/* img_a->rows is sanitized above, so a division by zero is avoided here */
if (img_a->columns > G_MAXINT32 / img_a->rows)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported or invalid image size: %dx%d"),
img_a->columns, img_a->rows);
return -1;
}
if (img_a->color_mode != PSD_BITMAP
&& img_a->color_mode != PSD_GRAYSCALE
&& img_a->color_mode != PSD_INDEXED
......@@ -545,14 +554,16 @@ read_layer_block (PSDimage *img_a,
lyr_a[lidx]->num_channels);
return NULL;
}
if (lyr_a[lidx]->bottom - lyr_a[lidx]->top > GIMP_MAX_IMAGE_SIZE)
if (lyr_a[lidx]->bottom < lyr_a[lidx]->top ||
lyr_a[lidx]->bottom - lyr_a[lidx]->top > GIMP_MAX_IMAGE_SIZE)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported or invalid layer height: %d"),
lyr_a[lidx]->bottom - lyr_a[lidx]->top);
return NULL;
}
if (lyr_a[lidx]->right - lyr_a[lidx]->left > GIMP_MAX_IMAGE_SIZE)
if (lyr_a[lidx]->right < lyr_a[lidx]->left ||
lyr_a[lidx]->right - lyr_a[lidx]->left > GIMP_MAX_IMAGE_SIZE)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported or invalid layer width: %d"),
......@@ -560,6 +571,16 @@ read_layer_block (PSDimage *img_a,
return NULL;
}
if ((lyr_a[lidx]->right - lyr_a[lidx]->left) >
G_MAXINT32 / MAX (lyr_a[lidx]->bottom - lyr_a[lidx]->top, 1))
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported or invalid layer size: %dx%d"),
lyr_a[lidx]->right - lyr_a[lidx]->left,
lyr_a[lidx]->bottom - lyr_a[lidx]->top);
return NULL;
}
IFDBG(2) g_debug ("Layer %d, Coords %d %d %d %d, channels %d, ",
lidx, lyr_a[lidx]->left, lyr_a[lidx]->top,
lyr_a[lidx]->right, lyr_a[lidx]->bottom,
......@@ -733,6 +754,34 @@ read_layer_block (PSDimage *img_a,
}
}
/* sanity checks */
if (lyr_a[lidx]->layer_mask.bottom < lyr_a[lidx]->layer_mask.top ||
lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top > GIMP_MAX_IMAGE_SIZE)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported or invalid layer mask height: %d"),
lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top);
return NULL;
}
if (lyr_a[lidx]->layer_mask.right < lyr_a[lidx]->layer_mask.left ||
lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left > GIMP_MAX_IMAGE_SIZE)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported or invalid layer mask width: %d"),
lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left);
return NULL;
}
if ((lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left) >
G_MAXINT32 / MAX (lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top, 1))
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Unsupported or invalid layer mask size: %dx%d"),
lyr_a[lidx]->layer_mask.right - lyr_a[lidx]->layer_mask.left,
lyr_a[lidx]->layer_mask.bottom - lyr_a[lidx]->layer_mask.top);
return NULL;
}
IFDBG(2) g_debug ("Layer mask coords %d %d %d %d, Rel pos %d",
lyr_a[lidx]->layer_mask.left,
lyr_a[lidx]->layer_mask.top,
......@@ -1134,7 +1183,7 @@ add_layers (const gint32 image_id,
psd_set_error (feof (f), errno, error);
return -1;
}
rle_pack_len[rowi] = GUINT16_FROM_BE (rle_pack_len[rowi]);
rle_pack_len[rowi] = GUINT16_FROM_BE (rle_pack_len[rowi]);
}
IFDBG(3) g_debug ("RLE decode - data");
......@@ -1760,6 +1809,16 @@ read_channel_data (PSDchannel *channel,
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);
switch (compression)
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment