[libtiff/f16] Update to libtiff 3.9.6
Tom Lane
tgl at fedoraproject.org
Thu Jun 28 15:49:38 UTC 2012
commit 0b0cd1d0427cb9232c08ed19d9368f4dc1c3cd27
Author: Tom Lane <tgl at redhat.com>
Date: Thu Jun 28 11:39:20 2012 -0400
Update to libtiff 3.9.6
.gitignore | 2 +-
libtiff-CVE-2012-2088.patch | 129 ++++++++++++++++++++++
libtiff-CVE-2012-2113.patch | 246 +++++++++++++++++++++++++++++++++++++++++++
libtiff.spec | 12 ++-
sources | 2 +-
5 files changed, 387 insertions(+), 4 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 9d99bf5..b29c7e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-/tiff-3.9.5.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 5c2d63d..8e960c0 100644
--- a/libtiff.spec
+++ b/libtiff.spec
@@ -1,7 +1,7 @@
Summary: Library of functions for manipulating TIFF format image files
Name: libtiff
-Version: 3.9.5
-Release: 3%{?dist}
+Version: 3.9.6
+Release: 1%{?dist}
License: libtiff
Group: System Environment/Libraries
@@ -10,6 +10,8 @@ URL: http://www.remotesensing.org/libtiff/
Source: ftp://ftp.remotesensing.org/pub/libtiff/tiff-%{version}.tar.gz
Patch1: libtiff-CVE-2012-1173.patch
+Patch2: libtiff-CVE-2012-2088.patch
+Patch3: libtiff-CVE-2012-2113.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: zlib-devel libjpeg-devel
@@ -63,6 +65,8 @@ image files using the libtiff library.
%setup -q -n tiff-%{version}
%patch1 -p1
+%patch2 -p1
+%patch3 -p1
# Use build system's libtool.m4, not the one in the package.
rm -f libtool.m4
@@ -174,6 +178,10 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/*
%changelog
+* Thu Jun 28 2012 Tom Lane <tgl at redhat.com> 3.9.6-1
+- Update to libtiff 3.9.6, and add patches for CVE-2012-2088, CVE-2012-2113
+Resolves: #832866
+
* Thu Apr 5 2012 Tom Lane <tgl at redhat.com> 3.9.5-3
- Add fix for CVE-2012-1173
Resolves: #CVE-2012-1173
diff --git a/sources b/sources
index 04027f5..fef759e 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-8fc7ce3b4e1d0cc8a319336967815084 tiff-3.9.5.tar.gz
+6920f3bf628d791d49f268b83612ed23 tiff-3.9.6.tar.gz
More information about the scm-commits
mailing list