File gimp-CVE-2025-10922.patch of Package gimp
From 3d909166463731e94dfe62042d76225ecfc4c1e4 Mon Sep 17 00:00:00 2001
From: Jacob Boerema <jgboerema@gmail.com>
Date: Wed, 3 Sep 2025 13:31:45 -0400
Subject: [PATCH] plug-ins: fix dicom plug-in ZDI-CAN-27863
GIMP DCM File Parsing Heap-based Buffer Overflow Remote Code Execution
Vulnerability
This adds more safety checks and sets actual GError's instead of just
calling gimp_quit.
Closes #14811
(cherry picked from commit 0f309f9a8d82f43fa01383bc5a5c41d28727d9e3)
---
plug-ins/common/file-dicom.c | 65 ++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 14 deletions(-)
diff --git a/plug-ins/common/file-dicom.c b/plug-ins/common/file-dicom.c
index 31039050f2..a11a13ef40 100644
--- a/plug-ins/common/file-dicom.c
+++ b/plug-ins/common/file-dicom.c
@@ -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;
--
2.49.0