SOURCES: libtiff-sec.patch - fixes for: CVE-2006-3459, CVE-2006-3...

adamg adamg at pld-linux.org
Sun Aug 6 22:06:05 CEST 2006


Author: adamg                        Date: Sun Aug  6 20:06:05 2006 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- fixes for:  CVE-2006-3459, CVE-2006-3460,  CVE-2006-3461, CVE-2006-3462, 
  CVE-2006-3463, CVE-2006-3464, CVE-2006-346

---- Files affected:
SOURCES:
   libtiff-sec.patch (1.1 -> 1.2) 

---- Diffs:

================================================================
Index: SOURCES/libtiff-sec.patch
diff -u SOURCES/libtiff-sec.patch:1.1 SOURCES/libtiff-sec.patch:1.2
--- SOURCES/libtiff-sec.patch:1.1	Wed Jul 26 13:40:56 2006
+++ SOURCES/libtiff-sec.patch	Sun Aug  6 22:06:00 2006
@@ -18,3 +18,672 @@
  			out = TIFFOpen(path, TIFFIsBigEndian(in)?"wb":"wl");
  			if (out == NULL)
  				return (-2);
+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.
<<Diff was trimmed, longer than 597 lines>>

---- CVS-web:
    http://cvs.pld-linux.org/SOURCES/libtiff-sec.patch?r1=1.1&r2=1.2&f=u



More information about the pld-cvs-commit mailing list