rpms/libtiff/devel libtiff-3.8.2-ormandy.patch, NONE, 1.1 libtiff.spec, 1.45, 1.46

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Tue Aug 1 20:28:00 UTC 2006


Author: mclasen

Update of /cvs/dist/rpms/libtiff/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv3577

Modified Files:
	libtiff.spec 
Added Files:
	libtiff-3.8.2-ormandy.patch 
Log Message:
fix several vulnerabilities


libtiff-3.8.2-ormandy.patch:
 tif_dir.c      |   25 +++++++++----
 tif_dirinfo.c  |    6 ++-
 tif_dirread.c  |  107 +++++++++++++++++++++++++++++++++++++++++++--------------
 tif_fax3.c     |    9 ++++
 tif_jpeg.c     |   64 +++++++++++++++++++++++++++++-----
 tif_next.c     |    7 +++
 tif_pixarlog.c |   14 ++++++-
 tif_read.c     |   18 ++++++++-
 8 files changed, 202 insertions(+), 48 deletions(-)

--- NEW FILE libtiff-3.8.2-ormandy.patch ---
diff -ru tiff-3.8.2/libtiff/tif_dir.c tiff-3.8.2-goo/libtiff/tif_dir.c
--- tiff-3.8.2/libtiff/tif_dir.c	2006-03-21 16:42:50.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_dir.c	2006-07-14 13:52:01.027562000 +0100
@@ -122,6 +122,7 @@
 {
 	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 @@
 		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 @@
 	     * 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 at 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 @@
 	    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 @@
           }
 	}
 	if (status) {
-		TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
+		TIFFSetFieldBit(tif, fip->field_bit);
 		tif->tif_flags |= TIFF_DIRTYDIRECT;
 	}
 
@@ -572,12 +579,12 @@
 	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 @@
              * 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 at 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 -ru tiff-3.8.2/libtiff/tif_dirinfo.c tiff-3.8.2-goo/libtiff/tif_dirinfo.c
--- tiff-3.8.2/libtiff/tif_dirinfo.c	2006-02-07 13:51:03.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_dirinfo.c	2006-07-14 13:52:00.953558000 +0100
@@ -775,7 +775,8 @@
 		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 @@
 	if (!fip) {
 		TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
 			  "Internal error, unknown tag %s", field_name);
-		assert(fip != NULL);
+		/* assert(fip != NULL); */
+		
 		/*NOTREACHED*/
 	}
 	return (fip);
diff -ru tiff-3.8.2/libtiff/tif_dirread.c tiff-3.8.2-goo/libtiff/tif_dirread.c
--- tiff-3.8.2/libtiff/tif_dirread.c	2006-03-21 16:42:50.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_dirread.c	2006-07-14 13:52:00.842557000 +0100
@@ -29,6 +29,9 @@
  *
  * Directory Read Support Routines.
  */
+
+#include <limits.h>
+
 #include "tiffiop.h"
 
 #define	IGNORE	0		/* tag placeholder used below */
@@ -81,6 +84,7 @@
 	uint16 dircount;
 	toff_t nextdiroff;
 	int diroutoforderwarning = 0;
+	int compressionknown = 0;
 	toff_t* new_dirlist;
 
 	tif->tif_diroff = tif->tif_nextdiroff;
@@ -147,13 +151,20 @@
 	} else {
 		toff_t off = tif->tif_diroff;
 
-		if (off + sizeof (uint16) > tif->tif_size) {
-			TIFFErrorExt(tif->tif_clientdata, module,
-			    "%s: Can not read TIFF directory count",
-                            tif->tif_name);
-			return (0);
+		/*
+		 * Check for integer overflow when validating the dir_off, otherwise
+		 * a very high offset may cause an OOB read and crash the client.
+		 * -- taviso at google.com, 14 Jun 2006.
+		 */
+		if (off + sizeof (uint16) > tif->tif_size || 
+			off > (UINT_MAX - sizeof(uint16))) {
+				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 +265,7 @@
 		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 +276,23 @@
 						       dp->tdir_tag,
 						       dp->tdir_tag,
 						       dp->tdir_type);
-
-                    TIFFMergeFieldInfo(tif,
-                                       _TIFFCreateAnonFieldInfo(tif,
-						dp->tdir_tag,
-						(TIFFDataType) dp->tdir_type),
-				       1 );
+					/*
+					 * creating anonymous fields prior to knowing the compression
+					 * algorithm (ie, when the field info has been merged) could cause
+					 * crashes with pathological directories.
+					 * -- taviso at google.com 15 Jun 2006
+					 */
+					if (compressionknown)
+			                    TIFFMergeFieldInfo(tif, _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)
 			fix++;
 		}
+		
 		/*
 		 * Null out old tags that we ignore.
 		 */
@@ -326,6 +344,7 @@
 				    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 +559,7 @@
 	 * 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 +576,7 @@
 			"%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 +600,7 @@
 	} 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 +610,14 @@
 		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 +626,7 @@
 		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 +892,13 @@
 
 	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 at google.com 15 Jun 2006
+	 */
+
+	uint32 i;
 
 	if (td->td_stripbytecount)
 		_TIFFfree(td->td_stripbytecount);
@@ -947,16 +975,18 @@
 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 +1000,7 @@
 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 +1044,7 @@
 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 +1070,12 @@
 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 +1192,20 @@
 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 at 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 +1376,15 @@
 	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 +1399,9 @@
 	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 +1544,7 @@
 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 +1562,10 @@
 
             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 +1587,7 @@
 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 +1605,10 @@
                 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 +1629,7 @@
 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 +1647,10 @@
 
             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 -ru tiff-3.8.2/libtiff/tif_fax3.c tiff-3.8.2-goo/libtiff/tif_fax3.c
