[libtiff] Update to libtiff 4.0.2

Tom Lane tgl at fedoraproject.org
Thu Jun 28 15:24:25 UTC 2012


commit 396b449b01818e506369d3a3721f166efd0fcdfa
Author: Tom Lane <tgl at redhat.com>
Date:   Thu Jun 28 11:24:16 2012 -0400

    Update to libtiff 4.0.2

 .gitignore                  |    4 +-
 libtiff-CVE-2012-1173.patch |   93 ----------------
 libtiff-CVE-2012-2088.patch |  129 ++++++++++++++++++++++
 libtiff-CVE-2012-2113.patch |  246 +++++++++++++++++++++++++++++++++++++++++++
 libtiff.spec                |   22 +++--
 sources                     |    4 +-
 6 files changed, 394 insertions(+), 104 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 3703381..f950744 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-/tiff-4.0.1.tar.gz
-/tiff-3.9.5.tar.gz
+/tiff-4.0.2.tar.gz
+/tiff-3.9.6.tar.gz
diff --git a/libtiff-CVE-2012-2088.patch b/libtiff-CVE-2012-2088.patch
new file mode 100644
index 0000000..f7f7998
--- /dev/null
+++ b/libtiff-CVE-2012-2088.patch
@@ -0,0 +1,129 @@
+Do strip and tile size calculations in unsigned arithmetic, and then
+complain if the result overflows signed int32, because callers of these
+functions expect signed results (tsize_t is signed).  CVE-2012-2088
+
+
+diff -Naur tiff-3.9.6.orig/libtiff/tif_strip.c tiff-3.9.6/libtiff/tif_strip.c
+--- tiff-3.9.6.orig/libtiff/tif_strip.c	2011-01-03 23:31:28.000000000 -0500
++++ tiff-3.9.6/libtiff/tif_strip.c	2012-06-28 11:10:17.898083177 -0400
+@@ -107,6 +107,7 @@
+ TIFFVStripSize(TIFF* tif, uint32 nrows)
+ {
+ 	TIFFDirectory *td = &tif->tif_dir;
++	uint32 stripsize;
+ 
+ 	if (nrows == (uint32) -1)
+ 		nrows = td->td_imagelength;
+@@ -122,7 +123,7 @@
+ 		 * YCbCr data for the extended image.
+ 		 */
+ 		uint16 ycbcrsubsampling[2];
+-		tsize_t w, scanline, samplingarea;
++		uint32 w, scanline, samplingarea;
+ 
+ 		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
+ 				      ycbcrsubsampling + 0,
+@@ -141,13 +142,27 @@
+ 		nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
+ 		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
+ 		scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
+-		return ((tsize_t)
+-		    summarize(tif, scanline,
+-			      multiply(tif, 2, scanline / samplingarea,
+-				       "TIFFVStripSize"), "TIFFVStripSize"));
++		/* a zero anywhere in here means overflow, must return zero */
++		if (scanline > 0) {
++			uint32 extra =
++			    multiply(tif, 2, scanline / samplingarea,
++				     "TIFFVStripSize");
++			if (extra > 0)
++				stripsize = summarize(tif, scanline, extra,
++						      "TIFFVStripSize");
++			else
++				stripsize = 0;
++		} else
++			stripsize = 0;
+ 	} else
+-		return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif),
+-					   "TIFFVStripSize"));
++		stripsize = multiply(tif, nrows, TIFFScanlineSize(tif),
++				     "TIFFVStripSize");
++	/* Because tsize_t is signed, we might have conversion overflow */
++	if (((tsize_t) stripsize) < 0) {
++		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", "TIFFVStripSize");
++		stripsize = 0;
++	}
++	return (tsize_t) stripsize;
+ }
+ 
+ 
+diff -Naur tiff-3.9.6.orig/libtiff/tif_tile.c tiff-3.9.6/libtiff/tif_tile.c
+--- tiff-3.9.6.orig/libtiff/tif_tile.c	2010-06-08 14:50:43.000000000 -0400
++++ tiff-3.9.6/libtiff/tif_tile.c	2012-06-28 11:10:17.899083079 -0400
+@@ -174,7 +174,7 @@
+ TIFFTileRowSize(TIFF* tif)
+ {
+ 	TIFFDirectory *td = &tif->tif_dir;
+-	tsize_t rowsize;
++	uint32 rowsize;
+ 	
+ 	if (td->td_tilelength == 0 || td->td_tilewidth == 0)
+ 		return ((tsize_t) 0);
+@@ -193,7 +193,7 @@
+ TIFFVTileSize(TIFF* tif, uint32 nrows)
+ {
+ 	TIFFDirectory *td = &tif->tif_dir;
+-	tsize_t tilesize;
++	uint32 tilesize;
+ 
+ 	if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
+ 	    td->td_tiledepth == 0)
+@@ -209,12 +209,12 @@
+ 		 * horizontal/vertical subsampling area include
+ 		 * YCbCr data for the extended image.
+ 		 */
+-		tsize_t w =
++		uint32 w =
+ 		    TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]);
+-		tsize_t rowsize =
++		uint32 rowsize =
+ 		    TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
+ 					  "TIFFVTileSize"));
+-		tsize_t samplingarea =
++		uint32 samplingarea =
+ 		    td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1];
+ 		if (samplingarea == 0) {
+ 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Invalid YCbCr subsampling");
+@@ -223,15 +223,27 @@
+ 		nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]);
+ 		/* NB: don't need TIFFhowmany here 'cuz everything is rounded */
+ 		tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize");
+-		tilesize = summarize(tif, tilesize,
+-				     multiply(tif, 2, tilesize / samplingarea,
+-					      "TIFFVTileSize"),
++		/* a zero anywhere in here means overflow, must return zero */
++		if (tilesize > 0) {
++			uint32 extra =
++			    multiply(tif, 2, tilesize / samplingarea,
+ 				     "TIFFVTileSize");
++			if (extra > 0)
++				tilesize = summarize(tif, tilesize, extra,
++						     "TIFFVTileSize");
++			else
++				tilesize = 0;
++		}
+ 	} else
+ 		tilesize = multiply(tif, nrows, TIFFTileRowSize(tif),
+ 				    "TIFFVTileSize");
+-	return ((tsize_t)
+-	    multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize"));
++	tilesize = multiply(tif, tilesize, td->td_tiledepth, "TIFFVTileSize");
++	/* Because tsize_t is signed, we might have conversion overflow */
++	if (((tsize_t) tilesize) < 0) {
++		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", "TIFFVTileSize");
++		tilesize = 0;
++	}
++	return (tsize_t) tilesize;
+ }
+ 
+ /*
diff --git a/libtiff-CVE-2012-2113.patch b/libtiff-CVE-2012-2113.patch
new file mode 100644
index 0000000..d70e5b6
--- /dev/null
+++ b/libtiff-CVE-2012-2113.patch
@@ -0,0 +1,246 @@
+Defend against integer overflow in buffer size calculations within tiff2pdf.
+(This is committed upstream, but is not yet in any 3.9.x release.)
+CVE-2012-2113
+
+
+diff -Naur tiff-3.9.6.orig/tools/tiff2pdf.c tiff-3.9.6/tools/tiff2pdf.c
+--- tiff-3.9.6.orig/tools/tiff2pdf.c	2010-12-13 20:45:51.000000000 -0500
++++ tiff-3.9.6/tools/tiff2pdf.c	2012-06-28 11:07:27.219923327 -0400
+@@ -431,6 +431,34 @@
+ 	(void) handle, (void) data, (void) offset;
+ }
+ 
++static uint64
++checkAdd64(uint64 summand1, uint64 summand2, T2P* t2p)
++{
++	uint64 bytes = summand1 + summand2;
++
++	if (bytes - summand1 != summand2) {
++		TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++		t2p->t2p_error = T2P_ERR_ERROR;
++		bytes = 0;
++	}
++
++	return bytes;
++}
++
++static uint64
++checkMultiply64(uint64 first, uint64 second, T2P* t2p)
++{
++	uint64 bytes = first * second;
++
++	if (second && bytes / second != first) {
++		TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++		t2p->t2p_error = T2P_ERR_ERROR;
++		bytes = 0;
++	}
++
++	return bytes;
++}
++
+ /*
+ 
+   This is the main function.
+@@ -1773,9 +1801,7 @@
+ 	tstrip_t i=0;
+ 	tstrip_t stripcount=0;
+ #endif
+-#ifdef OJPEG_SUPPORT
+-        tsize_t k = 0;
+-#endif
++        uint64 k = 0;
+ 
+ 	if(t2p->pdf_transcode == T2P_TRANSCODE_RAW){
+ #ifdef CCITT_SUPPORT
+@@ -1803,19 +1829,25 @@
+ 			}
+ 			stripcount=TIFFNumberOfStrips(input);
+ 			for(i=0;i<stripcount;i++){
+-				k += sbc[i];
++				k = checkAdd64(k, sbc[i], t2p);
+ 			}
+ 			if(TIFFGetField(input, TIFFTAG_JPEGIFOFFSET, &(t2p->tiff_dataoffset))){
+ 				if(t2p->tiff_dataoffset != 0){
+ 					if(TIFFGetField(input, TIFFTAG_JPEGIFBYTECOUNT, &(t2p->tiff_datasize))!=0){
+ 						if(t2p->tiff_datasize < k) {
+-							t2p->pdf_ojpegiflength=t2p->tiff_datasize;
+-							t2p->tiff_datasize+=k;
+-							t2p->tiff_datasize+=6;
+-							t2p->tiff_datasize+=2*stripcount;
+ 							TIFFWarning(TIFF2PDF_MODULE, 
+ 								"Input file %s has short JPEG interchange file byte count", 
+ 								TIFFFileName(input));
++							t2p->pdf_ojpegiflength=t2p->tiff_datasize;
++							k = checkAdd64(k, t2p->tiff_datasize, t2p);
++							k = checkAdd64(k, 6, t2p);
++							k = checkAdd64(k, stripcount, t2p);
++							k = checkAdd64(k, stripcount, t2p);
++							t2p->tiff_datasize = (tsize_t) k;
++							if ((uint64) t2p->tiff_datasize != k) {
++								TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++								t2p->t2p_error = T2P_ERR_ERROR;
++							}
+ 							return;
+ 						}
+ 						return;
+@@ -1828,9 +1860,14 @@
+ 					}
+ 				}
+ 			}
+-			t2p->tiff_datasize+=k;
+-			t2p->tiff_datasize+=2*stripcount;
+-			t2p->tiff_datasize+=2048;
++			k = checkAdd64(k, stripcount, t2p);
++			k = checkAdd64(k, stripcount, t2p);
++			k = checkAdd64(k, 2048, t2p);
++			t2p->tiff_datasize = (tsize_t) k;
++			if ((uint64) t2p->tiff_datasize != k) {
++				TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++				t2p->t2p_error = T2P_ERR_ERROR;
++			}
+ 			return;
+ 		}
+ #endif
+@@ -1839,11 +1876,11 @@
+ 			uint32 count = 0;
+ 			if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0 ){
+ 				if(count > 4){
+-					t2p->tiff_datasize += count;
+-					t2p->tiff_datasize -= 2; /* don't use EOI of header */
++					k += count;
++					k -= 2; /* don't use EOI of header */
+ 				}
+ 			} else {
+-				t2p->tiff_datasize = 2; /* SOI for first strip */
++				k = 2; /* SOI for first strip */
+ 			}
+ 			stripcount=TIFFNumberOfStrips(input);
+ 			if(!TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc)){
+@@ -1854,18 +1891,33 @@
+ 				return;
+ 			}
+ 			for(i=0;i<stripcount;i++){
+-				t2p->tiff_datasize += sbc[i];
+-				t2p->tiff_datasize -=4; /* don't use SOI or EOI of strip */
++				k = checkAdd64(k, sbc[i], t2p);
++				k -=4; /* don't use SOI or EOI of strip */
++			}
++			k = checkAdd64(k, 2, t2p); /* use EOI of last strip */
++			t2p->tiff_datasize = (tsize_t) k;
++			if ((uint64) t2p->tiff_datasize != k) {
++				TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++				t2p->t2p_error = T2P_ERR_ERROR;
+ 			}
+-			t2p->tiff_datasize +=2; /* use EOI of last strip */
+ 			return;
+ 		}
+ #endif
+ 		(void) 0;
+ 	}
+-	t2p->tiff_datasize=TIFFScanlineSize(input) * t2p->tiff_length;
++	k = checkMultiply64(TIFFScanlineSize(input), t2p->tiff_length, t2p);
+ 	if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){
+-		t2p->tiff_datasize*= t2p->tiff_samplesperpixel;
++		k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p);
++	}
++	if (k == 0) {
++		/* Assume we had overflow inside TIFFScanlineSize */
++		t2p->t2p_error = T2P_ERR_ERROR;
++	}
++
++	t2p->tiff_datasize = (tsize_t) k;
++	if ((uint64) t2p->tiff_datasize != k) {
++		TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++		t2p->t2p_error = T2P_ERR_ERROR;
+ 	}
+ 
+ 	return;
+@@ -1883,6 +1935,7 @@
+ #ifdef JPEG_SUPPORT
+ 	unsigned char* jpt;
+ #endif
++        uint64 k;
+ 
+ 	edge |= t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile);
+ 	edge |= t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile);
+@@ -1894,14 +1947,17 @@
+ #endif
+ 		){
+ 			t2p->tiff_datasize=TIFFTileSize(input);
++			if (t2p->tiff_datasize == 0) {
++				/* Assume we had overflow inside TIFFTileSize */
++				t2p->t2p_error = T2P_ERR_ERROR;
++			}
+ 			return;
+ 		} else {
+ 			TIFFGetField(input, TIFFTAG_TILEBYTECOUNTS, &tbc);
+-			t2p->tiff_datasize=tbc[tile];
++			k=tbc[tile];
+ #ifdef OJPEG_SUPPORT
+ 			if(t2p->tiff_compression==COMPRESSION_OJPEG){
+-				t2p->tiff_datasize+=2048;
+-				return;
++			  	k = checkAdd64(k, 2048, t2p);
+ 			}
+ #endif
+ #ifdef JPEG_SUPPORT
+@@ -1909,18 +1965,33 @@
+ 				uint32 count = 0;
+ 				if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt)!=0){
+ 					if(count > 4){
+-						t2p->tiff_datasize += count;
+-						t2p->tiff_datasize -= 2; /* don't use EOI of header or SOI of tile */
++						k = checkAdd64(k, count, t2p);
++						k -= 2; /* don't use EOI of header or SOI of tile */
+ 					}
+ 				}
+ 			}
+ #endif
++			t2p->tiff_datasize = (tsize_t) k;
++			if ((uint64) t2p->tiff_datasize != k) {
++				TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++				t2p->t2p_error = T2P_ERR_ERROR;
++			}
+ 			return;
+ 		}
+ 	}
+-	t2p->tiff_datasize=TIFFTileSize(input);
++	k = TIFFTileSize(input);
+ 	if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){
+-		t2p->tiff_datasize*= t2p->tiff_samplesperpixel;
++		k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p);
++	}
++	if (k == 0) {
++		/* Assume we had overflow inside TIFFTileSize */
++		t2p->t2p_error = T2P_ERR_ERROR;
++	}
++
++	t2p->tiff_datasize = (tsize_t) k;
++	if ((uint64) t2p->tiff_datasize != k) {
++		TIFFError(TIFF2PDF_MODULE, "Integer overflow");
++		t2p->t2p_error = T2P_ERR_ERROR;
+ 	}
+ 
+ 	return;
+@@ -2013,6 +2084,10 @@
+ 	uint32 max_striplength=0;
+ #endif
+ 
++	/* Fail if prior error (in particular, can't trust tiff_datasize) */
++	if (t2p->t2p_error != T2P_ERR_OK)
++		return(0);
++
+ 	if(t2p->pdf_transcode == T2P_TRANSCODE_RAW){
+ #ifdef CCITT_SUPPORT
+ 		if(t2p->pdf_compression == T2P_COMPRESS_G4){
+@@ -2586,6 +2661,10 @@
+ 	uint32 xuint32=0;
+ #endif
+ 
++	/* Fail if prior error (in particular, can't trust tiff_datasize) */
++	if (t2p->t2p_error != T2P_ERR_OK)
++		return(0);
++
+ 	edge |= t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile);
+ 	edge |= t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile);
+ 
diff --git a/libtiff.spec b/libtiff.spec
index c4ba7d4..df1b2cf 100644
--- a/libtiff.spec
+++ b/libtiff.spec
@@ -1,7 +1,7 @@
 Summary: Library of functions for manipulating TIFF format image files
 Name: libtiff
