blob: 406001d579a6f5b29b83663143dda8f1602f2bdb [file] [log] [blame]
Brad Bishop316dfdd2018-06-25 12:45:53 -04001From 6cdea15213be6b67d9f8380c7bb40e325d3adace Mon Sep 17 00:00:00 2001
2From: Nathan Baker <nathanb@lenovo-chrome.com>
3Date: Tue, 6 Feb 2018 10:13:57 -0500
4Subject: [PATCH] Fix for bug 2772
5
6It is possible to craft a TIFF document where the IFD list is circular,
7leading to an infinite loop while traversing the chain. The libtiff
8directory reader has a failsafe that will break out of this loop after
9reading 65535 directory entries, but it will continue processing,
10consuming time and resources to process what is essentially a bogus TIFF
11document.
12
13This change fixes the above behavior by breaking out of processing when
14a TIFF document has >= 65535 directories and terminating with an error.
15
16Upstream-Status: Backport
17[https://gitlab.com/libtiff/libtiff/commit/473851d211cf8805a161820337ca74cc9615d6ef]
18
19CVE: CVE-2018-5784
20
21Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
22---
23 contrib/addtiffo/tif_overview.c | 14 +++++++++++++-
24 tools/tiff2pdf.c | 10 ++++++++++
25 tools/tiffcrop.c | 13 +++++++++++--
26 3 files changed, 34 insertions(+), 3 deletions(-)
27
28diff --git a/contrib/addtiffo/tif_overview.c b/contrib/addtiffo/tif_overview.c
29index c61ffbb..03b3573 100644
30--- a/contrib/addtiffo/tif_overview.c
31+++ b/contrib/addtiffo/tif_overview.c
32@@ -65,6 +65,8 @@
33 # define MAX(a,b) ((a>b) ? a : b)
34 #endif
35
36+#define TIFF_DIR_MAX 65534
37+
38 void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
39 int (*)(double,void*), void * );
40
41@@ -91,6 +93,7 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
42 {
43 toff_t nBaseDirOffset;
44 toff_t nOffset;
45+ tdir_t iNumDir;
46
47 (void) bUseSubIFDs;
48
49@@ -147,7 +150,16 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
50 return 0;
51
52 TIFFWriteDirectory( hTIFF );
53- TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) );
54+ iNumDir = TIFFNumberOfDirectories(hTIFF);
55+ if( iNumDir > TIFF_DIR_MAX )
56+ {
57+ TIFFErrorExt( TIFFClientdata(hTIFF),
58+ "TIFF_WriteOverview",
59+ "File `%s' has too many directories.\n",
60+ TIFFFileName(hTIFF) );
61+ exit(-1);
62+ }
63+ TIFFSetDirectory( hTIFF, (tdir_t) (iNumDir - 1) );
64
65 nOffset = TIFFCurrentDirOffset( hTIFF );
66
67diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
68index 0b5973e..ef5d6a0 100644
69--- a/tools/tiff2pdf.c
70+++ b/tools/tiff2pdf.c
71@@ -68,6 +68,8 @@ extern int getopt(int, char**, char*);
72
73 #define PS_UNIT_SIZE 72.0F
74
75+#define TIFF_DIR_MAX 65534
76+
77 /* This type is of PDF color spaces. */
78 typedef enum {
79 T2P_CS_BILEVEL = 0x01, /* Bilevel, black and white */
80@@ -1051,6 +1053,14 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){
81 float* tiff_transferfunction[3];
82
83 directorycount=TIFFNumberOfDirectories(input);
84+ if(directorycount > TIFF_DIR_MAX) {
85+ TIFFError(
86+ TIFF2PDF_MODULE,
87+ "TIFF contains too many directories, %s",
88+ TIFFFileName(input));
89+ t2p->t2p_error = T2P_ERR_ERROR;
90+ return;
91+ }
92 t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_PAGE)));
93 if(t2p->tiff_pages==NULL){
94 TIFFError(
95diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
96index c69177e..c60cb38 100644
97--- a/tools/tiffcrop.c
98+++ b/tools/tiffcrop.c
99@@ -217,6 +217,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
100 #define DUMP_TEXT 1
101 #define DUMP_RAW 2
102
103+#define TIFF_DIR_MAX 65534
104+
105 /* Offsets into buffer for margins and fixed width and length segments */
106 struct offset {
107 uint32 tmargin;
108@@ -2233,7 +2235,7 @@ main(int argc, char* argv[])
109 pageNum = -1;
110 else
111 total_images = 0;
112- /* read multiple input files and write to output file(s) */
113+ /* Read multiple input files and write to output file(s) */
114 while (optind < argc - 1)
115 {
116 in = TIFFOpen (argv[optind], "r");
117@@ -2241,7 +2243,14 @@ main(int argc, char* argv[])
118 return (-3);
119
120 /* If only one input file is specified, we can use directory count */
121- total_images = TIFFNumberOfDirectories(in);
122+ total_images = TIFFNumberOfDirectories(in);
123+ if (total_images > TIFF_DIR_MAX)
124+ {
125+ TIFFError (TIFFFileName(in), "File contains too many directories");
126+ if (out != NULL)
127+ (void) TIFFClose(out);
128+ return (1);
129+ }
130 if (image_count == 0)
131 {
132 dirnum = 0;
133--
1342.7.4
135