[gimp/gimp-2-10] plug-ins: add more safety checks when loading a TIFF image.



commit 2ead36db7d43fbddf72b517e030221c958317cd5
Author: Jacob Boerema <jgboerema gmail com>
Date:   Tue Mar 2 15:23:09 2021 -0500

    plug-ins: add more safety checks when loading a TIFF image.
    
    Testing some fuzzed TIFF images from the imagetestsuite
    revealed we should add some more checks for valid input
    and function returns.
    
    We now stop whenever the reported bps is above 64.
    Even if it is valid we can't handle it anyway and I'm not
    aware of any actual valid image like that.
    
    Make sure the image dimensions are valid and in the range
    that GIMP can handle.
    
    Return directly when TIFFReadRGBAImage fails instead
    of doing further processing and improve the error message.
    
    Check result of TIFFReadTile and return if it fails.
    
    (cherry picked from commit 2ff9ccf46c4fd9a559d57ddca83b32e1c758985b)

 plug-ins/file-tiff/file-tiff-load.c | 48 ++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)
---
diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c
index fc8127deb7..40bdf9a9ef 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -480,6 +480,13 @@ load_image (GFile        *file,
             *profile_loaded = TRUE;
         }
 
+      if (bps > 64)
+        {
+          g_message (_("Suspicious bit depth: %d for page %d. Image may be corrupt."),
+                     bps, li+1);
+          continue;
+        }
+
       if (bps > 8 && bps != 8 && bps != 16 && bps != 32 && bps != 64)
         worst_case = TRUE; /* Wrong sample width => RGBA */
 
@@ -580,6 +587,20 @@ load_image (GFile        *file,
           return GIMP_PDB_EXECUTION_ERROR;
         }
 
+      if (cols > GIMP_MAX_IMAGE_SIZE || cols <= 0 ||
+          rows > GIMP_MAX_IMAGE_SIZE || rows <= 0)
+        {
+          g_message ("Invalid image dimensions (%u x %u) for page %d. "
+                     "Image may be corrupt.",
+                     (guint32) cols, (guint32) rows, li+1);
+          continue;
+        }
+      else
+        {
+          g_printerr ("Image dimensions: %u x %u.\n",
+                      (guint32) cols, (guint32) rows);
+        }
+
       if (! TIFFGetField (tif, TIFFTAG_PHOTOMETRIC, &photomet))
         {
           guint16 compression;
@@ -1540,7 +1561,12 @@ load_rgba (TIFF        *tif,
   buffer = g_new (uint32, image_width * image_height);
 
   if (! TIFFReadRGBAImage (tif, image_width, image_height, buffer, 0))
-    g_message ("Unsupported layout, no RGBA loader");
+    {
+      g_message ("%s: Unsupported image format, no RGBA loader available",
+                 G_STRFUNC);
+      g_free (buffer);
+      return;
+    }
 
   for (row = 0; row < image_height; row++)
     {
@@ -1841,7 +1867,15 @@ load_contiguous (TIFF        *tif,
                                 ((gdouble) x / (gdouble) image_width));
 
           if (TIFFIsTiled (tif))
-            TIFFReadTile (tif, buffer, x, y, 0, 0);
+            {
+              if (TIFFReadTile (tif, buffer, x, y, 0, 0) == -1)
+                {
+                  g_message (_("Reading tile failed. Image may be corrupt at line %d."), y);
+                  g_free (buffer);
+                  g_free (bw_buffer);
+                  return;
+                }
+            }
           else if (TIFFReadScanline (tif, buffer, y, 0) == -1)
             {
               /* Error reading scanline, stop loading */
@@ -2021,7 +2055,15 @@ load_separate (TIFF        *tif,
                                         ((gdouble) x / (gdouble) image_width));
 
                   if (TIFFIsTiled (tif))
-                    TIFFReadTile (tif, buffer, x, y, 0, compindex);
+                    {
+                      if (TIFFReadTile (tif, buffer, x, y, 0, compindex) == -1)
+                        {
+                          g_message (_("Reading tile failed. Image may be corrupt at line %d."), y);
+                          g_free (buffer);
+                          g_free (bw_buffer);
+                          return;
+                        }
+                    }
                   else if (TIFFReadScanline (tif, buffer, y, compindex) == -1)
                     {
                       /* Error reading scanline, stop loading */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]