summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsalo <salo@pkgsrc.org>2006-08-02 15:42:25 +0000
committersalo <salo@pkgsrc.org>2006-08-02 15:42:25 +0000
commit7708e440573f8f5b9a67461ac67890f6ea0bf12d (patch)
tree69ada8740c53c828d14c1f9d8db1345c8c00003c
parentc86b1f7bcf0fe43d46a3e6fa4446ed2de433e502 (diff)
downloadpkgsrc-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.
-rw-r--r--graphics/tiff/Makefile4
-rw-r--r--graphics/tiff/distinfo10
-rw-r--r--graphics/tiff/patches/patch-av96
-rw-r--r--graphics/tiff/patches/patch-aw26
-rw-r--r--graphics/tiff/patches/patch-ax308
-rw-r--r--graphics/tiff/patches/patch-ay29
-rw-r--r--graphics/tiff/patches/patch-az119
-rw-r--r--graphics/tiff/patches/patch-ba24
-rw-r--r--graphics/tiff/patches/patch-bb27
-rw-r--r--graphics/tiff/patches/patch-bc37
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);
+ }