File gimp-CVE-2022-32990.patch of Package gimp.26724
diff -urp gimp-2.10.30.orig/app/core/gimpchannel.c gimp-2.10.30/app/core/gimpchannel.c
--- gimp-2.10.30.orig/app/core/gimpchannel.c 2021-12-19 14:48:32.000000000 -0600
+++ gimp-2.10.30/app/core/gimpchannel.c 2022-08-01 16:19:08.966210849 -0500
@@ -1824,7 +1824,7 @@ gimp_channel_boundary (GimpChannel
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.10.30.orig/app/xcf/xcf-load.c gimp-2.10.30/app/xcf/xcf-load.c
--- gimp-2.10.30.orig/app/xcf/xcf-load.c 2021-12-19 14:48:33.000000000 -0600
+++ gimp-2.10.30/app/xcf/xcf-load.c 2022-08-01 16:19:20.814273376 -0500
@@ -183,10 +183,19 @@ xcf_load_image (Gimp *gimp,
xcf_read_int32 (info, (guint32 *) &width, 1);
xcf_read_int32 (info, (guint32 *) &height, 1);
xcf_read_int32 (info, (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)
+ {
+ GIMP_LOG (XCF, "Invalid image size %d x %d, setting to 1x1.", width, height);
+ width = 1;
+ height = 1;
+ }
+
if (info->file_version >= 4)
{
gint p;
@@ -476,6 +485,13 @@ xcf_load_image (Gimp *gimp,
*/
saved_pos = info->cp;
+ if (offset < saved_pos)
+ {
+ GIMP_LOG (XCF, "Invalid layer offset: %" G_GOFFSET_FORMAT
+ " at offset: %" G_GOFFSET_FORMAT, offset, saved_pos);
+ goto error;
+ }
+
/* seek to the layer offset */
if (! xcf_seek_pos (info, offset, NULL))
goto error;
@@ -616,6 +632,13 @@ xcf_load_image (Gimp *gimp,
*/
saved_pos = info->cp;
+ if (offset < saved_pos)
+ {
+ GIMP_LOG (XCF, "Invalid channel offset: %" G_GOFFSET_FORMAT
+ " at offset: % "G_GOFFSET_FORMAT, offset, saved_pos);
+ goto error;
+ }
+
/* seek to the channel offset */
if (! xcf_seek_pos (info, offset, NULL))
goto error;
@@ -625,6 +648,7 @@ xcf_load_image (Gimp *gimp,
if (!channel)
{
n_broken_channels++;
+ GIMP_LOG (XCF, "Failed to load channel.");
if (! xcf_seek_pos (info, saved_pos, NULL))
goto error;
@@ -1867,6 +1891,7 @@ xcf_load_layer (XcfInfo *info,
const Babl *format;
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.
@@ -1918,7 +1943,8 @@ xcf_load_layer (XcfInfo *info,
return NULL;
}
- if (width <= 0 || height <= 0)
+ if (width <= 0 || height <= 0 ||
+ width > GIMP_MAX_IMAGE_SIZE || height > GIMP_MAX_IMAGE_SIZE)
{
gboolean is_group_layer = FALSE;
gboolean is_text_layer = FALSE;
@@ -1983,6 +2009,7 @@ xcf_load_layer (XcfInfo *info,
}
/* read the hierarchy and layer mask offsets */
+ cur_offset = info->cp;
xcf_read_offset (info, &hierarchy_offset, 1);
xcf_read_offset (info, &layer_mask_offset, 1);
@@ -1992,6 +2019,11 @@ xcf_load_layer (XcfInfo *info,
*/
if (! gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{
+ if (hierarchy_offset < cur_offset)
+ {
+ GIMP_LOG (XCF, "Invalid layer hierarchy offset!");
+ goto error;
+ }
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
@@ -2015,6 +2047,11 @@ xcf_load_layer (XcfInfo *info,
/* read in the layer mask */
if (layer_mask_offset != 0)
{
+ if (layer_mask_offset < cur_offset)
+ {
+ GIMP_LOG (XCF, "Invalid layer mask offset!");
+ goto error;
+ }
if (! xcf_seek_pos (info, layer_mask_offset, NULL))
goto error;
@@ -2071,6 +2108,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.
@@ -2080,10 +2118,16 @@ xcf_load_channel (XcfInfo *info,
/* read in the layer width, height and name */
xcf_read_int32 (info, (guint32 *) &width, 1);
xcf_read_int32 (info, (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)
+ {
+ GIMP_LOG (XCF, "Invalid channel size %d x %d.", width, height);
+ return NULL;
+ }
xcf_read_string (info, &name, 1);
+ GIMP_LOG (XCF, "Channel width=%d, height=%d, name='%s'",
+ width, height, name);
/* create a new channel */
channel = gimp_channel_new (image, width, height, name, &color);
@@ -2097,9 +2141,16 @@ xcf_load_channel (XcfInfo *info,
xcf_progress_update (info);
- /* read the hierarchy and layer mask offsets */
+ /* read the hierarchy offset */
+ cur_offset = info->cp;
xcf_read_offset (info, &hierarchy_offset, 1);
+ if (hierarchy_offset < cur_offset)
+ {
+ GIMP_LOG (XCF, "Invalid hierarchy offset!");
+ goto error;
+ }
+
/* read in the hierarchy */
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
@@ -2143,6 +2194,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.
@@ -2152,10 +2204,16 @@ xcf_load_layer_mask (XcfInfo *info,
/* read in the layer width, height and name */
xcf_read_int32 (info, (guint32 *) &width, 1);
xcf_read_int32 (info, (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)
+ {
+ GIMP_LOG (XCF, "Invalid layer mask size %d x %d.", width, height);
+ return NULL;
+ }
xcf_read_string (info, &name, 1);
+ GIMP_LOG (XCF, "Layer mask width=%d, height=%d, name='%s'",
+ width, height, name);
/* create a new layer mask */
layer_mask = gimp_layer_mask_new (image, width, height, name, &color);
@@ -2170,9 +2228,16 @@ 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;
xcf_read_offset (info, &hierarchy_offset, 1);
+ if (hierarchy_offset < cur_offset)
+ {
+ GIMP_LOG (XCF, "Invalid hierarchy offset!");
+ goto error;
+ }
+
/* read in the hierarchy */
if (! xcf_seek_pos (info, hierarchy_offset, NULL))
goto error;
@@ -2210,6 +2275,7 @@ xcf_load_buffer (XcfInfo *info,
gint width;
gint height;
gint bpp;
+ goffset cur_offset;
format = gegl_buffer_get_format (buffer);
@@ -2225,8 +2291,15 @@ xcf_load_buffer (XcfInfo *info,
bpp != babl_format_get_bytes_per_pixel (format))
return FALSE;
+ cur_offset = info->cp;
xcf_read_offset (info, &offset, 1); /* top level */
+ if (offset < cur_offset)
+ {
+ GIMP_LOG (XCF, "Invalid buffer offset!");
+ return FALSE;
+ }
+
/* seek to the level offset */
if (! xcf_seek_pos (info, offset, NULL))
return FALSE;