Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
From 473851d211cf8805a161820337ca74cc9615d6ef Mon Sep 17 00:00:00 2001
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
From: Nathan Baker <nathanb@lenovo-chrome.com>
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
Date: Tue, 6 Feb 2018 10:13:57 -0500
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
Subject: [PATCH] Fix for bug 2772
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
It is possible to craft a TIFF document where the IFD list is circular,
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
leading to an infinite loop while traversing the chain. The libtiff
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
directory reader has a failsafe that will break out of this loop after
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
reading 65535 directory entries, but it will continue processing,
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
consuming time and resources to process what is essentially a bogus TIFF
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
document.
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
This change fixes the above behavior by breaking out of processing when
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
a TIFF document has >= 65535 directories and terminating with an error.
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
---
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 contrib/addtiffo/tif_overview.c | 14 +++++++++++++-
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 tools/tiff2pdf.c                | 10 ++++++++++
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 tools/tiffcrop.c                | 13 +++++++++++--
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 3 files changed, 34 insertions(+), 3 deletions(-)
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
diff --git a/contrib/addtiffo/tif_overview.c b/contrib/addtiffo/tif_overview.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
index c61ffbb..03b3573 100644
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
--- a/contrib/addtiffo/tif_overview.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+++ b/contrib/addtiffo/tif_overview.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -65,6 +65,8 @@
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 #  define MAX(a,b)      ((a>b) ? a : b)
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 #endif
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+#define TIFF_DIR_MAX  65534
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
                          int (*)(double,void*), void * );
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -91,6 +93,7 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     toff_t	nBaseDirOffset;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     toff_t	nOffset;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    tdir_t	iNumDir;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     (void) bUseSubIFDs;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -147,7 +150,16 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
         return 0;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     TIFFWriteDirectory( hTIFF );
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
-    TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) );
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    iNumDir = TIFFNumberOfDirectories(hTIFF);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    if( iNumDir > TIFF_DIR_MAX )
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+        TIFFErrorExt( TIFFClientdata(hTIFF),
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+                      "TIFF_WriteOverview",
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+                      "File `%s' has too many directories.\n",
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+                      TIFFFileName(hTIFF) );
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+        exit(-1);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    }
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    TIFFSetDirectory( hTIFF, (tdir_t) (iNumDir - 1) );
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     nOffset = TIFFCurrentDirOffset( hTIFF );
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
index 984ef65..832a247 100644
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
--- a/tools/tiff2pdf.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+++ b/tools/tiff2pdf.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -68,6 +68,8 @@ extern int getopt(int, char**, char*);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 #define PS_UNIT_SIZE	72.0F
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+#define TIFF_DIR_MAX    65534
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 /* This type is of PDF color spaces. */
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 typedef enum {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 	T2P_CS_BILEVEL = 0x01,	/* Bilevel, black and white */
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -1049,6 +1053,14 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 	uint16* tiff_transferfunction[3];
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 	directorycount=TIFFNumberOfDirectories(input);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+	if(directorycount > TIFF_DIR_MAX) {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+		TIFFError(
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+			TIFF2PDF_MODULE,
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+			"TIFF contains too many directories, %s",
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+			TIFFFileName(input));
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+		t2p->t2p_error = T2P_ERR_ERROR;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+		return;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+	}
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 	t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_PAGE)));
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 	if(t2p->tiff_pages==NULL){
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 		TIFFError(
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
index 91a38f6..e466dae 100644
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
--- a/tools/tiffcrop.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+++ b/tools/tiffcrop.c
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -217,6 +215,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 #define DUMP_TEXT   1
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 #define DUMP_RAW    2
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+#define TIFF_DIR_MAX  65534
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 /* Offsets into buffer for margins and fixed width and length segments */
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 struct offset {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
   uint32  tmargin;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -2233,7 +2234,7 @@ main(int argc, char* argv[])
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     pageNum = -1;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
   else
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     total_images = 0;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
-  /* read multiple input files and write to output file(s) */
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+  /* Read multiple input files and write to output file(s) */
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
   while (optind < argc - 1)
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     in = TIFFOpen (argv[optind], "r");
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
@@ -2241,7 +2242,14 @@ main(int argc, char* argv[])
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
       return (-3);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     /* If only one input file is specified, we can use directory count */
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
-    total_images = TIFFNumberOfDirectories(in); 
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    total_images = TIFFNumberOfDirectories(in);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+    if (total_images > TIFF_DIR_MAX)
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+      {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+      TIFFError (TIFFFileName(in), "File contains too many directories");
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+      if (out != NULL)
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+        (void) TIFFClose(out);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+      return (1);
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
+      }
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
     if (image_count == 0)
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
       {
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
       dirnum = 0;
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
--
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc
libgit2 0.26.0
Lucio Andrés Illanes Albornoz (arab, vxp) af7abc