-Version: 4.0.1
-Release: 2%{?dist}
+Version: 4.0.2
+Release: 1%{?dist}
 
 License: libtiff
 Group: System Environment/Libraries
@@ -12,15 +12,16 @@ URL: http://www.remotesensing.org/libtiff/
 # be recompiled.  The compatibility library is placed in a separate
 # sub-RPM, libtiff-compat.  There is no support for recompiling source code
 # against the old version.
-%global prevversion 3.9.5
+%global prevversion 3.9.6
 
 Source0: ftp://ftp.remotesensing.org/pub/libtiff/tiff-%{version}.tar.gz
 
 Source1: ftp://ftp.remotesensing.org/pub/libtiff/tiff-%{prevversion}.tar.gz
 
-Patch1: libtiff-CVE-2012-1173.patch
-# same patch for prevversion:
+# these patches are only needed for prevversion:
 Patch2: libtiff-CVE-2012-1173-3.9.patch
+Patch3: libtiff-CVE-2012-2088.patch
+Patch4: libtiff-CVE-2012-2113.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 BuildRequires: zlib-devel libjpeg-devel jbigkit-devel
@@ -79,8 +80,6 @@ This package contains shared libraries (only) for libtiff 3.9.x.
 %prep
 %setup -q -n tiff-%{version}
 
