Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
gimp
gimp-bnc555166-psd-hardening.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gimp-bnc555166-psd-hardening.patch of Package gimp
commit f53faac253bbf2f8326a4898c805fb3596694665 Author: Nils Philippsen <nils@redhat.com> Date: Tue Nov 17 11:56:08 2009 +0100 patch: psd-hardening Squashed commit of the following: commit de05a3ec3d0a452fb48d4705cec8d4bb505364d2 Author: Simon Budig <simon@gimp.org> Date: Tue Nov 17 00:41:39 2009 +0100 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. (cherry picked from commit 9cc8d78ff33b7a36852b74e64b427489cad44d0e) (cherry picked from commit 88eccea84aa375197cc04a2a0e2e29debb56bfa5) Signed-off-by: Nils Philippsen <nils@redhat.com> commit 35ec53d2a1363380a0c6c3f64280e99d7d07f90a Author: Simon Budig <simon@gimp.org> Date: Tue Nov 17 01:12:19 2009 +0100 Fix the PSD structs to use signed ints for bounding box coordinates. (cherry picked from commit 0e440cb6d4d6ee029667363d244aff61b154c33c) (cherry picked from commit 687ec47914ec08d6e460918cb641c196d80140a3) Signed-off-by: Nils Philippsen <nils@redhat.com> diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c index d0a8455..1b4e944 100644 --- a/plug-ins/file-psd/psd-load.c +++ b/plug-ins/file-psd/psd-load.c @@ -304,6 +304,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 @@ -533,10 +542,10 @@ read_layer_block (PSDimage *img_a, psd_set_error (feof (f), errno, error); return NULL; } - lyr_a[lidx]->top = GUINT32_FROM_BE (lyr_a[lidx]->top); - lyr_a[lidx]->left = GUINT32_FROM_BE (lyr_a[lidx]->left); - lyr_a[lidx]->bottom = GUINT32_FROM_BE (lyr_a[lidx]->bottom); - lyr_a[lidx]->right = GUINT32_FROM_BE (lyr_a[lidx]->right); + lyr_a[lidx]->top = GINT32_FROM_BE (lyr_a[lidx]->top); + lyr_a[lidx]->left = GINT32_FROM_BE (lyr_a[lidx]->left); + lyr_a[lidx]->bottom = GINT32_FROM_BE (lyr_a[lidx]->bottom); + lyr_a[lidx]->right = GINT32_FROM_BE (lyr_a[lidx]->right); lyr_a[lidx]->num_channels = GUINT16_FROM_BE (lyr_a[lidx]->num_channels); if (lyr_a[lidx]->num_channels > MAX_CHANNELS) @@ -546,14 +555,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"), @@ -561,6 +572,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, @@ -670,13 +691,13 @@ read_layer_block (PSDimage *img_a, return NULL; } lyr_a[lidx]->layer_mask.top = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.top); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.top); lyr_a[lidx]->layer_mask.left = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.left); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.left); lyr_a[lidx]->layer_mask.bottom = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom); lyr_a[lidx]->layer_mask.right = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.right); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.right); lyr_a[lidx]->layer_mask.mask_flags.relative_pos = lyr_a[lidx]->layer_mask.flags & 1 ? TRUE : FALSE; lyr_a[lidx]->layer_mask.mask_flags.disabled = @@ -702,21 +723,21 @@ read_layer_block (PSDimage *img_a, return NULL; } lyr_a[lidx]->layer_mask_extra.top = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.top); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.top); lyr_a[lidx]->layer_mask_extra.left = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.left); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.left); lyr_a[lidx]->layer_mask_extra.bottom = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.bottom); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.bottom); lyr_a[lidx]->layer_mask_extra.right = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.right); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask_extra.right); lyr_a[lidx]->layer_mask.top = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.top); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.top); lyr_a[lidx]->layer_mask.left = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.left); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.left); lyr_a[lidx]->layer_mask.bottom = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.bottom); lyr_a[lidx]->layer_mask.right = - GUINT32_FROM_BE (lyr_a[lidx]->layer_mask.right); + GINT32_FROM_BE (lyr_a[lidx]->layer_mask.right); lyr_a[lidx]->layer_mask.mask_flags.relative_pos = lyr_a[lidx]->layer_mask.flags & 1 ? TRUE : FALSE; lyr_a[lidx]->layer_mask.mask_flags.disabled = @@ -734,6 +755,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, @@ -1135,7 +1184,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"); @@ -1761,6 +1810,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) { diff --git a/plug-ins/file-psd/psd.h b/plug-ins/file-psd/psd.h index 6292747..b0c28ff 100644 --- a/plug-ins/file-psd/psd.h +++ b/plug-ins/file-psd/psd.h @@ -447,10 +447,10 @@ typedef struct /* PSD Layer mask data (length 20) */ typedef struct { - guint32 top; /* Layer top */ - guint32 left; /* Layer left */ - guint32 bottom; /* Layer bottom */ - guint32 right; /* Layer right */ + gint32 top; /* Layer top */ + gint32 left; /* Layer left */ + gint32 bottom; /* Layer bottom */ + gint32 right; /* Layer right */ guchar def_color; /* Default background colour */ guchar flags; /* Layer flags */ guchar extra_def_color; /* Real default background colour */ @@ -461,20 +461,20 @@ typedef struct /* PSD Layer mask data (length 36) */ typedef struct { - guint32 top; /* Layer top */ - guint32 left; /* Layer left */ - guint32 bottom; /* Layer bottom */ - guint32 right; /* Layer right */ + gint32 top; /* Layer top */ + gint32 left; /* Layer left */ + gint32 bottom; /* Layer bottom */ + gint32 right; /* Layer right */ } LayerMaskExtra; /* PSD Layer data structure */ typedef struct { gboolean drop; /* Do not add layer to GIMP image */ - guint32 top; /* Layer top */ - guint32 left; /* Layer left */ - guint32 bottom; /* Layer bottom */ - guint32 right; /* Layer right */ + gint32 top; /* Layer top */ + gint32 left; /* Layer left */ + gint32 bottom; /* Layer bottom */ + gint32 right; /* Layer right */ guint16 num_channels; /* Number of channels */ ChannelLengthInfo *chn_info; /* Channel length info */ gchar mode_key[4]; /* Blend mode key */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor