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