Commit | Line | Data |
---|---|---|
e7fcd379 VM |
1 | # Security fix for multiple issues (CVE-2006-34{59-65}) |
2 | # | |
3 | # http://securitytracker.com/alerts/2006/Aug/1016628.html | |
4 | # http://bugs.gentoo.org/show_bug.cgi?id=142383 | |
5 | ||
6 | diff -ru tiff-3.8.2/libtiff/tif_dir.c tiff-3.8.2-goo/libtiff/tif_dir.c | |
7 | --- tiff-3.8.2/libtiff/tif_dir.c 2006-03-21 16:42:50.000000000 +0000 | |
8 | +++ tiff-3.8.2-goo/libtiff/tif_dir.c 2006-07-14 13:52:01.027562000 +0100 | |
9 | @@ -122,6 +122,7 @@ | |
10 | { | |
11 | static const char module[] = "_TIFFVSetField"; | |
12 | ||
13 | + const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); | |
14 | TIFFDirectory* td = &tif->tif_dir; | |
15 | int status = 1; | |
16 | uint32 v32, i, v; | |
17 | @@ -195,10 +196,12 @@ | |
18 | break; | |
19 | case TIFFTAG_ORIENTATION: | |
20 | v = va_arg(ap, uint32); | |
21 | + const TIFFFieldInfo* fip; | |
22 | if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) { | |
23 | + fip = _TIFFFieldWithTag(tif, tag); | |
24 | TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
25 | "Bad value %lu for \"%s\" tag ignored", | |
26 | - v, _TIFFFieldWithTag(tif, tag)->field_name); | |
27 | + v, fip ? fip->field_name : "Unknown"); | |
28 | } else | |
29 | td->td_orientation = (uint16) v; | |
30 | break; | |
31 | @@ -387,11 +390,15 @@ | |
32 | * happens, for example, when tiffcp is used to convert between | |
33 | * compression schemes and codec-specific tags are blindly copied. | |
34 | */ | |
35 | + /* | |
36 | + * better not dereference fip if it is NULL. | |
37 | + * -- taviso@google.com 15 Jun 2006 | |
38 | + */ | |
39 | if(fip == NULL || fip->field_bit != FIELD_CUSTOM) { | |
40 | TIFFErrorExt(tif->tif_clientdata, module, | |
41 | "%s: Invalid %stag \"%s\" (not supported by codec)", | |
42 | tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", | |
43 | - _TIFFFieldWithTag(tif, tag)->field_name); | |
44 | + fip ? fip->field_name : "Unknown"); | |
45 | status = 0; | |
46 | break; | |
47 | } | |
48 | @@ -468,7 +475,7 @@ | |
49 | if (fip->field_type == TIFF_ASCII) | |
50 | _TIFFsetString((char **)&tv->value, va_arg(ap, char *)); | |
51 | else { | |
52 | - tv->value = _TIFFmalloc(tv_size * tv->count); | |
53 | + tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count, "Tag Value"); | |
54 | if (!tv->value) { | |
55 | status = 0; | |
56 | goto end; | |
57 | @@ -563,7 +570,7 @@ | |
58 | } | |
59 | } | |
60 | if (status) { | |
61 | - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); | |
62 | + TIFFSetFieldBit(tif, fip->field_bit); | |
63 | tif->tif_flags |= TIFF_DIRTYDIRECT; | |
64 | } | |
65 | ||
66 | @@ -572,12 +579,12 @@ | |
67 | return (status); | |
68 | badvalue: | |
69 | TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %d for \"%s\"", | |
70 | - tif->tif_name, v, _TIFFFieldWithTag(tif, tag)->field_name); | |
71 | + tif->tif_name, v, fip ? fip->field_name : "Unknown"); | |
72 | va_end(ap); | |
73 | return (0); | |
74 | badvalue32: | |
75 | TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %ld for \"%s\"", | |
76 | - tif->tif_name, v32, _TIFFFieldWithTag(tif, tag)->field_name); | |
77 | + tif->tif_name, v32, fip ? fip->field_name : "Unknown"); | |
78 | va_end(ap); | |
79 | return (0); | |
80 | } | |
81 | @@ -813,12 +820,16 @@ | |
82 | * If the client tries to get a tag that is not valid | |
83 | * for the image's codec then we'll arrive here. | |
84 | */ | |
85 | + /* | |
86 | + * dont dereference fip if it's NULL. | |
87 | + * -- taviso@google.com 15 Jun 2006 | |
88 | + */ | |
89 | if( fip == NULL || fip->field_bit != FIELD_CUSTOM ) | |
90 | { | |
91 | TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField", | |
92 | "%s: Invalid %stag \"%s\" (not supported by codec)", | |
93 | tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", | |
94 | - _TIFFFieldWithTag(tif, tag)->field_name); | |
95 | + fip ? fip->field_name : "Unknown"); | |
96 | ret_val = 0; | |
97 | break; | |
98 | } | |
99 | diff -ru tiff-3.8.2/libtiff/tif_dirinfo.c tiff-3.8.2-goo/libtiff/tif_dirinfo.c | |
100 | --- tiff-3.8.2/libtiff/tif_dirinfo.c 2006-02-07 13:51:03.000000000 +0000 | |
101 | +++ tiff-3.8.2-goo/libtiff/tif_dirinfo.c 2006-07-14 13:52:00.953558000 +0100 | |
102 | @@ -775,7 +775,8 @@ | |
103 | TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag", | |
104 | "Internal error, unknown tag 0x%x", | |
105 | (unsigned int) tag); | |
106 | - assert(fip != NULL); | |
107 | + /* assert(fip != NULL); */ | |
108 | + | |
109 | /*NOTREACHED*/ | |
110 | } | |
111 | return (fip); | |
112 | @@ -789,7 +790,8 @@ | |
113 | if (!fip) { | |
114 | TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName", | |
115 | "Internal error, unknown tag %s", field_name); | |
116 | - assert(fip != NULL); | |
117 | + /* assert(fip != NULL); */ | |
118 | + | |
119 | /*NOTREACHED*/ | |
120 | } | |
121 | return (fip); | |
122 | diff -ru tiff-3.8.2/libtiff/tif_dirread.c tiff-3.8.2-goo/libtiff/tif_dirread.c | |
123 | --- tiff-3.8.2/libtiff/tif_dirread.c 2006-03-21 16:42:50.000000000 +0000 | |
124 | +++ tiff-3.8.2-goo/libtiff/tif_dirread.c 2006-07-14 13:52:00.842557000 +0100 | |
125 | @@ -29,6 +29,9 @@ | |
126 | * | |
127 | * Directory Read Support Routines. | |
128 | */ | |
129 | + | |
130 | +#include <limits.h> | |
131 | + | |
132 | #include "tiffiop.h" | |
133 | ||
134 | #define IGNORE 0 /* tag placeholder used below */ | |
135 | @@ -81,6 +84,7 @@ | |
136 | uint16 dircount; | |
137 | toff_t nextdiroff; | |
138 | int diroutoforderwarning = 0; | |
139 | + int compressionknown = 0; | |
140 | toff_t* new_dirlist; | |
141 | ||
142 | tif->tif_diroff = tif->tif_nextdiroff; | |
143 | @@ -147,13 +151,20 @@ | |
144 | } else { | |
145 | toff_t off = tif->tif_diroff; | |
146 | ||
147 | - if (off + sizeof (uint16) > tif->tif_size) { | |
148 | - TIFFErrorExt(tif->tif_clientdata, module, | |
149 | - "%s: Can not read TIFF directory count", | |
150 | - tif->tif_name); | |
151 | - return (0); | |
152 | + /* | |
153 | + * Check for integer overflow when validating the dir_off, otherwise | |
154 | + * a very high offset may cause an OOB read and crash the client. | |
155 | + * -- taviso@google.com, 14 Jun 2006. | |
156 | + */ | |
157 | + if (off + sizeof (uint16) > tif->tif_size || | |
158 | + off > (UINT_MAX - sizeof(uint16))) { | |
159 | + TIFFErrorExt(tif->tif_clientdata, module, | |
160 | + "%s: Can not read TIFF directory count", | |
161 | + tif->tif_name); | |
162 | + return (0); | |
163 | } else | |
164 | - _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16)); | |
165 | + _TIFFmemcpy(&dircount, tif->tif_base + off, | |
166 | + sizeof (uint16)); | |
167 | off += sizeof (uint16); | |
168 | if (tif->tif_flags & TIFF_SWAB) | |
169 | TIFFSwabShort(&dircount); | |
170 | @@ -254,6 +265,7 @@ | |
171 | while (fix < tif->tif_nfields && | |
172 | tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) | |
173 | fix++; | |
174 | + | |
175 | if (fix >= tif->tif_nfields || | |
176 | tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) { | |
177 | ||
178 | @@ -264,17 +276,23 @@ | |
179 | dp->tdir_tag, | |
180 | dp->tdir_tag, | |
181 | dp->tdir_type); | |
182 | - | |
183 | - TIFFMergeFieldInfo(tif, | |
184 | - _TIFFCreateAnonFieldInfo(tif, | |
185 | - dp->tdir_tag, | |
186 | - (TIFFDataType) dp->tdir_type), | |
187 | - 1 ); | |
188 | + /* | |
189 | + * creating anonymous fields prior to knowing the compression | |
190 | + * algorithm (ie, when the field info has been merged) could cause | |
191 | + * crashes with pathological directories. | |
192 | + * -- taviso@google.com 15 Jun 2006 | |
193 | + */ | |
194 | + if (compressionknown) | |
195 | + TIFFMergeFieldInfo(tif, _TIFFCreateAnonFieldInfo(tif, dp->tdir_tag, | |
196 | + (TIFFDataType) dp->tdir_type), 1 ); | |
197 | + else goto ignore; | |
198 | + | |
199 | fix = 0; | |
200 | while (fix < tif->tif_nfields && | |
201 | tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) | |
202 | fix++; | |
203 | } | |
204 | + | |
205 | /* | |
206 | * Null out old tags that we ignore. | |
207 | */ | |
208 | @@ -326,6 +344,7 @@ | |
209 | dp->tdir_type, dp->tdir_offset); | |
210 | if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v)) | |
211 | goto bad; | |
212 | + else compressionknown++; | |
213 | break; | |
214 | /* XXX: workaround for broken TIFFs */ | |
215 | } else if (dp->tdir_type == TIFF_LONG) { | |
216 | @@ -540,6 +559,7 @@ | |
217 | * Attempt to deal with a missing StripByteCounts tag. | |
218 | */ | |
219 | if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) { | |
220 | + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS); | |
221 | /* | |
222 | * Some manufacturers violate the spec by not giving | |
223 | * the size of the strips. In this case, assume there | |
224 | @@ -556,7 +576,7 @@ | |
225 | "%s: TIFF directory is missing required " | |
226 | "\"%s\" field, calculating from imagelength", | |
227 | tif->tif_name, | |
228 | - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); | |
229 | + fip ? fip->field_name : "Unknown"); | |
230 | if (EstimateStripByteCounts(tif, dir, dircount) < 0) | |
231 | goto bad; | |
232 | /* | |
233 | @@ -580,6 +600,7 @@ | |
234 | } else if (td->td_nstrips == 1 | |
235 | && td->td_stripoffset[0] != 0 | |
236 | && BYTECOUNTLOOKSBAD) { | |
237 | + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS); | |
238 | /* | |
239 | * XXX: Plexus (and others) sometimes give a value of zero for | |
240 | * a tag when they don't know what the correct value is! Try | |
241 | @@ -589,13 +610,14 @@ | |
242 | TIFFWarningExt(tif->tif_clientdata, module, | |
243 | "%s: Bogus \"%s\" field, ignoring and calculating from imagelength", | |
244 | tif->tif_name, | |
245 | - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); | |
246 | + fip ? fip->field_name : "Unknown"); | |
247 | if(EstimateStripByteCounts(tif, dir, dircount) < 0) | |
248 | goto bad; | |
249 | } else if (td->td_planarconfig == PLANARCONFIG_CONTIG | |
250 | && td->td_nstrips > 2 | |
251 | && td->td_compression == COMPRESSION_NONE | |
252 | && td->td_stripbytecount[0] != td->td_stripbytecount[1]) { | |
253 | + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS); | |
254 | /* | |
255 | * XXX: Some vendors fill StripByteCount array with absolutely | |
256 | * wrong values (it can be equal to StripOffset array, for | |
257 | @@ -604,7 +626,7 @@ | |
258 | TIFFWarningExt(tif->tif_clientdata, module, | |
259 | "%s: Wrong \"%s\" field, ignoring and calculating from imagelength", | |
260 | tif->tif_name, | |
261 | - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); | |
262 | + fip ? fip->field_name : "Unknown"); | |
263 | if (EstimateStripByteCounts(tif, dir, dircount) < 0) | |
264 | goto bad; | |
265 | } | |
266 | @@ -870,7 +892,13 @@ | |
267 | ||
268 | register TIFFDirEntry *dp; | |
269 | register TIFFDirectory *td = &tif->tif_dir; | |
270 | - uint16 i; | |
271 | + | |
272 | + /* i is used to iterate over td->td_nstrips, so must be | |
273 | + * at least the same width. | |
274 | + * -- taviso@google.com 15 Jun 2006 | |
275 | + */ | |
276 | + | |
277 | + uint32 i; | |
278 | ||
279 | if (td->td_stripbytecount) | |
280 | _TIFFfree(td->td_stripbytecount); | |
281 | @@ -947,16 +975,18 @@ | |
282 | static int | |
283 | CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) | |
284 | { | |
285 | + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
286 | + | |
287 | if (count > dir->tdir_count) { | |
288 | TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
289 | "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored", | |
290 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, | |
291 | + fip ? fip->field_name : "Unknown", | |
292 | dir->tdir_count, count); | |
293 | return (0); | |
294 | } else if (count < dir->tdir_count) { | |
295 | TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
296 | "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed", | |
297 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, | |
298 | + fip ? fip->field_name : "Unknown", | |
299 | dir->tdir_count, count); | |
300 | return (1); | |
301 | } | |
302 | @@ -970,6 +1000,7 @@ | |
303 | TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp) | |
304 | { | |
305 | int w = TIFFDataWidth((TIFFDataType) dir->tdir_type); | |
306 | + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
307 | tsize_t cc = dir->tdir_count * w; | |
308 | ||
309 | /* Check for overflow. */ | |
310 | @@ -1013,7 +1044,7 @@ | |
311 | bad: | |
312 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
313 | "Error fetching data for field \"%s\"", | |
314 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); | |
315 | + fip ? fip->field_name : "Unknown"); | |
316 | return (tsize_t) 0; | |
317 | } | |
318 | ||
319 | @@ -1039,10 +1070,12 @@ | |
320 | static int | |
321 | cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv) | |
322 | { | |
323 | + const TIFFFieldInfo* fip; | |
324 | if (denom == 0) { | |
325 | + fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
326 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
327 | "%s: Rational with zero denominator (num = %lu)", | |
328 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num); | |
329 | + fip ? fip->field_name : "Unknown", num); | |
330 | return (0); | |
331 | } else { | |
332 | if (dir->tdir_type == TIFF_RATIONAL) | |
333 | @@ -1159,6 +1192,20 @@ | |
334 | static int | |
335 | TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir) | |
336 | { | |
337 | + /* | |
338 | + * Prevent overflowing the v stack arrays below by performing a sanity | |
339 | + * check on tdir_count, this should never be greater than two. | |
340 | + * -- taviso@google.com 14 Jun 2006. | |
341 | + */ | |
342 | + if (dir->tdir_count > 2) { | |
343 | + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
344 | + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
345 | + "unexpected count for field \"%s\", %lu, expected 2; ignored.", | |
346 | + fip ? fip->field_name : "Unknown", | |
347 | + dir->tdir_count); | |
348 | + return 0; | |
349 | + } | |
350 | + | |
351 | switch (dir->tdir_type) { | |
352 | case TIFF_BYTE: | |
353 | case TIFF_SBYTE: | |
354 | @@ -1329,14 +1376,15 @@ | |
355 | case TIFF_DOUBLE: | |
356 | return (TIFFFetchDoubleArray(tif, dir, (double*) v)); | |
357 | default: | |
358 | + { const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
359 | /* TIFF_NOTYPE */ | |
360 | /* TIFF_ASCII */ | |
361 | /* TIFF_UNDEFINED */ | |
362 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
363 | "cannot read TIFF_ANY type %d for field \"%s\"", | |
364 | dir->tdir_type, | |
365 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); | |
366 | - return (0); | |
367 | + fip ? fip->field_name : "Unknown"); | |
368 | + return (0); } | |
369 | } | |
370 | return (1); | |
371 | } | |
372 | @@ -1351,6 +1399,9 @@ | |
373 | int ok = 0; | |
374 | const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag); | |
375 | ||
376 | + if (fip == NULL) { | |
377 | + return (0); | |
378 | + } | |
379 | if (dp->tdir_count > 1) { /* array of values */ | |
380 | char* cp = NULL; | |
381 | ||
382 | @@ -1493,6 +1544,7 @@ | |
383 | TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, uint16* pl) | |
384 | { | |
385 | uint16 samples = tif->tif_dir.td_samplesperpixel; | |
386 | + const TIFFFieldInfo* fip; | |
387 | int status = 0; | |
388 | ||
389 | if (CheckDirCount(tif, dir, (uint32) samples)) { | |
390 | @@ -1510,9 +1562,10 @@ | |
391 | ||
392 | for (i = 1; i < check_count; i++) | |
393 | if (v[i] != v[0]) { | |
394 | + fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
395 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
396 | "Cannot handle different per-sample values for field \"%s\"", | |
397 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); | |
398 | + fip ? fip->field_name : "Unknown"); | |
399 | goto bad; | |
400 | } | |
401 | *pl = v[0]; | |
402 | @@ -1534,6 +1587,7 @@ | |
403 | TIFFFetchPerSampleLongs(TIFF* tif, TIFFDirEntry* dir, uint32* pl) | |
404 | { | |
405 | uint16 samples = tif->tif_dir.td_samplesperpixel; | |
406 | + const TIFFFieldInfo* fip; | |
407 | int status = 0; | |
408 | ||
409 | if (CheckDirCount(tif, dir, (uint32) samples)) { | |
410 | @@ -1551,9 +1605,10 @@ | |
411 | check_count = samples; | |
412 | for (i = 1; i < check_count; i++) | |
413 | if (v[i] != v[0]) { | |
414 | + fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
415 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
416 | "Cannot handle different per-sample values for field \"%s\"", | |
417 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); | |
418 | + fip ? fip->field_name : "Unknown"); | |
419 | goto bad; | |
420 | } | |
421 | *pl = v[0]; | |
422 | @@ -1574,6 +1629,7 @@ | |
423 | TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl) | |
424 | { | |
425 | uint16 samples = tif->tif_dir.td_samplesperpixel; | |
426 | + const TIFFFieldInfo* fip; | |
427 | int status = 0; | |
428 | ||
429 | if (CheckDirCount(tif, dir, (uint32) samples)) { | |
430 | @@ -1591,9 +1647,10 @@ | |
431 | ||
432 | for (i = 1; i < check_count; i++) | |
433 | if (v[i] != v[0]) { | |
434 | + fip = _TIFFFieldWithTag(tif, dir->tdir_tag); | |
435 | TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
436 | "Cannot handle different per-sample values for field \"%s\"", | |
437 | - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); | |
438 | + fip ? fip->field_name : "Unknown"); | |
439 | goto bad; | |
440 | } | |
441 | *pl = v[0]; | |
442 | diff -ru tiff-3.8.2/libtiff/tif_fax3.c tiff-3.8.2-goo/libtiff/tif_fax3.c | |
443 | --- tiff-3.8.2/libtiff/tif_fax3.c 2006-03-21 16:42:50.000000000 +0000 | |
444 | +++ tiff-3.8.2-goo/libtiff/tif_fax3.c 2006-07-14 13:52:00.669557000 +0100 | |
445 | @@ -1136,6 +1136,7 @@ | |
446 | Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap) | |
447 | { | |
448 | Fax3BaseState* sp = Fax3State(tif); | |
449 | + const TIFFFieldInfo* fip; | |
450 | ||
451 | assert(sp != 0); | |
452 | assert(sp->vsetparent != 0); | |
453 | @@ -1181,7 +1182,13 @@ | |
454 | default: | |
455 | return (*sp->vsetparent)(tif, tag, ap); | |
456 | } | |
457 | - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); | |
458 | + | |
459 | + if ((fip = _TIFFFieldWithTag(tif, tag))) { | |
460 | + TIFFSetFieldBit(tif, fip->field_bit); | |
461 | + } else { | |
462 | + return (0); | |
463 | + } | |
464 | + | |
465 | tif->tif_flags |= TIFF_DIRTYDIRECT; | |
466 | return (1); | |
467 | } | |
468 | diff -ru tiff-3.8.2/libtiff/tif_jpeg.c tiff-3.8.2-goo/libtiff/tif_jpeg.c | |
469 | --- tiff-3.8.2/libtiff/tif_jpeg.c 2006-03-21 16:42:50.000000000 +0000 | |
470 | +++ tiff-3.8.2-goo/libtiff/tif_jpeg.c 2006-07-14 13:52:00.655560000 +0100 | |
471 | @@ -722,15 +722,31 @@ | |
472 | segment_width = TIFFhowmany(segment_width, sp->h_sampling); | |
473 | segment_height = TIFFhowmany(segment_height, sp->v_sampling); | |
474 | } | |
475 | - if (sp->cinfo.d.image_width != segment_width || | |
476 | - sp->cinfo.d.image_height != segment_height) { | |
477 | + if (sp->cinfo.d.image_width < segment_width || | |
478 | + sp->cinfo.d.image_height < segment_height) { | |
479 | TIFFWarningExt(tif->tif_clientdata, module, | |
480 | "Improper JPEG strip/tile size, expected %dx%d, got %dx%d", | |
481 | segment_width, | |
482 | segment_height, | |
483 | sp->cinfo.d.image_width, | |
484 | sp->cinfo.d.image_height); | |
485 | + } | |
486 | + | |
487 | + if (sp->cinfo.d.image_width > segment_width || | |
488 | + sp->cinfo.d.image_height > segment_height) { | |
489 | + /* | |
490 | + * This case could be dangerous, if the strip or tile size has been | |
491 | + * reported as less than the amount of data jpeg will return, some | |
492 | + * potential security issues arise. Catch this case and error out. | |
493 | + * -- taviso@google.com 14 Jun 2006 | |
494 | + */ | |
495 | + TIFFErrorExt(tif->tif_clientdata, module, | |
496 | + "JPEG strip/tile size exceeds expected dimensions," | |
497 | + "expected %dx%d, got %dx%d", segment_width, segment_height, | |
498 | + sp->cinfo.d.image_width, sp->cinfo.d.image_height); | |
499 | + return (0); | |
500 | } | |
501 | + | |
502 | if (sp->cinfo.d.num_components != | |
503 | (td->td_planarconfig == PLANARCONFIG_CONTIG ? | |
504 | td->td_samplesperpixel : 1)) { | |
505 | @@ -761,6 +777,22 @@ | |
506 | sp->cinfo.d.comp_info[0].v_samp_factor, | |
507 | sp->h_sampling, sp->v_sampling); | |
508 | ||
509 | + /* | |
510 | + * There are potential security issues here for decoders that | |
511 | + * have already allocated buffers based on the expected sampling | |
512 | + * factors. Lets check the sampling factors dont exceed what | |
513 | + * we were expecting. | |
514 | + * -- taviso@google.com 14 June 2006 | |
515 | + */ | |
516 | + if (sp->cinfo.d.comp_info[0].h_samp_factor > sp->h_sampling || | |
517 | + sp->cinfo.d.comp_info[0].v_samp_factor > sp->v_sampling) { | |
518 | + TIFFErrorExt(tif->tif_clientdata, module, | |
519 | + "Cannot honour JPEG sampling factors that" | |
520 | + " exceed those specified."); | |
521 | + return (0); | |
522 | + } | |
523 | + | |
524 | + | |
525 | /* | |
526 | * XXX: Files written by the Intergraph software | |
527 | * has different sampling factors stored in the | |
528 | @@ -1521,15 +1553,18 @@ | |
529 | { | |
530 | JPEGState *sp = JState(tif); | |
531 | ||
532 | - assert(sp != 0); | |
533 | + /* assert(sp != 0); */ | |
534 | ||
535 | tif->tif_tagmethods.vgetfield = sp->vgetparent; | |
536 | tif->tif_tagmethods.vsetfield = sp->vsetparent; | |
537 | ||
538 | - if( sp->cinfo_initialized ) | |
539 | - TIFFjpeg_destroy(sp); /* release libjpeg resources */ | |
540 | - if (sp->jpegtables) /* tag value */ | |
541 | - _TIFFfree(sp->jpegtables); | |
542 | + if (sp != NULL) { | |
543 | + if( sp->cinfo_initialized ) | |
544 | + TIFFjpeg_destroy(sp); /* release libjpeg resources */ | |
545 | + if (sp->jpegtables) /* tag value */ | |
546 | + _TIFFfree(sp->jpegtables); | |
547 | + } | |
548 | + | |
549 | _TIFFfree(tif->tif_data); /* release local state */ | |
550 | tif->tif_data = NULL; | |
551 | ||
552 | @@ -1541,6 +1576,7 @@ | |
553 | { | |
554 | JPEGState* sp = JState(tif); | |
555 | TIFFDirectory* td = &tif->tif_dir; | |
556 | + const TIFFFieldInfo* fip; | |
557 | uint32 v32; | |
558 | ||
559 | assert(sp != NULL); | |
560 | @@ -1606,7 +1642,13 @@ | |
561 | default: | |
562 | return (*sp->vsetparent)(tif, tag, ap); | |
563 | } | |
564 | - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); | |
565 | + | |
566 | + if ((fip = _TIFFFieldWithTag(tif, tag))) { | |
567 | + TIFFSetFieldBit(tif, fip->field_bit); | |
568 | + } else { | |
569 | + return (0); | |
570 | + } | |
571 | + | |
572 | tif->tif_flags |= TIFF_DIRTYDIRECT; | |
573 | return (1); | |
574 | } | |
575 | @@ -1726,7 +1768,11 @@ | |
576 | { | |
577 | JPEGState* sp = JState(tif); | |
578 | ||
579 | - assert(sp != NULL); | |
580 | + /* assert(sp != NULL); */ | |
581 | + if (sp == NULL) { | |
582 | + TIFFWarningExt(tif->tif_clientdata, "JPEGPrintDir", "Unknown JPEGState"); | |
583 | + return; | |
584 | + } | |
585 | ||
586 | (void) flags; | |
587 | if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) | |
588 | diff -ru tiff-3.8.2/libtiff/tif_next.c tiff-3.8.2-goo/libtiff/tif_next.c | |
589 | --- tiff-3.8.2/libtiff/tif_next.c 2005-12-21 12:33:56.000000000 +0000 | |
590 | +++ tiff-3.8.2-goo/libtiff/tif_next.c 2006-07-14 13:52:00.556567000 +0100 | |
591 | @@ -105,11 +105,16 @@ | |
592 | * as codes of the form <color><npixels> | |
593 | * until we've filled the scanline. | |
594 | */ | |
595 | + /* | |
596 | + * Ensure the run does not exceed the scanline | |
597 | + * bounds, potentially resulting in a security issue. | |
598 | + * -- taviso@google.com 14 Jun 2006. | |
599 | + */ | |
600 | op = row; | |
601 | for (;;) { | |
602 | grey = (n>>6) & 0x3; | |
603 | n &= 0x3f; | |
604 | - while (n-- > 0) | |
605 | + while (n-- > 0 && npixels < imagewidth) | |
606 | SETPIXEL(op, grey); | |
607 | if (npixels >= (int) imagewidth) | |
608 | break; | |
609 | diff -ru tiff-3.8.2/libtiff/tif_pixarlog.c tiff-3.8.2-goo/libtiff/tif_pixarlog.c | |
610 | --- tiff-3.8.2/libtiff/tif_pixarlog.c 2006-03-21 16:42:50.000000000 +0000 | |
611 | +++ tiff-3.8.2-goo/libtiff/tif_pixarlog.c 2006-07-14 13:52:00.483557000 +0100 | |
612 | @@ -768,7 +768,19 @@ | |
613 | if (tif->tif_flags & TIFF_SWAB) | |
614 | TIFFSwabArrayOfShort(up, nsamples); | |
615 | ||
616 | - for (i = 0; i < nsamples; i += llen, up += llen) { | |
617 | + /* | |
618 | + * if llen is not an exact multiple of nsamples, the decode operation | |
619 | + * may overflow the output buffer, so truncate it enough to prevent that | |
620 | + * but still salvage as much data as possible. | |
621 | + * -- taviso@google.com 14th June 2006 | |
622 | + */ | |
623 | + if (nsamples % llen) | |
624 | + TIFFWarningExt(tif->tif_clientdata, module, | |
625 | + "%s: stride %lu is not a multiple of sample count, " | |
626 | + "%lu, data truncated.", tif->tif_name, llen, nsamples); | |
627 | + | |
628 | + | |
629 | + for (i = 0; i < nsamples - (nsamples % llen); i += llen, up += llen) { | |
630 | switch (sp->user_datafmt) { | |
631 | case PIXARLOGDATAFMT_FLOAT: | |
632 | horizontalAccumulateF(up, llen, sp->stride, | |
633 | diff -ru tiff-3.8.2/libtiff/tif_read.c tiff-3.8.2-goo/libtiff/tif_read.c | |
634 | --- tiff-3.8.2/libtiff/tif_read.c 2005-12-21 12:33:56.000000000 +0000 | |
635 | +++ tiff-3.8.2-goo/libtiff/tif_read.c 2006-07-14 13:52:00.467568000 +0100 | |
636 | @@ -31,6 +31,8 @@ | |
637 | #include "tiffiop.h" | |
638 | #include <stdio.h> | |
639 | ||
640 | +#include <limits.h> | |
641 | + | |
642 | int TIFFFillStrip(TIFF*, tstrip_t); | |
643 | int TIFFFillTile(TIFF*, ttile_t); | |
644 | static int TIFFStartStrip(TIFF*, tstrip_t); | |
645 | @@ -272,7 +274,13 @@ | |
646 | if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) | |
647 | _TIFFfree(tif->tif_rawdata); | |
648 | tif->tif_flags &= ~TIFF_MYBUFFER; | |
649 | - if ( td->td_stripoffset[strip] + bytecount > tif->tif_size) { | |
650 | + /* | |
651 | + * This sanity check could potentially overflow, causing an OOB read. | |
652 | + * verify that offset + bytecount is > offset. | |
653 | + * -- taviso@google.com 14 Jun 2006 | |
654 | + */ | |
655 | + if ( td->td_stripoffset[strip] + bytecount > tif->tif_size || | |
656 | + bytecount > (UINT_MAX - td->td_stripoffset[strip])) { | |
657 | /* | |
658 | * This error message might seem strange, but it's | |
659 | * what would happen if a read were done instead. | |
660 | @@ -470,7 +478,13 @@ | |
661 | if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) | |
662 | _TIFFfree(tif->tif_rawdata); | |
663 | tif->tif_flags &= ~TIFF_MYBUFFER; | |
664 | - if ( td->td_stripoffset[tile] + bytecount > tif->tif_size) { | |
665 | + /* | |
666 | + * We must check this calculation doesnt overflow, potentially | |
667 | + * causing an OOB read. | |
668 | + * -- taviso@google.com 15 Jun 2006 | |
669 | + */ | |
670 | + if (td->td_stripoffset[tile] + bytecount > tif->tif_size || | |
671 | + bytecount > (UINT_MAX - td->td_stripoffset[tile])) { | |
672 | tif->tif_curtile = NOTILE; | |
673 | return (0); | |
674 | } |