File gimp-CVE-2022-32990.patch of Package gimp.25275
diff -urp gimp-2.8.18.orig/app/core/gimpchannel.c gimp-2.8.18/app/core/gimpchannel.c
--- gimp-2.8.18.orig/app/core/gimpchannel.c 2015-08-20 17:57:24.000000000 -0500
+++ gimp-2.8.18/app/core/gimpchannel.c 2022-07-26 16:12:47.163604475 -0500
@@ -1994,7 +1994,7 @@ gimp_channel_bounds (GimpChannel *channe
gboolean
gimp_channel_is_empty (GimpChannel *channel)
{
- g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
+ g_return_val_if_fail (GIMP_IS_CHANNEL (channel), TRUE);
return GIMP_CHANNEL_GET_CLASS (channel)->is_empty (channel);
}
diff -urp gimp-2.8.18.orig/app/xcf/xcf-load.c gimp-2.8.18/app/xcf/xcf-load.c
--- gimp-2.8.18.orig/app/xcf/xcf-load.c 2022-07-26 16:12:26.275494168 -0500
+++ gimp-2.8.18/app/xcf/xcf-load.c 2022-07-27 11:38:45.368964480 -0500
@@ -174,10 +174,18 @@ xcf_load_image (Gimp *gimp,
info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &image_type, 1);
- if (image_type < GIMP_RGB || image_type > GIMP_INDEXED ||
- width <= 0 || height <= 0)
+ if (image_type < GIMP_RGB || image_type > GIMP_INDEXED)
goto hard_error;
+ /* Be lenient with corrupt image dimensions.
+ * Hopefully layer dimensions will be valid. */
+ if (width <= 0 || height <= 0 ||
+ width > GIMP_MAX_IMAGE_SIZE || height > GIMP_MAX_IMAGE_SIZE)
+ {
+ width = 1;
+ height = 1;
+ }
+
image = gimp_create_image (gimp, width, height, image_type, FALSE);
gimp_image_undo_disable (image);
@@ -235,6 +243,11 @@ xcf_load_image (Gimp *gimp,
*/
saved_pos = info->cp;
+ if (offset < saved_pos)
+ {
+ goto error;
+ }
+
/* seek to the layer offset */
if (! xcf_seek_pos (info, offset, NULL))
goto error;
@@ -318,6 +331,11 @@ xcf_load_image (Gimp *gimp,
*/
saved_pos = info->cp;
+ if (offset < saved_pos)
+ {
+ goto error;
+ }
+
/* seek to the channel offset */
if (! xcf_seek_pos (info, offset, NULL))
goto error;
@@ -1178,6 +1196,7 @@ xcf_load_layer (XcfInfo *info,
gint type;
gboolean is_fs_drawable;
gchar *name;
+ goffset cur_offset;
/* check and see if this is the drawable the floating selection
* is attached to. if it is then we'll do the attachment in our caller.
@@ -1188,9 +1207,10 @@ xcf_load_layer (XcfInfo *info,
info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &type, 1);
- if (width <= 0 || height <= 0)
- return NULL;
-
+ if (width <= 0 || height <= 0 ||
+ width > GIMP_MAX_IMAGE_SIZE || height > GIMP_MAX_IMAGE_SIZE)
+ return NULL;
+
info->cp += xcf_read_string (info->fp, &name, 1);
/* create a new layer */
@@ -1224,6 +1244,7 @@ xcf_load_layer (XcfInfo *info,
}
/* read the hierarchy and layer mask offsets */
+ cur_offset = info->cp;
info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
info->cp += xcf_read_int32 (info->fp, &layer_mask_offset, 1);
@@ -1233,6 +1254,10 @@ xcf_load_layer (XcfInfo *info,
*/
if (! gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{
+ if (hierarchy_offset < cur_offset)
+ {
+ goto error;
+ }
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
@@ -1252,6 +1277,10 @@ xcf_load_layer (XcfInfo *info,
/* read in the layer mask */
if (layer_mask_offset != 0)
{
+ if (layer_mask_offset < cur_offset)
+ {
+ goto error;
+ }
if (! xcf_seek_pos (info, layer_mask_offset, NULL))
goto error;
@@ -1296,6 +1325,7 @@ xcf_load_channel (XcfInfo *info,
gboolean is_fs_drawable;
gchar *name;
GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
+ goffset cur_offset;
/* check and see if this is the drawable the floating selection
* is attached to. if it is then we'll do the attachment in our caller.
@@ -1305,7 +1335,8 @@ xcf_load_channel (XcfInfo *info,
/* read in the layer width, height and name */
info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
- if (width <= 0 || height <= 0)
+ if (width <= 0 || height <= 0 ||
+ width > GIMP_MAX_IMAGE_SIZE || height > GIMP_MAX_IMAGE_SIZE)
return NULL;
info->cp += xcf_read_string (info->fp, &name, 1);
@@ -1322,9 +1353,15 @@ xcf_load_channel (XcfInfo *info,
xcf_progress_update (info);
- /* read the hierarchy and layer mask offsets */
+ /* read the hierarchy offset */
+ cur_offset = info->cp;
info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
+ if (hierarchy_offset < cur_offset)
+ {
+ goto error;
+ }
+
/* read in the hierarchy */
if (!xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
@@ -1357,6 +1394,7 @@ xcf_load_layer_mask (XcfInfo *info,
gboolean is_fs_drawable;
gchar *name;
GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
+ goffset cur_offset;
/* check and see if this is the drawable the floating selection
* is attached to. if it is then we'll do the attachment in our caller.
@@ -1366,8 +1404,11 @@ xcf_load_layer_mask (XcfInfo *info,
/* read in the layer width, height and name */
info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
- if (width <= 0 || height <= 0)
- return NULL;
+ if (width <= 0 || height <= 0 ||
+ width > GIMP_MAX_IMAGE_SIZE || height > GIMP_MAX_IMAGE_SIZE)
+ {
+ return NULL;
+ }
info->cp += xcf_read_string (info->fp, &name, 1);
@@ -1384,9 +1425,15 @@ xcf_load_layer_mask (XcfInfo *info,
xcf_progress_update (info);
- /* read the hierarchy and layer mask offsets */
+ /* read the hierarchy offset */
+ cur_offset = info->cp;
info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
+ if (hierarchy_offset < cur_offset)
+ {
+ goto error;
+ }
+
/* read in the hierarchy */
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
@@ -1416,6 +1463,7 @@ xcf_load_hierarchy (XcfInfo *info,
gint width;
gint height;
gint bpp;
+ goffset cur_offset;
info->cp += xcf_read_int32 (info->fp, (guint32 *) &width, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
@@ -1429,8 +1477,14 @@ xcf_load_hierarchy (XcfInfo *info,
bpp != tile_manager_bpp (tiles))
return FALSE;
+ cur_offset = info->cp;
info->cp += xcf_read_int32 (info->fp, &offset, 1); /* top level */
+ if (offset < cur_offset)
+ {
+ return FALSE;
+ }
+
/* seek to the level offset */
if (!xcf_seek_pos (info, offset, NULL))
return FALSE;