-%patch1 -p1
-
 # Use build system's libtool.m4, not the one in the package.
 rm -f libtool.m4
 
@@ -94,6 +93,8 @@ autoheader
 	tar xfz %{SOURCE1}
 	pushd tiff-%{prevversion}
 %patch2 -p1
+%patch3 -p1
+%patch4 -p1
 	# Use build system's libtool.m4, not the one in the package.
 	rm -f libtool.m4
 	libtoolize --force  --copy
@@ -232,6 +233,13 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/libtiffxx.so.3*
 
 %changelog
+* Thu Jun 28 2012 Tom Lane <tgl at redhat.com> 4.0.2-1
+- Update to libtiff 4.0.2, includes fix for CVE-2012-2113
+  (note that CVE-2012-2088 does not apply to 4.0.x)
+- Update libtiff-compat to 3.9.6 and add patches to it for
+  CVE-2012-2088, CVE-2012-2113
+Resolves: #832866
+
 * Fri Jun  1 2012 Tom Lane <tgl at redhat.com> 4.0.1-2
 - Enable JBIG support
 Resolves: #826240
diff --git a/sources b/sources
index 69ae280..93a7da1 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-fae149cc9da35c598d8be897826dfc63  tiff-4.0.1.tar.gz
-8fc7ce3b4e1d0cc8a319336967815084  tiff-3.9.5.tar.gz
+04a08fa1e07e696e820a0c3f32465a13  tiff-4.0.2.tar.gz
+6920f3bf628d791d49f268b83612ed23  tiff-3.9.6.tar.gz


More information about the scm-commits mailing list