diff --git a/SOURCES/gimp-3.0.4-CVE-2025-10920-10925-10934.patch b/SOURCES/gimp-3.0.4-CVE-2025-10920-10925-10934.patch new file mode 100644 index 0000000..abcf7e8 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2025-10920-10925-10934.patch @@ -0,0 +1,189 @@ +diff -urNp a/plug-ins/common/file-dicom.c b/plug-ins/common/file-dicom.c +--- a/plug-ins/common/file-dicom.c 2025-11-20 10:40:07.878919653 +0100 ++++ b/plug-ins/common/file-dicom.c 2025-11-20 10:47:48.219305960 +0100 +@@ -344,6 +344,7 @@ load_image (GFile *file, + gint bits_stored = 0; + gint high_bit = 0; + guint8 *pix_buf = NULL; ++ guint64 pixbuf_size = 0; + gboolean is_signed = FALSE; + guint8 in_sequence = 0; + gboolean implicit_encoding = FALSE; +@@ -399,6 +400,7 @@ load_image (GFile *file, + guint16 ctx_us; + guint8 *value; + guint32 tag; ++ size_t actual_read; + + if (fread (&group_word, 1, 2, dicom) == 0) + break; +@@ -503,15 +505,24 @@ load_image (GFile *file, + + if (element_length >= (G_MAXUINT - 6)) + { +- g_message ("'%s' seems to have an incorrect value field length.", +- gimp_file_get_utf8_name (file)); +- gimp_quit (); ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("'%s' has an an incorrect value for field size. Possibly corrupt image."), ++ gimp_file_get_utf8_name (file)); ++ g_free (dicominfo); ++ fclose (dicom); ++ return NULL; + } + + /* Read contents. Allocate a bit more to make room for casts to int + below. */ + value = g_new0 (guint8, element_length + 4); +- fread (value, 1, element_length, dicom); ++ actual_read = fread (value, 1, element_length, dicom); ++ if (actual_read < element_length) ++ { ++ g_warning ("Missing data: needed %u bytes, got %u. Possibly corrupt image.", ++ element_length, (guint32) actual_read); ++ element_length = actual_read; ++ } + + /* ignore everything inside of a sequence */ + if (in_sequence) +@@ -524,7 +535,7 @@ load_image (GFile *file, + if (big_endian && group_word != 0x0002) + ctx_us = GUINT16_SWAP_LE_BE (ctx_us); + +- g_debug ("group: %04x, element: %04x, length: %d", ++ g_debug ("group: %04x, element: %04x, length: %u", + group_word, element_word, element_length); + g_debug ("Value: %s", (char*)value); + /* Recognize some critical tags */ +@@ -658,6 +669,7 @@ load_image (GFile *file, + if (group_word == 0x7fe0 && element_word == 0x0010) + { + pix_buf = value; ++ pixbuf_size = element_length; + } + else + { +@@ -688,25 +700,50 @@ load_image (GFile *file, + } + } + ++ g_debug ("Bpp: %d, wxh: %u x %u, spp: %d\n", bpp, width, height, samples_per_pixel); ++ + if ((bpp != 8) && (bpp != 16)) + { +- g_message ("'%s' has a bpp of %d which GIMP cannot handle.", +- gimp_file_get_utf8_name (file), bpp); +- gimp_quit (); ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("'%s' has a bpp of %d which GIMP cannot handle."), ++ gimp_file_get_utf8_name (file), bpp); ++ g_free (pix_buf); ++ g_free (dicominfo); ++ fclose (dicom); ++ return NULL; + } + + if ((width > GIMP_MAX_IMAGE_SIZE) || (height > GIMP_MAX_IMAGE_SIZE)) + { +- g_message ("'%s' has a larger image size (%d x %d) than GIMP can handle.", +- gimp_file_get_utf8_name (file), width, height); +- gimp_quit (); ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("'%s' has a larger image size (%d x %d) than GIMP can handle."), ++ gimp_file_get_utf8_name (file), width, height); ++ g_free (pix_buf); ++ g_free (dicominfo); ++ fclose (dicom); ++ return NULL; + } + + if (samples_per_pixel > 3) + { +- g_message ("'%s' has samples per pixel of %d which GIMP cannot handle.", +- gimp_file_get_utf8_name (file), samples_per_pixel); +- gimp_quit (); ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("'%s' has samples per pixel of %d which GIMP cannot handle."), ++ gimp_file_get_utf8_name (file), samples_per_pixel); ++ g_free (pix_buf); ++ g_free (dicominfo); ++ fclose (dicom); ++ return NULL; ++ } ++ ++ if ((guint64) width * height * (bpp >> 3) * samples_per_pixel > pixbuf_size) ++ { ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("'%s' has not enough pixel data. Possibly corrupt image."), ++ gimp_file_get_utf8_name (file)); ++ g_free (pix_buf); ++ g_free (dicominfo); ++ fclose (dicom); ++ return NULL; + } + + dicominfo->width = width; +diff -urNp a/plug-ins/common/file-wbmp.c b/plug-ins/common/file-wbmp.c +--- a/plug-ins/common/file-wbmp.c 2025-11-20 10:40:07.879708221 +0100 ++++ b/plug-ins/common/file-wbmp.c 2025-11-20 10:50:11.843417667 +0100 +@@ -256,6 +256,7 @@ read_image (FILE *fd, + GeglBuffer *buffer; + guchar *dest, *temp; + gint i, cur_progress, max_progress; ++ size_t n_read; + + /* Make a new image in GIMP */ + if ((width < 0) || (width > GIMP_MAX_IMAGE_SIZE)) +@@ -280,14 +281,14 @@ read_image (FILE *fd, + + gimp_image_insert_layer (image, layer, NULL, 0); + +- dest = g_malloc0 (width * height); ++ dest = g_malloc0 ((gsize) width * height); + + ypos = 0; + + cur_progress = 0; + max_progress = height; + +- while (ReadOK (fd, &v, 1)) ++ while ((n_read = ReadOK (fd, &v, 1)) != 0) + { + for (i = 1; (i <= 8) && (xpos < width); i++, xpos++) + { +@@ -312,6 +313,9 @@ read_image (FILE *fd, + break; + } + ++ if (n_read == 0) ++ g_warning (_("Read failure at position %u. Possibly corrupt image."), ypos * width + xpos); ++ + buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)); + + gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0, NULL, dest, +diff -urNp a/plug-ins/common/file-xwd.c b/plug-ins/common/file-xwd.c +--- a/plug-ins/common/file-xwd.c 2025-11-20 10:40:07.879708221 +0100 ++++ b/plug-ins/common/file-xwd.c 2025-11-20 10:41:46.852626816 +0100 +@@ -1683,9 +1683,20 @@ load_xwd_f2_d16_b16 (GFile *fi + greenval = (green * 255) / maxgreen; + for (blue = 0; blue <= maxblue; blue++) + { ++ guint32 offset = ((red << redshift) + (green << greenshift) + ++ (blue << blueshift)) * 3; ++ ++ if (offset+2 >= maxval) ++ { ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("Invalid colormap offset. Possibly corrupt image.")); ++ g_free (data); ++ g_free (ColorMap); ++ g_object_unref (buffer); ++ return NULL; ++ } + blueval = (blue * 255) / maxblue; +- cm = ColorMap + ((red << redshift) + (green << greenshift) +- + (blue << blueshift)) * 3; ++ cm = ColorMap + offset; + *(cm++) = redval; + *(cm++) = greenval; + *cm = blueval; diff --git a/SOURCES/gimp-3.0.4-CVE-2025-14422.patch b/SOURCES/gimp-3.0.4-CVE-2025-14422.patch new file mode 100644 index 0000000..db17710 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2025-14422.patch @@ -0,0 +1,64 @@ +From 4ff2d773d58064e6130495de498e440f4a6d5edb Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Sun, 23 Nov 2025 16:43:51 +0000 +Subject: [PATCH] plug-ins: Fix ZDI-CAN-28273 + +Resolves #15286 +Adds a check to the memory allocation +in pnm_load_raw () with g_size_checked_mul () +to see if the size would go out of bounds. +If so, we don't try to allocate and load the +image. +--- + plug-ins/common/file-pnm.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/plug-ins/common/file-pnm.c b/plug-ins/common/file-pnm.c +index 32a33a4f35..9d349e967e 100644 +--- a/plug-ins/common/file-pnm.c ++++ b/plug-ins/common/file-pnm.c +@@ -674,7 +674,7 @@ load_image (GFile *file, + GError **error) + { + GInputStream *input; +- GeglBuffer *buffer; ++ GeglBuffer *buffer = NULL; + GimpImage * volatile image = NULL; + GimpLayer *layer; + char buf[BUFLEN + 4]; /* buffer for random things like scanning */ +@@ -708,6 +708,9 @@ load_image (GFile *file, + g_object_unref (input); + g_free (pnminfo); + ++ if (buffer) ++ g_object_unref (buffer); ++ + if (image) + gimp_image_delete (image); + +@@ -1060,6 +1063,7 @@ pnm_load_raw (PNMScanner *scan, + const Babl *format = NULL; + gint bpc; + guchar *data, *d; ++ gsize data_size; + gushort *s; + gint x, y, i; + gint start, end, scanlines; +@@ -1070,7 +1074,12 @@ pnm_load_raw (PNMScanner *scan, + bpc = 1; + + /* No overflow as long as gimp_tile_height() < 1365 = 2^(31 - 18) / 6 */ +- data = g_new (guchar, gimp_tile_height () * info->xres * info->np * bpc); ++ if (! g_size_checked_mul (&data_size, gimp_tile_height (), info->xres) || ++ ! g_size_checked_mul (&data_size, data_size, info->np) || ++ ! g_size_checked_mul (&data_size, data_size, bpc)) ++ CHECK_FOR_ERROR (FALSE, info->jmpbuf, _("Unsupported maximum value.")); ++ ++ data = g_new (guchar, data_size); + + input = pnmscanner_input (scan); + +-- +GitLab + + diff --git a/SOURCES/gimp-3.0.4-CVE-2025-14423.patch b/SOURCES/gimp-3.0.4-CVE-2025-14423.patch new file mode 100644 index 0000000..5443106 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2025-14423.patch @@ -0,0 +1,104 @@ +From 481cdbbb97746be1145ec3a633c567a68633c521 Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Sun, 23 Nov 2025 04:22:49 +0000 +Subject: [PATCH] plug-ins: Fix ZDI-CAN-28311 + +Resolves #15292 +The IFF specification states that EHB format images +have exactly 32 colors in their palette. However, it +is possible for images in the wild to place an incorrect +palette size. This patch checks for this, and either limits +the palette size or breaks accordingly. +--- + plug-ins/common/file-iff.c | 32 ++++++++++++++++++++++---------- + 1 file changed, 22 insertions(+), 10 deletions(-) + +diff --git a/plug-ins/common/file-iff.c b/plug-ins/common/file-iff.c +index d144a96a4c..f0879470c2 100644 +--- a/plug-ins/common/file-iff.c ++++ b/plug-ins/common/file-iff.c +@@ -337,7 +337,7 @@ load_image (GFile *file, + width = bitMapHeader->w; + height = bitMapHeader->h; + nPlanes = bitMapHeader->nPlanes; +- row_length = (width + 15) / 16; ++ row_length = ((width + 15) / 16) * 2; + pixel_size = nPlanes / 8; + aspect_x = bitMapHeader->xAspect; + aspect_y = bitMapHeader->yAspect; +@@ -375,6 +375,18 @@ load_image (GFile *file, + { + /* EHB mode adds 32 more colors. Each are half the RGB values + * of the first 32 colors */ ++ if (palette_size < 32) ++ { ++ g_set_error (error, G_FILE_ERROR, ++ g_file_error_from_errno (errno), ++ _("Invalid ILBM colormap size")); ++ return NULL; ++ } ++ else if (palette_size > 32) ++ { ++ palette_size = 32; ++ } ++ + for (gint j = 0; j < palette_size * 2; j++) + { + gint offset_index = j + 32; +@@ -386,7 +398,7 @@ load_image (GFile *file, + gimp_cmap[offset_index * 3 + 2] = + colorMap->colorRegister[j].blue / 2; + } +- /* EHB mode always has 64 colors */ ++ /* EHB mode always has 64 colors in total */ + palette_size = 64; + } + } +@@ -447,7 +459,7 @@ load_image (GFile *file, + { + guchar *pixel_row; + +- pixel_row = g_malloc (width * pixel_size * sizeof (guchar)); ++ pixel_row = g_malloc0 (width * pixel_size); + + /* PBM uses one byte per pixel index */ + if (ILBM_imageIsPBM (true_image)) +@@ -459,7 +471,7 @@ load_image (GFile *file, + else + deleave_rgb_row (bitplanes, pixel_row, width, nPlanes, pixel_size); + +- bitplanes += (row_length * 2 * nPlanes); ++ bitplanes += (row_length * nPlanes); + + gegl_buffer_set (buffer, GEGL_RECTANGLE (0, y_height, width, 1), 0, + NULL, pixel_row, GEGL_AUTO_ROWSTRIDE); +@@ -528,7 +540,7 @@ deleave_ham_row (const guchar *gimp_cmap, + /* Deleave rows */ + for (gint i = 0; i < row_length; i++) + { +- for (gint j = 0; j < 8; j++) ++ for (gint j = 0; j < nPlanes; j++) + { + guint8 bitmask = (1 << (8 - j)) - (1 << (7 - j)); + guint8 control = 0; +@@ -590,11 +602,11 @@ deleave_ham_row (const guchar *gimp_cmap, + } + + static void +-deleave_rgb_row (IFF_UByte *bitplanes, +- guchar *pixel_row, +- gint width, +- gint nPlanes, +- gint pixel_size) ++deleave_rgb_row (IFF_UByte *bitplanes, ++ guchar *pixel_row, ++ gint width, ++ gint nPlanes, ++ gint pixel_size) + { + gint row_length = ((width + 15) / 16) * 2; + gint current_pixel = 0; +-- +GitLab + + diff --git a/SOURCES/gimp-3.0.4-CVE-2025-14424.patch b/SOURCES/gimp-3.0.4-CVE-2025-14424.patch new file mode 100644 index 0000000..aa65749 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2025-14424.patch @@ -0,0 +1,32 @@ +From 5cc55d078b7fba995cef77d195fac325ee288ddd Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Thu, 13 Nov 2025 18:26:51 -0500 +Subject: [PATCH] app: fix #15288 crash when loading malformed xcf + +ZDI-CAN-28376 vulnerability + +Add extra tests to not crash on a NULL g_class. +--- + app/core/gimpitemlist.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/app/core/gimpitemlist.c b/app/core/gimpitemlist.c +index 93dfc83427..5aeb4916d8 100644 +--- a/app/core/gimpitemlist.c ++++ b/app/core/gimpitemlist.c +@@ -345,7 +345,10 @@ gimp_item_list_named_new (GimpImage *image, + g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); + + for (iter = items; iter; iter = iter->next) +- g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (iter->data), item_type), NULL); ++ { ++ g_return_val_if_fail (iter->data && ((GTypeInstance*) (iter->data))->g_class, NULL); ++ g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (iter->data), item_type), NULL); ++ } + + if (! items) + { +-- +GitLab + + diff --git a/SOURCES/gimp-3.0.4-CVE-2025-14425.patch b/SOURCES/gimp-3.0.4-CVE-2025-14425.patch new file mode 100644 index 0000000..e4ae054 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2025-14425.patch @@ -0,0 +1,77 @@ +From cd1c88a0364ad1444c06536731972a99bd8643fd Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Wed, 12 Nov 2025 13:25:44 +0000 +Subject: [PATCH] plug-ins: Mitigate ZDI-CAN-28248 for JP2 images + +Resolves #15285 +Per the report, it's possible to exceed the size of the pixel buffer +with a high precision_scaled value, as we size it to the width * bpp. +This patch includes precision_scaled in the allocation calculation. +It also adds a g_size_checked_mul () check to ensure there's no +overflow, and moves the pixel and buffer memory freeing to occur +in the out section so that it always runs even on failure. +--- + plug-ins/common/file-jp2-load.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/plug-ins/common/file-jp2-load.c b/plug-ins/common/file-jp2-load.c +index cc05727894..87ba8761a2 100644 +--- a/plug-ins/common/file-jp2-load.c ++++ b/plug-ins/common/file-jp2-load.c +@@ -1354,14 +1354,15 @@ load_image (GimpProcedure *procedure, + GimpColorProfile *profile = NULL; + GimpImage *gimp_image = NULL; + GimpLayer *layer; ++ GeglBuffer *buffer = NULL; ++ guchar *pixels = NULL; ++ gsize pixels_size; + GimpImageType image_type; + GimpImageBaseType base_type; + gint width; + gint height; + gint num_components; +- GeglBuffer *buffer; + gint i, j, k, it; +- guchar *pixels; + const Babl *file_format; + gint bpp; + GimpPrecision image_precision; +@@ -1627,7 +1628,15 @@ load_image (GimpProcedure *procedure, + bpp = babl_format_get_bytes_per_pixel (file_format); + + buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)); +- pixels = g_new0 (guchar, width * bpp); ++ ++ if (! g_size_checked_mul (&pixels_size, width, (bpp * (precision_scaled / 8)))) ++ { ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("Defined row size is too large in JP2 image '%s'."), ++ gimp_file_get_utf8_name (file)); ++ goto out; ++ } ++ pixels = g_new0 (guchar, pixels_size); + + for (i = 0; i < height; i++) + { +@@ -1653,13 +1662,13 @@ load_image (GimpProcedure *procedure, + gegl_buffer_set (buffer, GEGL_RECTANGLE (0, i, width, 1), 0, + file_format, pixels, GEGL_AUTO_ROWSTRIDE); + } +- +- g_free (pixels); +- +- g_object_unref (buffer); + gimp_progress_update (1.0); + + out: ++ if (pixels) ++ g_free (pixels); ++ if (buffer) ++ g_object_unref (buffer); + if (profile) + g_object_unref (profile); + if (image) +-- +GitLab + + diff --git a/SOURCES/gimp-3.0.4-CVE-2025-15059.patch b/SOURCES/gimp-3.0.4-CVE-2025-15059.patch new file mode 100644 index 0000000..25f28e7 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2025-15059.patch @@ -0,0 +1,39 @@ +From 03575ac8cbb0ef3103b0a15d6598475088dcc15e Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Sat, 20 Dec 2025 10:10:48 -0500 +Subject: [PATCH] plug-ins: fix #15284 ZDI-CAN-28232 vulnerability in file-psp + +We were not checking whether channel types were valid for grayscale +images. Using a blue color channel caused an invalid computation of +the offset which could cause us to access an invalid memory location. + +Now we separate RGB from non-RGB images when checking which channels +are valid, and if not return with an error. +--- + plug-ins/common/file-psp.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/plug-ins/common/file-psp.c b/plug-ins/common/file-psp.c +index f00251c573..3f6970561f 100644 +--- a/plug-ins/common/file-psp.c ++++ b/plug-ins/common/file-psp.c +@@ -2171,11 +2171,12 @@ read_layer_block (FILE *f, + } + else + { +- if (channel_type > PSP_CHANNEL_BLUE) ++ if ((ia->base_type == GIMP_RGB && channel_type > PSP_CHANNEL_BLUE) || ++ (ia->base_type != GIMP_RGB && channel_type >= PSP_CHANNEL_RED)) + { + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, +- _("Invalid channel type %d in channel information chunk"), +- channel_type); ++ _("Invalid channel type %d in channel information chunk"), ++ channel_type); + return NULL; + } + +-- +GitLab + + diff --git a/SOURCES/gimp-3.0.4-CVE-2026-0797.patch b/SOURCES/gimp-3.0.4-CVE-2026-0797.patch new file mode 100644 index 0000000..569e926 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2026-0797.patch @@ -0,0 +1,91 @@ +From c54bf22acb04b83ae38ed50add58f300e898dd81 Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Fri, 26 Dec 2025 15:49:45 +0000 +Subject: [PATCH] plug-ins: Add more fread () checks in ICO loading + +Resolves #15555 + +This patch adds some guards for ico_read_int8 (), +which was used for loading palettes and maps +without verifying that it returned the same number +of bytes as what it tried to read in. +--- + plug-ins/file-ico/ico-load.c | 33 ++++++++++++++++++++++++++------- + 1 file changed, 26 insertions(+), 7 deletions(-) + +diff --git a/plug-ins/file-ico/ico-load.c b/plug-ins/file-ico/ico-load.c +index 818cf23cd31..68637cbd745 100644 +--- a/plug-ins/file-ico/ico-load.c ++++ b/plug-ins/file-ico/ico-load.c +@@ -69,7 +69,9 @@ ico_read_int32 (FILE *fp, + total = count; + if (count > 0) + { +- ico_read_int8 (fp, (guint8 *) data, count * 4); ++ if (ico_read_int8 (fp, (guint8 *) data, count * 4) != (count * 4)) ++ return FALSE; ++ + for (i = 0; i < count; i++) + data[i] = GUINT32_FROM_LE (data[i]); + } +@@ -88,7 +90,9 @@ ico_read_int16 (FILE *fp, + total = count; + if (count > 0) + { +- ico_read_int8 (fp, (guint8 *) data, count * 2); ++ if (ico_read_int8 (fp, (guint8 *) data, count * 2) != (count * 2)) ++ return FALSE; ++ + for (i = 0; i < count; i++) + data[i] = GUINT16_FROM_LE (data[i]); + } +@@ -109,8 +113,8 @@ ico_read_int8 (FILE *fp, + while (count > 0) + { + bytes = fread ((gchar *) data, sizeof (gchar), count, fp); +- if (bytes <= 0) /* something bad happened */ +- break; ++ if (bytes != count) /* something bad happened */ ++ return -1; + + count -= bytes; + data += bytes; +@@ -489,16 +493,31 @@ ico_read_icon (FILE *fp, + data.used_clrs, data.bpp)); + + palette = g_new0 (guint32, data.used_clrs); +- ico_read_int8 (fp, (guint8 *) palette, data.used_clrs * 4); ++ if (ico_read_int8 (fp, ++ (guint8 *) palette, ++ data.used_clrs * 4) != (data.used_clrs * 4)) ++ { ++ D(("skipping image: too large\n")); ++ return FALSE; ++ } ++ + } + + xor_map = ico_alloc_map (w, h, data.bpp, &length); +- ico_read_int8 (fp, xor_map, length); ++ if (ico_read_int8 (fp, xor_map, length) != length) ++ { ++ D(("skipping image: too large\n")); ++ return FALSE; ++ } + D((" length of xor_map: %i\n", length)); + + /* Read in and_map. It's padded out to 32 bits per line: */ + and_map = ico_alloc_map (w, h, 1, &length); +- ico_read_int8 (fp, and_map, length); ++ if (! ico_read_int8 (fp, and_map, length) != length) ++ { ++ D(("skipping image: too large\n")); ++ return FALSE; ++ } + D((" length of and_map: %i\n", length)); + + dest_vec = (guint32 *) buf; +-- +GitLab + + diff --git a/SOURCES/gimp-3.0.4-CVE-2026-2044.patch b/SOURCES/gimp-3.0.4-CVE-2026-2044.patch new file mode 100644 index 0000000..d448289 --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2026-2044.patch @@ -0,0 +1,26 @@ +From 112a5e038f0646eae5ae314988ec074433d2b365 Mon Sep 17 00:00:00 2001 +From: Gabriele Barbero +Date: Fri, 5 Dec 2025 19:13:01 +0100 +Subject: [PATCH] ZDI-CAN-28158: use g_malloc0 instead of g_malloc + +To avoid accessing uninitialized memory, replace calls to g_malloc with +g_malloc0 which initializes the allocated memory to zero. +--- + plug-ins/common/file-pnm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plug-ins/common/file-pnm.c b/plug-ins/common/file-pnm.c +index 9d349e967e7..65619be59de 100644 +--- a/plug-ins/common/file-pnm.c ++++ b/plug-ins/common/file-pnm.c +@@ -693,7 +693,7 @@ load_image (GFile *file, + return NULL; + + /* allocate the necessary structures */ +- pnminfo = g_new (PNMInfo, 1); ++ pnminfo = g_new0 (PNMInfo, 1); + + pnminfo->tupltype = NULL; + +-- +GitLab diff --git a/SOURCES/gimp-3.0.4-CVE-2026-2045.patch b/SOURCES/gimp-3.0.4-CVE-2026-2045.patch new file mode 100644 index 0000000..ee36a7c --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2026-2045.patch @@ -0,0 +1,35 @@ +From 68b27dfb1cbd9b3f22d7fa624dbab8647ee5f275 Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Thu, 15 Jan 2026 10:12:07 -0500 +Subject: [PATCH] plug-ins: fix #15293 security issue ZDI-CAN-28265 + +Just like we did in commit 4eb106f2bff2d9b8e518aa455a884c6f38d70c6a +we need to make sure that the offset in the colormap is valid before +using it, before using it to compute the RGB values. +--- + plug-ins/common/file-xwd.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/plug-ins/common/file-xwd.c b/plug-ins/common/file-xwd.c +index 77d9ea5d9f3..a016c55cd8a 100644 +--- a/plug-ins/common/file-xwd.c ++++ b/plug-ins/common/file-xwd.c +@@ -1712,7 +1712,15 @@ load_xwd_f2_d16_b16 (GFile *file, + + for (j = 0; j < ncols; j++) + { +- cm = ColorMap + xwdcolmap[j].l_pixel * 3; ++ goffset offset = xwdcolmap[j].l_pixel * 3; ++ ++ if (offset+2 >= maxval) ++ { ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("Invalid colormap offset. Possibly corrupt image.")); ++ return NULL; ++ } ++ cm = ColorMap + offset; + *(cm++) = (xwdcolmap[j].l_red >> 8); + *(cm++) = (xwdcolmap[j].l_green >> 8); + *cm = (xwdcolmap[j].l_blue >> 8); +-- +GitLab diff --git a/SOURCES/gimp-3.0.4-CVE-2026-2047.patch b/SOURCES/gimp-3.0.4-CVE-2026-2047.patch new file mode 100644 index 0000000..d98fbff --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2026-2047.patch @@ -0,0 +1,161 @@ +From dd2faac351f1ff2588529fedc606e6a5f815577c Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Sat, 17 Jan 2026 16:59:17 +0000 +Subject: [PATCH] plug-ins: Resolve ZDI-CAN-28530 for ICNS load + +Our ICNS importer did not verify that the ICNS resource +data size was defined as larger than 0. Therefore, it +was possible to create a malicious file that would infinitely +load since the file cursor would not advance. This patch +adds a check for the icon size being 0, and stops the loop +if this is encountered. + +Additionally, there is no header defined limit for the number of +icons in an ICNS file. This patch switches from using a hardcoded +256 icon limit to using GLists to dynamically add icons as we read +them in. +--- + plug-ins/file-icns/file-icns-load.c | 59 ++++++++++++++++++++--------- + 1 file changed, 42 insertions(+), 17 deletions(-) + +diff --git a/plug-ins/file-icns/file-icns-load.c b/plug-ins/file-icns/file-icns-load.c +index f2298c056e1..9b5b7fc7743 100644 +--- a/plug-ins/file-icns/file-icns-load.c ++++ b/plug-ins/file-icns/file-icns-load.c +@@ -40,7 +40,7 @@ + + IcnsResource * resource_load (FILE *file); + +-IcnsResource * resource_find (IcnsResource *list, ++IcnsResource * resource_find (GList *resources, + gchar *type, + gint max); + +@@ -118,14 +118,18 @@ resource_load (FILE *file) + } + + IcnsResource * +-resource_find (IcnsResource *list, ++resource_find (GList *resources, + gchar *type, + gint max) + { +- for (gint i = 0; i < max; i++) ++ GList *list; ++ ++ for (list = resources; list; list = g_list_next (list)) + { +- if (! strncmp (list[i].type, type, 4)) +- return &list[i]; ++ IcnsResource *res = list->data; ++ ++ if (! strncmp (res->type, type, 4)) ++ return res; + } + return NULL; + } +@@ -145,10 +149,14 @@ resource_get_next (IcnsResource *icns, + res->cursor = sizeof (IcnsResourceHeader); + res->data = &(icns->data[icns->cursor]); + ++ if (! res->size) ++ return FALSE; ++ + icns->cursor += res->size; + if (icns->cursor > icns->size) + { + gchar typestring[5]; ++ + fourcc_get_string (icns->type, typestring); + g_message ("icns resource_get_next: resource too big! type '%s', size %u\n", + typestring, icns->size); +@@ -162,18 +170,25 @@ GimpImage * + icns_load (IcnsResource *icns, + GFile *file) + { +- IcnsResource *resources; ++ GList *resources; ++ IcnsResource *resource; + guint nResources; + gfloat current_resources = 0; + GimpImage *image; + +- resources = g_new (IcnsResource, 256); ++ resources = NULL; ++ resource = g_new (IcnsResource, 1); + + /* Largest .icns icon is 1024 x 1024 */ + image = gimp_image_new (1024, 1024, GIMP_RGB); + + nResources = 0; +- while (resource_get_next (icns, &resources[nResources++])) {} ++ while (resource_get_next (icns, resource)) ++ { ++ resources = g_list_append (resources, resource); ++ ++ resource = g_new (IcnsResource, 1); ++ } + + for (gint i = 0; iconTypes[i].type; i++) + { +@@ -192,7 +207,8 @@ icns_load (IcnsResource *icns, + } + + gimp_image_resize_to_layers (image); +- g_free (resources); ++ g_list_free_full (resources, g_free); ++ g_free (resource); + return image; + } + +@@ -585,7 +601,8 @@ icns_load_thumbnail_image (GFile *file, + FILE *fp; + GimpImage *image = NULL; + IcnsResource *icns; +- IcnsResource *resources; ++ GList *resources; ++ IcnsResource *resource; + IcnsResource *mask = NULL; + guint i; + gint match = -1; +@@ -610,15 +627,22 @@ icns_load_thumbnail_image (GFile *file, + fclose (fp); + + if (! icns) +- { +- g_message ("Invalid or corrupt icns resource file."); +- return NULL; +- } ++ { ++ g_message ("Invalid or corrupt icns resource file."); ++ return NULL; ++ } + + image = gimp_image_new (1024, 1024, GIMP_RGB); + +- resources = g_new (IcnsResource, 256); +- while (resource_get_next (icns, &resources[nResources++])) {} ++ resources = NULL; ++ resource = g_new (IcnsResource, 1); ++ ++ while (resource_get_next (icns, resource)) ++ { ++ resources = g_list_append (resources, resource); ++ ++ resource = g_new (IcnsResource, 1); ++ } + + *width = 0; + *height = 0; +@@ -671,7 +695,8 @@ icns_load_thumbnail_image (GFile *file, + return NULL; + } + +- g_free (resources); ++ g_list_free_full (resources, g_free); ++ g_free (resource); + + gimp_progress_update (1.0); + +-- +GitLab diff --git a/SOURCES/gimp-3.0.4-CVE-2026-2048.patch b/SOURCES/gimp-3.0.4-CVE-2026-2048.patch new file mode 100644 index 0000000..9d6b9aa --- /dev/null +++ b/SOURCES/gimp-3.0.4-CVE-2026-2048.patch @@ -0,0 +1,86 @@ +From 57712677007793118388c5be6fb8231f22a2b341 Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Wed, 31 Dec 2025 14:45:15 +0000 +Subject: [PATCH] plug-ins: Add OoB check for loading XWD + +Resolves #15554 +This patch adds a check for if our pointer arithmetic +exceeds the memory allocated for the dest array. If so, +we throw an error rather than access memory outside +the bounds. +--- + plug-ins/common/file-xwd.c | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +diff --git a/plug-ins/common/file-xwd.c b/plug-ins/common/file-xwd.c +index c4c41e5bea7..77d9ea5d9f3 100644 +--- a/plug-ins/common/file-xwd.c ++++ b/plug-ins/common/file-xwd.c +@@ -2241,6 +2241,7 @@ load_xwd_f1_d24_b1 (GFile *file, + guint32 redmask, greenmask, bluemask; + guint redshift, greenshift, blueshift; + guint32 g; ++ guint32 maxval; + guchar redmap[256], greenmap[256], bluemap[256]; + guchar bit_reverse[256]; + guchar *xwddata, *xwdin, *data; +@@ -2332,7 +2333,8 @@ load_xwd_f1_d24_b1 (GFile *file, + &layer, &buffer); + + tile_height = gimp_tile_height (); +- data = g_malloc (tile_height * width * bytes_per_pixel); ++ data = g_malloc (tile_height * width * bytes_per_pixel); ++ maxval = tile_height * width * bytes_per_pixel; + + ncols = xwdhdr->l_colormap_entries; + if (xwdhdr->l_ncolors < ncols) +@@ -2357,6 +2359,8 @@ load_xwd_f1_d24_b1 (GFile *file, + + for (tile_start = 0; tile_start < height; tile_start += tile_height) + { ++ guint current_dest = 0; ++ + memset (data, 0, width*tile_height*bytes_per_pixel); + + tile_end = tile_start + tile_height - 1; +@@ -2384,7 +2388,18 @@ load_xwd_f1_d24_b1 (GFile *file, + else /* 3 bytes per pixel */ + { + fromright = xwdhdr->l_pixmap_depth-1-plane; +- dest += 2 - fromright/8; ++ ++ current_dest += 2 - fromright / 8; ++ if (current_dest < maxval) ++ { ++ dest += 2 - fromright / 8; ++ } ++ else ++ { ++ err = 1; ++ break; ++ } ++ + outmask = (1 << (fromright % 8)); + } + +@@ -2439,7 +2454,17 @@ load_xwd_f1_d24_b1 (GFile *file, + + if (g & inmask) + *dest |= outmask; +- dest += bytes_per_pixel; ++ ++ current_dest += bytes_per_pixel; ++ if (current_dest < maxval) ++ { ++ dest += bytes_per_pixel; ++ } ++ else ++ { ++ err = 1; ++ break; ++ } + + inmask >>= 1; + } +-- +GitLab diff --git a/SOURCES/gimp-CVE-2026-4150.patch b/SOURCES/gimp-CVE-2026-4150.patch new file mode 100644 index 0000000..34eb599 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-4150.patch @@ -0,0 +1,196 @@ +From 00afdabdadeb5457fd897878b1e5aebc3780af10 Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Fri, 6 Mar 2026 10:01:09 -0500 +Subject: [PATCH] plug-ins: fix #15967 integer overflow in psd-load + +Reported as ZDI-CAN-28807 +With large row and column sizes 32-bit int values are not large +enough to hold the product and thus can cause overflow. + +While we are at it, we not only fix the location from the report, but +also other occurrences that could overflow. +- We change certain variables to gsize to make sure they can hold a +64-bit value. +- Other intermediate results are promoted to (gsize) to make sure that +the product is computed as gsize. +- Move some i,j variables to the loops where they are used. + +(cherry picked from commit 7e1241f75147bf6e705a31c81e4d5efab1df1668) +--- + plug-ins/file-psd/psd-load.c | 44 ++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 24 deletions(-) + +diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c +index 0ec888c2ec9..676f3da9b41 100644 +--- a/plug-ins/file-psd/psd-load.c ++++ b/plug-ins/file-psd/psd-load.c +@@ -2813,14 +2813,13 @@ add_merged_image (GimpImage *image, + guint16 bps; + guint32 *rle_pack_len[MAX_CHANNELS]; + guint32 alpha_id; +- gint32 layer_size; ++ gsize layer_size; + GimpLayer *layer = NULL; + GimpChannel *channel = NULL; + gint16 alpha_opacity; + gint cidx; /* Channel index */ + gint rowi; /* Row index */ + gint offset; +- gint i; + gboolean alpha_visible; + gboolean alpha_channel = FALSE; + GeglBuffer *buffer; +@@ -2975,11 +2974,11 @@ add_merged_image (GimpImage *image, + image_type = get_gimp_image_type (img_a->base_type, + img_a->transparency || alpha_channel); + +- layer_size = img_a->columns * img_a->rows; ++ layer_size = (gsize) img_a->columns * img_a->rows; + pixels = g_malloc (layer_size * base_channels * bps); + for (cidx = 0; cidx < base_channels; ++cidx) + { +- for (i = 0; i < layer_size; ++i) ++ for (gint64 i = 0; i < layer_size; ++i) + { + memcpy (&pixels[((i * base_channels) + cidx) * bps], + &chn_a[cidx].data[i * bps], bps); +@@ -3051,7 +3050,7 @@ add_merged_image (GimpImage *image, + { + gfloat *data = iter->items[0].data; + +- for (i = 0; i < iter->length; i++) ++ for (gint i = 0; i < iter->length; i++) + { + gint c; + +@@ -3103,7 +3102,7 @@ add_merged_image (GimpImage *image, + + /* Draw channels */ + IFDBG(2) g_debug ("Number of channels: %d", extra_channels); +- for (i = 0; i < extra_channels; ++i) ++ for (gint i = 0; i < extra_channels; ++i) + { + /* Alpha channel name */ + alpha_name = NULL; +@@ -3144,8 +3143,8 @@ add_merged_image (GimpImage *image, + } + + cidx = base_channels + i; +- pixels = g_realloc (pixels, chn_a[cidx].columns * chn_a[cidx].rows * bps); +- memcpy (pixels, chn_a[cidx].data, chn_a[cidx].columns * chn_a[cidx].rows * bps); ++ pixels = g_realloc (pixels, (gsize) chn_a[cidx].columns * chn_a[cidx].rows * bps); ++ memcpy (pixels, chn_a[cidx].data, (gsize) chn_a[cidx].columns * chn_a[cidx].rows * bps); + channel = gimp_channel_new (image, alpha_name, + chn_a[cidx].columns, chn_a[cidx].rows, + alpha_opacity, alpha_rgb); +@@ -3332,7 +3331,6 @@ read_channel_data (PSDchannel *channel, + gchar *raw_data = NULL; + gchar *src; + guint32 readline_len; +- gint i, j; + + if (bps == 1) + readline_len = ((channel->columns + 7) / 8); +@@ -3364,7 +3362,7 @@ read_channel_data (PSDchannel *channel, + break; + + case PSD_COMP_RLE: +- for (i = 0; i < channel->rows; ++i) ++ for (gint i = 0; i < channel->rows; ++i) + { + src = gegl_scratch_alloc (rle_pack_len[i]); + /* FIXME check for over-run +@@ -3433,12 +3431,11 @@ read_channel_data (PSDchannel *channel, + case 32: + { + guint32 *data; +- guint64 pos; + + if (compression == PSD_COMP_ZIP_PRED) + { + IFDBG(3) g_debug ("Converting 32 bit predictor data"); +- channel->data = (gchar *) g_malloc0 (channel->rows * channel->columns * 4); ++ channel->data = (gchar *) g_malloc0 ((gsize) channel->rows * channel->columns * 4); + decode_32_bit_predictor (raw_data, channel->data, + channel->rows, channel->columns); + } +@@ -3450,7 +3447,7 @@ read_channel_data (PSDchannel *channel, + } + + data = (guint32*) channel->data; +- for (pos = 0; pos < channel->rows * channel->columns; ++pos) ++ for (gsize pos = 0; pos < (gsize) channel->rows * channel->columns; ++pos) + data[pos] = GUINT32_FROM_BE (data[pos]); + + break; +@@ -3463,14 +3460,14 @@ read_channel_data (PSDchannel *channel, + channel->data = raw_data; + raw_data = NULL; + +- for (i = 0; i < channel->rows * channel->columns; ++i) ++ for (gsize i = 0; i < (gsize) channel->rows * channel->columns; ++i) + data[i] = GUINT16_FROM_BE (data[i]); + + if (compression == PSD_COMP_ZIP_PRED) + { + IFDBG(3) g_debug ("Converting 16 bit predictor data"); +- for (i = 0; i < channel->rows; ++i) +- for (j = 1; j < channel->columns; ++j) ++ for (gsize i = 0; i < channel->rows; ++i) ++ for (gsize j = 1; j < channel->columns; ++j) + data[i * channel->columns + j] += data[i * channel->columns + j - 1]; + } + break; +@@ -3483,14 +3480,14 @@ read_channel_data (PSDchannel *channel, + if (compression == PSD_COMP_ZIP_PRED) + { + IFDBG(3) g_debug ("Converting 8 bit predictor data"); +- for (i = 0; i < channel->rows; ++i) +- for (j = 1; j < channel->columns; ++j) ++ for (gsize i = 0; i < channel->rows; ++i) ++ for (gsize j = 1; j < channel->columns; ++j) + channel->data[i * channel->columns + j] += channel->data[i * channel->columns + j - 1]; + } + break; + + case 1: +- channel->data = (gchar *) g_malloc (channel->rows * channel->columns); ++ channel->data = (gchar *) g_malloc ((gsize) channel->rows * channel->columns); + convert_1_bit (raw_data, channel->data, channel->rows, channel->columns); + break; + +@@ -3540,7 +3537,7 @@ decode_32_bit_predictor (gchar *src, + + /* restore byte order */ + dstpos = 0; +- for (row = 0; row < rows * rowsize; row += rowsize) ++ for (row = 0; row < (gsize) rows * rowsize; row += rowsize) + { + guint64 offset; + +@@ -3567,18 +3564,17 @@ convert_1_bit (const gchar *src, + Rows are padded out to a byte boundary. + */ + guint32 row_pos = 0; +- gint i, j; + + IFDBG(3) g_debug ("Start 1 bit conversion"); + +- for (i = 0; i < rows * ((columns + 7) / 8); ++i) ++ for (gsize i = 0; i < (gsize) rows * ((columns + 7) / 8); ++i) + { + guchar mask = 0x80; +- for (j = 0; j < 8 && row_pos < columns; ++j) ++ for (gint j = 0; j < 8 && row_pos < columns; ++j) + { + *dst = (*src & mask) ? 0 : 1; + IFDBG(4) g_debug ("byte %d, bit %d, offset %d, src %d, dst %d", +- i , j, row_pos, *src, *dst); ++ (gint) i , j, row_pos, *src, *dst); + dst++; + mask >>= 1; + row_pos++; +-- +GitLab + + diff --git a/SOURCES/gimp-CVE-2026-4151.patch b/SOURCES/gimp-CVE-2026-4151.patch new file mode 100644 index 0000000..2196b40 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-4151.patch @@ -0,0 +1,59 @@ +From 09e5459de913172fc51da3bd6b6adc533acd368e Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Thu, 5 Mar 2026 23:58:45 +0000 +Subject: [PATCH] plug-ins: Resolve ZDI-CAN-28813 in ANI loading + +Resolves #15968 +It is possible to cause a buffer overflow in our ANI +loading code by setting the Name or Artist metadata +files to 0xFFFFFFFF. This patch changes our allocation +code to use g_try_new0 () instead of g_new0 (), and +verifies if it is NULL before trying to read data into it. +--- + plug-ins/file-ico/ico-load.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/plug-ins/file-ico/ico-load.c b/plug-ins/file-ico/ico-load.c +index 29ad4c5eb59..e20d79a713f 100644 +--- a/plug-ins/file-ico/ico-load.c ++++ b/plug-ins/file-ico/ico-load.c +@@ -893,7 +893,16 @@ ani_load_image (GFile *file, + if (inam) + g_free (inam); + +- inam = g_new0 (gchar, size + 1); ++ inam = g_try_new0 (gchar, size + 1); ++ if (inam == NULL) ++ { ++ fclose (fp); ++ g_set_error (error, G_FILE_ERROR, ++ g_file_error_from_errno (errno), ++ _("Invalid ANI metadata")); ++ return NULL; ++ } ++ + n_read = fread (inam, sizeof (gchar), size, fp); + inam[size] = '\0'; + } +@@ -924,7 +933,16 @@ ani_load_image (GFile *file, + if (iart) + g_free (iart); + +- iart = g_new0 (gchar, size + 1); ++ iart = g_try_new0 (gchar, size + 1); ++ if (iart == NULL) ++ { ++ fclose (fp); ++ g_set_error (error, G_FILE_ERROR, ++ g_file_error_from_errno (errno), ++ _("Invalid ANI metadata")); ++ return NULL; ++ } ++ + n_read = fread (iart, sizeof (gchar), size, fp); + iart[size] = '\0'; + } +-- +GitLab + + diff --git a/SOURCES/gimp-CVE-2026-4152.patch b/SOURCES/gimp-CVE-2026-4152.patch new file mode 100644 index 0000000..82f7bc0 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-4152.patch @@ -0,0 +1,55 @@ +From f64c9c23ba3c37dc7b875a9fb477c23953b4666e Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Thu, 12 Mar 2026 13:48:45 +0000 +Subject: [PATCH] plug-ins: Mitigate ZDI-CAN-28863 + +Resolves #15969 + +It is possible to set the number of color components +in the JPEG 2000 file separate from the color space, +and OpenJPEG reports that value as-is. This can result +in a buffer overflow if the num_components variable is +larger than the number of channels in the color space. + +This patch adds a check to make sure num_components +is within range. If it's larger, then we clamp it to the maximum +value for that color model. +--- + plug-ins/common/file-jp2-load.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/plug-ins/common/file-jp2-load.c b/plug-ins/common/file-jp2-load.c +index cb420f9cb37..5c99a093d49 100644 +--- a/plug-ins/common/file-jp2-load.c ++++ b/plug-ins/common/file-jp2-load.c +@@ -1563,16 +1563,22 @@ load_image (GimpProcedure *procedure, + base_type = GIMP_GRAY; + image_type = GIMP_GRAY_IMAGE; + +- if (num_components == 2) +- image_type = GIMP_GRAYA_IMAGE; ++ if (num_components >= 2) ++ { ++ image_type = GIMP_GRAYA_IMAGE; ++ num_components = 2; ++ } + } + else if (image->color_space == OPJ_CLRSPC_SRGB) + { + base_type = GIMP_RGB; + image_type = GIMP_RGB_IMAGE; + +- if (num_components == 4) +- image_type = GIMP_RGBA_IMAGE; ++ if (num_components >= 4) ++ { ++ image_type = GIMP_RGBA_IMAGE; ++ num_components = 4; ++ } + } + else + { +-- +GitLab + + diff --git a/SOURCES/gimp-CVE-2026-4153.patch b/SOURCES/gimp-CVE-2026-4153.patch new file mode 100644 index 0000000..f710fc1 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-4153.patch @@ -0,0 +1,62 @@ +From 98cb1371fd4e22cca75017ea3252dc32fc218712 Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Sat, 7 Mar 2026 15:55:04 -0500 +Subject: [PATCH] plug-ins: fix #15970 buffer overflow in file-psp + +Reported as ZDI-CAN-28874. + +For psp images with bit depth 1 or 4 bits and small widths, it was +possible to overflow the buffer because these bit depths are stored +in multiples of 4 bytes per line. +Because these formats are converted to regular RGB, this means that for +small widths, more bytes are needed than expected when we are upscaling +to 8-bit. + +To fix this, we compute the line size when depth < 8, and adjust +line width if that value is larger. +--- + plug-ins/common/file-psp.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/plug-ins/common/file-psp.c b/plug-ins/common/file-psp.c +index 286cbed2bb7..763dd994fcd 100644 +--- a/plug-ins/common/file-psp.c ++++ b/plug-ins/common/file-psp.c +@@ -2127,7 +2127,23 @@ read_layer_block (FILE *f, + + if (can_handle_layer) + { +- pixel = g_malloc0 (height * width * bytespp); ++ gint line_width = width * bytespp; ++ ++ if (ia->depth < 8) ++ { ++ gint min_line_width = (((width * ia->depth + 7) / 8) + (ia->depth - 1)) / 4 * 4; ++ ++ /* For small widths, when depth is 1, or 4, the number of bytes ++ * used can be larger than the width * bytespp. Adjust for that. */ ++ if (min_line_width > line_width) ++ { ++ IFDBG(3) g_message ("Adjusting line width from %d to %d\n", ++ line_width, min_line_width); ++ line_width = min_line_width; ++ } ++ } ++ ++ pixel = g_malloc0 (height * line_width); + if (null_layer) + { + pixels = NULL; +@@ -2136,7 +2152,7 @@ read_layer_block (FILE *f, + { + pixels = g_new (guchar *, height); + for (i = 0; i < height; i++) +- pixels[i] = pixel + width * bytespp * i; ++ pixels[i] = pixel + line_width * i; + } + + buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)); +-- +GitLab + + diff --git a/SOURCES/gimp-CVE-2026-4154.patch b/SOURCES/gimp-CVE-2026-4154.patch new file mode 100644 index 0000000..024b368 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-4154.patch @@ -0,0 +1,90 @@ +From 2e7ed91793792d9e980b2df4c829e9aa60459253 Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Fri, 6 Mar 2026 13:54:44 +0000 +Subject: [PATCH] plug-in: Resolve ZDI-CAN-28901 for file-xpm + +Resolves #15971 +It was possible to set a XPM image to have a width and/or height +that is larger than what GIMP can create an image for. In addition to +causing gimp_image_new () to fail, it can also lead to buffer overflow +when allocating space to read in the image. + +This patch adds a GError parameter to parse_image (), then uses it to +pass up an error for either oversized images or buffer overflows. +--- + plug-ins/common/file-xpm.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/plug-ins/common/file-xpm.c b/plug-ins/common/file-xpm.c +index ba02961f1c0..71a0b19e8d3 100644 +--- a/plug-ins/common/file-xpm.c ++++ b/plug-ins/common/file-xpm.c +@@ -125,7 +125,8 @@ static GimpImage * load_image (GFile *file, + static guchar * parse_colors (XpmImage *xpm_image); + static void parse_image (GimpImage *image, + XpmImage *xpm_image, +- guchar *cmap); ++ guchar *cmap, ++ GError **error); + static gboolean export_image (GFile *file, + GimpImage *image, + GimpDrawable *drawable, +@@ -385,12 +386,28 @@ load_image (GFile *file, + + cmap = parse_colors (&xpm_image); + ++ if (xpm_image.width > GIMP_MAX_IMAGE_SIZE) ++ { ++ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, ++ _("Unsupported or invalid image width: %d"), ++ xpm_image.width); ++ return NULL; ++ } ++ ++ if (xpm_image.height > GIMP_MAX_IMAGE_SIZE) ++ { ++ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, ++ _("Unsupported or invalid image height: %d"), ++ xpm_image.height); ++ return NULL; ++ } ++ + image = gimp_image_new (xpm_image.width, + xpm_image.height, + GIMP_RGB); + + /* fill it */ +- parse_image (image, &xpm_image, cmap); ++ parse_image (image, &xpm_image, cmap, error); + + g_free (cmap); + +@@ -472,7 +489,8 @@ parse_colors (XpmImage *xpm_image) + static void + parse_image (GimpImage *image, + XpmImage *xpm_image, +- guchar *cmap) ++ guchar *cmap, ++ GError **error) + { + GeglBuffer *buffer; + gint tile_height; +@@ -498,7 +516,13 @@ parse_image (GimpImage *image, + + tile_height = gimp_tile_height (); + +- buf = g_new (guchar, tile_height * xpm_image->width * 4); ++ buf = g_try_new (guchar, tile_height * xpm_image->width * 4); ++ if (buf == NULL) ++ { ++ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, ++ "%s", _("XPM file invalid")); ++ return; ++ } + + src = xpm_image->data; + for (i = 0; i < xpm_image->height; i += tile_height) +-- +GitLab + + diff --git a/SOURCES/gimp-CVE-2026-42169.patch b/SOURCES/gimp-CVE-2026-42169.patch new file mode 100644 index 0000000..1a5b241 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-42169.patch @@ -0,0 +1,41 @@ +From a854b6c409abc4a37a86526634d99111767adcbc Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Fri, 10 Apr 2026 02:27:51 +0000 +Subject: [PATCH] plug-in: Protect against invalid BPP in DDS import + +Resolves #16161 +DDS images have multiple locations for loading BPP values. +It is possible to craft a DDS file with conflicting BPP values +so that not enough space is allocated to read in the image. +This patch adds checks to make sure we use the largest BPP +value to allocate space to prevent this. +--- + plug-ins/file-dds/ddsread.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/plug-ins/file-dds/ddsread.c b/plug-ins/file-dds/ddsread.c +index 85a0e20b85..41285e2505 100644 +--- a/plug-ins/file-dds/ddsread.c ++++ b/plug-ins/file-dds/ddsread.c +@@ -229,13 +229,18 @@ read_dds (GFile *file, + /* If format search was successful, get info needed to parse the file */ + if (load_info.d3d9_format || load_info.dxgi_format) + { ++ gint d3d9_bpp = 0; ++ gint dxgi_bpp = 0; ++ + load_info.read_info = get_format_read_info (load_info.d3d9_format, + load_info.dxgi_format); + +- if ((! hdr.pixelfmt.bpp) && load_info.d3d9_format) +- hdr.pixelfmt.bpp = get_bpp_d3d9 (load_info.d3d9_format); ++ if (load_info.d3d9_format) ++ d3d9_bpp = get_bpp_d3d9 (load_info.d3d9_format); + else if (load_info.dxgi_format) +- hdr.pixelfmt.bpp = get_bpp_dxgi (load_info.dxgi_format); ++ dxgi_bpp = get_bpp_dxgi (load_info.dxgi_format); ++ ++ hdr.pixelfmt.bpp = MAX (MAX (hdr.pixelfmt.bpp, d3d9_bpp), dxgi_bpp); + + /* Unset the FourCC flag as D3D formats will be handled as uncompressed */ + if ((load_info.fmt_flags & DDPF_FOURCC) && load_info.d3d9_format) diff --git a/SOURCES/gimp-CVE-2026-4887.patch b/SOURCES/gimp-CVE-2026-4887.patch new file mode 100644 index 0000000..c73076b --- /dev/null +++ b/SOURCES/gimp-CVE-2026-4887.patch @@ -0,0 +1,128 @@ +From aabce89271a9943a43bda9225aa43fc524f1c8a4 Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Sun, 8 Mar 2026 15:18:33 -0400 +Subject: [PATCH] plug-ins:: fix #15960 PCX buffer overflow + +A buffer overflow in the PCX reader was reported. + +The +1 was added in commit da217088d0fab77b7a696e782f6e2fb3b597f48f +to allow loading where the images have an off by 1 value. However, +this leaves the problem that allocated buffers may be 1 byte too small. + +Because we prefer to keep loading as many images as possible, we choose +not to return an error. Instead we allocate 1 extra byte for the +line buffers. +In addition to that, we add check for valid values of bpp and error +out early when invalid. +If the bytesperline value is off by more than 1, we output a warning +message and use the manually computed value instead. + +Additionally add a comment that we need to fix a British English +word in a string after string freeze. +--- + plug-ins/common/file-pcx.c | 35 ++++++++++++++++++++++++++--------- + 1 file changed, 26 insertions(+), 9 deletions(-) + +diff --git a/plug-ins/common/file-pcx.c b/plug-ins/common/file-pcx.c +index 3cf1070d2d4..276b568e78b 100644 +--- a/plug-ins/common/file-pcx.c ++++ b/plug-ins/common/file-pcx.c +@@ -632,7 +632,7 @@ load_image (GimpProcedure *procedure, + GError **error) + { + GeglBuffer *buffer; +- guint16 offset_x, offset_y, bytesperline; ++ guint16 offset_x, offset_y, bytesperline, computed_bytesperline; + gint32 width, height; + guint16 resolution_x, resolution_y; + GimpImage *image; +@@ -681,13 +681,29 @@ load_image (GimpProcedure *procedure, + height); + return NULL; + } +- if ((bytesperline + 1) < ((width * pcx_header.bpp + 7) / 8) || +- bytesperline == 0) ++ ++ if (pcx_header.bpp != 1 && pcx_header.bpp != 2 && pcx_header.bpp != 4 && ++ pcx_header.bpp != 8) + { ++ /* FIXME: After string freeze this should be changed to a more descriptive error. */ + g_set_error (error, GIMP_PLUG_IN_ERROR, 0, +- _("Invalid number of bytes per line in PCX header")); ++ _("Unusual PCX flavour, giving up")); + return NULL; + } ++ ++ /* Some legacy images have incorrect values for bytesperline, that are ++ * off by 1. To be able to load these, we will allow a difference of 1 here. ++ * However, that means we need to allocate 1 more byte than officially ++ * required to make sure we don't cause a buffer overrun. ++ * For larger differences we will compute the value of bytesperline. ++ */ ++ computed_bytesperline = (width * pcx_header.bpp + 7) / 8; ++ if (bytesperline + 1 < computed_bytesperline || bytesperline == 0) ++ { ++ g_message (_("Invalid number of bytes per line in PCX header")); ++ bytesperline = (width * pcx_header.bpp + 7) / 8; ++ } ++ + if ((resolution_x < 1) || (resolution_x > GIMP_MAX_RESOLUTION) || + (resolution_y < 1) || (resolution_y > GIMP_MAX_RESOLUTION)) + { +@@ -838,6 +854,7 @@ load_image (GimpProcedure *procedure, + } + else + { ++ /* FIXME: flavour is British English, should be flavor. */ + g_set_error (error, GIMP_PLUG_IN_ERROR, 0, + _("Unusual PCX flavour, giving up")); + g_object_unref (buffer); +@@ -889,7 +906,7 @@ load_8 (FILE *fp, + guint16 bytes) + { + gint row; +- guchar *line = g_new (guchar, bytes); ++ guchar *line = g_new0 (guchar, bytes + 1); + + for (row = 0; row < height; buf += width, ++row) + { +@@ -910,7 +927,7 @@ load_24 (FILE *fp, + guint8 planes) + { + gint x, y, c; +- guchar *line = g_new (guchar, bytes); ++ guchar *line = g_new0 (guchar, bytes + 1); + + for (y = 0; y < height; buf += width * planes, ++y) + { +@@ -936,7 +953,7 @@ load_1 (FILE *fp, + guint16 bytes) + { + gint x, y; +- guchar *line = g_new (guchar, bytes); ++ guchar *line = g_new0 (guchar, bytes + 1); + + for (y = 0; y < height; buf += width, ++y) + { +@@ -962,7 +979,7 @@ load_4 (FILE *fp, + guint16 bytes) + { + gint x, y, c; +- guchar *line = g_new (guchar, bytes); ++ guchar *line = g_new0 (guchar, bytes + 1); + + for (y = 0; y < height; buf += width, ++y) + { +@@ -993,7 +1010,7 @@ load_sub_8 (FILE *fp, + guint16 bytes) + { + gint x, y, c, b; +- guchar *line = g_new (guchar, bytes); ++ guchar *line = g_new0 (guchar, bytes + 1); + gint real_bpp = bpp - 1; + gint current_bit = 0; + +-- +GitLab + + diff --git a/SOURCES/gimp-CVE-2026-58379.patch b/SOURCES/gimp-CVE-2026-58379.patch new file mode 100644 index 0000000..9dda107 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-58379.patch @@ -0,0 +1,64 @@ +From b630f167ba7b73b17e7dd6df1fee1623f8324575 Mon Sep 17 00:00:00 2001 +From: Jacob Boerema +Date: Wed, 22 Apr 2026 11:09:36 -0400 +Subject: [PATCH] plug-ins: Fix #16205 PSP File Parsing Heap Buffer Overflow + +A heap buffer overflow write vulnerability exists in GIMP's PSP file +format parser. When parsing a specially crafted .psp file, the +read_channel_data() function in file-psp.c writes beyond the bounds of +a heap-allocated buffer due to an inconsistency between the buffer +allocation size (line_width) and the read size (width). Opening a +crafted PSP file causes memory corruption during parsing. + +The first part of the fix corrects the computation of the line_width, +which was incorrect for 1-bit per pixel. Since it needs to be on a +4 byte boundary, always add 3 instead of depending on bit depth. + +Second, use the line_width instead of width to determine the number +of bytes to read and process because that is the correct number to use. + +Backported to 3.0.4. +--- + plug-ins/common/file-psp.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/plug-ins/common/file-psp.c b/plug-ins/common/file-psp.c +index 6aae78c15f1..1af2125c980 100644 +--- a/plug-ins/common/file-psp.c ++++ b/plug-ins/common/file-psp.c +@@ -1530,7 +1530,7 @@ upscale_indexed_sub_8 (FILE *f, + guchar *tmpbuf, *buf_start, *src; + + /* Scanlines for 1 and 4 bit only end on a 4-byte boundary. */ +- line_width = (((width * bpp + 7) / 8) + bpp_zero_based) / 4 * 4; ++ line_width = (((width * bpp + 7) / 8) + 3) / 4 * 4; + buf_start = g_malloc0 (width * height); + tmpbuf = buf_start; + +@@ -1576,7 +1576,7 @@ read_channel_data (FILE *f, + if (ia->depth < 8) + { + /* Scanlines for 1 and 4 bit only end on a 4-byte boundary. */ +- line_width = (((width * ia->depth + 7) / 8) + ia->depth - 1) / 4 * 4; ++ line_width = ((width * ia->depth + 7) / 8 + 3) / 4 * 4; + } + else + { +@@ -1599,12 +1599,12 @@ read_channel_data (FILE *f, + { + guchar *p, *q; + +- fread (buf, width, 1, f); ++ fread (buf, line_width, 1, f); + /* Contrary to what the PSP specification seems to suggest + scanlines are not stored on a 4-byte boundary. */ + p = buf; + q = pixels[y] + offset; +- for (i = 0; i < width; i++) ++ for (i = 0; i < line_width; i++) + { + *q = *p++; + q += bytespp; +-- +GitLab + diff --git a/SOURCES/gimp-CVE-2026-58380.patch b/SOURCES/gimp-CVE-2026-58380.patch new file mode 100644 index 0000000..cc1e0ce --- /dev/null +++ b/SOURCES/gimp-CVE-2026-58380.patch @@ -0,0 +1,31 @@ +From 8369981756fc2742226b79296fd1886156001d94 Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Sat, 11 Apr 2026 14:33:42 +0000 +Subject: [PATCH] plug-ins: Boost buffer size for pnmscanner_gettoken + +Resolves #16206 +pnmscanner_gettoken () in file-pnm assumes that the +buffer it receives is larger than its bufsize parameter. +In almost all cases this is true, except in pnm_load_ascii (). +This patch adds the + 4 that is used everywhere else to ensure +we don't have an issue with buffer overflow. +--- + plug-ins/common/file-pnm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plug-ins/common/file-pnm.c b/plug-ins/common/file-pnm.c +index 65619be59de..81d73c14507 100644 +--- a/plug-ins/common/file-pnm.c ++++ b/plug-ins/common/file-pnm.c +@@ -958,7 +958,7 @@ pnm_load_ascii (PNMScanner *scan, + gint x, y, i, b; + gint start, end, scanlines; + gint np; +- gchar buf[BUFLEN]; ++ gchar buf[BUFLEN + 4]; + gboolean aborted = FALSE; + + np = (info->np) ? (info->np) : 1; +-- +GitLab + diff --git a/SOURCES/gimp-CVE-2026-58384.patch b/SOURCES/gimp-CVE-2026-58384.patch new file mode 100644 index 0000000..ee611d7 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-58384.patch @@ -0,0 +1,51 @@ +From da29e21779a851fcd95d2af29294bee4071a67a7 Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Sat, 11 Apr 2026 17:41:50 +0000 +Subject: [PATCH] plug-ins: Guard against too large PSD channel sizes + +Resolves #16216 +If a PSD channel row size is intentionally set very high, multiplying +it by 4 in our code can cause an overflow and wraparound to a lower +value for memory allocation. +This patch adds checks to prevent this if the total size exceeds +G_MAXUINT32. + +Backported to 3.0.4. +--- + plug-ins/file-psd/psd-load.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c +index 152af6c1148..ac6adadf0cf 100644 +--- a/plug-ins/file-psd/psd-load.c ++++ b/plug-ins/file-psd/psd-load.c +@@ -1790,6 +1790,7 @@ read_RLE_channel (PSDimage *img_a, + { + gint rle_count_size = (img_a->version == 1 ? 2 : 4); + gint rle_row_size = lyr_chn->rows * rle_count_size; ++ gsize row_allocation; + guint32 *rle_pack_len; + gint rowi; + +@@ -1799,7 +1800,17 @@ read_RLE_channel (PSDimage *img_a, + channel_data_len - 2, + rle_row_size, + (channel_data_len - 2 - rle_row_size)); +- rle_pack_len = g_malloc (lyr_chn->rows * 4); /* Always 4 since this is the data size in memory. */ ++ ++ /* Always 4 since this is the data size in memory. */ ++ if (! g_size_checked_mul (&row_allocation, lyr_chn->rows, 4) || ++ row_allocation >= G_MAXUINT32) ++ { ++ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, ++ _("Unsupported or invalid channel size")); ++ return FALSE; ++ } ++ ++ rle_pack_len = g_malloc ((guint32) row_allocation); + for (rowi = 0; rowi < lyr_chn->rows; ++rowi) + { + if (psd_read (input, &rle_pack_len[rowi], rle_count_size, +-- +GitLab + diff --git a/SOURCES/gimp-CVE-2026-66758.patch b/SOURCES/gimp-CVE-2026-66758.patch new file mode 100644 index 0000000..489b186 --- /dev/null +++ b/SOURCES/gimp-CVE-2026-66758.patch @@ -0,0 +1,95 @@ +From f47b74857a0ef14e81a134f1c455365b23ca438d Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Wed, 8 Jul 2026 19:29:17 +0000 +Subject: [PATCH] plug-ins: Add more memory checks for FITS imports + +As suggested by Michael Catanzaro and Tristan Madani, +this patch adds calls to g_size_checked_mul () to determine +if the requested size for FITS import memory allocation would +overflow in the two places we allocate. +--- + plug-ins/file-fits/fits.c | 49 ++++++++++++++++++++++++++++++++------- + 1 file changed, 41 insertions(+), 8 deletions(-) + +diff --git a/plug-ins/file-fits/fits.c b/plug-ins/file-fits/fits.c +index b4a8dbb433..ef59d5c497 100644 +--- a/plug-ins/file-fits/fits.c ++++ b/plug-ins/file-fits/fits.c +@@ -351,6 +351,7 @@ load_image (GFile *file, + const Babl *type = NULL; + const Babl *format = NULL; + gdouble *pixels; ++ gsize allocate; + gdouble datamin = 1.0E30f; + gdouble datamax = -1.0E30f; + gint channels = 1; +@@ -474,12 +475,32 @@ load_image (GFile *file, + NULL); + } + +- /* If RGB FITS image, we need to read in the whole image so we can convert +- * the planes format to RGB */ +- if (hdu.naxis == 2) +- pixels = (gdouble *) malloc (width * sizeof (gdouble) * channels); +- else +- pixels = (gdouble *) malloc (width * height * sizeof (gdouble) * channels); ++ if (width <= 0 || ++ height <= 0 || ++ width > GIMP_MAX_IMAGE_SIZE || ++ height > GIMP_MAX_IMAGE_SIZE) ++ { ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("'%s' has a larger image size (%d x %d) " ++ "than GIMP can handle."), ++ gimp_file_get_utf8_name (file), width, height); ++ fits_close_file (ifp, &status); ++ return image; ++ } ++ ++ /* If RGB FITS image, we need to read in the whole image so we can ++ * convert the planes format to RGB */ ++ if (! g_size_checked_mul (&allocate, width, sizeof (gdouble)) || ++ ! g_size_checked_mul (&allocate, allocate, channels) || ++ (hdu.naxis > 2 && ! g_size_checked_mul (&allocate, allocate, height)) || ++ ! (pixels = (gdouble *) g_try_malloc (allocate))) ++ { ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("There was not enough memory to complete the " ++ "operation.")); ++ fits_close_file (ifp, &status); ++ return image; ++ } + + if (! image) + { +@@ -549,8 +570,20 @@ load_image (GFile *file, + if (! status) + { + gdouble *temp; ++ gsize allocate; + +- temp = (gdouble *) malloc (width * height * sizeof (gdouble) * channels); ++ if (! g_size_checked_mul (&allocate, width, sizeof (gdouble)) || ++ ! g_size_checked_mul (&allocate, allocate, channels) || ++ ! g_size_checked_mul (&allocate, allocate, height) || ++ ! (temp = (gdouble *) g_try_malloc (allocate))) ++ { ++ g_set_error (error, GIMP_PLUG_IN_ERROR, 0, ++ _("There was not enough memory to complete the " ++ "operation.")); ++ fits_close_file (ifp, &status); ++ g_object_unref (buffer); ++ return image; ++ } + + if (datamin < datamax) + { +@@ -926,7 +959,7 @@ export_fits (GFile *file, + } + + src_offset += width * channelnum; +- offset += width; ++ offset += width; + } + + if (export_type == TFLOAT) diff --git a/SOURCES/gimp-CVE-2026-66759.patch b/SOURCES/gimp-CVE-2026-66759.patch new file mode 100644 index 0000000..60d30ec --- /dev/null +++ b/SOURCES/gimp-CVE-2026-66759.patch @@ -0,0 +1,166 @@ +From b6858e92e6b01c546ede26789594042c3bf52867 Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Tue, 7 Jul 2026 15:54:40 +0000 +Subject: [PATCH 1/2] plug-ins: Mitigate OOB write on ICNS mask data + +As reported by Tristan, it is possible to create an ICNS +icon with mask data smaller than the icon size. In this case, +our current code could potentially go out of bounds when writing +from file. This patch adds a check to stop executing the code if +we reach the end of the mask data in the file. +--- + plug-ins/file-icns/file-icns-load.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/plug-ins/file-icns/file-icns-load.c b/plug-ins/file-icns/file-icns-load.c +index cd76c710fd..18cd007a39 100644 +--- a/plug-ins/file-icns/file-icns-load.c ++++ b/plug-ins/file-icns/file-icns-load.c +@@ -341,7 +341,7 @@ icns_decompress (guchar *dest, + { + if (out > max) + { +- g_message ("Corrupt icon? compressed run overflows output size."); ++ g_message ("Corrupt icon: compressed run overflows output size."); + return FALSE; + } + dest[out++ * 4 + channel] = val; +@@ -387,10 +387,19 @@ icns_decompress (guchar *dest, + else if (mask) + { + gchar typestring[5]; +- fourcc_get_string (mask->type, typestring); + ++ fourcc_get_string (mask->type, typestring); + for (out = 0; out < max; out++) +- dest[out * 4 + 3] = mask->data[mask->cursor++]; ++ { ++ if (mask->cursor >= mask->size) ++ { ++ g_message ("Corrupt icon mask: uncompressed run overflows input " ++ "size."); ++ return FALSE; ++ } ++ ++ dest[out * 4 + 3] = mask->data[mask->cursor++]; ++ } + } + return TRUE; + } + +From 7bda2e466779fa3164b45abc3fc088370542c1db Mon Sep 17 00:00:00 2001 +From: Alx Sa +Date: Tue, 7 Jul 2026 16:49:21 +0000 +Subject: [PATCH 2/2] plug-ins: Correct mask loading in ICNS + +In some instances, we did checks on and pulled bytes +from the icon data instead of the mask data. +This patch corrects the issue. + +In addition, in the unlikely event that GIMP is packaged +on a 32-bit system, we now also guard against an overflow +when allocating IcnsResources. +--- + plug-ins/file-icns/file-icns-load.c | 42 ++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 10 deletions(-) + +diff --git a/plug-ins/file-icns/file-icns-load.c b/plug-ins/file-icns/file-icns-load.c +index 18cd007a39..fcefefa8f8 100644 +--- a/plug-ins/file-icns/file-icns-load.c ++++ b/plug-ins/file-icns/file-icns-load.c +@@ -82,14 +82,17 @@ resource_load (FILE *file) + { + gchar type[5]; + guint32 size; ++ gsize allocation; + + strncpy (type, header.type, 4); + type[4] = '\0'; + size = GUINT32_FROM_BE (header.size); + +- if (! strncmp (header.type, "icns", 4) && size > sizeof (IcnsResourceHeader)) ++ if (! strncmp (header.type, "icns", 4) && ++ size > sizeof (IcnsResourceHeader) && ++ g_size_checked_add (&allocation, sizeof (IcnsResource), size)) + { +- res = (IcnsResource *) g_new (guchar, sizeof (IcnsResource) + size); ++ res = (IcnsResource *) g_new (guchar, allocation); + strncpy (res->type, header.type, 4); + res->type[4] = '\0'; + res->size = size; +@@ -235,8 +238,8 @@ icns_slurp (guchar *dest, + if (out % 8 == 0) + bucket = icns->data[icns->cursor++]; + +- bit = (bucket & 0x80) ? 0 : 255; +- bucket = bucket << 1; ++ bit = (bucket & 0x80) ? 0 : 255; ++ bucket = bucket << 1; + dest[out * 4] = bit; + dest[out * 4 + 1] = bit; + dest[out * 4 + 2] = bit; +@@ -250,8 +253,8 @@ icns_slurp (guchar *dest, + if (out % 2 == 0) + bucket = icns->data[icns->cursor++]; + +- index = 3 * (bucket & 0xf0) >> 4; +- bucket = bucket << 4; ++ index = 3 * (bucket & 0xf0) >> 4; ++ bucket = bucket << 4; + dest[out * 4] = icns_colormap_4[index]; + dest[out * 4 + 1] = icns_colormap_4[index + 1]; + dest[out * 4 + 2] = icns_colormap_4[index + 2]; +@@ -260,7 +263,13 @@ icns_slurp (guchar *dest, + case 8: + for (out = 0; out < max; out++) + { +- index = 3 * icns->data[icns->cursor++]; ++ if (icns->cursor >= icns->size) ++ { ++ g_message ("Invalid or corrupt icns resource file."); ++ return; ++ } ++ ++ index = 3 * icns->data[icns->cursor++]; + dest[out * 4] = icns_colormap_8[index]; + dest[out * 4 + 1] = icns_colormap_8[index + 1]; + dest[out * 4 + 2] = icns_colormap_8[index + 2]; +@@ -270,13 +279,26 @@ icns_slurp (guchar *dest, + case 32: + for (out = 0; out < max; out++) + { ++ if (icns->size < 4 || icns->cursor > icns->size - 4) ++ { ++ g_message ("Invalid or corrupt icns resource file."); ++ return; ++ } ++ + dest[out * 4] = icns->data[icns->cursor++]; + dest[out * 4 + 1] = icns->data[icns->cursor++]; + dest[out * 4 + 2] = icns->data[icns->cursor++]; + /* Throw away alpha, use the mask */ + icns->cursor++; ++ ++ if (mask && mask->cursor >= mask->size) ++ { ++ g_message ("Invalid or corrupt icns resource file."); ++ return; ++ } ++ + if (mask) +- dest[out * 4 + 3] = icns->data[mask->cursor++]; ++ dest[out * 4 + 3] = mask->data[mask->cursor++]; + else + dest[out * 4 + 3] = 255; + } +@@ -292,8 +314,8 @@ icns_slurp (guchar *dest, + if (out % 8 == 0) + bucket = mask->data[mask->cursor++]; + +- bit = (bucket & 0x80) ? 255 : 0; +- bucket = bucket << 1; ++ bit = (bucket & 0x80) ? 255 : 0; ++ bucket = bucket << 1; + dest[out * 4 + 3] = bit; + } + } diff --git a/SPECS/gimp.spec b/SPECS/gimp.spec index 1d35f31..749eb41 100644 --- a/SPECS/gimp.spec +++ b/SPECS/gimp.spec @@ -66,8 +66,8 @@ Summary: GNU Image Manipulation Program Name: gimp Epoch: 2 Version: 3.0.4 -%global rel 1 -Release: %{rel}%{?dist} +%global rel 7 +Release: %{rel}.1.1.1%{?dist} # https://bugzilla.redhat.com/show_bug.cgi?id=2318369 ExcludeArch: s390x @@ -253,6 +253,31 @@ Patch2: gimp-2.10.12-default-font.patch # Modifications for RHEL-9 enablement Patch3: gimp-3.0.4-glib.patch +# CVEs +Patch4: gimp-3.0.4-CVE-2025-10920-10925-10934.patch +Patch5: gimp-3.0.4-CVE-2025-14424.patch +Patch6: gimp-3.0.4-CVE-2025-14425.patch +Patch7: gimp-3.0.4-CVE-2025-14423.patch +Patch8: gimp-3.0.4-CVE-2025-14422.patch +Patch9: gimp-3.0.4-CVE-2025-15059.patch +Patch10: gimp-3.0.4-CVE-2026-0797.patch +Patch11: gimp-3.0.4-CVE-2026-2044.patch +Patch12: gimp-3.0.4-CVE-2026-2045.patch +Patch13: gimp-3.0.4-CVE-2026-2047.patch +Patch14: gimp-3.0.4-CVE-2026-2048.patch +Patch15: gimp-CVE-2026-4150.patch +Patch16: gimp-CVE-2026-4151.patch +Patch17: gimp-CVE-2026-4152.patch +Patch18: gimp-CVE-2026-4153.patch +Patch19: gimp-CVE-2026-4154.patch +Patch20: gimp-CVE-2026-4887.patch +Patch21: gimp-CVE-2026-58379.patch +Patch22: gimp-CVE-2026-58380.patch +Patch23: gimp-CVE-2026-58384.patch +Patch24: gimp-CVE-2026-66759.patch +Patch25: gimp-CVE-2026-66758.patch +Patch26: gimp-CVE-2026-42169.patch + # use external help browser directly if help browser plug-in is not built Patch100: gimp-3.0.2-external-help-browser.patch @@ -327,6 +352,30 @@ EOF %patch1 -p1 -b .cm-system-monitor %patch2 -p1 -b .font-default %patch3 -p1 -b .glib +%patch4 -p1 -b .CVE-2025-fixes +%patch5 -p1 -b .CVE-2025-14424 +%patch6 -p1 -b .CVE-2025-14425 +%patch7 -p1 -b .CVE-2025-14423 +%patch8 -p1 -b .CVE-2025-14422 +%patch9 -p1 -b .CVE-2025-15059 +%patch10 -p1 -b .CVE-2026-0797 +%patch11 -p1 -b .CVE-2026-2044 +%patch12 -p1 -b .CVE-2026-2045 +%patch13 -p1 -b .CVE-2026-2047 +%patch14 -p1 -b .CVE-2026-2048 +%patch15 -p1 -b .CVE-2026-4150 +%patch16 -p1 -b .CVE-2026-4151 +%patch17 -p1 -b .CVE-2026-4152 +%patch18 -p1 -b .CVE-2026-4153 +%patch19 -p1 -b .CVE-2026-4154 +%patch20 -p1 -b .CVE-2026-4887 +%patch21 -p1 -b .CVE-2026-58379 +%patch22 -p1 -b .CVE-2026-58380 +%patch23 -p1 -b .CVE-2026-58384 +%patch24 -p1 -b .CVE-2026-66759 +%patch25 -p1 -b .CVE-2026-66758 +%patch26 -p1 -b .CVE-2026-42169 + %patch100 -p1 -b .external-help-browser %build @@ -641,6 +690,53 @@ done %endif %changelog +* Thu Aug 06 2026 RHEL Packaging Agent - 2:3.0.4-7.1.1.1 +- fix CVE-2026-42169 + +* Thu Aug 06 2026 RHEL Packaging Agent - 2:3.0.4-7.1.1 +- fix CVE-2026-66758 + +* Thu Aug 06 2026 RHEL Packaging Agent - 2:3.0.4-7.1 +- fix CVE-2026-66759 + +* Mon Jul 13 2026 Josef Ridky - 2:3.0.4-7 +- fix CVE-2026-58379 +- fix CVE-2026-58380 +- fix CVE-2026-58384 + +* Mon May 11 2026 Josef Ridky - 2:3.0.4-6 +- fix CVE-2026-4150 +- fix CVE-2026-4151 +- fix CVE-2026-4152 +- fix CVE-2026-4153 +- fix CVE-2026-4154 +- fix CVE-2026-4887 + +* Fri Mar 06 2026 Josef Ridky - 2:3.0.4-5 +- fix CVE-2026-0797 +- fix CVE-2026-2044 +- fix CVE-2026-2045 +- fix CVE-2026-2047 +- fix CVE-2026-2048 + +* Tue Feb 10 2026 Josef Ridky - 2:3.0.4-4 +- fix CVE-2025-15059 + +* Tue Jan 20 2026 Josef Ridky - 2:3.0.4-3 +- fix CVE-2025-14424 +- fix CVE-2025-14425 +- fix CVE-2025-14423 +- fix CVE-2025-14422 + +* Thu Nov 20 2025 Josef Ridky - 2:3.0.4-2 +- fix CVE-2025-10920 +- fix CVE-2025-10921 +- fix CVE-2025-10922 +- fix CVE-2025-10923 +- fix CVE-2025-10924 +- fix CVE-2025-10925 +- fix CVE-2025-10934 + * Tue May 20 2025 Josef Ridky - 2:3.0.4-1 - Rebase to 3.0.4 stable version and exclude s390x arch (RHEL-40106)