| 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 | } |