--- tiff-v3.6.1/libtiff/tif_next.c.cve-2006-3459-thru-3464 2006-07-27 07:00:36.192981659 -0600 +++ tiff-v3.6.1/libtiff/tif_next.c 2006-07-27 07:00:36.241972816 -0600 @@ -109,7 +109,7 @@ NeXTDecode(TIFF* tif, tidata_t buf, tsiz for (;;) { grey = (n>>6) & 0x3; n &= 0x3f; - while (n-- > 0) + while (n-- > 0 && npixels < imagewidth) SETPIXEL(op, grey); if (npixels >= (int) imagewidth) break; --- tiff-v3.6.1/libtiff/tif_pixarlog.c.cve-2006-3459-thru-3464 2006-07-27 07:00:36.223976065 -0600 +++ tiff-v3.6.1/libtiff/tif_pixarlog.c 2006-07-27 07:00:36.241972816 -0600 @@ -767,7 +767,13 @@ PixarLogDecode(TIFF* tif, tidata_t op, t if (tif->tif_flags & TIFF_SWAB) TIFFSwabArrayOfShort(up, nsamples); - for (i = 0; i < nsamples; i += llen, up += llen) { + if (nsamples % llen) + TIFFWarning(module, + "%s: stride %lu is not a multiple of sample count, " + "%lu, data truncated.", tif->tif_name, llen, nsamples); + + + for (i = 0; i < nsamples - (nsamples % llen); i += llen, up += llen) { switch (sp->user_datafmt) { case PIXARLOGDATAFMT_FLOAT: horizontalAccumulateF(up, llen, sp->stride, --- tiff-v3.6.1/libtiff/tif_dir.c.cve-2006-3459-thru-3464 2006-07-27 07:00:36.229974982 -0600 +++ tiff-v3.6.1/libtiff/tif_dir.c 2006-07-27 07:00:36.242972635 -0600 @@ -122,6 +122,7 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va { static const char module[] = "_TIFFVSetField"; + const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); TIFFDirectory* td = &tif->tif_dir; int status = 1; uint32 v32; @@ -217,10 +218,12 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va break; case TIFFTAG_ORIENTATION: v = va_arg(ap, int); + const TIFFFieldInfo* fip; if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) { + fip = _TIFFFieldWithTag(tif, tag); TIFFWarning(tif->tif_name, "Bad value %ld for \"%s\" tag ignored", - v, _TIFFFieldWithTag(tif, tag)->field_name); + v, fip ? fip->field_name : "Unknown"); } else td->td_orientation = (uint16) v; break; @@ -503,7 +506,7 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va TIFFError(module, "%s: Invalid %stag \"%s\" (not supported by codec)", tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - _TIFFFieldWithTag(tif, tag)->field_name); + fip ? fip->field_name : "Unknown"); status = 0; break; } @@ -591,19 +594,19 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va } } if (status) { - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); + TIFFSetFieldBit(tif, fip->field_bit); tif->tif_flags |= TIFF_DIRTYDIRECT; } va_end(ap); return (status); badvalue: TIFFError(module, "%.1000s: Bad value %d for \"%s\"", - tif->tif_name, v, _TIFFFieldWithTag(tif, tag)->field_name); + tif->tif_name, v, fip ? fip->field_name : "Unknown"); va_end(ap); return (0); badvalue32: TIFFError(module, "%.1000s: Bad value %ld for \"%s\"", - tif->tif_name, v32, _TIFFFieldWithTag(tif, tag)->field_name); + tif->tif_name, v32, fip ? fip->field_name : "Unknown"); va_end(ap); return (0); badvaluedbl: @@ -944,7 +947,7 @@ _TIFFVGetField(TIFF* tif, ttag_t tag, va TIFFError("_TIFFVGetField", "%s: Invalid %stag \"%s\" (not supported by codec)", tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - _TIFFFieldWithTag(tif, tag)->field_name); + fip ? fip->field_name : "Unknown"); ret_val = 0; break; } --- tiff-v3.6.1/libtiff/tif_read.c.cve-2006-3459-thru-3464 2002-08-11 09:01:45.000000000 -0600 +++ tiff-v3.6.1/libtiff/tif_read.c 2006-07-27 07:00:36.243972455 -0600 @@ -32,6 +32,8 @@ #include <stdio.h> #include <assert.h> +#include <limits.h> + int TIFFFillStrip(TIFF*, tstrip_t); int TIFFFillTile(TIFF*, ttile_t); static int TIFFStartStrip(TIFF*, tstrip_t); @@ -271,7 +273,8 @@ TIFFFillStrip(TIFF* tif, tstrip_t strip) if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) _TIFFfree(tif->tif_rawdata); tif->tif_flags &= ~TIFF_MYBUFFER; - if ( td->td_stripoffset[strip] + bytecount > tif->tif_size) { + if ( td->td_stripoffset[strip] + bytecount > tif->tif_size || + bytecount > (UINT_MAX - td->td_stripoffset[strip])) { /* * This error message might seem strange, but it's * what would happen if a read were done instead. @@ -468,7 +471,8 @@ TIFFFillTile(TIFF* tif, ttile_t tile) if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) _TIFFfree(tif->tif_rawdata); tif->tif_flags &= ~TIFF_MYBUFFER; - if ( td->td_stripoffset[tile] + bytecount > tif->tif_size) { + if (td->td_stripoffset[tile] + bytecount > tif->tif_size || + bytecount > (UINT_MAX - td->td_stripoffset[tile])) { tif->tif_curtile = NOTILE; return (0); } --- tiff-v3.6.1/libtiff/tif_jpeg.c.cve-2006-3459-thru-3464 2006-07-27 07:00:36.221976426 -0600 +++ tiff-v3.6.1/libtiff/tif_jpeg.c 2006-07-27 07:00:36.243972455 -0600 @@ -673,8 +673,8 @@ JPEGPreDecode(TIFF* tif, tsample_t s) segment_width = TIFFhowmany(segment_width, sp->h_sampling); segment_height = TIFFhowmany(segment_height, sp->v_sampling); } - if (sp->cinfo.d.image_width != segment_width || - sp->cinfo.d.image_height != segment_height) { + if (sp->cinfo.d.image_width < segment_width || + sp->cinfo.d.image_height < segment_height) { TIFFWarning(module, "Improper JPEG strip/tile size, expected %dx%d, got %dx%d", segment_width, @@ -682,6 +682,14 @@ JPEGPreDecode(TIFF* tif, tsample_t s) sp->cinfo.d.image_width, sp->cinfo.d.image_height); } + if (sp->cinfo.d.image_width > segment_width || + sp->cinfo.d.image_height > segment_height) { + TIFFError(module, + "JPEG strip/tile size exceeds expected dimensions," + "expected %dx%d, got %dx%d", segment_width, segment_height, + sp->cinfo.d.image_width, sp->cinfo.d.image_height); + return (0); + } if (sp->cinfo.d.num_components != (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1)) { @@ -708,6 +716,13 @@ JPEGPreDecode(TIFF* tif, tsample_t s) sp->cinfo.d.comp_info[0].h_samp_factor, sp->cinfo.d.comp_info[0].v_samp_factor ); + if (sp->cinfo.d.comp_info[0].h_samp_factor > sp->h_sampling || + sp->cinfo.d.comp_info[0].v_samp_factor > sp->v_sampling) { + TIFFError(module, + "Cannot honour JPEG sampling factors that" + " exceed those specified."); + return (0); + } sp->h_sampling = (uint16) sp->cinfo.d.comp_info[0].h_samp_factor; sp->v_sampling = (uint16) @@ -1325,15 +1340,17 @@ JPEGCleanup(TIFF* tif) { JPEGState *sp = JState(tif); - assert(sp != 0); + /* assert(sp != 0); */ tif->tif_tagmethods.vgetfield = sp->vgetparent; tif->tif_tagmethods.vsetfield = sp->vsetparent; + if (sp != NULL) { if( sp->cinfo_initialized ) TIFFjpeg_destroy(sp); /* release libjpeg resources */ if (sp->jpegtables) /* tag value */ _TIFFfree(sp->jpegtables); + } _TIFFfree(tif->tif_data); /* release local state */ tif->tif_data = NULL; @@ -1345,6 +1362,7 @@ JPEGVSetField(TIFF* tif, ttag_t tag, va_ { JPEGState* sp = JState(tif); TIFFDirectory* td = &tif->tif_dir; + const TIFFFieldInfo* fip; uint32 v32; switch (tag) { @@ -1503,6 +1521,11 @@ JPEGPrintDir(TIFF* tif, FILE* fd, long f { JPEGState* sp = JState(tif); + if (sp == NULL) { + TIFFWarning("JPEGPrintDir", "Unknown JPEGState"); + return; + } + (void) flags; if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) fprintf(fd, " JPEG Tables: (%lu bytes)\n", --- tiff-v3.6.1/libtiff/tif_dirinfo.c.cve-2006-3459-thru-3464 2006-07-27 07:00:36.187982562 -0600 +++ tiff-v3.6.1/libtiff/tif_dirinfo.c 2006-07-27 07:00:36.244972275 -0600 @@ -432,7 +432,8 @@ _TIFFFieldWithTag(TIFF* tif, ttag_t tag) if (!fip) { TIFFError("TIFFFieldWithTag", "Internal error, unknown tag 0x%x", (u_int) tag); - assert(fip != NULL); + /* assert(fip != NULL); */ + /*NOTREACHED*/ } return (fip); --- tiff-v3.6.1/libtiff/tif_fax3.c.cve-2006-3459-thru-3464 2006-07-27 07:00:36.221976426 -0600 +++ tiff-v3.6.1/libtiff/tif_fax3.c 2006-07-27 07:00:36.245972094 -0600 @@ -1137,6 +1137,7 @@ static int Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap) { Fax3BaseState* sp = Fax3State(tif); + const TIFFFieldInfo* fip; assert(sp != 0); assert(sp->vsetparent != 0); @@ -1173,7 +1174,13 @@ Fax3VSetField(TIFF* tif, ttag_t tag, va_ default: return (*sp->vsetparent)(tif, tag, ap); } - TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); + + if ((fip = _TIFFFieldWithTag(tif, tag))) { + TIFFSetFieldBit(tif, fip->field_bit); + } else { + return (0); + } + tif->tif_flags |= TIFF_DIRTYDIRECT; return (1); } --- tiff-v3.6.1/libtiff/tif_dirread.c.cve-2006-3459-thru-3464 2006-07-27 07:00:36.226975523 -0600 +++ tiff-v3.6.1/libtiff/tif_dirread.c 2006-07-27 07:09:12.789682696 -0600 @@ -29,6 +29,9 @@ * * Directory Read Support Routines. */ + +#include <limits.h> + #include "tiffiop.h" #define IGNORE 0 /* tag placeholder used below */ @@ -103,6 +106,7 @@ TIFFReadDirectory(TIFF* tif) toff_t nextdiroff; char* cp; int diroutoforderwarning = 0; + int compressionknown = 0; tif->tif_diroff = tif->tif_nextdiroff; if (tif->tif_diroff == 0) /* no more directories */ @@ -166,7 +170,8 @@ TIFFReadDirectory(TIFF* tif) } else { toff_t off = tif->tif_diroff; - if (off + sizeof (uint16) > tif->tif_size) { + if (off + sizeof (uint16) > tif->tif_size || + off > (UINT_MAX - sizeof(uint16))) { TIFFError(module, "%.1000s: Can not read TIFF directory count", tif->tif_name); @@ -279,6 +284,7 @@ TIFFReadDirectory(TIFF* tif) while (fix < tif->tif_nfields && tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) fix++; + if (fix >= tif->tif_nfields || tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) { @@ -286,11 +292,11 @@ TIFFReadDirectory(TIFF* tif) "%.1000s: unknown field with tag %d (0x%x) encountered", tif->tif_name, dp->tdir_tag, dp->tdir_tag); + if (compressionknown) TIFFMergeFieldInfo( tif, - _TIFFCreateAnonFieldInfo( tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type ), - 1 ); + _TIFFCreateAnonFieldInfo( tif, dp->tdir_tag, + (TIFFDataType) dp->tdir_type ), 1 ); + else goto ignore; fix = 0; while (fix < tif->tif_nfields && tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) @@ -345,6 +351,7 @@ TIFFReadDirectory(TIFF* tif) dp->tdir_type, dp->tdir_offset); if (!TIFFSetField(tif, dp->tdir_tag, (int)v)) goto bad; + else compressionknown++; break; } if (!TIFFFetchPerSampleShorts(tif, dp, &iv) || @@ -545,6 +552,7 @@ TIFFReadDirectory(TIFF* tif) * Attempt to deal with a missing StripByteCounts tag. */ if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) { + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS); /* * Some manufacturers violate the spec by not giving * the size of the strips. In this case, assume there @@ -561,7 +569,7 @@ TIFFReadDirectory(TIFF* tif) "%.1000s: TIFF directory is missing required " "\"%s\" field, calculating from imagelength", tif->tif_name, - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); + fip ? fip->field_name : "Unknown"); if (EstimateStripByteCounts(tif, dir, dircount) < 0) goto bad; /* @@ -573,8 +581,15 @@ TIFFReadDirectory(TIFF* tif) #define BYTECOUNTLOOKSBAD \ ( (td->td_stripbytecount[0] == 0 && td->td_stripoffset[0] != 0) || \ (td->td_compression == COMPRESSION_NONE && \ - td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]) ) - } else if (td->td_nstrips == 1 && BYTECOUNTLOOKSBAD) { + td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]) || \ + (tif->tif_mode == O_RDONLY && \ + td->td_compression == COMPRESSION_NONE && \ + td->td_stripbytecount[0] < TIFFScanlineSize(tif) * td->td_imagelength) ) + + } else if (td->td_nstrips == 1 + && td->td_stripoffset[0] != 0 + && BYTECOUNTLOOKSBAD) { + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS); /* * Plexus (and others) sometimes give a value * of zero for a tag when they don't know what @@ -585,7 +600,23 @@ TIFFReadDirectory(TIFF* tif) TIFFWarning(module, "%.1000s: Bogus \"%s\" field, ignoring and calculating from imagelength", tif->tif_name, - _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); + fip ? fip->field_name : "Unknown"); + if(EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + } else if (td->td_planarconfig == PLANARCONFIG_CONTIG + && td->td_nstrips > 2 + && td->td_compression == COMPRESSION_NONE + && td->td_stripbytecount[0] != td->td_stripbytecount[1]) { + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS); + /* + * XXX: Some vendors fill StripByteCount array with absolutely + * wrong values (it can be equal to StripOffset array, for + * example). Catch this case here. + */ + TIFFWarning(module, + "%s: Wrong \"%s\" field, ignoring and calculating from imagelength", + tif->tif_name, + fip ? fip->field_name : "Unknown"); if(EstimateStripByteCounts(tif, dir, dircount) < 0) goto bad; } @@ -655,7 +686,8 @@ EstimateStripByteCounts(TIFF* tif, TIFFD register TIFFDirEntry *dp; register TIFFDirectory *td = &tif->tif_dir; - uint16 i; + + uint32 i; if (td->td_stripbytecount) _TIFFfree(td->td_stripbytecount); @@ -732,10 +764,12 @@ MissingRequired(TIFF* tif, const char* t static int CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) { + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); + if (count != dir->tdir_count) { TIFFWarning(tif->tif_name, "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, + fip ? fip->field_name : "Unknown", dir->tdir_count, count); return (0); } @@ -749,6 +783,7 @@ static tsize_t TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp) { int w = TIFFDataWidth((TIFFDataType) dir->tdir_type); + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); tsize_t cc = dir->tdir_count * w; /* Check for overflow. */ @@ -791,7 +826,7 @@ TIFFFetchData(TIFF* tif, TIFFDirEntry* d return (cc); bad: TIFFError(tif->tif_name, "Error fetching data for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + fip ? fip->field_name : "Unknown"); return ((tsize_t) 0); } @@ -817,10 +852,12 @@ TIFFFetchString(TIFF* tif, TIFFDirEntry* static int cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv) { + const TIFFFieldInfo* fip; if (denom == 0) { + fip = _TIFFFieldWithTag(tif, dir->tdir_tag); TIFFError(tif->tif_name, "%s: Rational with zero denominator (num = %lu)", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num); + fip ? fip->field_name : "Unknown", num); return (0); } else { if (dir->tdir_type == TIFF_RATIONAL) @@ -938,6 +975,15 @@ TIFFFetchShortPair(TIFF* tif, TIFFDirEnt uint16 v[4]; int ok = 0; + if (dir->tdir_count > 2) { + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFWarning(tif->tif_name, + "unexpected count for field \"%s\", %lu, expected 2; ignored.", + fip ? fip->field_name : "Unknown", + dir->tdir_count); + return 0; + } + switch (dir->tdir_type) { case TIFF_SHORT: case TIFF_SSHORT: @@ -1103,14 +1149,15 @@ TIFFFetchAnyArray(TIFF* tif, TIFFDirEntr case TIFF_DOUBLE: return (TIFFFetchDoubleArray(tif, dir, (double*) v)); default: + { const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); /* TIFF_NOTYPE */ /* TIFF_ASCII */ /* TIFF_UNDEFINED */ TIFFError(tif->tif_name, "cannot read TIFF_ANY type %d for field \"%s\"", dir->tdir_type, - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); - return (0); + fip ? fip->field_name : "Unknown"); + return (0); } } return (1); } @@ -1124,6 +1171,10 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEnt static const char mesg[] = "to fetch tag value"; int ok = 0; const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag); + + if (fip == NULL) { + return (0); + } /* * another potential crash case */ @@ -1270,6 +1321,7 @@ static int TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl) { int samples = tif->tif_dir.td_samplesperpixel; + const TIFFFieldInfo* fip; int status = 0; if (CheckDirCount(tif, dir, (uint32) samples)) { @@ -1287,9 +1339,10 @@ TIFFFetchPerSampleShorts(TIFF* tif, TIFF for (i = 1; i < check_count; i++) if (v[i] != v[0]) { + fip = _TIFFFieldWithTag(tif, dir->tdir_tag); TIFFError(tif->tif_name, "Cannot handle different per-sample values for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + fip ? fip->field_name : "Unknown"); goto bad; } *pl = v[0]; @@ -1311,6 +1364,7 @@ static int TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl) { int samples = (int) tif->tif_dir.td_samplesperpixel; + const TIFFFieldInfo* fip; int status = 0; if (CheckDirCount(tif, dir, (uint32) samples)) { @@ -1328,9 +1382,10 @@ TIFFFetchPerSampleAnys(TIFF* tif, TIFFDi for (i = 1; i < check_count; i++) if (v[i] != v[0]) { + fip = _TIFFFieldWithTag(tif, dir->tdir_tag); TIFFError(tif->tif_name, "Cannot handle different per-sample values for field \"%s\"", - _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + fip ? fip->field_name : "Unknown"); goto bad; } *pl = v[0];