1From e1cd2d7ab032e7fe80b4c13e07895194c8bac85e Mon Sep 17 00:00:00 2001 2From: Brian May <brian@linuxpenguins.xyz> 3Date: Thu, 7 Dec 2017 07:46:47 +1100 4Subject: [PATCH 1/4] [PATCH] tiff2pdf: Fix CVE-2017-9935 5 6Fix for http://bugzilla.maptools.org/show_bug.cgi?id=2704 7 8This vulnerability - at least for the supplied test case - is because we 9assume that a tiff will only have one transfer function that is the same 10for all pages. This is not required by the TIFF standards. 11 12We than read the transfer function for every page. Depending on the 13transfer function, we allocate either 2 or 4 bytes to the XREF buffer. 14We allocate this memory after we read in the transfer function for the 15page. 16 17For the first exploit - POC1, this file has 3 pages. For the first page 18we allocate 2 extra extra XREF entries. Then for the next page 2 more 19entries. Then for the last page the transfer function changes and we 20allocate 4 more entries. 21 22When we read the file into memory, we assume we have 4 bytes extra for 23each and every page (as per the last transfer function we read). Which 24is not correct, we only have 2 bytes extra for the first 2 pages. As a 25result, we end up writing past the end of the buffer. 26 27There are also some related issues that this also fixes. For example, 28TIFFGetField can return uninitalized pointer values, and the logic to 29detect a N=3 vs N=1 transfer function seemed rather strange. 30 31It is also strange that we declare the transfer functions to be of type 32float, when the standard says they are unsigned 16 bit values. This is 33fixed in another patch. 34 35This patch will check to ensure that the N value for every transfer 36function is the same for every page. If this changes, we abort with an 37error. In theory, we should perhaps check that the transfer function 38itself is identical for every page, however we don't do that due to the 39confusion of the type of the data in the transfer function. 40--- 41 libtiff/tif_dir.c | 3 +++ 42 tools/tiff2pdf.c | 69 +++++++++++++++++++++++++++++++---------------- 43 2 files changed, 49 insertions(+), 23 deletions(-) 44 45diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c 46index f00f808..c36a5f3 100644 47--- a/libtiff/tif_dir.c 48+++ b/libtiff/tif_dir.c 49@@ -1067,6 +1067,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) 50 if (td->td_samplesperpixel - td->td_extrasamples > 1) { 51 *va_arg(ap, uint16**) = td->td_transferfunction[1]; 52 *va_arg(ap, uint16**) = td->td_transferfunction[2]; 53+ } else { 54+ *va_arg(ap, uint16**) = NULL; 55+ *va_arg(ap, uint16**) = NULL; 56 } 57 break; 58 case TIFFTAG_REFERENCEBLACKWHITE: 59diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c 60index bdb9126..bd23c9e 100644 61--- a/tools/tiff2pdf.c 62+++ b/tools/tiff2pdf.c 63@@ -239,7 +239,7 @@ typedef struct { 64 float tiff_whitechromaticities[2]; 65 float tiff_primarychromaticities[6]; 66 float tiff_referenceblackwhite[2]; 67- float* tiff_transferfunction[3]; 68+ uint16* tiff_transferfunction[3]; 69 int pdf_image_interpolate; /* 0 (default) : do not interpolate, 70 1 : interpolate */ 71 uint16 tiff_transferfunctioncount; 72@@ -1049,6 +1049,8 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){ 73 uint16 pagen=0; 74 uint16 paged=0; 75 uint16 xuint16=0; 76+ uint16 tiff_transferfunctioncount=0; 77+ uint16* tiff_transferfunction[3]; 78 79 directorycount=TIFFNumberOfDirectories(input); 80 if(directorycount > TIFF_DIR_MAX) { 81@@ -1157,26 +1159,48 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){ 82 } 83 #endif 84 if (TIFFGetField(input, TIFFTAG_TRANSFERFUNCTION, 85- &(t2p->tiff_transferfunction[0]), 86- &(t2p->tiff_transferfunction[1]), 87- &(t2p->tiff_transferfunction[2]))) { 88- if((t2p->tiff_transferfunction[1] != (float*) NULL) && 89- (t2p->tiff_transferfunction[2] != (float*) NULL) && 90- (t2p->tiff_transferfunction[1] != 91- t2p->tiff_transferfunction[0])) { 92- t2p->tiff_transferfunctioncount = 3; 93- t2p->tiff_pages[i].page_extra += 4; 94- t2p->pdf_xrefcount += 4; 95- } else { 96- t2p->tiff_transferfunctioncount = 1; 97- t2p->tiff_pages[i].page_extra += 2; 98- t2p->pdf_xrefcount += 2; 99- } 100- if(t2p->pdf_minorversion < 2) 101- t2p->pdf_minorversion = 2; 102+ &(tiff_transferfunction[0]), 103+ &(tiff_transferfunction[1]), 104+ &(tiff_transferfunction[2]))) { 105+ 106+ if((tiff_transferfunction[1] != (uint16*) NULL) && 107+ (tiff_transferfunction[2] != (uint16*) NULL) 108+ ) { 109+ tiff_transferfunctioncount=3; 110+ } else { 111+ tiff_transferfunctioncount=1; 112+ } 113 } else { 114- t2p->tiff_transferfunctioncount=0; 115+ tiff_transferfunctioncount=0; 116 } 117+ 118+ if (i > 0){ 119+ if (tiff_transferfunctioncount != t2p->tiff_transferfunctioncount){ 120+ TIFFError( 121+ TIFF2PDF_MODULE, 122+ "Different transfer function on page %d", 123+ i); 124+ t2p->t2p_error = T2P_ERR_ERROR; 125+ return; 126+ } 127+ } 128+ 129+ t2p->tiff_transferfunctioncount = tiff_transferfunctioncount; 130+ t2p->tiff_transferfunction[0] = tiff_transferfunction[0]; 131+ t2p->tiff_transferfunction[1] = tiff_transferfunction[1]; 132+ t2p->tiff_transferfunction[2] = tiff_transferfunction[2]; 133+ if(tiff_transferfunctioncount == 3){ 134+ t2p->tiff_pages[i].page_extra += 4; 135+ t2p->pdf_xrefcount += 4; 136+ if(t2p->pdf_minorversion < 2) 137+ t2p->pdf_minorversion = 2; 138+ } else if (tiff_transferfunctioncount == 1){ 139+ t2p->tiff_pages[i].page_extra += 2; 140+ t2p->pdf_xrefcount += 2; 141+ if(t2p->pdf_minorversion < 2) 142+ t2p->pdf_minorversion = 2; 143+ } 144+ 145 if( TIFFGetField( 146 input, 147 TIFFTAG_ICCPROFILE, 148@@ -1837,10 +1861,9 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){ 149 &(t2p->tiff_transferfunction[0]), 150 &(t2p->tiff_transferfunction[1]), 151 &(t2p->tiff_transferfunction[2]))) { 152- if((t2p->tiff_transferfunction[1] != (float*) NULL) && 153- (t2p->tiff_transferfunction[2] != (float*) NULL) && 154- (t2p->tiff_transferfunction[1] != 155- t2p->tiff_transferfunction[0])) { 156+ if((t2p->tiff_transferfunction[1] != (uint16*) NULL) && 157+ (t2p->tiff_transferfunction[2] != (uint16*) NULL) 158+ ) { 159 t2p->tiff_transferfunctioncount=3; 160 } else { 161 t2p->tiff_transferfunctioncount=1; 162-- 1632.17.0 164 165