--- tiff-3.8.2/libtiff/tif_fax3.c	2006-03-21 16:42:50.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_fax3.c	2006-07-14 13:52:00.669557000 +0100
@@ -1136,6 +1136,7 @@
 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 @@
 	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 -ru tiff-3.8.2/libtiff/tif_jpeg.c tiff-3.8.2-goo/libtiff/tif_jpeg.c
--- tiff-3.8.2/libtiff/tif_jpeg.c	2006-03-21 16:42:50.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_jpeg.c	2006-07-14 13:52:00.655560000 +0100
@@ -722,15 +722,31 @@
 		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, 
                           segment_height,
                           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 at 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)) {
@@ -761,6 +777,22 @@
                                     sp->cinfo.d.comp_info[0].v_samp_factor,
                                     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 at 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
@@ -1521,15 +1553,18 @@
 {
 	JPEGState *sp = JState(tif);
 	
-	assert(sp != 0);
+	/* assert(sp != 0); */
 
 	tif->tif_tagmethods.vgetfield = sp->vgetparent;
 	tif->tif_tagmethods.vsetfield = sp->vsetparent;
 
-	if( sp->cinfo_initialized )
-	    TIFFjpeg_destroy(sp);	/* release libjpeg resources */
-	if (sp->jpegtables)		/* tag value */
-		_TIFFfree(sp->jpegtables);
+	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 @@
 {
 	JPEGState* sp = JState(tif);
 	TIFFDirectory* td = &tif->tif_dir;
+	const TIFFFieldInfo* fip;
 	uint32 v32;
 
 	assert(sp != NULL);
@@ -1606,7 +1642,13 @@
 	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 @@
 {
 	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 -ru tiff-3.8.2/libtiff/tif_next.c tiff-3.8.2-goo/libtiff/tif_next.c
--- tiff-3.8.2/libtiff/tif_next.c	2005-12-21 12:33:56.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_next.c	2006-07-14 13:52:00.556567000 +0100
@@ -105,11 +105,16 @@
 			 * 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 at google.com 14 Jun 2006.
+			 */
 			op = row;
 			for (;;) {
 				grey = (n>>6) & 0x3;
 				n &= 0x3f;
-				while (n-- > 0)
+				while (n-- > 0 && npixels < imagewidth)
 					SETPIXEL(op, grey);
 				if (npixels >= (int) imagewidth)
 					break;
diff -ru tiff-3.8.2/libtiff/tif_pixarlog.c tiff-3.8.2-goo/libtiff/tif_pixarlog.c
--- tiff-3.8.2/libtiff/tif_pixarlog.c	2006-03-21 16:42:50.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_pixarlog.c	2006-07-14 13:52:00.483557000 +0100
@@ -768,7 +768,19 @@
 	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 at 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 -ru tiff-3.8.2/libtiff/tif_read.c tiff-3.8.2-goo/libtiff/tif_read.c
--- tiff-3.8.2/libtiff/tif_read.c	2005-12-21 12:33:56.000000000 +0000
+++ tiff-3.8.2-goo/libtiff/tif_read.c	2006-07-14 13:52:00.467568000 +0100
@@ -31,6 +31,8 @@
 #include "tiffiop.h"
 #include <stdio.h>
 
+#include <limits.h>
+
 	int TIFFFillStrip(TIFF*, tstrip_t);
 	int TIFFFillTile(TIFF*, ttile_t);
 static	int TIFFStartStrip(TIFF*, tstrip_t);
@@ -272,7 +274,13 @@
 		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 at google.com 14 Jun 2006
+		 */
+		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.
@@ -470,7 +478,13 @@
 		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 at google.com 15 Jun 2006
+		 */
+		if (td->td_stripoffset[tile] + bytecount > tif->tif_size ||
+			bytecount > (UINT_MAX - td->td_stripoffset[tile])) {
 			tif->tif_curtile = NOTILE;
 			return (0);
 		}


Index: libtiff.spec
===================================================================
RCS file: /cvs/dist/rpms/libtiff/devel/libtiff.spec,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- libtiff.spec	12 Jul 2006 06:57:53 -0000	1.45
+++ libtiff.spec	1 Aug 2006 20:27:58 -0000	1.46
@@ -1,11 +1,12 @@
 Summary: Library of functions for manipulating TIFF format image files
 Name: libtiff
 Version: 3.8.2
-Release: 4.1
+Release: 5
 License: distributable
 Group: System Environment/Libraries
 Source: ftp://ftp.remotesensing.org/pub/libtiff/tiff-%{version}.tar.gz
 Patch0: tiffsplit-overflow.patch
+Patch1: libtiff-3.8.2-ormandy.patch
 URL: http://www.libtiff.org/
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 BuildRequires: zlib-devel libjpeg-devel
@@ -37,6 +38,7 @@
 %prep
 %setup -q -n tiff-%{version}
 %patch0 -p1 -b .overflow
+%patch1 -p1 -b .ormandy
 
 %build
 %configure
@@ -109,6 +111,10 @@
 %{_mandir}/man3/*
 
 %changelog
+* Mon Jul 24 2006 Matthias Clasen <mclasen at redhat.com>
+- Fix several vulnerabilities (CVE-2006-3460 CVE-2006-3461
+  CVE-2006-3462 CVE-2006-3463 CVE-2006-3464 CVE-2006-3465)
+
 * Wed Jul 12 2006 Jesse Keating <jkeating at redhat.com> - 3.8.2-4.1
 - rebuild
 




More information about the fedora-cvs-commits mailing list