Blame SOURCES/0003-CVE-2018-5784-Fix-for-bug-2772.patch

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