File gimp-CVE-2023-44441.patch of Package gimp

--- gimp-2.10.30.orig/plug-ins/file-dds/ddsread.c	2023-11-17 19:46:12.782841827 +0530
+++ gimp-2.10.30/plug-ins/file-dds/ddsread.c	2023-11-28 15:42:07.554295500 +0530
@@ -109,6 +109,7 @@ read_dds (gchar    *filename,
   guchar *pixels;
   gchar *tmp;
   FILE *fp;
+  gsize file_size;
   dds_header_t hdr;
   dds_header_dx10_t dx10hdr;
   dds_load_info_t d;
@@ -116,6 +117,7 @@ read_dds (gchar    *filename,
   GimpImageBaseType type;
   GimpPrecision     precision;
   int i, j;
+  guint computed_pitch_or_linsize;
 
   if (interactive_dds)
     {
@@ -130,6 +132,10 @@ read_dds (gchar    *filename,
       return GIMP_PDB_EXECUTION_ERROR;
     }
 
+  fseek (fp, 0L, SEEK_END);
+  file_size = ftell (fp);
+  fseek (fp, 0, SEEK_SET);
+
   if (strrchr (filename, '/'))
     tmp = g_strdup_printf ("Loading %s:", strrchr (filename, '/') + 1);
   else
@@ -162,29 +168,32 @@ read_dds (gchar    *filename,
     }
 
   /* a lot of DDS images out there don't have this for some reason -_- */
-  if (hdr.pitch_or_linsize == 0)
-    {
       if (hdr.pixelfmt.flags & DDPF_FOURCC) /* assume linear size */
         {
-          hdr.pitch_or_linsize = ((hdr.width + 3) >> 2) * ((hdr.height + 3) >> 2);
-          switch (GETL32(hdr.pixelfmt.fourcc))
-            {
+          computed_pitch_or_linsize = ((hdr.width + 3) >> 2) * ((hdr.height + 3) >> 2);
+      	   switch (GETL32 (hdr.pixelfmt.fourcc))
+           {
             case FOURCC ('D','X','T','1'):
             case FOURCC ('A','T','I','1'):
             case FOURCC ('B','C','4','U'):
             case FOURCC ('B','C','4','S'):
-              hdr.pitch_or_linsize *= 8;
-              break;
+             computed_pitch_or_linsize *= 8;
+             break;
             default:
-              hdr.pitch_or_linsize *= 16;
-              break;
-            }
+             computed_pitch_or_linsize *= 16;
+             break;
+           }
         }
       else /* assume pitch */
         {
-          hdr.pitch_or_linsize = hdr.height * hdr.width * (hdr.pixelfmt.bpp >> 3);
+          computed_pitch_or_linsize = hdr.height * hdr.width * (hdr.pixelfmt.bpp >> 3);
         }
-    }
+      if (computed_pitch_or_linsize != hdr.pitch_or_linsize)
+      {
+        g_printerr ("Unexpected 'pitch_or_linsize' (%u) set to %u\n",
+                  hdr.pitch_or_linsize, computed_pitch_or_linsize);
+        hdr.pitch_or_linsize = computed_pitch_or_linsize;
+      }
 
   if (hdr.pixelfmt.flags & DDPF_FOURCC)
     {
@@ -295,6 +304,14 @@ read_dds (gchar    *filename,
       precision = GIMP_PRECISION_U8_GAMMA;
     }
 
+    /* verify header information is accurate */
+  if (d.bpp < 1                                           ||
+      (hdr.pitch_or_linsize > (file_size - sizeof (hdr)))) 
+    {
+      fclose (fp);
+      g_printerr ("Invalid or corrupted DDS header");
+      return GIMP_PDB_EXECUTION_ERROR;
+    }
   image = gimp_image_new_with_precision (hdr.width, hdr.height, type, precision);
 
   if (image == -1)
@@ -908,6 +925,13 @@ load_layer (FILE            *fp,
   unsigned int   size = hdr->pitch_or_linsize >> (2 * level);
   unsigned int   layerw;
   int            format = DDS_COMPRESS_NONE;
+  gsize          file_size;
+  gsize          current_position;
+
+  current_position = ftell (fp);
+  fseek (fp, 0L, SEEK_END);
+  file_size = ftell (fp);
+  fseek (fp, current_position, SEEK_SET);
 
   if (width < 1) width = 1;
   if (height < 1) height = 1;
@@ -1011,6 +1035,12 @@ load_layer (FILE            *fp,
       else
         size *= 16;
     }
+  if (size > (file_size - current_position) ||
+      size > hdr->pitch_or_linsize)
+    {
+      g_printerr ("Requested data exceeds size of file.\n");
+      return FALSE;
+    }
 
   if ((hdr->flags & DDSD_LINEARSIZE) &&
       !fread (buf, size, 1, fp))
@@ -1049,7 +1079,14 @@ load_layer (FILE            *fp,
               n = 0;
               gimp_progress_update ((double)y / (double)hdr->height);
             }
-
+           current_position = ftell (fp);
+          if ((hdr->flags & DDSD_PITCH)                          &&
+              ((width * d->bpp) > (file_size - current_position) ||
+               (width * d->bpp) > hdr->pitch_or_linsize))
+            {
+              g_printerr ("Requested data exceeds size of file.\n");
+              return FALSE;
+            }
           if ((hdr->flags & DDSD_PITCH) &&
               !fread (buf, width * d->bpp, 1, fp))
             {
openSUSE Build Service is sponsored by