diff options
author | salo <salo@pkgsrc.org> | 2006-08-02 15:42:25 +0000 |
---|---|---|
committer | salo <salo@pkgsrc.org> | 2006-08-02 15:42:25 +0000 |
commit | 7708e440573f8f5b9a67461ac67890f6ea0bf12d (patch) | |
tree | 69ada8740c53c828d14c1f9d8db1345c8c00003c /graphics/tiff | |
parent | c86b1f7bcf0fe43d46a3e6fa4446ed2de433e502 (diff) | |
download | pkgsrc-7708e440573f8f5b9a67461ac67890f6ea0bf12d.tar.gz |
Security fixes for SA21304:
"Some vulnerabilities have been reported in libTIFF, which can be
exploited by malicious people to cause a DoS (Denial of Service)
or potentially compromise a vulnerable system.
The vulnerabilities are caused due to various heap and integer
overflows when processing TIFF images and can be exploited via
a specially crafted TIFF image.
Successful exploitation allows crashing applications linked against
libTIFF and may also allow execution of arbitrary code."
http://secunia.com/advisories/21304/
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3459
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3460
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3461
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3462
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3463
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3464
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3465
Patches from Tavis Ormandy, Google Security Team via SUSE.
Bump PKGREVISION.
Diffstat (limited to 'graphics/tiff')
-rw-r--r-- | graphics/tiff/Makefile | 4 | ||||
-rw-r--r-- | graphics/tiff/distinfo | 10 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-av | 96 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-aw | 26 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-ax | 308 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-ay | 29 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-az | 119 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-ba | 24 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-bb | 27 | ||||
-rw-r--r-- | graphics/tiff/patches/patch-bc | 37 |
10 files changed, 677 insertions, 3 deletions
diff --git a/graphics/tiff/Makefile b/graphics/tiff/Makefile index 968c1d9ba44..e22efd50998 100644 --- a/graphics/tiff/Makefile +++ b/graphics/tiff/Makefile @@ -1,7 +1,7 @@ -# $NetBSD: Makefile,v 1.83 2006/06/17 20:25:23 reed Exp $ +# $NetBSD: Makefile,v 1.84 2006/08/02 15:42:25 salo Exp $ DISTNAME= tiff-3.8.2 -PKGREVISION= 2 +PKGREVISION= 3 CATEGORIES= graphics MASTER_SITES= ftp://ftp.remotesensing.org/pub/libtiff/ \ http://libtiff.maptools.org/dl/ diff --git a/graphics/tiff/distinfo b/graphics/tiff/distinfo index d5be039a8e6..d4720ce8086 100644 --- a/graphics/tiff/distinfo +++ b/graphics/tiff/distinfo @@ -1,4 +1,4 @@ -$NetBSD: distinfo,v 1.38 2006/06/08 11:05:14 salo Exp $ +$NetBSD: distinfo,v 1.39 2006/08/02 15:42:25 salo Exp $ SHA1 (tiff-3.8.2.tar.gz) = 549e67b6a15b42bfcd72fe17cda7c9a198a393eb RMD160 (tiff-3.8.2.tar.gz) = 1b4d825e3be08764e953fc58246d0c25ab4dd17d @@ -7,3 +7,11 @@ SHA1 (patch-aa) = edac79a6f3b61e9fc787fe14f750d88023a29bfa SHA1 (patch-ab) = b517cb8bc2212d3e6c5a70db1bdf45b85b78fc72 SHA1 (patch-at) = 4006ed90f6ab88aff30e2537d613a1b44b5c7347 SHA1 (patch-au) = c53ed7521c3918081526ad63cd0c1c45c9a0b9ff +SHA1 (patch-av) = e1b8cec32b9706af0074c2a54bdd1fd2ea2b8e36 +SHA1 (patch-aw) = 8df07a9bc23092cfde2b364a1965efcfdc848b1e +SHA1 (patch-ax) = 1a111d7a80bf98a650d147c035cd719d34aafc8a +SHA1 (patch-ay) = db50f1d97b5d3b94e4d470b49642fe105977e0b7 +SHA1 (patch-az) = ec57ebacc6052221ae63084d23c7c7b4aea029d8 +SHA1 (patch-ba) = d4bd9c67a9bf2be93286f8268ac520c4b88ba3ae +SHA1 (patch-bb) = cbc7feda655a02809de55be6470cc25cda942a08 +SHA1 (patch-bc) = 9baa1c138cd3cb6366ae3e638518b94dfea172cc diff --git a/graphics/tiff/patches/patch-av b/graphics/tiff/patches/patch-av new file mode 100644 index 00000000000..3e70af3d269 --- /dev/null +++ b/graphics/tiff/patches/patch-av @@ -0,0 +1,96 @@ +$NetBSD: patch-av,v 1.5 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_dir.c.orig 2006-03-21 17:42:50.000000000 +0100 ++++ libtiff/tif_dir.c 2006-08-02 17:18:41.000000000 +0200 +@@ -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, i, v; +@@ -195,10 +196,12 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va + break; + case TIFFTAG_ORIENTATION: + v = va_arg(ap, uint32); ++ const TIFFFieldInfo* fip; + if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) { ++ fip = _TIFFFieldWithTag(tif, tag); + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "Bad value %lu for \"%s\" tag ignored", +- v, _TIFFFieldWithTag(tif, tag)->field_name); ++ v, fip ? fip->field_name : "Unknown"); + } else + td->td_orientation = (uint16) v; + break; +@@ -387,11 +390,15 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va + * happens, for example, when tiffcp is used to convert between + * compression schemes and codec-specific tags are blindly copied. + */ ++ /* ++ * better not dereference fip if it is NULL. ++ * -- taviso@google.com 15 Jun 2006 ++ */ + if(fip == NULL || fip->field_bit != FIELD_CUSTOM) { + TIFFErrorExt(tif->tif_clientdata, 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; + } +@@ -468,7 +475,7 @@ _TIFFVSetField(TIFF* tif, ttag_t tag, va + if (fip->field_type == TIFF_ASCII) + _TIFFsetString((char **)&tv->value, va_arg(ap, char *)); + else { +- tv->value = _TIFFmalloc(tv_size * tv->count); ++ tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count, "Tag Value"); + if (!tv->value) { + status = 0; + goto end; +@@ -563,7 +570,7 @@ _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; + } + +@@ -572,12 +579,12 @@ end: + return (status); + badvalue: + TIFFErrorExt(tif->tif_clientdata, module, "%s: 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: + TIFFErrorExt(tif->tif_clientdata, module, "%s: 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); + } +@@ -813,12 +820,16 @@ _TIFFVGetField(TIFF* tif, ttag_t tag, va + * If the client tries to get a tag that is not valid + * for the image's codec then we'll arrive here. + */ ++ /* ++ * dont dereference fip if it's NULL. ++ * -- taviso@google.com 15 Jun 2006 ++ */ + if( fip == NULL || fip->field_bit != FIELD_CUSTOM ) + { + TIFFErrorExt(tif->tif_clientdata, "_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; + } diff --git a/graphics/tiff/patches/patch-aw b/graphics/tiff/patches/patch-aw new file mode 100644 index 00000000000..06a32f949b9 --- /dev/null +++ b/graphics/tiff/patches/patch-aw @@ -0,0 +1,26 @@ +$NetBSD: patch-aw,v 1.5 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_dirinfo.c.orig 2006-02-07 14:51:03.000000000 +0100 ++++ libtiff/tif_dirinfo.c 2006-08-02 17:18:41.000000000 +0200 +@@ -775,7 +775,8 @@ _TIFFFieldWithTag(TIFF* tif, ttag_t tag) + TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag", + "Internal error, unknown tag 0x%x", + (unsigned int) tag); +- assert(fip != NULL); ++ /* assert(fip != NULL); */ ++ + /*NOTREACHED*/ + } + return (fip); +@@ -789,7 +790,8 @@ _TIFFFieldWithName(TIFF* tif, const char + if (!fip) { + TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName", + "Internal error, unknown tag %s", field_name); +- assert(fip != NULL); ++ /* assert(fip != NULL); */ ++ + /*NOTREACHED*/ + } + return (fip); diff --git a/graphics/tiff/patches/patch-ax b/graphics/tiff/patches/patch-ax new file mode 100644 index 00000000000..314c70fc336 --- /dev/null +++ b/graphics/tiff/patches/patch-ax @@ -0,0 +1,308 @@ +$NetBSD: patch-ax,v 1.5 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_dirread.c.orig 2006-03-21 17:42:50.000000000 +0100 ++++ libtiff/tif_dirread.c 2006-08-02 17:18:41.000000000 +0200 +@@ -81,6 +81,7 @@ TIFFReadDirectory(TIFF* tif) + uint16 dircount; + toff_t nextdiroff; + int diroutoforderwarning = 0; ++ int compressionknown = 0; + toff_t* new_dirlist; + + tif->tif_diroff = tif->tif_nextdiroff; +@@ -147,13 +148,20 @@ TIFFReadDirectory(TIFF* tif) + } else { + toff_t off = tif->tif_diroff; + +- if (off + sizeof (uint16) > tif->tif_size) { ++ /* ++ * Check for integer overflow when validating the dir_off, otherwise ++ * a very high offset may cause an OOB read and crash the client. ++ * -- taviso@google.com, 14 Jun 2006. ++ */ ++ if (off + sizeof (uint16) > tif->tif_size || ++ off + sizeof (uint16) < off) { + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return (0); + } else +- _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16)); ++ _TIFFmemcpy(&dircount, tif->tif_base + off, ++ sizeof (uint16)); + off += sizeof (uint16); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); +@@ -254,6 +262,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) { + +@@ -264,17 +273,23 @@ TIFFReadDirectory(TIFF* tif) + dp->tdir_tag, + dp->tdir_tag, + dp->tdir_type); ++ /* ++ * creating anonymous fields prior to knowing the compression ++ * algorithm (ie, when the field info has been merged) could cause ++ * crashes with pathological directories. ++ * -- taviso@google.com 15 Jun 2006 ++ */ ++ if (compressionknown) ++ TIFFMergeFieldInfo(tif, _TIFFCreateAnonFieldInfo(tif, dp->tdir_tag, ++ (TIFFDataType) dp->tdir_type), 1 ); ++ else goto ignore; + +- TIFFMergeFieldInfo(tif, +- _TIFFCreateAnonFieldInfo(tif, +- dp->tdir_tag, +- (TIFFDataType) dp->tdir_type), +- 1 ); + fix = 0; + while (fix < tif->tif_nfields && + tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) + fix++; + } ++ + /* + * Null out old tags that we ignore. + */ +@@ -326,6 +341,7 @@ TIFFReadDirectory(TIFF* tif) + dp->tdir_type, dp->tdir_offset); + if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v)) + goto bad; ++ else compressionknown++; + break; + /* XXX: workaround for broken TIFFs */ + } else if (dp->tdir_type == TIFF_LONG) { +@@ -540,6 +556,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 +@@ -556,7 +573,7 @@ TIFFReadDirectory(TIFF* tif) + "%s: 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; + /* +@@ -580,6 +597,7 @@ TIFFReadDirectory(TIFF* tif) + } else if (td->td_nstrips == 1 + && td->td_stripoffset[0] != 0 + && BYTECOUNTLOOKSBAD) { ++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, TIFFTAG_STRIPBYTECOUNTS); + /* + * XXX: Plexus (and others) sometimes give a value of zero for + * a tag when they don't know what the correct value is! Try +@@ -589,13 +607,14 @@ TIFFReadDirectory(TIFF* tif) + TIFFWarningExt(tif->tif_clientdata, module, + "%s: 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 +@@ -604,7 +623,7 @@ TIFFReadDirectory(TIFF* tif) + TIFFWarningExt(tif->tif_clientdata, module, + "%s: Wrong \"%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; + } +@@ -870,7 +889,13 @@ EstimateStripByteCounts(TIFF* tif, TIFFD + + register TIFFDirEntry *dp; + register TIFFDirectory *td = &tif->tif_dir; +- uint16 i; ++ ++ /* i is used to iterate over td->td_nstrips, so must be ++ * at least the same width. ++ * -- taviso@google.com 15 Jun 2006 ++ */ ++ ++ uint32 i; + + if (td->td_stripbytecount) + _TIFFfree(td->td_stripbytecount); +@@ -947,16 +972,18 @@ 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) { + TIFFWarningExt(tif->tif_clientdata, 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); + } else if (count < dir->tdir_count) { + TIFFWarningExt(tif->tif_clientdata, tif->tif_name, + "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed", +- _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, ++ fip ? fip->field_name : "Unknown", + dir->tdir_count, count); + return (1); + } +@@ -970,6 +997,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. */ +@@ -1013,7 +1041,7 @@ TIFFFetchData(TIFF* tif, TIFFDirEntry* d + bad: + TIFFErrorExt(tif->tif_clientdata, 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; + } + +@@ -1039,10 +1067,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); + TIFFErrorExt(tif->tif_clientdata, 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) +@@ -1159,6 +1189,20 @@ TIFFFetchShortArray(TIFF* tif, TIFFDirEn + static int + TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir) + { ++ /* ++ * Prevent overflowing the v stack arrays below by performing a sanity ++ * check on tdir_count, this should never be greater than two. ++ * -- taviso@google.com 14 Jun 2006. ++ */ ++ if (dir->tdir_count > 2) { ++ const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dir->tdir_tag); ++ TIFFWarningExt(tif->tif_clientdata, 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_BYTE: + case TIFF_SBYTE: +@@ -1329,14 +1373,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 */ + TIFFErrorExt(tif->tif_clientdata, 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); + } +@@ -1351,6 +1396,9 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEnt + int ok = 0; + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag); + ++ if (fip == NULL) { ++ return (0); ++ } + if (dp->tdir_count > 1) { /* array of values */ + char* cp = NULL; + +@@ -1493,6 +1541,7 @@ static int + TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, uint16* pl) + { + uint16 samples = tif->tif_dir.td_samplesperpixel; ++ const TIFFFieldInfo* fip; + int status = 0; + + if (CheckDirCount(tif, dir, (uint32) samples)) { +@@ -1510,9 +1559,10 @@ TIFFFetchPerSampleShorts(TIFF* tif, TIFF + + for (i = 1; i < check_count; i++) + if (v[i] != v[0]) { ++ fip = _TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFErrorExt(tif->tif_clientdata, 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]; +@@ -1534,6 +1584,7 @@ static int + TIFFFetchPerSampleLongs(TIFF* tif, TIFFDirEntry* dir, uint32* pl) + { + uint16 samples = tif->tif_dir.td_samplesperpixel; ++ const TIFFFieldInfo* fip; + int status = 0; + + if (CheckDirCount(tif, dir, (uint32) samples)) { +@@ -1551,9 +1602,10 @@ TIFFFetchPerSampleLongs(TIFF* tif, TIFFD + check_count = samples; + for (i = 1; i < check_count; i++) + if (v[i] != v[0]) { ++ fip = _TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFErrorExt(tif->tif_clientdata, 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]; +@@ -1574,6 +1626,7 @@ static int + TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl) + { + uint16 samples = tif->tif_dir.td_samplesperpixel; ++ const TIFFFieldInfo* fip; + int status = 0; + + if (CheckDirCount(tif, dir, (uint32) samples)) { +@@ -1591,9 +1644,10 @@ TIFFFetchPerSampleAnys(TIFF* tif, TIFFDi + + for (i = 1; i < check_count; i++) + if (v[i] != v[0]) { ++ fip = _TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFErrorExt(tif->tif_clientdata, 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]; diff --git a/graphics/tiff/patches/patch-ay b/graphics/tiff/patches/patch-ay new file mode 100644 index 00000000000..67f3f662e35 --- /dev/null +++ b/graphics/tiff/patches/patch-ay @@ -0,0 +1,29 @@ +$NetBSD: patch-ay,v 1.3 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_fax3.c.orig 2006-03-21 17:42:50.000000000 +0100 ++++ libtiff/tif_fax3.c 2006-08-02 17:18:41.000000000 +0200 +@@ -1136,6 +1136,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); +@@ -1181,7 +1182,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); + } diff --git a/graphics/tiff/patches/patch-az b/graphics/tiff/patches/patch-az new file mode 100644 index 00000000000..8face0b7944 --- /dev/null +++ b/graphics/tiff/patches/patch-az @@ -0,0 +1,119 @@ +$NetBSD: patch-az,v 1.1 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_jpeg.c.orig 2006-03-21 17:42:50.000000000 +0100 ++++ libtiff/tif_jpeg.c 2006-08-02 17:18:41.000000000 +0200 +@@ -722,8 +722,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) { + TIFFWarningExt(tif->tif_clientdata, module, + "Improper JPEG strip/tile size, expected %dx%d, got %dx%d", + segment_width, +@@ -731,6 +731,22 @@ 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) { ++ /* ++ * This case could be dangerous, if the strip or tile size has been ++ * reported as less than the amount of data jpeg will return, some ++ * potential security issues arise. Catch this case and error out. ++ * -- taviso@google.com 14 Jun 2006 ++ */ ++ TIFFErrorExt(tif->tif_clientdata, 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)) { +@@ -762,6 +778,22 @@ JPEGPreDecode(TIFF* tif, tsample_t s) + sp->h_sampling, sp->v_sampling); + + /* ++ * There are potential security issues here for decoders that ++ * have already allocated buffers based on the expected sampling ++ * factors. Lets check the sampling factors dont exceed what ++ * we were expecting. ++ * -- taviso@google.com 14 June 2006 ++ */ ++ 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) { ++ TIFFErrorExt(tif->tif_clientdata, module, ++ "Cannot honour JPEG sampling factors that" ++ " exceed those specified."); ++ return (0); ++ } ++ ++ ++ /* + * XXX: Files written by the Intergraph software + * has different sampling factors stored in the + * TIFF tags and in the JPEG structures. We will +@@ -1521,15 +1553,18 @@ 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; + +@@ -1541,6 +1576,7 @@ JPEGVSetField(TIFF* tif, ttag_t tag, va_ + { + JPEGState* sp = JState(tif); + TIFFDirectory* td = &tif->tif_dir; ++ const TIFFFieldInfo* fip; + uint32 v32; + + assert(sp != NULL); +@@ -1606,7 +1642,13 @@ JPEGVSetField(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); + } +@@ -1726,7 +1768,11 @@ JPEGPrintDir(TIFF* tif, FILE* fd, long f + { + JPEGState* sp = JState(tif); + +- assert(sp != NULL); ++ /* assert(sp != NULL); */ ++ if (sp == NULL) { ++ TIFFWarningExt(tif->tif_clientdata, "JPEGPrintDir", "Unknown JPEGState"); ++ return; ++ } + + (void) flags; + if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) diff --git a/graphics/tiff/patches/patch-ba b/graphics/tiff/patches/patch-ba new file mode 100644 index 00000000000..a7959582c7e --- /dev/null +++ b/graphics/tiff/patches/patch-ba @@ -0,0 +1,24 @@ +$NetBSD: patch-ba,v 1.1 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_next.c.orig 2005-12-21 13:33:56.000000000 +0100 ++++ libtiff/tif_next.c 2006-08-02 17:18:41.000000000 +0200 +@@ -105,11 +105,16 @@ NeXTDecode(TIFF* tif, tidata_t buf, tsiz + * as codes of the form <color><npixels> + * until we've filled the scanline. + */ ++ /* ++ * Ensure the run does not exceed the scanline ++ * bounds, potentially resulting in a security issue. ++ * -- taviso@google.com 14 Jun 2006. ++ */ + op = row; + for (;;) { + grey = (n>>6) & 0x3; + n &= 0x3f; +- while (n-- > 0) ++ while (n-- > 0 && npixels < scanline) + SETPIXEL(op, grey); + if (npixels >= (int) imagewidth) + break; diff --git a/graphics/tiff/patches/patch-bb b/graphics/tiff/patches/patch-bb new file mode 100644 index 00000000000..51e920f1f78 --- /dev/null +++ b/graphics/tiff/patches/patch-bb @@ -0,0 +1,27 @@ +$NetBSD: patch-bb,v 1.1 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_pixarlog.c.orig 2006-03-21 17:42:50.000000000 +0100 ++++ libtiff/tif_pixarlog.c 2006-08-02 17:18:41.000000000 +0200 +@@ -768,7 +768,19 @@ 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 llen is not an exact multiple of nsamples, the decode operation ++ * may overflow the output buffer, so truncate it enough to prevent that ++ * but still salvage as much data as possible. ++ * -- taviso@google.com 14th June 2006 ++ */ ++ if (nsamples % llen) ++ TIFFWarningExt(tif->tif_clientdata, 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, diff --git a/graphics/tiff/patches/patch-bc b/graphics/tiff/patches/patch-bc new file mode 100644 index 00000000000..64998563e4f --- /dev/null +++ b/graphics/tiff/patches/patch-bc @@ -0,0 +1,37 @@ +$NetBSD: patch-bc,v 1.1 2006/08/02 15:42:25 salo Exp $ + +Security fix for SA21304. + +--- libtiff/tif_read.c.orig 2005-12-21 13:33:56.000000000 +0100 ++++ libtiff/tif_read.c 2006-08-02 17:18:41.000000000 +0200 +@@ -272,7 +272,13 @@ 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) { ++ /* ++ * This sanity check could potentially overflow, causing an OOB read. ++ * verify that offset + bytecount is > offset. ++ * -- taviso@google.com 14 Jun 2006 ++ */ ++ if ( td->td_stripoffset[strip] + bytecount > tif->tif_size || ++ (td->td_stripoffset[strip] + bytecount) < td->td_stripoffset[strip]) { + /* + * This error message might seem strange, but it's + * what would happen if a read were done instead. +@@ -470,7 +476,14 @@ 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) { ++ /* ++ * We must check this calculation doesnt overflow, potentially ++ * causing an OOB read. ++ * -- taviso@google.com 15 Jun 2006 ++ */ ++ if ( td->td_stripoffset[tile] + bytecount > tif->tif_size || ++ (td->td_stripoffset[tile] + bytecount) < ++ td->td_stripoffset[tile]) { + tif->tif_curtile = NOTILE; + return (0); + } |