blob: 8345295d07be5bd69402a20f30706717379b5261 [file] [log] [blame]
Brad Bishop00e122a2019-10-05 11:10:57 -04001From 95ac1e3fcc6b643b5bd100f2ea54faca0a003315 Mon Sep 17 00:00:00 2001
2From: Trevor Gamblin <trevor.gamblin@windriver.com>
3Date: Fri, 20 Sep 2019 09:33:22 -0400
4Subject: [PATCH] libtiff-fix-CVE-2019-14973
5
6Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/commit/2218055ca67d84be596a13080e8f50f22116555c]
7CVE: CVE-2019-14973
8
9Signed-off-by: Trevor Gamblin <trevor.gamblin@windriver.com>
10---
11 libtiff/tif_aux.c | 49 +++++++++++++++++++++++++++++++++++++-----
12 libtiff/tif_getimage.c | 6 ++----
13 libtiff/tif_luv.c | 8 +------
14 libtiff/tif_pixarlog.c | 7 +-----
15 libtiff/tif_read.c | 38 +++++++++-----------------------
16 libtiff/tif_strip.c | 35 ++++--------------------------
17 libtiff/tif_tile.c | 27 +++--------------------
18 libtiff/tiffiop.h | 7 +++++-
19 8 files changed, 71 insertions(+), 106 deletions(-)
20
21diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c
22index 4ece162f..33fb8a44 100644
23--- a/libtiff/tif_aux.c
24+++ b/libtiff/tif_aux.c
25@@ -57,18 +57,57 @@ _TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
26 return bytes;
27 }
28
29+tmsize_t
30+_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where)
31+{
32+ if( first <= 0 || second <= 0 )
33+ {
34+ if( tif != NULL && where != NULL )
35+ {
36+ TIFFErrorExt(tif->tif_clientdata, where,
37+ "Invalid argument to _TIFFMultiplySSize() in %s", where);
38+ }
39+ return 0;
40+ }
41+
42+ if( first > TIFF_TMSIZE_T_MAX / second )
43+ {
44+ if( tif != NULL && where != NULL )
45+ {
46+ TIFFErrorExt(tif->tif_clientdata, where,
47+ "Integer overflow in %s", where);
48+ }
49+ return 0;
50+ }
51+ return first * second;
52+}
53+
54+tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64 val, const char* module)
55+{
56+ if( val > (uint64)TIFF_TMSIZE_T_MAX )
57+ {
58+ if( tif != NULL && module != NULL )
59+ {
60+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
61+ }
62+ return 0;
63+ }
64+ return (tmsize_t)val;
65+}
66+
67 void*
68 _TIFFCheckRealloc(TIFF* tif, void* buffer,
69 tmsize_t nmemb, tmsize_t elem_size, const char* what)
70 {
71 void* cp = NULL;
72- tmsize_t bytes = nmemb * elem_size;
73-
74+ tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
75 /*
76- * XXX: Check for integer overflow.
77+ * Check for integer overflow.
78 */
79- if (nmemb && elem_size && bytes / elem_size == nmemb)
80- cp = _TIFFrealloc(buffer, bytes);
81+ if (count != 0)
82+ {
83+ cp = _TIFFrealloc(buffer, count);
84+ }
85
86 if (cp == NULL) {
87 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
88diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
89index 6a9d5a7c..2106ca21 100644
90--- a/libtiff/tif_getimage.c
91+++ b/libtiff/tif_getimage.c
92@@ -755,9 +755,8 @@ gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
93 uint32 leftmost_tw;
94
95 tilesize = TIFFTileSize(tif);
96- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
97+ bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate");
98 if (bufsize == 0) {
99- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
100 return (0);
101 }
102
103@@ -1019,9 +1018,8 @@ gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
104 uint16 colorchannels;
105
106 stripsize = TIFFStripSize(tif);
107- bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
108+ bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate");
109 if (bufsize == 0) {
110- TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
111 return (0);
112 }
113
114diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c
115index aa35ea07..46d2dff2 100644
116--- a/libtiff/tif_luv.c
117+++ b/libtiff/tif_luv.c
118@@ -1264,16 +1264,10 @@ LogL16GuessDataFmt(TIFFDirectory *td)
119 return (SGILOGDATAFMT_UNKNOWN);
120 }
121
122-
123-#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
124-#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
125-
126 static tmsize_t
127 multiply_ms(tmsize_t m1, tmsize_t m2)
128 {
129- if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
130- return 0;
131- return m1 * m2;
132+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
133 }
134
135 static int
136diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c
137index 7438d692..b52a3ee4 100644
138--- a/libtiff/tif_pixarlog.c
139+++ b/libtiff/tif_pixarlog.c
140@@ -634,15 +634,10 @@ PixarLogGuessDataFmt(TIFFDirectory *td)
141 return guess;
142 }
143
144-#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
145-#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
146-
147 static tmsize_t
148 multiply_ms(tmsize_t m1, tmsize_t m2)
149 {
150- if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 )
151- return 0;
152- return m1 * m2;
153+ return _TIFFMultiplySSize(NULL, m1, m2, NULL);
154 }
155
156 static tmsize_t
157diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c
158index e63810cc..8db39d7a 100644
159--- a/libtiff/tif_read.c
160+++ b/libtiff/tif_read.c
161@@ -29,9 +29,6 @@
162 #include "tiffiop.h"
163 #include <stdio.h>
164
165-#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
166-#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
167-
168 int TIFFFillStrip(TIFF* tif, uint32 strip);
169 int TIFFFillTile(TIFF* tif, uint32 tile);
170 static int TIFFStartStrip(TIFF* tif, uint32 strip);
171@@ -49,6 +46,8 @@ TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
172 #define THRESHOLD_MULTIPLIER 10
173 #define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
174
175+#define TIFF_INT64_MAX ((((int64)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
176+
177 /* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
178 * Returns 1 in case of success, 0 otherwise. */
179 static int TIFFReadAndRealloc( TIFF* tif, tmsize_t size,
180@@ -734,23 +733,8 @@ TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
181 return ((tmsize_t)(-1));
182 }
183 bytecount = td->td_stripbytecount[strip];
184- if ((int64)bytecount <= 0) {
185-#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
186- TIFFErrorExt(tif->tif_clientdata, module,
187- "%I64u: Invalid strip byte count, strip %lu",
188- (unsigned __int64) bytecount,
189- (unsigned long) strip);
190-#else
191- TIFFErrorExt(tif->tif_clientdata, module,
192- "%llu: Invalid strip byte count, strip %lu",
193- (unsigned long long) bytecount,
194- (unsigned long) strip);
195-#endif
196- return ((tmsize_t)(-1));
197- }
198- bytecountm = (tmsize_t)bytecount;
199- if ((uint64)bytecountm!=bytecount) {
200- TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
201+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount, module);
202+ if (bytecountm == 0) {
203 return ((tmsize_t)(-1));
204 }
205 if (size != (tmsize_t)(-1) && size < bytecountm)
206@@ -774,7 +758,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
207 if ((tif->tif_flags&TIFF_NOREADRAW)==0)
208 {
209 uint64 bytecount = td->td_stripbytecount[strip];
210- if ((int64)bytecount <= 0) {
211+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
212 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
213 TIFFErrorExt(tif->tif_clientdata, module,
214 "Invalid strip byte count %I64u, strip %lu",
215@@ -801,7 +785,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip)
216 (bytecount - 4096) / 10 > (uint64)stripsize )
217 {
218 uint64 newbytecount = (uint64)stripsize * 10 + 4096;
219- if( (int64)newbytecount >= 0 )
220+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
221 {
222 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
223 TIFFWarningExt(tif->tif_clientdata, module,
224@@ -1196,10 +1180,8 @@ TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
225 bytecount64 = td->td_stripbytecount[tile];
226 if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
227 bytecount64 = (uint64)size;
228- bytecountm = (tmsize_t)bytecount64;
229- if ((uint64)bytecountm!=bytecount64)
230- {
231- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
232+ bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
233+ if( bytecountm == 0 ) {
234 return ((tmsize_t)(-1));
235 }
236 return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
237@@ -1221,7 +1203,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
238 if ((tif->tif_flags&TIFF_NOREADRAW)==0)
239 {
240 uint64 bytecount = td->td_stripbytecount[tile];
241- if ((int64)bytecount <= 0) {
242+ if( bytecount == 0 || bytecount > (uint64)TIFF_INT64_MAX ) {
243 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
244 TIFFErrorExt(tif->tif_clientdata, module,
245 "%I64u: Invalid tile byte count, tile %lu",
246@@ -1248,7 +1230,7 @@ TIFFFillTile(TIFF* tif, uint32 tile)
247 (bytecount - 4096) / 10 > (uint64)stripsize )
248 {
249 uint64 newbytecount = (uint64)stripsize * 10 + 4096;
250- if( (int64)newbytecount >= 0 )
251+ if( newbytecount == 0 || newbytecount > (uint64)TIFF_INT64_MAX )
252 {
253 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
254 TIFFWarningExt(tif->tif_clientdata, module,
255diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c
256index 5b76fba5..2366acf0 100644
257--- a/libtiff/tif_strip.c
258+++ b/libtiff/tif_strip.c
259@@ -129,15 +129,8 @@ TIFFVStripSize(TIFF* tif, uint32 nrows)
260 {
261 static const char module[] = "TIFFVStripSize";
262 uint64 m;
263- tmsize_t n;
264 m=TIFFVStripSize64(tif,nrows);
265- n=(tmsize_t)m;
266- if ((uint64)n!=m)
267- {
268- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
269- n=0;
270- }
271- return(n);
272+ return _TIFFCastUInt64ToSSize(tif, m, module);
273 }
274
275 /*
276@@ -211,15 +204,8 @@ TIFFStripSize(TIFF* tif)
277 {
278 static const char module[] = "TIFFStripSize";
279 uint64 m;
280- tmsize_t n;
281 m=TIFFStripSize64(tif);
282- n=(tmsize_t)m;
283- if ((uint64)n!=m)
284- {
285- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
286- n=0;
287- }
288- return(n);
289+ return _TIFFCastUInt64ToSSize(tif, m, module);
290 }
291
292 /*
293@@ -330,14 +316,8 @@ TIFFScanlineSize(TIFF* tif)
294 {
295 static const char module[] = "TIFFScanlineSize";
296 uint64 m;
297- tmsize_t n;
298 m=TIFFScanlineSize64(tif);
299- n=(tmsize_t)m;
300- if ((uint64)n!=m) {
301- TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
302- n=0;
303- }
304- return(n);
305+ return _TIFFCastUInt64ToSSize(tif, m, module);
306 }
307
308 /*
309@@ -366,15 +346,8 @@ TIFFRasterScanlineSize(TIFF* tif)
310 {
311 static const char module[] = "TIFFRasterScanlineSize";
312 uint64 m;
313- tmsize_t n;
314 m=TIFFRasterScanlineSize64(tif);
315- n=(tmsize_t)m;
316- if ((uint64)n!=m)
317- {
318- TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
319- n=0;
320- }
321- return(n);
322+ return _TIFFCastUInt64ToSSize(tif, m, module);
323 }
324
325 /* vim: set ts=8 sts=8 sw=8 noet: */
326diff --git a/libtiff/tif_tile.c b/libtiff/tif_tile.c
327index 58fe9354..661cc771 100644
328--- a/libtiff/tif_tile.c
329+++ b/libtiff/tif_tile.c
330@@ -181,15 +181,8 @@ TIFFTileRowSize(TIFF* tif)
331 {
332 static const char module[] = "TIFFTileRowSize";
333 uint64 m;
334- tmsize_t n;
335 m=TIFFTileRowSize64(tif);
336- n=(tmsize_t)m;
337- if ((uint64)n!=m)
338- {
339- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
340- n=0;
341- }
342- return(n);
343+ return _TIFFCastUInt64ToSSize(tif, m, module);
344 }
345
346 /*
347@@ -248,15 +241,8 @@ TIFFVTileSize(TIFF* tif, uint32 nrows)
348 {
349 static const char module[] = "TIFFVTileSize";
350 uint64 m;
351- tmsize_t n;
352 m=TIFFVTileSize64(tif,nrows);
353- n=(tmsize_t)m;
354- if ((uint64)n!=m)
355- {
356- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
357- n=0;
358- }
359- return(n);
360+ return _TIFFCastUInt64ToSSize(tif, m, module);
361 }
362
363 /*
364@@ -272,15 +258,8 @@ TIFFTileSize(TIFF* tif)
365 {
366 static const char module[] = "TIFFTileSize";
367 uint64 m;
368- tmsize_t n;
369 m=TIFFTileSize64(tif);
370- n=(tmsize_t)m;
371- if ((uint64)n!=m)
372- {
373- TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
374- n=0;
375- }
376- return(n);
377+ return _TIFFCastUInt64ToSSize(tif, m, module);
378 }
379
380 /*
381diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
382index 186c291f..558484fe 100644
383--- a/libtiff/tiffiop.h
384+++ b/libtiff/tiffiop.h
385@@ -77,6 +77,9 @@ extern int snprintf(char* str, size_t size, const char* format, ...);
386 #define FALSE 0
387 #endif
388
389+#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0))
390+#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1)
391+
392 typedef struct client_info {
393 struct client_info *next;
394 void *data;
395@@ -258,7 +261,7 @@ struct tiff {
396 #define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
397 #define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
398
399-/* Safe multiply which returns zero if there is an integer overflow */
400+/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This macro is not safe for *signed* integer types */
401 #define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
402
403 #define TIFFmax(A,B) ((A)>(B)?(A):(B))
404@@ -368,6 +371,8 @@ extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
405
406 extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
407 extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
408+extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*);
409+extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64, const char*);
410 extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
411 extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
412
413--
4142.17.1
415