Browse code

libtiff : Fix CVE-2018-7456, CVE-2018-8905, CVE-2018-5784, CVE-2017-11613.

Change-Id: I74eab9282df59f904b1853b5443872a0b0b536eb
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/5161
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George

Xiaolin Li authored on 2018/05/15 03:41:54
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
1
+index 3fc0c8e..1a3259c 100644
2
+--- a/libtiff/tif_dirread.c
3
+@@ -5696,6 +5696,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
4
+         if( nstrips == 0 )
5
+             return;
6
+ 
7
++        /* If we are going to allocate a lot of memory, make sure that the */
8
++        /* file is as big as needed */
9
++        if( tif->tif_mode == O_RDONLY &&
10
++            nstrips > 1000000 &&
11
++            (tif->tif_dir.td_stripoffset[0] >= TIFFGetFileSize(tif) ||
12
++             tif->tif_dir.td_stripbytecount[0] >
13
++                    TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) )
14
++        {
15
++            return;
16
++        }
17
++
18
+ 	newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
19
+ 				"for chopped \"StripByteCounts\" array");
20
+ 	newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
0 21
new file mode 100644
... ...
@@ -0,0 +1,16 @@
0
+diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
1
+index 1a3259c..6baa7b3 100644
2
+--- a/libtiff/tif_dirread.c
3
+@@ -5700,9 +5700,8 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
4
+         /* file is as big as needed */
5
+         if( tif->tif_mode == O_RDONLY &&
6
+             nstrips > 1000000 &&
7
+-            (tif->tif_dir.td_stripoffset[0] >= TIFFGetFileSize(tif) ||
8
+-             tif->tif_dir.td_stripbytecount[0] >
9
+-                    TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) )
10
++            (offset >= TIFFGetFileSize(tif) ||
11
++             stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)) )
12
+         {
13
+             return;
14
+         }
0 15
new file mode 100644
... ...
@@ -0,0 +1,107 @@
0
+diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
1
+index 6baa7b3..af5b84a 100644
2
+--- a/libtiff/tif_dirread.c
3
+@@ -165,6 +165,7 @@ static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uin
4
+ static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
5
+ static void ChopUpSingleUncompressedStrip(TIFF*);
6
+ static uint64 TIFFReadUInt64(const uint8 *value);
7
++static int _TIFFGetMaxColorChannels(uint16 photometric);
8
+ 
9
+ static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount );
10
+ 
11
+@@ -3505,6 +3506,35 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c
12
+ }
13
+ 
14
+ /*
15
++ * Return the maximum number of color channels specified for a given photometric
16
++ * type. 0 is returned if photometric type isn't supported or no default value
17
++ * is defined by the specification.
18
++ */
19
++static int _TIFFGetMaxColorChannels( uint16 photometric )
20
++{
21
++    switch (photometric) {
22
++	case PHOTOMETRIC_PALETTE:
23
++	case PHOTOMETRIC_MINISWHITE:
24
++	case PHOTOMETRIC_MINISBLACK:
25
++            return 1;
26
++	case PHOTOMETRIC_YCBCR:
27
++	case PHOTOMETRIC_RGB:
28
++	case PHOTOMETRIC_CIELAB:
29
++            return 3;
30
++	case PHOTOMETRIC_SEPARATED:
31
++	case PHOTOMETRIC_MASK:
32
++            return 4;
33
++	case PHOTOMETRIC_LOGL:
34
++	case PHOTOMETRIC_LOGLUV:
35
++	case PHOTOMETRIC_CFA:
36
++	case PHOTOMETRIC_ITULAB:
37
++	case PHOTOMETRIC_ICCLAB:
38
++	default:
39
++            return 0;
40
++    }
41
++}
42
++
43
++/*
44
+  * Read the next TIFF directory from a file and convert it to the internal
45
+  * format. We read directories sequentially.
46
+  */
47
+@@ -3520,6 +3550,7 @@ TIFFReadDirectory(TIFF* tif)
48
+ 	uint32 fii=FAILED_FII;
49
+         toff_t nextdiroff;
50
+     int bitspersample_read = FALSE;
51
++        int color_channels;
52
+ 
53
+ 	tif->tif_diroff=tif->tif_nextdiroff;
54
+ 	if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
55
+@@ -4024,6 +4055,37 @@ TIFFReadDirectory(TIFF* tif)
56
+ 			}
57
+ 		}
58
+ 	}
59
++
60
++	/*
61
++	 * Make sure all non-color channels are extrasamples.
62
++	 * If it's not the case, define them as such.
63
++	 */
64
++        color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric);
65
++        if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) {
66
++                uint16 old_extrasamples;
67
++                uint16 *new_sampleinfo;
68
++
69
++                TIFFWarningExt(tif->tif_clientdata,module, "Sum of Photometric type-related "
70
++                    "color channels and ExtraSamples doesn't match SamplesPerPixel. "
71
++                    "Defining non-color channels as ExtraSamples.");
72
++
73
++                old_extrasamples = tif->tif_dir.td_extrasamples;
74
++                tif->tif_dir.td_extrasamples = (tif->tif_dir.td_samplesperpixel - color_channels);
75
++
76
++                // sampleinfo should contain information relative to these new extra samples
77
++                new_sampleinfo = (uint16*) _TIFFcalloc(tif->tif_dir.td_extrasamples, sizeof(uint16));
78
++                if (!new_sampleinfo) {
79
++                    TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate memory for "
80
++                                "temporary new sampleinfo array (%d 16 bit elements)",
81
++                                tif->tif_dir.td_extrasamples);
82
++                    goto bad;
83
++                }
84
++
85
++                memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16));
86
++                _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples);
87
++                _TIFFfree(new_sampleinfo);
88
++        }
89
++
90
+ 	/*
91
+ 	 * Verify Palette image has a Colormap.
92
+ 	 */
93
+diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
94
+index 8deceb2..1d86adb 100644
95
+--- a/libtiff/tif_print.c
96
+@@ -544,7 +544,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
97
+ 				uint16 i;
98
+ 				fprintf(fd, "    %2ld: %5u",
99
+ 				    l, td->td_transferfunction[0][l]);
100
+-				for (i = 1; i < td->td_samplesperpixel; i++)
101
++				for (i = 1; i < td->td_samplesperpixel - td->td_extrasamples && i < 3; i++)
102
+ 					fprintf(fd, " %5u",
103
+ 					    td->td_transferfunction[i][l]);
104
+ 				fputc('\n', fd);
0 105
new file mode 100644
... ...
@@ -0,0 +1,128 @@
0
+From 473851d211cf8805a161820337ca74cc9615d6ef Mon Sep 17 00:00:00 2001
1
+From: Nathan Baker <nathanb@lenovo-chrome.com>
2
+Date: Tue, 6 Feb 2018 10:13:57 -0500
3
+Subject: [PATCH] Fix for bug 2772
4
+
5
+It is possible to craft a TIFF document where the IFD list is circular,
6
+leading to an infinite loop while traversing the chain. The libtiff
7
+directory reader has a failsafe that will break out of this loop after
8
+reading 65535 directory entries, but it will continue processing,
9
+consuming time and resources to process what is essentially a bogus TIFF
10
+document.
11
+
12
+This change fixes the above behavior by breaking out of processing when
13
+a TIFF document has >= 65535 directories and terminating with an error.
14
+---
15
+ contrib/addtiffo/tif_overview.c | 14 +++++++++++++-
16
+ tools/tiff2pdf.c                | 10 ++++++++++
17
+ tools/tiffcrop.c                | 13 +++++++++++--
18
+ 3 files changed, 34 insertions(+), 3 deletions(-)
19
+
20
+diff --git a/contrib/addtiffo/tif_overview.c b/contrib/addtiffo/tif_overview.c
21
+index c61ffbb..03b3573 100644
22
+--- a/contrib/addtiffo/tif_overview.c
23
+@@ -65,6 +65,8 @@
24
+ #  define MAX(a,b)      ((a>b) ? a : b)
25
+ #endif
26
+ 
27
++#define TIFF_DIR_MAX  65534
28
++
29
+ void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
30
+                          int (*)(double,void*), void * );
31
+ 
32
+@@ -91,6 +93,7 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
33
+ {
34
+     toff_t	nBaseDirOffset;
35
+     toff_t	nOffset;
36
++    tdir_t	iNumDir;
37
+ 
38
+     (void) bUseSubIFDs;
39
+ 
40
+@@ -147,7 +150,16 @@ uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
41
+         return 0;
42
+ 
43
+     TIFFWriteDirectory( hTIFF );
44
+-    TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) );
45
++    iNumDir = TIFFNumberOfDirectories(hTIFF);
46
++    if( iNumDir > TIFF_DIR_MAX )
47
++    {
48
++        TIFFErrorExt( TIFFClientdata(hTIFF),
49
++                      "TIFF_WriteOverview",
50
++                      "File `%s' has too many directories.\n",
51
++                      TIFFFileName(hTIFF) );
52
++        exit(-1);
53
++    }
54
++    TIFFSetDirectory( hTIFF, (tdir_t) (iNumDir - 1) );
55
+ 
56
+     nOffset = TIFFCurrentDirOffset( hTIFF );
57
+ 
58
+diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c
59
+index 984ef65..832a247 100644
60
+--- a/tools/tiff2pdf.c
61
+@@ -68,6 +68,8 @@ extern int getopt(int, char**, char*);
62
+ 
63
+ #define PS_UNIT_SIZE	72.0F
64
+ 
65
++#define TIFF_DIR_MAX    65534
66
++
67
+ /* This type is of PDF color spaces. */
68
+ typedef enum {
69
+ 	T2P_CS_BILEVEL = 0x01,	/* Bilevel, black and white */
70
+@@ -1053,6 +1053,14 @@ void t2p_read_tiff_init(T2P* t2p, TIFF* input){
71
+ 	float* tiff_transferfunction[3];
72
+ 
73
+ 	directorycount=TIFFNumberOfDirectories(input);
74
++	if(directorycount > TIFF_DIR_MAX) {
75
++		TIFFError(
76
++			TIFF2PDF_MODULE,
77
++			"TIFF contains too many directories, %s",
78
++			TIFFFileName(input));
79
++		t2p->t2p_error = T2P_ERR_ERROR;
80
++		return;
81
++	}
82
+ 	t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_PAGE)));
83
+ 	if(t2p->tiff_pages==NULL){
84
+ 		TIFFError(
85
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
86
+index 91a38f6..e466dae 100644
87
+--- a/tools/tiffcrop.c
88
+@@ -215,6 +215,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
89
+ #define DUMP_TEXT   1
90
+ #define DUMP_RAW    2
91
+ 
92
++#define TIFF_DIR_MAX  65534
93
++
94
+ /* Offsets into buffer for margins and fixed width and length segments */
95
+ struct offset {
96
+   uint32  tmargin;
97
+@@ -2232,7 +2234,7 @@ main(int argc, char* argv[])
98
+     pageNum = -1;
99
+   else
100
+     total_images = 0;
101
+-  /* read multiple input files and write to output file(s) */
102
++  /* Read multiple input files and write to output file(s) */
103
+   while (optind < argc - 1)
104
+     {
105
+     in = TIFFOpen (argv[optind], "r");
106
+@@ -2240,7 +2242,14 @@ main(int argc, char* argv[])
107
+       return (-3);
108
+ 
109
+     /* If only one input file is specified, we can use directory count */
110
+-    total_images = TIFFNumberOfDirectories(in); 
111
++    total_images = TIFFNumberOfDirectories(in);
112
++    if (total_images > TIFF_DIR_MAX)
113
++      {
114
++      TIFFError (TIFFFileName(in), "File contains too many directories");
115
++      if (out != NULL)
116
++        (void) TIFFClose(out);
117
++      return (1);
118
++      }
119
+     if (image_count == 0)
120
+       {
121
+       dirnum = 0;
122
+--
123
+libgit2 0.27.0
124
+
0 125
new file mode 100644
... ...
@@ -0,0 +1,37 @@
0
+diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c
1
+index 4ccb443..94d85e3 100644
2
+--- a/libtiff/tif_lzw.c
3
+@@ -602,6 +602,7 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
4
+ 	char *tp;
5
+ 	unsigned char *bp;
6
+ 	int code, nbits;
7
++	int len;
8
+ 	long nextbits, nextdata, nbitsmask;
9
+ 	code_t *codep, *free_entp, *maxcodep, *oldcodep;
10
+ 
11
+@@ -753,13 +754,18 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
12
+ 				}  while (--occ);
13
+ 				break;
14
+ 			}
15
+-			assert(occ >= codep->length);
16
+-			op += codep->length;
17
+-			occ -= codep->length;
18
+-			tp = op;
19
++			len = codep->length;
20
++			tp = op + len;
21
+ 			do {
22
+-				*--tp = codep->value;
23
+-			} while( (codep = codep->next) != NULL );
24
++				int t;
25
++				--tp;
26
++				t = codep->value;
27
++				codep = codep->next;
28
++				*tp = (char)t;
29
++			} while (codep && tp > op);
30
++			assert(occ >= len);
31
++			op += len;
32
++			occ -= len;
33
+ 		} else {
34
+ 			*op++ = (char)code;
35
+ 			occ--;
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:        TIFF libraries and associated utilities.
2 2
 Name:           libtiff
3 3
 Version:        4.0.9
4
-Release:        3%{?dist}
4
+Release:        4%{?dist}
5 5
 License:        libtiff
6 6
 URL:            http://www.simplesystems.org/libtiff/
7 7
 Group:          System Environment/Libraries
... ...
@@ -12,6 +12,11 @@ Source0:        http://download.osgeo.org/%{name}/tiff-%{version}.tar.gz
12 12
 Patch0:         libtiff-4.0.9-CVE-2017-18013.patch
13 13
 Patch1:         libtiff-4.0.9-CVE-2017-9935.patch
14 14
 Patch2:         libtiff-4.0.9-CVE-2017-17095.patch
15
+Patch3:         libtiff-4.0.9-CVE-2018-5784.patch
16
+Patch4:         libtiff-4.0-9-CVE-2017-11613-1.patch
17
+Patch5:         libtiff-4.0-9-CVE-2017-11613-2.patch
18
+Patch6:         libtiff-4.0-9-CVE-2018-7456.patch
19
+Patch7:         libtiff-4.0.9-CVE-2018-8905.patch
15 20
 BuildRequires:  libjpeg-turbo-devel
16 21
 Requires:       libjpeg-turbo
17 22
 %description
... ...
@@ -29,6 +34,11 @@ It contains the libraries and header files to create applications
29 29
 %patch0 -p1
30 30
 %patch1 -p1
31 31
 %patch2 -p1
32
+%patch3 -p1
33
+%patch4 -p1
34
+%patch5 -p1
35
+%patch6 -p1
36
+%patch7 -p1
32 37
 %build
33 38
 %configure \
34 39
     --disable-static
... ...
@@ -62,6 +72,8 @@ make %{?_smp_mflags} -k check
62 62
 %{_datadir}/man/man3/*
63 63
 
64 64
 %changelog
65
+*   Mon May 14 2018 Xiaolin Li <xiaolinl@vmware.com> 4.0.9-4
66
+-   Fix CVE-2018-7456, CVE-2018-8905, CVE-2018-5784, CVE-2017-11613
65 67
 *   Wed Feb 14 2018 Dheeraj Shetty <dheerajs@vmware.com> 4.0.9-3
66 68
 -   Patch for CVE-2017-17095
67 69
 *   Wed Jan 31 2018 Dheeraj Shetty <dheerajs@vmware.com> 4.0.9-2