summaryrefslogtreecommitdiffstats
path: root/debian/patches/plug-ins-Fix-DDS-import-regression-from-7db71cd0.patch
blob: 85e54f5479516987de00852d5f9dd76a5dc5821d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
From: Alx Sa <cmyk.student@gmail.com>
Date: Fri, 27 Oct 2023 22:04:48 +0000
Subject: plug-ins: Fix DDS import regression from 7db71cd0
Origin: https://gitlab.gnome.org/GNOME/gimp/-/commit/e92f279c97282a2b20dca0d923db7465f2057703
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2023-44441
Bug-Debian: https://bugs.debian.org/1055984

@Wormnest pointed out that compressed files are likely smaller than
width * height * bps, so our check to prevent ZDI-CAN-22093
also caught valid files.
The size check is removed from load_image () and moved to load_layer ()
before the two fread() functions, as we know exactly how much we'll
try to read at that point.
(Backport of 8faad92e)
---
 plug-ins/file-dds/ddsread.c | 39 +++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

--- a/plug-ins/file-dds/ddsread.c
+++ b/plug-ins/file-dds/ddsread.c
@@ -189,16 +189,6 @@ read_dds (gchar    *filename,
         }
     }
 
-  /* verify header information is accurate */
-  if (hdr.depth < 1                                       ||
-      (hdr.pitch_or_linsize > (file_size - sizeof (hdr))) ||
-      (((guint64) hdr.height * hdr.width * hdr.depth) > (file_size - sizeof (hdr))))
-    {
-      fclose (fp);
-      g_message ("Invalid or corrupted DDS header\n");
-      return GIMP_PDB_EXECUTION_ERROR;
-    }
-
   if (hdr.pixelfmt.flags & DDPF_FOURCC)
     {
       /* fourcc is dXt* or rXgb */
@@ -288,6 +278,15 @@ read_dds (gchar    *filename,
         }
     }
 
+  /* verify header information is accurate */
+  if (d.bpp < 1 ||
+      (hdr.pitch_or_linsize > (file_size - sizeof (hdr))))
+    {
+      fclose (fp);
+      g_message ("Invalid or corrupted DDS header\n");
+      return GIMP_PDB_EXECUTION_ERROR;
+    }
+
   image = gimp_image_new (hdr.width, hdr.height, type);
 
   if (image == -1)
@@ -896,6 +895,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;
@@ -993,6 +999,12 @@ load_layer (FILE            *fp,
         size *= 16;
     }
 
+  if (size > (file_size - current_position))
+    {
+      g_message ("Requested data exceeds size of file.\n");
+      return 0;
+    }
+
   if ((hdr->flags & DDSD_LINEARSIZE) &&
       !fread (buf, size, 1, fp))
     {
@@ -1014,6 +1026,13 @@ load_layer (FILE            *fp,
               gimp_progress_update ((double)y / (double)hdr->height);
             }
 
+          current_position = ftell (fp);
+          if ((width * d->bpp) > (file_size - current_position))
+            {
+              g_message ("Requested data exceeds size of file.\n");
+              return 0;
+            }
+
           if ((hdr->flags & DDSD_PITCH) &&
               !fread (buf, width * d->bpp, 1, fp))
             {