summaryrefslogtreecommitdiffhomepage
path: root/patches/tiff/CVE-2018-5784.patch
blob: 92fc2daf35e436b38f33dbd8d8e60b30f848493d (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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From 473851d211cf8805a161820337ca74cc9615d6ef Mon Sep 17 00:00:00 2001
From: Nathan Baker <nathanb@lenovo-chrome.com>
Date: Tue, 6 Feb 2018 10:13:57 -0500
Subject: [PATCH] Fix for bug 2772

It is possible to craft a TIFF document where the IFD list is circular,
leading to an infinite loop while traversing the chain. The libtiff
directory reader has a failsafe that will break out of this loop after
reading 65535 directory entries, but it will continue processing,
consuming time and resources to process what is essentially a bogus TIFF
document.

This change fixes the above behavior by breaking out of processing when
a TIFF document has >= 65535 directories and terminating with an error.
---
 contrib/addtiffo/tif_overview.c | 14 +++++++++++++-
 tools/tiff2pdf.c                | 10 ++++++++++
 tools/tiffcrop.c                | 13 +++++++++++--
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/contrib/addtiffo/tif_overview.c b/contrib/addtiffo/tif_overview.c
index c61ffbb..03b3573 100644
--- a/contrib/addtiffo/tif_overview.c
+++ b/contrib/addtiffo/tif_overview.c
@@ -65,6 +65,8 @@
 #  define MAX(a,b)      ((a>b) ? a : b)
 #endif
 
+#define TIFF_DIR_MAX  65534
+
 void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
                          int (*)(double,void*), void * );
 
@@ -91,6 +93,7 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
 {
     toff_t	nBaseDirOffset;
     toff_t	nOffset;
+    tdir_t	iNumDir;
 
     (void) bUseSubIFDs;
 
@@ -147,7 +150,16 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
         return 0;
 
     TIFFWriteDirectory( hTIFF );
-    TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) );
+    iNumDir = TIFFNumberOfDirectories(hTIFF);
+    if( iNumDir > TIFF_DIR_MAX )
+    {
+        TIFFErrorExt( TIFFClientdata(hTIFF),
+                      "TIFF_WriteOverview",
+                      "File `%s' has too many directories.\n",
+                      TIFFFileName(hTIFF) );
+        exit(-1);
+    }
+    TIFFSetDirectory( hTIFF, (tdir_t) (iNumDir - 1) );
 
     nOffset = TIFFCurrentDirOffset( hTIFF );
 
diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
index 984ef65..832a247 100644
--- a/tools/tiff2pdf.c
+++ b/tools/tiff2pdf.c
@@ -68,6 +68,8 @@ extern int getopt(int, char**, char*);
 
 #define PS_UNIT_SIZE	72.0F
 
+#define TIFF_DIR_MAX    65534
+
 /* This type is of PDF color spaces. */
 typedef enum {
 	T2P_CS_BILEVEL = 0x01,	/* Bilevel, black and white */
@@ -1049,6 +1053,14 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){
 	uint16* tiff_transferfunction[3];
 
 	directorycount=TIFFNumberOfDirectories(input);
+	if(directorycount > TIFF_DIR_MAX) {
+		TIFFError(
+			TIFF2PDF_MODULE,
+			"TIFF contains too many directories, %s",
+			TIFFFileName(input));
+		t2p->t2p_error = T2P_ERR_ERROR;
+		return;
+	}
 	t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_PAGE)));
 	if(t2p->tiff_pages==NULL){
 		TIFFError(
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index 91a38f6..e466dae 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -217,6 +215,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
 #define DUMP_TEXT   1
 #define DUMP_RAW    2
 
+#define TIFF_DIR_MAX  65534
+
 /* Offsets into buffer for margins and fixed width and length segments */
 struct offset {
   uint32  tmargin;
@@ -2233,7 +2234,7 @@ main(int argc, char* argv[])
     pageNum = -1;
   else
     total_images = 0;
-  /* read multiple input files and write to output file(s) */
+  /* Read multiple input files and write to output file(s) */
   while (optind < argc - 1)
     {
     in = TIFFOpen (argv[optind], "r");
@@ -2241,7 +2242,14 @@ main(int argc, char* argv[])
       return (-3);
 
     /* If only one input file is specified, we can use directory count */
-    total_images = TIFFNumberOfDirectories(in); 
+    total_images = TIFFNumberOfDirectories(in);
+    if (total_images > TIFF_DIR_MAX)
+      {
+      TIFFError (TIFFFileName(in), "File contains too many directories");
+      if (out != NULL)
+        (void) TIFFClose(out);
+      return (1);
+      }
     if (image_count == 0)
       {
       dirnum = 0;
--
libgit2 0.26.0