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



commit 2ff9ccf46c4fd9a559d57ddca83b32e1c758985b
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.

 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 0a8e950cb2..5c35a2b895 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -468,6 +468,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 */
 
@@ -568,6 +575,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;
@@ -1568,7 +1589,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++)
     {
@@ -1869,7 +1895,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 */
@@ -2049,7 +2083,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]