File gimp-CVE-2025-10922.patch of Package gimp.41817

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.

--- a/plug-ins/common/file-dicom.c
+++ b/plug-ins/common/file-dicom.c
@@ -329,6 +329,7 @@
   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;
@@ -384,6 +385,7 @@
       guint16  ctx_us;
       guint8  *value;
       guint32  tag;
+      size_t   actual_read;
 
       if (fread (&group_word, 1, 2, DICOM) == 0)
         break;
@@ -488,15 +490,24 @@
 
       if (element_length >= (G_MAXUINT - 6))
         {
-          g_message ("'%s' seems to have an incorrect value field length.",
-                     gimp_filename_to_utf8 (filename));
-          gimp_quit ();
+          g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
+                       _("'%s' has an an incorrect value for field size. Possibly corrupt image."),
+                       filename);
+          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)
@@ -509,7 +520,7 @@
       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 */
@@ -598,7 +609,7 @@
       /* Pixel data */
       if (group_word == 0x7fe0 && element_word == 0x0010)
         {
-          pix_buf = value;
+          pixbuf_size = element_length;
         }
       else
         {
@@ -629,25 +640,50 @@
         }
     }
 
+  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_filename_to_utf8 (filename), bpp);
-      gimp_quit ();
+      g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
+                   _("'%s' has a bpp of %d which GIMP cannot handle."),
+                   filename, 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_filename_to_utf8 (filename), 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."),
+                   filename, 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_filename_to_utf8 (filename), 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."),
+                   filename, 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."),
+                   filename);
+      g_free (pix_buf);
+      g_free (dicominfo);
+      fclose (DICOM);
+      return NULL;
     }
 
   dicominfo->width  = width;
openSUSE Build Service is sponsored by