From 170ff31c87a8568c773f10c13c73e01049c36fe3 Mon Sep 17 00:00:00 2001 From: James Antill Date: Thu, 26 May 2022 01:13:01 -0400 Subject: [PATCH] Auto sync2gitlab import of compat-libtiff3-3.9.4-13.el8.src.rpm --- .gitignore | 1 + EMPTY | 1 - compat-libtiff3.spec | 137 ++++++ libtiff-3samples.patch | 21 + libtiff-CVE-2009-5022.patch | 28 ++ libtiff-CVE-2011-0192.patch | 27 ++ libtiff-CVE-2011-1167.patch | 53 +++ libtiff-CVE-2012-1173.patch | 71 ++++ libtiff-CVE-2012-2088.patch | 131 ++++++ libtiff-CVE-2012-2113.patch | 253 +++++++++++ libtiff-CVE-2012-3401.patch | 30 ++ libtiff-CVE-2012-4447.patch | 191 +++++++++ libtiff-CVE-2012-4564.patch | 77 ++++ libtiff-CVE-2012-5581.patch | 255 +++++++++++ libtiff-CVE-2013-1960.patch | 145 +++++++ libtiff-CVE-2013-1961.patch | 791 +++++++++++++++++++++++++++++++++++ libtiff-CVE-2013-4231.patch | 15 + libtiff-CVE-2013-4232.patch | 12 + libtiff-CVE-2013-4243.patch | 37 ++ libtiff-CVE-2013-4244.patch | 15 + libtiff-CVE-2018-7456.patch | 196 +++++++++ libtiff-acversion.patch | 16 + libtiff-checkbytecount.patch | 48 +++ libtiff-coverity.patch | 262 ++++++++++++ libtiff-getimage-64bit.patch | 48 +++ libtiff-mantypo.patch | 17 + libtiff-printdir-width.patch | 36 ++ libtiff-scanlinesize.patch | 72 ++++ libtiff-subsampling.patch | 51 +++ libtiff-tiffdump.patch | 35 ++ libtiff-tiffinfo-exif.patch | 59 +++ libtiff-unknown-fix.patch | 47 +++ libtiff-ycbcr-clamp.patch | 35 ++ sources | 1 + 34 files changed, 3213 insertions(+), 1 deletion(-) create mode 100644 .gitignore delete mode 100644 EMPTY create mode 100644 compat-libtiff3.spec create mode 100644 libtiff-3samples.patch create mode 100644 libtiff-CVE-2009-5022.patch create mode 100644 libtiff-CVE-2011-0192.patch create mode 100644 libtiff-CVE-2011-1167.patch create mode 100644 libtiff-CVE-2012-1173.patch create mode 100644 libtiff-CVE-2012-2088.patch create mode 100644 libtiff-CVE-2012-2113.patch create mode 100644 libtiff-CVE-2012-3401.patch create mode 100644 libtiff-CVE-2012-4447.patch create mode 100644 libtiff-CVE-2012-4564.patch create mode 100644 libtiff-CVE-2012-5581.patch create mode 100644 libtiff-CVE-2013-1960.patch create mode 100644 libtiff-CVE-2013-1961.patch create mode 100644 libtiff-CVE-2013-4231.patch create mode 100644 libtiff-CVE-2013-4232.patch create mode 100644 libtiff-CVE-2013-4243.patch create mode 100644 libtiff-CVE-2013-4244.patch create mode 100644 libtiff-CVE-2018-7456.patch create mode 100644 libtiff-acversion.patch create mode 100644 libtiff-checkbytecount.patch create mode 100644 libtiff-coverity.patch create mode 100644 libtiff-getimage-64bit.patch create mode 100644 libtiff-mantypo.patch create mode 100644 libtiff-printdir-width.patch create mode 100644 libtiff-scanlinesize.patch create mode 100644 libtiff-subsampling.patch create mode 100644 libtiff-tiffdump.patch create mode 100644 libtiff-tiffinfo-exif.patch create mode 100644 libtiff-unknown-fix.patch create mode 100644 libtiff-ycbcr-clamp.patch create mode 100644 sources diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..591093a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/tiff-3.9.4.tar.gz diff --git a/EMPTY b/EMPTY deleted file mode 100644 index 0519ecb..0000000 --- a/EMPTY +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/compat-libtiff3.spec b/compat-libtiff3.spec new file mode 100644 index 0000000..7e54725 --- /dev/null +++ b/compat-libtiff3.spec @@ -0,0 +1,137 @@ +Summary: Compatibility package for libtiff 3 +Name: compat-libtiff3 +Version: 3.9.4 +Release: 13%{?dist} + +License: libtiff +Group: System Environment/Libraries +URL: http://www.remotesensing.org/libtiff/ + +Source: ftp://ftp.remotesensing.org/pub/libtiff/tiff-%{version}.tar.gz +Patch1: libtiff-acversion.patch +Patch2: libtiff-mantypo.patch +Patch3: libtiff-scanlinesize.patch +Patch4: libtiff-getimage-64bit.patch +Patch5: libtiff-ycbcr-clamp.patch +Patch6: libtiff-3samples.patch +Patch7: libtiff-subsampling.patch +Patch8: libtiff-unknown-fix.patch +Patch9: libtiff-checkbytecount.patch +Patch10: libtiff-tiffdump.patch +Patch11: libtiff-CVE-2011-0192.patch +Patch12: libtiff-CVE-2011-1167.patch +Patch13: libtiff-CVE-2009-5022.patch +Patch14: libtiff-CVE-2012-1173.patch +Patch15: libtiff-CVE-2012-2088.patch +Patch16: libtiff-CVE-2012-2113.patch +Patch17: libtiff-CVE-2012-3401.patch +Patch18: libtiff-CVE-2012-4447.patch +Patch19: libtiff-CVE-2012-4564.patch +Patch20: libtiff-CVE-2012-5581.patch +Patch21: libtiff-tiffinfo-exif.patch +Patch22: libtiff-printdir-width.patch +Patch27: libtiff-CVE-2013-1960.patch +Patch28: libtiff-CVE-2013-1961.patch +Patch29: libtiff-CVE-2013-4231.patch +Patch30: libtiff-CVE-2013-4232.patch +Patch31: libtiff-CVE-2013-4244.patch +Patch32: libtiff-CVE-2013-4243.patch +Patch33: libtiff-CVE-2018-7456.patch +Patch34: libtiff-coverity.patch + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +BuildRequires: zlib-devel libjpeg-devel +BuildRequires: libtool automake autoconf + +%global LIBVER %(echo %{version} | cut -f 1-2 -d .) + +%description +The libtiff3 package provides libtiff 3, an older version of libtiff +library for manipulating TIFF (Tagged Image File Format) +image format files. This version should be used only if you are unable +to use the current version of libtiff. + +%prep +%setup -q -n tiff-%{version} + +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 + +# Use build system's libtool.m4, not the one in the package. +rm -f libtool.m4 + +libtoolize --force --copy +aclocal -I . -I m4 +automake --add-missing --copy +autoconf +autoheader + +%build +export CFLAGS="%{optflags} -fno-strict-aliasing" +%configure +make %{?_smp_mflags} + +LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH make check + +%install +rm -rf $RPM_BUILD_ROOT + +make DESTDIR=$RPM_BUILD_ROOT install + +# remove what we didn't want installed +rm $RPM_BUILD_ROOT%{_libdir}/*.la +rm $RPM_BUILD_ROOT%{_libdir}/*.a +rm $RPM_BUILD_ROOT%{_libdir}/{libtiff,libtiffxx}.so + +rm -rf $RPM_BUILD_ROOT%{_datadir}/* +rm -rf $RPM_BUILD_ROOT%{_bindir}/* +rm -rf $RPM_BUILD_ROOT%{_includedir}/* + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,0755) +%{_libdir}/libtiff.so.* +%{_libdir}/libtiffxx.so.* + +%changelog +* Wed Jun 12 2019 Nikola Forró - 3.9.4-13 +- Fix important Covscan defects + related: #1687584 + +* Thu Jun 06 2019 Nikola Forró - 3.9.4-12 +- New package for RHEL 8.1.0 + resolves: #1687584 diff --git a/libtiff-3samples.patch b/libtiff-3samples.patch new file mode 100644 index 0000000..c305bd0 --- /dev/null +++ b/libtiff-3samples.patch @@ -0,0 +1,21 @@ +Patch for bug #603081: failure to guard against bogus SamplesPerPixel +when converting a YCbCr image to RGB. + +This patch duplicates into PickContigCase() a safety check that already +existed in PickSeparateCase(). + +Filed upstream at http://bugzilla.maptools.org/show_bug.cgi?id=2216 + + +diff -Naur tiff-3.9.2.orig/libtiff/tif_getimage.c tiff-3.9.2/libtiff/tif_getimage.c +--- tiff-3.9.2.orig/libtiff/tif_getimage.c 2009-08-30 12:21:46.000000000 -0400 ++++ tiff-3.9.2/libtiff/tif_getimage.c 2010-06-11 12:06:47.000000000 -0400 +@@ -2397,7 +2397,7 @@ + } + break; + case PHOTOMETRIC_YCBCR: +- if (img->bitspersample == 8) ++ if ((img->bitspersample==8) && (img->samplesperpixel==3)) + { + if (initYCbCrConversion(img)!=0) + { diff --git a/libtiff-CVE-2009-5022.patch b/libtiff-CVE-2009-5022.patch new file mode 100644 index 0000000..6437eb8 --- /dev/null +++ b/libtiff-CVE-2009-5022.patch @@ -0,0 +1,28 @@ +Check that image width shown in SOF doesn't exceed what libtiff has +allocated based on ImageWidth. Patch from upstream bug +http://bugzilla.maptools.org/show_bug.cgi?id=1999 + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_ojpeg.c tiff-3.9.4/libtiff/tif_ojpeg.c +--- tiff-3.9.4.orig/libtiff/tif_ojpeg.c 2010-06-08 19:29:51.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_ojpeg.c 2011-04-13 11:38:55.486008471 -0400 +@@ -1537,7 +1537,6 @@ + OJPEGReadSkip(sp,4); + else + { +- /* TODO: probably best to also add check on allowed upper bound, especially x, may cause buffer overflow otherwise i think */ + /* Y: Number of lines */ + if (OJPEGReadWord(sp,&p)==0) + return(0); +@@ -1555,6 +1554,11 @@ + TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width"); + return(0); + } ++ if ((uint32)p>sp->strile_width) ++ { ++ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width"); ++ return(0); ++ } + sp->sof_x=p; + } + /* Nf: Number of image components in frame */ diff --git a/libtiff-CVE-2011-0192.patch b/libtiff-CVE-2011-0192.patch new file mode 100644 index 0000000..892f70e --- /dev/null +++ b/libtiff-CVE-2011-0192.patch @@ -0,0 +1,27 @@ +Protect against a fax VL(n) codeword commanding a move left. Without +this, a malicious input file can generate an indefinitely large series +of runs without a0 ever reaching the right margin, thus overrunning +our buffer of run lengths. Per CVE-2011-0192. This is a modified +version of a patch proposed by Drew Yao of Apple Product Security. +It adds an unexpected() report, and disallows the equality case except +for the first run of a line, since emitting a run without increasing a0 +still allows buffer overrun. (We have to allow it for the first run to +cover the case of encoding a zero-length run at start of line using VL.) + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_fax3.h tiff-3.9.4/libtiff/tif_fax3.h +--- tiff-3.9.4.orig/libtiff/tif_fax3.h 2010-06-08 14:50:42.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_fax3.h 2011-03-10 12:11:20.850839162 -0500 +@@ -478,6 +478,12 @@ + break; \ + case S_VL: \ + CHECK_b1; \ ++ if (b1 <= (int) (a0 + TabEnt->Param)) { \ ++ if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) { \ ++ unexpected("VL", a0); \ ++ goto eol2d; \ ++ } \ ++ } \ + SETVALUE(b1 - a0 - TabEnt->Param); \ + b1 -= *--pb; \ + break; \ diff --git a/libtiff-CVE-2011-1167.patch b/libtiff-CVE-2011-1167.patch new file mode 100644 index 0000000..d3fcf6f --- /dev/null +++ b/libtiff-CVE-2011-1167.patch @@ -0,0 +1,53 @@ +Upstream patch for CVE-2011-1167, heap-based buffer overflow in thunder +decoder (ZDI-CAN-1004). + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_thunder.c tiff-3.9.4/libtiff/tif_thunder.c +--- tiff-3.9.4.orig/libtiff/tif_thunder.c 2010-06-08 14:50:43.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_thunder.c 2011-03-18 12:17:13.635796403 -0400 +@@ -55,12 +55,32 @@ + static const int twobitdeltas[4] = { 0, 1, 0, -1 }; + static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 }; + +-#define SETPIXEL(op, v) { \ +- lastpixel = (v) & 0xf; \ +- if (npixels++ & 1) \ +- *op++ |= lastpixel; \ +- else \ ++#define SETPIXEL(op, v) { \ ++ lastpixel = (v) & 0xf; \ ++ if ( npixels < maxpixels ) \ ++ { \ ++ if (npixels++ & 1) \ ++ *op++ |= lastpixel; \ ++ else \ + op[0] = (tidataval_t) (lastpixel << 4); \ ++ } \ ++} ++ ++static int ++ThunderSetupDecode(TIFF* tif) ++{ ++ static const char module[] = "ThunderSetupDecode"; ++ ++ if( tif->tif_dir.td_bitspersample != 4 ) ++ { ++ TIFFErrorExt(tif->tif_clientdata, module, ++ "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.", ++ (int) tif->tif_dir.td_bitspersample ); ++ return 0; ++ } ++ ++ ++ return (1); + } + + static int +@@ -151,6 +171,7 @@ + (void) scheme; + tif->tif_decoderow = ThunderDecodeRow; + tif->tif_decodestrip = ThunderDecodeRow; ++ tif->tif_setupdecode = ThunderSetupDecode; + return (1); + } + #endif /* THUNDER_SUPPORT */ diff --git a/libtiff-CVE-2012-1173.patch b/libtiff-CVE-2012-1173.patch new file mode 100644 index 0000000..0ada700 --- /dev/null +++ b/libtiff-CVE-2012-1173.patch @@ -0,0 +1,71 @@ +This patch is submitted to upstream for CVE-2012-1173 + + +diff -Naur tiff-3.9.5.orig/libtiff/tif_getimage.c tiff-3.9.5/libtiff/tif_getimage.c +--- tiff-3.9.5.orig/libtiff/tif_getimage.c 2010-07-08 12:17:59.000000000 -0400 ++++ tiff-3.9.5/libtiff/tif_getimage.c 2012-03-14 14:49:25.796728783 -0400 +@@ -673,18 +673,24 @@ + unsigned char* p2; + unsigned char* pa; + tsize_t tilesize; ++ tsize_t bufsize; + int32 fromskew, toskew; + int alpha = img->alpha; + uint32 nrow; + int ret = 1, flip; + + tilesize = TIFFTileSize(tif); +- buf = (unsigned char*) _TIFFmalloc((alpha?4:3)*tilesize); ++ bufsize = TIFFSafeMultiply(tsize_t,alpha?4:3,tilesize); ++ if (bufsize == 0) { ++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate"); ++ return (0); ++ } ++ buf = (unsigned char*) _TIFFmalloc(bufsize); + if (buf == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); + return (0); + } +- _TIFFmemset(buf, 0, (alpha?4:3)*tilesize); ++ _TIFFmemset(buf, 0, bufsize); + p0 = buf; + p1 = p0 + tilesize; + p2 = p1 + tilesize; +@@ -880,17 +886,23 @@ + uint32 rowsperstrip, offset_row; + uint32 imagewidth = img->width; + tsize_t stripsize; ++ tsize_t bufsize; + int32 fromskew, toskew; + int alpha = img->alpha; + int ret = 1, flip; + + stripsize = TIFFStripSize(tif); +- p0 = buf = (unsigned char *)_TIFFmalloc((alpha?4:3)*stripsize); ++ bufsize = TIFFSafeMultiply(tsize_t,alpha?4:3,stripsize); ++ if (bufsize == 0) { ++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate"); ++ return (0); ++ } ++ p0 = buf = (unsigned char *)_TIFFmalloc(bufsize); + if (buf == 0) { + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer"); + return (0); + } +- _TIFFmemset(buf, 0, (alpha?4:3)*stripsize); ++ _TIFFmemset(buf, 0, bufsize); + p1 = p0 + stripsize; + p2 = p1 + stripsize; + pa = (alpha?(p2+stripsize):NULL); +diff -Naur tiff-3.9.5.orig/libtiff/tiffiop.h tiff-3.9.5/libtiff/tiffiop.h +--- tiff-3.9.5.orig/libtiff/tiffiop.h 2011-03-28 09:43:43.000000000 -0400 ++++ tiff-3.9.5/libtiff/tiffiop.h 2012-03-14 14:49:25.797728754 -0400 +@@ -246,7 +246,7 @@ + #define TIFFroundup(x, y) (TIFFhowmany(x,y)*(y)) + + /* Safe multiply which returns zero if there is an integer overflow */ +-#define TIFFSafeMultiply(t,v,m) ((((t)m != (t)0) && (((t)((v*m)/m)) == (t)v)) ? (t)(v*m) : (t)0) ++#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) + + #define TIFFmax(A,B) ((A)>(B)?(A):(B)) + #define TIFFmin(A,B) ((A)<(B)?(A):(B)) diff --git a/libtiff-CVE-2012-2088.patch b/libtiff-CVE-2012-2088.patch new file mode 100644 index 0000000..ae2759a --- /dev/null +++ b/libtiff-CVE-2012-2088.patch @@ -0,0 +1,131 @@ +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 + +NB: must be applied after libtiff-subsampling.patch to avoid fuzz issues. + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_strip.c tiff-3.9.4/libtiff/tif_strip.c +--- tiff-3.9.4.orig/libtiff/tif_strip.c 2010-06-08 14:50:43.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_strip.c 2012-06-27 12:37:55.054788399 -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.4.orig/libtiff/tif_tile.c tiff-3.9.4/libtiff/tif_tile.c +--- tiff-3.9.4.orig/libtiff/tif_tile.c 2010-06-08 14:50:43.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_tile.c 2012-06-27 12:37:55.055788446 -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..5868b47 --- /dev/null +++ b/libtiff-CVE-2012-2113.patch @@ -0,0 +1,253 @@ +Defend against integer overflow in buffer size calculations within tiff2pdf. +CVE-2012-2113 + + +diff -Naur tiff-3.9.4.orig/tools/tiff2pdf.c tiff-3.9.4/tools/tiff2pdf.c +--- tiff-3.9.4.orig/tools/tiff2pdf.c 2010-06-13 16:51:44.000000000 -0400 ++++ tiff-3.9.4/tools/tiff2pdf.c 2012-06-27 13:13:44.581229393 -0400 +@@ -44,6 +44,7 @@ + # include + #endif + ++#include "tiffiop.h" + #include "tiffio.h" + + #ifndef HAVE_GETOPT +@@ -414,6 +415,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. +@@ -1828,9 +1857,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 +@@ -1858,19 +1885,25 @@ + } + stripcount=TIFFNumberOfStrips(input); + for(i=0;itiff_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; +@@ -1883,9 +1916,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 +@@ -1894,11 +1932,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)){ +@@ -1909,18 +1947,33 @@ + return; + } + for(i=0;itiff_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; +@@ -1938,6 +1991,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); +@@ -1949,14 +2003,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 +@@ -1964,18 +2021,33 @@ + uint32 count = 0; + if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt)!=0){ + if(count > 4){ +- t2p->tiff_datasize += count; +- t2p->tiff_datasize -= 4; /* don't use EOI of header or SOI of tile */ ++ k = checkAdd64(k, count, t2p); ++ k -= 4; /* 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; +@@ -2068,6 +2140,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){ +@@ -2641,6 +2717,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-CVE-2012-3401.patch b/libtiff-CVE-2012-3401.patch new file mode 100644 index 0000000..06d6a5d --- /dev/null +++ b/libtiff-CVE-2012-3401.patch @@ -0,0 +1,30 @@ +Upstream patch for CVE-2012-3401. + + +diff -Naur tiff-3.9.4.orig/tools/tiff2pdf.c tiff-3.9.4/tools/tiff2pdf.c +--- tiff-3.9.4.orig/tools/tiff2pdf.c 2010-06-13 16:51:44.000000000 -0400 ++++ tiff-3.9.4/tools/tiff2pdf.c 2012-12-11 11:17:56.506344841 -0500 +@@ -1090,6 +1090,7 @@ + "Can't set directory %u of input file %s", + i, + TIFFFileName(input)); ++ t2p->t2p_error = T2P_ERR_ERROR; + return; + } + if(TIFFGetField(input, TIFFTAG_PAGENUMBER, &pagen, &paged)){ +@@ -3153,6 +3154,7 @@ + "Can't allocate %u bytes of memory for t2p_process_ojpeg_tables, %s", + 2048, + TIFFFileName(input)); ++ t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } + _TIFFmemset(t2p->pdf_ojpegdata, 0x00, 2048); +@@ -5248,6 +5250,7 @@ + TIFF2PDF_MODULE, + "Can't allocate %u bytes of memory for t2p_write_pdf", + t2p->pdf_xrefcount * sizeof(uint32) ); ++ t2p->t2p_error = T2P_ERR_ERROR; + return(written); + } + t2p->pdf_xrefcount=0; diff --git a/libtiff-CVE-2012-4447.patch b/libtiff-CVE-2012-4447.patch new file mode 100644 index 0000000..6c28dc6 --- /dev/null +++ b/libtiff-CVE-2012-4447.patch @@ -0,0 +1,191 @@ +Upstream patch for CVE-2012-4447. This also covers an out-of-bounds-read +possibility in the same file, which wasn't given a separate CVE. + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_pixarlog.c tiff-3.9.4/libtiff/tif_pixarlog.c +--- tiff-3.9.4.orig/libtiff/tif_pixarlog.c 2010-06-08 14:50:42.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_pixarlog.c 2012-12-10 15:50:14.421538317 -0500 +@@ -117,9 +117,9 @@ + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { +- t0 = ToLinearF[cr = wp[0]]; +- t1 = ToLinearF[cg = wp[1]]; +- t2 = ToLinearF[cb = wp[2]]; ++ t0 = ToLinearF[cr = (wp[0] & mask)]; ++ t1 = ToLinearF[cg = (wp[1] & mask)]; ++ t2 = ToLinearF[cb = (wp[2] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; +@@ -136,10 +136,10 @@ + op[2] = t2; + } + } else if (stride == 4) { +- t0 = ToLinearF[cr = wp[0]]; +- t1 = ToLinearF[cg = wp[1]]; +- t2 = ToLinearF[cb = wp[2]]; +- t3 = ToLinearF[ca = wp[3]]; ++ t0 = ToLinearF[cr = (wp[0] & mask)]; ++ t1 = ToLinearF[cg = (wp[1] & mask)]; ++ t2 = ToLinearF[cb = (wp[2] & mask)]; ++ t3 = ToLinearF[ca = (wp[3] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; +@@ -183,9 +183,9 @@ + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { +- t0 = ToLinearF[cr = wp[0]] * SCALE12; +- t1 = ToLinearF[cg = wp[1]] * SCALE12; +- t2 = ToLinearF[cb = wp[2]] * SCALE12; ++ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; ++ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; ++ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); +@@ -202,10 +202,10 @@ + op[2] = CLAMP12(t2); + } + } else if (stride == 4) { +- t0 = ToLinearF[cr = wp[0]] * SCALE12; +- t1 = ToLinearF[cg = wp[1]] * SCALE12; +- t2 = ToLinearF[cb = wp[2]] * SCALE12; +- t3 = ToLinearF[ca = wp[3]] * SCALE12; ++ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; ++ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; ++ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; ++ t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); +@@ -247,9 +247,9 @@ + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { +- op[0] = ToLinear16[cr = wp[0]]; +- op[1] = ToLinear16[cg = wp[1]]; +- op[2] = ToLinear16[cb = wp[2]]; ++ op[0] = ToLinear16[cr = (wp[0] & mask)]; ++ op[1] = ToLinear16[cg = (wp[1] & mask)]; ++ op[2] = ToLinear16[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) { + wp += 3; +@@ -260,10 +260,10 @@ + op[2] = ToLinear16[(cb += wp[2]) & mask]; + } + } else if (stride == 4) { +- op[0] = ToLinear16[cr = wp[0]]; +- op[1] = ToLinear16[cg = wp[1]]; +- op[2] = ToLinear16[cb = wp[2]]; +- op[3] = ToLinear16[ca = wp[3]]; ++ op[0] = ToLinear16[cr = (wp[0] & mask)]; ++ op[1] = ToLinear16[cg = (wp[1] & mask)]; ++ op[2] = ToLinear16[cb = (wp[2] & mask)]; ++ op[3] = ToLinear16[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) { + wp += 4; +@@ -342,9 +342,9 @@ + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { +- op[0] = ToLinear8[cr = wp[0]]; +- op[1] = ToLinear8[cg = wp[1]]; +- op[2] = ToLinear8[cb = wp[2]]; ++ op[0] = ToLinear8[cr = (wp[0] & mask)]; ++ op[1] = ToLinear8[cg = (wp[1] & mask)]; ++ op[2] = ToLinear8[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) { + n -= 3; +@@ -355,10 +355,10 @@ + op[2] = ToLinear8[(cb += wp[2]) & mask]; + } + } else if (stride == 4) { +- op[0] = ToLinear8[cr = wp[0]]; +- op[1] = ToLinear8[cg = wp[1]]; +- op[2] = ToLinear8[cb = wp[2]]; +- op[3] = ToLinear8[ca = wp[3]]; ++ op[0] = ToLinear8[cr = (wp[0] & mask)]; ++ op[1] = ToLinear8[cg = (wp[1] & mask)]; ++ op[2] = ToLinear8[cb = (wp[2] & mask)]; ++ op[3] = ToLinear8[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) { + n -= 4; +@@ -393,9 +393,9 @@ + mask = CODE_MASK; + if (stride == 3) { + op[0] = 0; +- t1 = ToLinear8[cb = wp[2]]; +- t2 = ToLinear8[cg = wp[1]]; +- t3 = ToLinear8[cr = wp[0]]; ++ t1 = ToLinear8[cb = (wp[2] & mask)]; ++ t2 = ToLinear8[cg = (wp[1] & mask)]; ++ t3 = ToLinear8[cr = (wp[0] & mask)]; + op[1] = t1; + op[2] = t2; + op[3] = t3; +@@ -413,10 +413,10 @@ + op[3] = t3; + } + } else if (stride == 4) { +- t0 = ToLinear8[ca = wp[3]]; +- t1 = ToLinear8[cb = wp[2]]; +- t2 = ToLinear8[cg = wp[1]]; +- t3 = ToLinear8[cr = wp[0]]; ++ t0 = ToLinear8[ca = (wp[3] & mask)]; ++ t1 = ToLinear8[cb = (wp[2] & mask)]; ++ t2 = ToLinear8[cg = (wp[1] & mask)]; ++ t3 = ToLinear8[cr = (wp[0] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; +@@ -630,10 +630,10 @@ + return guess; + } + +-static uint32 +-multiply(size_t m1, size_t m2) ++static tsize_t ++multiply(tsize_t m1, tsize_t m2) + { +- uint32 bytes = m1 * m2; ++ tsize_t bytes = m1 * m2; + + if (m1 && bytes / m1 != m2) + bytes = 0; +@@ -641,6 +641,20 @@ + return bytes; + } + ++static tsize_t ++add_ms(tsize_t m1, tsize_t m2) ++{ ++ tsize_t bytes = m1 + m2; ++ ++ /* if either input is zero, assume overflow already occurred */ ++ if (m1 == 0 || m2 == 0) ++ bytes = 0; ++ else if (bytes <= m1 || bytes <= m2) ++ bytes = 0; ++ ++ return bytes; ++} ++ + static int + PixarLogSetupDecode(TIFF* tif) + { +@@ -661,6 +675,8 @@ + td->td_samplesperpixel : 1); + tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth), + td->td_rowsperstrip), sizeof(uint16)); ++ /* add one more stride in case input ends mid-stride */ ++ tbuf_size = add_ms(tbuf_size, sizeof(uint16) * sp->stride); + if (tbuf_size == 0) + return (0); + sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size); diff --git a/libtiff-CVE-2012-4564.patch b/libtiff-CVE-2012-4564.patch new file mode 100644 index 0000000..98a6e6c --- /dev/null +++ b/libtiff-CVE-2012-4564.patch @@ -0,0 +1,77 @@ +Upstream patch for CVE-2012-4564. + + +diff -Naur tiff-3.9.4.orig/tools/ppm2tiff.c tiff-3.9.4/tools/ppm2tiff.c +--- tiff-3.9.4.orig/tools/ppm2tiff.c 2010-06-08 14:50:44.000000000 -0400 ++++ tiff-3.9.4/tools/ppm2tiff.c 2012-12-10 16:16:05.154045877 -0500 +@@ -68,6 +68,17 @@ + exit(-2); + } + ++static tsize_t ++multiply_ms(tsize_t m1, tsize_t m2) ++{ ++ tsize_t bytes = m1 * m2; ++ ++ if (m1 && bytes / m1 != m2) ++ bytes = 0; ++ ++ return bytes; ++} ++ + int + main(int argc, char* argv[]) + { +@@ -85,6 +96,7 @@ + int c; + extern int optind; + extern char* optarg; ++ tsize_t scanline_size; + + if (argc < 2) { + fprintf(stderr, "%s: Too few arguments\n", argv[0]); +@@ -217,7 +229,8 @@ + } + switch (bpp) { + case 1: +- linebytes = (spp * w + (8 - 1)) / 8; ++ /* if round-up overflows, result will be zero, OK */ ++ linebytes = (multiply_ms(spp, w) + (8 - 1)) / 8; + if (rowsperstrip == (uint32) -1) { + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h); + } else { +@@ -226,15 +239,31 @@ + } + break; + case 8: +- linebytes = spp * w; ++ linebytes = multiply_ms(spp, w); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); + break; + } +- if (TIFFScanlineSize(out) > linebytes) ++ if (linebytes == 0) { ++ fprintf(stderr, "%s: scanline size overflow\n", infile); ++ (void) TIFFClose(out); ++ exit(-2); ++ } ++ scanline_size = TIFFScanlineSize(out); ++ if (scanline_size == 0) { ++ /* overflow - TIFFScanlineSize already printed a message */ ++ (void) TIFFClose(out); ++ exit(-2); ++ } ++ if (scanline_size < linebytes) + buf = (unsigned char *)_TIFFmalloc(linebytes); + else +- buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); ++ buf = (unsigned char *)_TIFFmalloc(scanline_size); ++ if (buf == NULL) { ++ fprintf(stderr, "%s: Not enough memory\n", infile); ++ (void) TIFFClose(out); ++ exit(-2); ++ } + if (resolution > 0) { + TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution); + TIFFSetField(out, TIFFTAG_YRESOLUTION, resolution); diff --git a/libtiff-CVE-2012-5581.patch b/libtiff-CVE-2012-5581.patch new file mode 100644 index 0000000..e26773e --- /dev/null +++ b/libtiff-CVE-2012-5581.patch @@ -0,0 +1,255 @@ +Fix unsafe handling of DotRange and related tags. Back-port of upstream +patch for CVE-2012-5581. (Note: I have not pushed this into upstream CVS +for the 3.9 branch, because I'm not entirely convinced that it won't create +application compatibility issues --- tgl) + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_dir.c tiff-3.9.4/libtiff/tif_dir.c +--- tiff-3.9.4.orig/libtiff/tif_dir.c 2010-06-09 17:15:27.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_dir.c 2012-12-10 15:12:38.442326919 -0500 +@@ -492,31 +492,28 @@ + goto end; + } + +- if ((fip->field_passcount ++ if (fip->field_tag == TIFFTAG_DOTRANGE ++ && strcmp(fip->field_name,"DotRange") == 0) { ++ /* TODO: This is an evil exception and should not have been ++ handled this way ... likely best if we move it into ++ the directory structure with an explicit field in ++ libtiff 4.1 and assign it a FIELD_ value */ ++ uint16 v[2]; ++ v[0] = (uint16)va_arg(ap, int); ++ v[1] = (uint16)va_arg(ap, int); ++ _TIFFmemcpy(tv->value, v, 4); ++ } ++ else if (fip->field_passcount + || fip->field_writecount == TIFF_VARIABLE + || fip->field_writecount == TIFF_VARIABLE2 + || fip->field_writecount == TIFF_SPP +- || tv->count > 1) +- && fip->field_tag != TIFFTAG_PAGENUMBER +- && fip->field_tag != TIFFTAG_HALFTONEHINTS +- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING +- && fip->field_tag != TIFFTAG_DOTRANGE) { ++ || tv->count > 1) { + _TIFFmemcpy(tv->value, va_arg(ap, void *), + tv->count * tv_size); + } else { +- /* +- * XXX: The following loop required to handle +- * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS, +- * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags. +- * These tags are actually arrays and should be passed as +- * array pointers to TIFFSetField() function, but actually +- * passed as a list of separate values. This behaviour +- * must be changed in the future! +- */ +- int i; + char *val = (char *)tv->value; + +- for (i = 0; i < tv->count; i++, val += tv_size) { ++ assert( tv->count == 1 ); + switch (fip->field_type) { + case TIFF_BYTE: + case TIFF_UNDEFINED: +@@ -575,7 +572,6 @@ + status = 0; + break; + } +- } + } + } + } +@@ -866,24 +862,27 @@ + *va_arg(ap, uint16*) = (uint16)tv->count; + *va_arg(ap, void **) = tv->value; + ret_val = 1; +- } else { +- if ((fip->field_type == TIFF_ASCII ++ } else if (fip->field_tag == TIFFTAG_DOTRANGE ++ && strcmp(fip->field_name,"DotRange") == 0) { ++ /* TODO: This is an evil exception and should not have been ++ handled this way ... likely best if we move it into ++ the directory structure with an explicit field in ++ libtiff 4.1 and assign it a FIELD_ value */ ++ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0]; ++ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1]; ++ ret_val = 1; ++ } else { ++ if (fip->field_type == TIFF_ASCII + || fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2 + || fip->field_readcount == TIFF_SPP +- || tv->count > 1) +- && fip->field_tag != TIFFTAG_PAGENUMBER +- && fip->field_tag != TIFFTAG_HALFTONEHINTS +- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING +- && fip->field_tag != TIFFTAG_DOTRANGE) { ++ || tv->count > 1) { + *va_arg(ap, void **) = tv->value; + ret_val = 1; + } else { +- int j; + char *val = (char *)tv->value; + +- for (j = 0; j < tv->count; +- j++, val += _TIFFDataSize(tv->info->field_type)) { ++ assert( tv->count == 1 ); + switch (fip->field_type) { + case TIFF_BYTE: + case TIFF_UNDEFINED: +@@ -933,7 +932,6 @@ + ret_val = 0; + break; + } +- } + } + } + break; +diff -Naur tiff-3.9.4.orig/libtiff/tif_print.c tiff-3.9.4/libtiff/tif_print.c +--- tiff-3.9.4.orig/libtiff/tif_print.c 2010-06-08 14:50:42.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_print.c 2012-12-10 15:41:42.860710914 -0500 +@@ -112,16 +112,22 @@ + } + + static int +-_TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag, ++_TIFFPrettyPrintField(TIFF* tif, const TIFFFieldInfo *fip, FILE* fd, ttag_t tag, + uint32 value_count, void *raw_data) + { + TIFFDirectory *td = &tif->tif_dir; + ++ /* do not try to pretty print auto-defined fields */ ++ if (strncmp(fip->field_name,"Tag ", 4) == 0) { ++ return 0; ++ } ++ + switch (tag) + { + case TIFFTAG_INKSET: +- fprintf(fd, " Ink Set: "); +- switch (*((uint16*)raw_data)) { ++ if (value_count == 2 && fip->field_type == TIFF_SHORT) { ++ fprintf(fd, " Ink Set: "); ++ switch (*((uint16*)raw_data)) { + case INKSET_CMYK: + fprintf(fd, "CMYK\n"); + break; +@@ -130,15 +136,26 @@ + *((uint16*)raw_data), + *((uint16*)raw_data)); + break; ++ } ++ return 1; + } +- return 1; ++ return 0; ++ + case TIFFTAG_DOTRANGE: +- fprintf(fd, " Dot Range: %u-%u\n", +- ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]); +- return 1; ++ if (value_count == 2 && fip->field_type == TIFF_SHORT) { ++ fprintf(fd, " Dot Range: %u-%u\n", ++ ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]); ++ return 1; ++ } ++ return 0; ++ + case TIFFTAG_WHITEPOINT: +- fprintf(fd, " White Point: %g-%g\n", +- ((float *)raw_data)[0], ((float *)raw_data)[1]); return 1; ++ if (value_count == 2 && fip->field_type == TIFF_RATIONAL) { ++ fprintf(fd, " White Point: %g-%g\n", ++ ((float *)raw_data)[0], ((float *)raw_data)[1]); return 1; ++ } ++ return 0; ++ + case TIFFTAG_REFERENCEBLACKWHITE: + { + uint16 i; +@@ -178,10 +195,13 @@ + (unsigned long) value_count); + return 1; + case TIFFTAG_STONITS: +- fprintf(fd, +- " Sample to Nits conversion factor: %.4e\n", +- *((double*)raw_data)); +- return 1; ++ if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { ++ fprintf(fd, ++ " Sample to Nits conversion factor: %.4e\n", ++ *((double*)raw_data)); ++ return 1; ++ } ++ return 0; + } + + return 0; +@@ -528,44 +548,28 @@ + value_count = td->td_samplesperpixel; + else + value_count = fip->field_readcount; +- if ((fip->field_type == TIFF_ASCII ++ if (fip->field_tag == TIFFTAG_DOTRANGE ++ && strcmp(fip->field_name,"DotRange") == 0) { ++ /* TODO: This is an evil exception and should not have been ++ handled this way ... likely best if we move it into ++ the directory structure with an explicit field in ++ libtiff 4.1 and assign it a FIELD_ value */ ++ static uint16 dotrange[2]; ++ raw_data = dotrange; ++ TIFFGetField(tif, tag, dotrange+0, dotrange+1); ++ } else if (fip->field_type == TIFF_ASCII + || fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2 + || fip->field_readcount == TIFF_SPP +- || value_count > 1) +- && fip->field_tag != TIFFTAG_PAGENUMBER +- && fip->field_tag != TIFFTAG_HALFTONEHINTS +- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING +- && fip->field_tag != TIFFTAG_DOTRANGE) { ++ || value_count > 1) { + if(TIFFGetField(tif, tag, &raw_data) != 1) + continue; +- } else if (fip->field_tag != TIFFTAG_PAGENUMBER +- && fip->field_tag != TIFFTAG_HALFTONEHINTS +- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING +- && fip->field_tag != TIFFTAG_DOTRANGE) { +- raw_data = _TIFFmalloc( +- _TIFFDataSize(fip->field_type) +- * value_count); +- mem_alloc = 1; +- if(TIFFGetField(tif, tag, raw_data) != 1) { +- _TIFFfree(raw_data); +- continue; +- } + } else { +- /* +- * XXX: Should be fixed and removed, see the +- * notes related to TIFFTAG_PAGENUMBER, +- * TIFFTAG_HALFTONEHINTS, +- * TIFFTAG_YCBCRSUBSAMPLING and +- * TIFFTAG_DOTRANGE tags in tif_dir.c. */ +- char *tmp; + raw_data = _TIFFmalloc( + _TIFFDataSize(fip->field_type) + * value_count); +- tmp = raw_data; + mem_alloc = 1; +- if(TIFFGetField(tif, tag, tmp, +- tmp + _TIFFDataSize(fip->field_type)) != 1) { ++ if(TIFFGetField(tif, tag, raw_data) != 1) { + _TIFFfree(raw_data); + continue; + } +@@ -578,7 +582,7 @@ + * _TIFFPrettyPrintField() fall down and print it as any other + * tag. + */ +- if (_TIFFPrettyPrintField(tif, fd, tag, value_count, raw_data)) { ++ if (_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) { + if(mem_alloc) + _TIFFfree(raw_data); + continue; diff --git a/libtiff-CVE-2013-1960.patch b/libtiff-CVE-2013-1960.patch new file mode 100644 index 0000000..1c8dfb7 --- /dev/null +++ b/libtiff-CVE-2013-1960.patch @@ -0,0 +1,145 @@ +diff -Naur tiff-4.0.3.orig/tools/tiff2pdf.c tiff-4.0.3/tools/tiff2pdf.c +--- tiff-4.0.3.orig/tools/tiff2pdf.c 2012-07-25 22:56:43.000000000 -0400 ++++ tiff-4.0.3/tools/tiff2pdf.c 2013-05-02 12:04:49.057090227 -0400 +@@ -3341,33 +3341,56 @@ + uint32 height){ + + tsize_t i=0; +- uint16 ri =0; +- uint16 v_samp=1; +- uint16 h_samp=1; +- int j=0; +- +- i++; +- +- while(i<(*striplength)){ ++ ++ while (i < *striplength) { ++ tsize_t datalen; ++ uint16 ri; ++ uint16 v_samp; ++ uint16 h_samp; ++ int j; ++ int ncomp; ++ ++ /* marker header: one or more FFs */ ++ if (strip[i] != 0xff) ++ return(0); ++ i++; ++ while (i < *striplength && strip[i] == 0xff) ++ i++; ++ if (i >= *striplength) ++ return(0); ++ /* SOI is the only pre-SOS marker without a length word */ ++ if (strip[i] == 0xd8) ++ datalen = 0; ++ else { ++ if ((*striplength - i) <= 2) ++ return(0); ++ datalen = (strip[i+1] << 8) | strip[i+2]; ++ if (datalen < 2 || datalen >= (*striplength - i)) ++ return(0); ++ } + switch( strip[i] ){ +- case 0xd8: +- /* SOI - start of image */ ++ case 0xd8: /* SOI - start of image */ + _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), 2); + *bufferoffset+=2; +- i+=2; + break; +- case 0xc0: +- case 0xc1: +- case 0xc3: +- case 0xc9: +- case 0xca: ++ case 0xc0: /* SOF0 */ ++ case 0xc1: /* SOF1 */ ++ case 0xc3: /* SOF3 */ ++ case 0xc9: /* SOF9 */ ++ case 0xca: /* SOF10 */ + if(no==0){ +- _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2); +- for(j=0;j>4) > h_samp) +- h_samp = (buffer[*bufferoffset+11+(2*j)]>>4); +- if( (buffer[*bufferoffset+11+(2*j)] & 0x0f) > v_samp) +- v_samp = (buffer[*bufferoffset+11+(2*j)] & 0x0f); ++ _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2); ++ ncomp = buffer[*bufferoffset+9]; ++ if (ncomp < 1 || ncomp > 4) ++ return(0); ++ v_samp=1; ++ h_samp=1; ++ for(j=0;j>4) > h_samp) ++ h_samp = (samp>>4); ++ if( (samp & 0x0f) > v_samp) ++ v_samp = (samp & 0x0f); + } + v_samp*=8; + h_samp*=8; +@@ -3381,45 +3404,43 @@ + (unsigned char) ((height>>8) & 0xff); + buffer[*bufferoffset+6]= + (unsigned char) (height & 0xff); +- *bufferoffset+=strip[i+2]+2; +- i+=strip[i+2]+2; +- ++ *bufferoffset+=datalen+2; ++ /* insert a DRI marker */ + buffer[(*bufferoffset)++]=0xff; + buffer[(*bufferoffset)++]=0xdd; + buffer[(*bufferoffset)++]=0x00; + buffer[(*bufferoffset)++]=0x04; + buffer[(*bufferoffset)++]=(ri >> 8) & 0xff; + buffer[(*bufferoffset)++]= ri & 0xff; +- } else { +- i+=strip[i+2]+2; + } + break; +- case 0xc4: +- case 0xdb: +- _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2); +- *bufferoffset+=strip[i+2]+2; +- i+=strip[i+2]+2; ++ case 0xc4: /* DHT */ ++ case 0xdb: /* DQT */ ++ _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2); ++ *bufferoffset+=datalen+2; + break; +- case 0xda: ++ case 0xda: /* SOS */ + if(no==0){ +- _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2); +- *bufferoffset+=strip[i+2]+2; +- i+=strip[i+2]+2; ++ _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2); ++ *bufferoffset+=datalen+2; + } else { + buffer[(*bufferoffset)++]=0xff; + buffer[(*bufferoffset)++]= + (unsigned char)(0xd0 | ((no-1)%8)); +- i+=strip[i+2]+2; + } +- _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), (*striplength)-i-1); +- *bufferoffset+=(*striplength)-i-1; ++ i += datalen + 1; ++ /* copy remainder of strip */ ++ _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i]), *striplength - i); ++ *bufferoffset+= *striplength - i; + return(1); + default: +- i+=strip[i+2]+2; ++ /* ignore any other marker */ ++ break; + } ++ i += datalen + 1; + } +- + ++ /* failed to find SOS marker */ + return(0); + } + #endif diff --git a/libtiff-CVE-2013-1961.patch b/libtiff-CVE-2013-1961.patch new file mode 100644 index 0000000..e96b913 --- /dev/null +++ b/libtiff-CVE-2013-1961.patch @@ -0,0 +1,791 @@ +diff -Naur tiff-3.9.4.orig/contrib/dbs/xtiff/xtiff.c tiff-3.9.4/contrib/dbs/xtiff/xtiff.c +--- tiff-3.9.4.orig/contrib/dbs/xtiff/xtiff.c 2010-06-08 14:50:40.000000000 -0400 ++++ tiff-3.9.4/contrib/dbs/xtiff/xtiff.c 2013-04-16 12:52:23.876253257 -0400 +@@ -512,9 +512,9 @@ + Arg args[1]; + + if (tfMultiPage) +- sprintf(buffer, "%s - page %d", fileName, tfDirectory); ++ snprintf(buffer, sizeof(buffer), "%s - page %d", fileName, tfDirectory); + else +- strcpy(buffer, fileName); ++ snprintf(buffer, sizeof(buffer), "%s", fileName); + XtSetArg(args[0], XtNlabel, buffer); + XtSetValues(labelWidget, args, 1); + } +diff -Naur tiff-3.9.4.orig/libtiff/tif_codec.c tiff-3.9.4/libtiff/tif_codec.c +--- tiff-3.9.4.orig/libtiff/tif_codec.c 2010-06-08 14:50:41.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_codec.c 2013-04-16 12:52:23.876253257 -0400 +@@ -104,7 +104,8 @@ + const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + char compression_code[20]; + +- sprintf( compression_code, "%d", tif->tif_dir.td_compression ); ++ snprintf(compression_code, sizeof(compression_code), "%d", ++ tif->tif_dir.td_compression ); + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "%s compression support is not configured", + c ? c->name : compression_code ); +diff -Naur tiff-3.9.4.orig/libtiff/tif_dirinfo.c tiff-3.9.4/libtiff/tif_dirinfo.c +--- tiff-3.9.4.orig/libtiff/tif_dirinfo.c 2010-06-09 17:15:27.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_dirinfo.c 2013-04-16 12:52:23.877253102 -0400 +@@ -873,7 +873,7 @@ + * note that this name is a special sign to TIFFClose() and + * _TIFFSetupFieldInfo() to free the field + */ +- sprintf(fld->field_name, "Tag %d", (int) tag); ++ snprintf(fld->field_name, 32, "Tag %d", (int) tag); + + return fld; + } +diff -Naur tiff-3.9.4.orig/tools/rgb2ycbcr.c tiff-3.9.4/tools/rgb2ycbcr.c +--- tiff-3.9.4.orig/tools/rgb2ycbcr.c 2010-06-08 14:50:44.000000000 -0400 ++++ tiff-3.9.4/tools/rgb2ycbcr.c 2013-04-16 12:52:23.878252947 -0400 +@@ -326,7 +326,8 @@ + TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + { char buf[2048]; + char *cp = strrchr(TIFFFileName(in), '/'); +- sprintf(buf, "YCbCr conversion of %s", cp ? cp+1 : TIFFFileName(in)); ++ snprintf(buf, sizeof(buf), "YCbCr conversion of %s", ++ cp ? cp+1 : TIFFFileName(in)); + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, buf); + } + TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion()); +diff -Naur tiff-3.9.4.orig/tools/tiff2bw.c tiff-3.9.4/tools/tiff2bw.c +--- tiff-3.9.4.orig/tools/tiff2bw.c 2010-06-08 14:50:44.000000000 -0400 ++++ tiff-3.9.4/tools/tiff2bw.c 2013-04-16 12:52:23.879252793 -0400 +@@ -201,7 +201,7 @@ + } + } + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); +- sprintf(thing, "B&W version of %s", argv[optind]); ++ snprintf(thing, sizeof(thing), "B&W version of %s", argv[optind]); + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); + TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw"); + outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); +diff -Naur tiff-3.9.4.orig/tools/tiff2pdf.c tiff-3.9.4/tools/tiff2pdf.c +--- tiff-3.9.4.orig/tools/tiff2pdf.c 2013-04-16 12:51:14.647783499 -0400 ++++ tiff-3.9.4/tools/tiff2pdf.c 2013-04-16 12:56:34.501865141 -0400 +@@ -3662,7 +3662,9 @@ + char buffer[16]; + int buflen=0; + +- buflen=sprintf(buffer, "%%PDF-%u.%u ", t2p->pdf_majorversion&0xff, t2p->pdf_minorversion&0xff); ++ buflen = snprintf(buffer, sizeof(buffer), "%%PDF-%u.%u ", ++ t2p->pdf_majorversion&0xff, ++ t2p->pdf_minorversion&0xff); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t)"\n%\342\343\317\323\n", 7); + +@@ -3676,10 +3678,10 @@ + tsize_t t2p_write_pdf_obj_start(uint32 number, TIFF* output){ + + tsize_t written=0; +- char buffer[16]; ++ char buffer[32]; + int buflen=0; + +- buflen=sprintf(buffer, "%lu", (unsigned long)number); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)number); + written += t2pWriteFile(output, (tdata_t) buffer, buflen ); + written += t2pWriteFile(output, (tdata_t) " 0 obj\n", 7); + +@@ -3718,13 +3720,13 @@ + written += t2pWriteFile(output, (tdata_t) "/", 1); + for (i=0;i 0x7E){ +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + nextchar=1; +@@ -3732,57 +3734,57 @@ + if (nextchar==0){ + switch (name[i]){ + case 0x23: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x25: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x28: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x29: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x2F: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x3C: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x3E: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x5B: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x5D: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x7B: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; + case 0x7D: +- sprintf(buffer, "#%.2X", name[i]); ++ snprintf(buffer, sizeof(buffer), "#%.2X", name[i]); + buffer[sizeof(buffer) - 1] = '\0'; + written += t2pWriteFile(output, (tdata_t) buffer, 3); + break; +@@ -3812,7 +3814,7 @@ + written += t2pWriteFile(output, (tdata_t) "(", 1); + for (i=0; ipdf_pages); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_pages); + written += t2pWriteFile(output, (tdata_t) buffer, buflen ); + written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6); + if(t2p->pdf_fitwindow){ +@@ -4003,8 +4005,7 @@ + written += t2p_write_pdf_string(t2p->pdf_datetime, output); + } + written += t2pWriteFile(output, (tdata_t) "\n/Producer ", 11); +- _TIFFmemset((tdata_t)buffer, 0x00, sizeof(buffer)); +- buflen = sprintf(buffer, "libtiff / tiff2pdf - %d", TIFFLIB_VERSION); ++ buflen = snprintf(buffer, sizeof(buffer), "libtiff / tiff2pdf - %d", TIFFLIB_VERSION); + written += t2p_write_pdf_string((unsigned char*)buffer, output); + written += t2pWriteFile(output, (tdata_t) "\n", 1); + if(t2p->pdf_creator != NULL){ +@@ -4179,7 +4180,7 @@ + { + tsize_t written=0; + tdir_t i=0; +- char buffer[16]; ++ char buffer[32]; + int buflen=0; + + int page=0; +@@ -4187,7 +4188,7 @@ + (tdata_t) "<< \n/Type /Pages \n/Kids [ ", 26); + page = t2p->pdf_pages+1; + for (i=0;itiff_pagecount;i++){ +- buflen=sprintf(buffer, "%d", page); ++ buflen=snprintf(buffer, sizeof(buffer), "%d", page); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); + if ( ((i+1)%8)==0 ) { +@@ -4202,8 +4203,7 @@ + } + } + written += t2pWriteFile(output, (tdata_t) "] \n/Count ", 10); +- _TIFFmemset(buffer, 0x00, 16); +- buflen=sprintf(buffer, "%d", t2p->tiff_pagecount); ++ buflen=snprintf(buffer, sizeof(buffer), "%d", t2p->tiff_pagecount); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " \n>> \n", 6); + +@@ -4218,28 +4218,28 @@ + + unsigned int i=0; + tsize_t written=0; +- char buffer[16]; ++ char buffer[256]; + int buflen=0; + + written += t2pWriteFile(output, (tdata_t) "<<\n/Type /Page \n/Parent ", 24); +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_pages); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_pages); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6); + written += t2pWriteFile(output, (tdata_t) "/MediaBox [", 11); +- buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.x1); ++ buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.x1); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " ", 1); +- buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.y1); ++ buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.y1); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " ", 1); +- buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.x2); ++ buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.x2); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " ", 1); +- buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.y2); ++ buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.y2); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "] \n", 3); + written += t2pWriteFile(output, (tdata_t) "/Contents ", 10); +- buflen=sprintf(buffer, "%lu", (unsigned long)(object + 1)); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)(object + 1)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6); + written += t2pWriteFile(output, (tdata_t) "/Resources << \n", 15); +@@ -4247,15 +4247,13 @@ + written += t2pWriteFile(output, (tdata_t) "/XObject <<\n", 12); + for(i=0;itiff_tiles[t2p->pdf_page].tiles_tilecount;i++){ + written += t2pWriteFile(output, (tdata_t) "/Im", 3); +- buflen = sprintf(buffer, "%u", t2p->pdf_page+1); ++ buflen = snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_page+1); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "_", 1); +- buflen = sprintf(buffer, "%u", i+1); ++ buflen = snprintf(buffer, sizeof(buffer), "%u", i+1); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " ", 1); +- buflen = sprintf( +- buffer, +- "%lu", ++ buflen = snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)(object+3+(2*i)+t2p->tiff_pages[t2p->pdf_page].page_extra)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); +@@ -4267,12 +4265,10 @@ + } else { + written += t2pWriteFile(output, (tdata_t) "/XObject <<\n", 12); + written += t2pWriteFile(output, (tdata_t) "/Im", 3); +- buflen = sprintf(buffer, "%u", t2p->pdf_page+1); ++ buflen = snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_page+1); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " ", 1); +- buflen = sprintf( +- buffer, +- "%lu", ++ buflen = snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)(object+3+(2*i)+t2p->tiff_pages[t2p->pdf_page].page_extra)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); +@@ -4281,9 +4277,7 @@ + if(t2p->tiff_transferfunctioncount != 0) { + written += t2pWriteFile(output, (tdata_t) "/ExtGState <<", 13); + t2pWriteFile(output, (tdata_t) "/GS1 ", 5); +- buflen = sprintf( +- buffer, +- "%lu", ++ buflen = snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)(object + 3)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); +@@ -4644,7 +4638,7 @@ + if(t2p->tiff_tiles[t2p->pdf_page].tiles_tilecount>0){ + for(i=0;itiff_tiles[t2p->pdf_page].tiles_tilecount; i++){ + box=t2p->tiff_tiles[t2p->pdf_page].tiles_tiles[i].tile_box; +- buflen=sprintf(buffer, ++ buflen=snprintf(buffer, sizeof(buffer), + "q %s %.4f %.4f %.4f %.4f %.4f %.4f cm /Im%d_%ld Do Q\n", + t2p->tiff_transferfunctioncount?"/GS1 gs ":"", + box.mat[0], +@@ -4659,7 +4653,7 @@ + } + } else { + box=t2p->pdf_imagebox; +- buflen=sprintf(buffer, ++ buflen=snprintf(buffer, sizeof(buffer), + "q %s %.4f %.4f %.4f %.4f %.4f %.4f cm /Im%d Do Q\n", + t2p->tiff_transferfunctioncount?"/GS1 gs ":"", + box.mat[0], +@@ -4684,59 +4678,48 @@ + TIFF* output){ + + tsize_t written=0; +- char buffer[16]; ++ char buffer[32]; + int buflen=0; + + written += t2p_write_pdf_stream_dict(0, t2p->pdf_xrefcount+1, output); + written += t2pWriteFile(output, + (tdata_t) "/Type /XObject \n/Subtype /Image \n/Name /Im", + 42); +- buflen=sprintf(buffer, "%u", t2p->pdf_page+1); ++ buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_page+1); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + if(tile != 0){ + written += t2pWriteFile(output, (tdata_t) "_", 1); +- buflen=sprintf(buffer, "%lu", (unsigned long)tile); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)tile); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + } + written += t2pWriteFile(output, (tdata_t) "\n/Width ", 8); +- _TIFFmemset((tdata_t)buffer, 0x00, 16); + if(tile==0){ +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_width); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->tiff_width); + } else { + if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)!=0){ +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth); + } else { +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth); + } + } + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "\n/Height ", 9); +- _TIFFmemset((tdata_t)buffer, 0x00, 16); + if(tile==0){ +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_length); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->tiff_length); + } else { + if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)!=0){ +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength); + } else { +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); + } + } + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "\n/BitsPerComponent ", 19); +- _TIFFmemset((tdata_t)buffer, 0x00, 16); +- buflen=sprintf(buffer, "%u", t2p->tiff_bitspersample); ++ buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->tiff_bitspersample); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "\n/ColorSpace ", 13); + written += t2p_write_pdf_xobject_cs(t2p, output); +@@ -4764,7 +4747,7 @@ + tsize_t t2p_write_pdf_xobject_cs(T2P* t2p, TIFF* output){ + + tsize_t written=0; +- char buffer[128]; ++ char buffer[256]; + int buflen=0; + + float X_W=1.0; +@@ -4780,11 +4763,10 @@ + t2p->pdf_colorspace ^= T2P_CS_PALETTE; + written += t2p_write_pdf_xobject_cs(t2p, output); + t2p->pdf_colorspace |= T2P_CS_PALETTE; +- buflen=sprintf(buffer, "%u", (0x0001 << t2p->tiff_bitspersample)-1 ); ++ buflen=snprintf(buffer, sizeof(buffer), "%u", (0x0001 << t2p->tiff_bitspersample)-1 ); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " ", 1); +- _TIFFmemset(buffer, 0x00, 16); +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_palettecs ); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_palettecs ); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ]\n", 7); + return(written); +@@ -4818,7 +4800,7 @@ + X_W /= Y_W; + Z_W /= Y_W; + Y_W = 1.0F; +- buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); ++ buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + X_W = 0.3457F; /* 0.3127F; */ /* D50, commented D65 */ + Y_W = 0.3585F; /* 0.3290F; */ +@@ -4826,10 +4808,10 @@ + X_W /= Y_W; + Z_W /= Y_W; + Y_W = 1.0F; +- buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); ++ buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "/Range ", 7); +- buflen=sprintf(buffer, "[%d %d %d %d] \n", ++ buflen=snprintf(buffer, sizeof(buffer), "[%d %d %d %d] \n", + t2p->pdf_labrange[0], + t2p->pdf_labrange[1], + t2p->pdf_labrange[2], +@@ -4845,26 +4827,26 @@ + tsize_t t2p_write_pdf_transfer(T2P* t2p, TIFF* output){ + + tsize_t written=0; +- char buffer[16]; ++ char buffer[32]; + int buflen=0; + + written += t2pWriteFile(output, (tdata_t) "<< /Type /ExtGState \n/TR ", 25); + if(t2p->tiff_transferfunctioncount == 1){ +- buflen=sprintf(buffer, "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)(t2p->pdf_xrefcount + 1)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); + } else { + written += t2pWriteFile(output, (tdata_t) "[ ", 2); +- buflen=sprintf(buffer, "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)(t2p->pdf_xrefcount + 1)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); +- buflen=sprintf(buffer, "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)(t2p->pdf_xrefcount + 2)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); +- buflen=sprintf(buffer, "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)(t2p->pdf_xrefcount + 3)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R ", 5); +@@ -4886,7 +4868,7 @@ + written += t2pWriteFile(output, (tdata_t) "/FunctionType 0 \n", 17); + written += t2pWriteFile(output, (tdata_t) "/Domain [0.0 1.0] \n", 19); + written += t2pWriteFile(output, (tdata_t) "/Range [0.0 1.0] \n", 18); +- buflen=sprintf(buffer, "/Size [%u] \n", (1<tiff_bitspersample)); ++ buflen=snprintf(buffer, sizeof(buffer), "/Size [%u] \n", (1<tiff_bitspersample)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "/BitsPerSample 16 \n", 19); + written += t2p_write_pdf_stream_dict(1<<(t2p->tiff_bitspersample+1), 0, output); +@@ -4913,7 +4895,7 @@ + tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){ + + tsize_t written=0; +- char buffer[128]; ++ char buffer[256]; + int buflen=0; + + float X_W=0.0; +@@ -4981,16 +4963,16 @@ + written += t2pWriteFile(output, (tdata_t) "<< \n", 4); + if(t2p->pdf_colorspace & T2P_CS_CALGRAY){ + written += t2pWriteFile(output, (tdata_t) "/WhitePoint ", 12); +- buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); ++ buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "/Gamma 2.2 \n", 12); + } + if(t2p->pdf_colorspace & T2P_CS_CALRGB){ + written += t2pWriteFile(output, (tdata_t) "/WhitePoint ", 12); +- buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); ++ buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "/Matrix ", 8); +- buflen=sprintf(buffer, "[%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f] \n", ++ buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f] \n", + X_R, Y_R, Z_R, + X_G, Y_G, Z_G, + X_B, Y_B, Z_B); +@@ -5009,11 +4991,11 @@ + tsize_t t2p_write_pdf_xobject_icccs(T2P* t2p, TIFF* output){ + + tsize_t written=0; +- char buffer[16]; ++ char buffer[32]; + int buflen=0; + + written += t2pWriteFile(output, (tdata_t) "[/ICCBased ", 11); +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_icccs); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_icccs); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " 0 R] \n", 7); + +@@ -5023,11 +5005,11 @@ + tsize_t t2p_write_pdf_xobject_icccs_dict(T2P* t2p, TIFF* output){ + + tsize_t written=0; +- char buffer[16]; ++ char buffer[32]; + int buflen=0; + + written += t2pWriteFile(output, (tdata_t) "/N ", 3); +- buflen=sprintf(buffer, "%u \n", t2p->tiff_samplesperpixel); ++ buflen=snprintf(buffer, sizeof(buffer), "%u \n", t2p->tiff_samplesperpixel); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) "/Alternate ", 11); + t2p->pdf_colorspace ^= T2P_CS_ICCBASED; +@@ -5092,7 +5074,7 @@ + tsize_t t2p_write_pdf_xobject_stream_filter(ttile_t tile, T2P* t2p, TIFF* output){ + + tsize_t written=0; +- char buffer[16]; ++ char buffer[32]; + int buflen=0; + + if(t2p->pdf_compression==T2P_COMPRESS_NONE){ +@@ -5107,41 +5089,33 @@ + written += t2pWriteFile(output, (tdata_t) "<< /K -1 ", 9); + if(tile==0){ + written += t2pWriteFile(output, (tdata_t) "/Columns ", 9); +- buflen=sprintf(buffer, "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_width); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " /Rows ", 7); +- buflen=sprintf(buffer, "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_length); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + } else { + if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)==0){ + written += t2pWriteFile(output, (tdata_t) "/Columns ", 9); +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + } else { + written += t2pWriteFile(output, (tdata_t) "/Columns ", 9); +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + } + if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)==0){ + written += t2pWriteFile(output, (tdata_t) " /Rows ", 7); +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + } else { + written += t2pWriteFile(output, (tdata_t) " /Rows ", 7); +- buflen=sprintf( +- buffer, +- "%lu", ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + } +@@ -5168,21 +5142,17 @@ + if(t2p->pdf_compressionquality%100){ + written += t2pWriteFile(output, (tdata_t) "/DecodeParms ", 13); + written += t2pWriteFile(output, (tdata_t) "<< /Predictor ", 14); +- _TIFFmemset(buffer, 0x00, 16); +- buflen=sprintf(buffer, "%u", t2p->pdf_compressionquality%100); ++ buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_compressionquality%100); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " /Columns ", 10); +- _TIFFmemset(buffer, 0x00, 16); +- buflen = sprintf(buffer, "%lu", ++ buflen = snprintf(buffer, sizeof(buffer), "%lu", + (unsigned long)t2p->tiff_width); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " /Colors ", 9); +- _TIFFmemset(buffer, 0x00, 16); +- buflen=sprintf(buffer, "%u", t2p->tiff_samplesperpixel); ++ buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->tiff_samplesperpixel); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " /BitsPerComponent ", 19); +- _TIFFmemset(buffer, 0x00, 16); +- buflen=sprintf(buffer, "%u", t2p->tiff_bitspersample); ++ buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->tiff_bitspersample); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) ">>\n", 3); + } +@@ -5202,16 +5172,16 @@ + tsize_t t2p_write_pdf_xreftable(T2P* t2p, TIFF* output){ + + tsize_t written=0; +- char buffer[21]; ++ char buffer[64]; + int buflen=0; + uint32 i=0; + + written += t2pWriteFile(output, (tdata_t) "xref\n0 ", 7); +- buflen=sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount + 1)); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)(t2p->pdf_xrefcount + 1)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); + written += t2pWriteFile(output, (tdata_t) " \n0000000000 65535 f \n", 22); + for (i=0;ipdf_xrefcount;i++){ +- sprintf(buffer, "%.10lu 00000 n \n", ++ snprintf(buffer, sizeof(buffer), "%.10lu 00000 n \n", + (unsigned long)t2p->pdf_xrefoffsets[i]); + written += t2pWriteFile(output, (tdata_t) buffer, 20); + } +@@ -5251,25 +5221,21 @@ + "%.2hhX", fileidbuf[i]); + } + written += t2pWriteFile(output, (tdata_t) "trailer\n<<\n/Size ", 17); +- buflen = sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount+1)); ++ buflen = snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)(t2p->pdf_xrefcount+1)); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); +- _TIFFmemset(buffer, 0x00, 32); + written += t2pWriteFile(output, (tdata_t) "\n/Root ", 7); +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_catalog); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_catalog); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); +- _TIFFmemset(buffer, 0x00, 32); + written += t2pWriteFile(output, (tdata_t) " 0 R \n/Info ", 12); +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_info); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_info); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); +- _TIFFmemset(buffer, 0x00, 32); + written += t2pWriteFile(output, (tdata_t) " 0 R \n/ID[<", 11); + written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid, 32); + written += t2pWriteFile(output, (tdata_t) "><", 2); + written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid, 32); + written += t2pWriteFile(output, (tdata_t) ">]\n>>\nstartxref\n", 16); +- buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_startxref); ++ buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_startxref); + written += t2pWriteFile(output, (tdata_t) buffer, buflen); +- _TIFFmemset(buffer, 0x00, 32); + written += t2pWriteFile(output, (tdata_t) "\n%%EOF\n", 7); + + return(written); +diff -Naur tiff-3.9.4.orig/tools/tiff2ps.c tiff-3.9.4/tools/tiff2ps.c +--- tiff-3.9.4.orig/tools/tiff2ps.c 2010-06-10 18:51:29.000000000 -0400 ++++ tiff-3.9.4/tools/tiff2ps.c 2013-04-16 12:52:23.884252045 -0400 +@@ -1079,8 +1079,8 @@ + imageOp = "imagemask"; + + (void)strcpy(im_x, "0"); +- (void)sprintf(im_y, "%lu", (long) h); +- (void)sprintf(im_h, "%lu", (long) h); ++ (void)snprintf(im_y, sizeof(im_y), "%lu", (long) h); ++ (void)snprintf(im_h, sizeof(im_h), "%lu", (long) h); + tile_width = w; + tile_height = h; + if (TIFFIsTiled(tif)) { +@@ -1101,7 +1101,7 @@ + } + if (tile_height < h) { + fputs("/im_y 0 def\n", fd); +- (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h); ++ (void)snprintf(im_y, sizeof(im_y), "%lu im_y sub", (unsigned long) h); + } + } else { + repeat_count = tf_numberstrips; +@@ -1113,7 +1113,7 @@ + fprintf(fd, "/im_h %lu def\n", + (unsigned long) tile_height); + (void)strcpy(im_h, "im_h"); +- (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h); ++ (void)snprintf(im_y, sizeof(im_y), "%lu im_y sub", (unsigned long) h); + } + } + +diff -Naur tiff-3.9.4.orig/tools/tiffcrop.c tiff-3.9.4/tools/tiffcrop.c +--- tiff-3.9.4.orig/tools/tiffcrop.c 2010-06-11 18:24:23.000000000 -0400 ++++ tiff-3.9.4/tools/tiffcrop.c 2013-04-16 12:57:52.968382205 -0400 +@@ -2063,7 +2063,7 @@ + strncpy (export_ext, ".tiff", 5); + export_ext[5] = '\0'; + +- sprintf (filenum, "-%03d%s", findex, export_ext); ++ snprintf(filenum, sizeof(filenum), "-%03d%s", findex, export_ext); + filenum[15] = '\0'; + strncat (exportname, filenum, 14); + } +@@ -2213,7 +2213,8 @@ + if (dump.infile != NULL) + fclose (dump.infile); + +- sprintf (temp_filename, "%s-read-%03d.%s", dump.infilename, dump_images, ++ snprintf(temp_filename, sizeof(temp_filename), "%s-read-%03d.%s", ++ dump.infilename, dump_images, + (dump.format == DUMP_TEXT) ? "txt" : "raw"); + if ((dump.infile = fopen(temp_filename, dump.mode)) == NULL) + { +@@ -2229,7 +2230,8 @@ + if (dump.outfile != NULL) + fclose (dump.outfile); + +- sprintf (temp_filename, "%s-write-%03d.%s", dump.outfilename, dump_images, ++ snprintf(temp_filename, sizeof(temp_filename), "%s-write-%03d.%s", ++ dump.outfilename, dump_images, + (dump.format == DUMP_TEXT) ? "txt" : "raw"); + if ((dump.outfile = fopen(temp_filename, dump.mode)) == NULL) + { +diff -Naur tiff-3.9.4.orig/tools/tiffdither.c tiff-3.9.4/tools/tiffdither.c +--- tiff-3.9.4.orig/tools/tiffdither.c 2010-06-08 14:50:44.000000000 -0400 ++++ tiff-3.9.4/tools/tiffdither.c 2013-04-16 12:52:23.890251187 -0400 +@@ -256,7 +256,7 @@ + TIFFSetField(out, TIFFTAG_FILLORDER, fillorder); + else + CopyField(TIFFTAG_FILLORDER, shortv); +- sprintf(thing, "Dithered B&W version of %s", argv[optind]); ++ snprintf(thing, sizeof(thing), "Dithered B&W version of %s", argv[optind]); + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); + CopyField(TIFFTAG_PHOTOMETRIC, shortv); + CopyField(TIFFTAG_ORIENTATION, shortv); diff --git a/libtiff-CVE-2013-4231.patch b/libtiff-CVE-2013-4231.patch new file mode 100644 index 0000000..8ae1e12 --- /dev/null +++ b/libtiff-CVE-2013-4231.patch @@ -0,0 +1,15 @@ +diff --git a/tools/gif2tiff.c b/tools/gif2tiff.c +index 17f7a19..375b152 100644 +--- a/tools/gif2tiff.c ++++ b/tools/gif2tiff.c +@@ -333,6 +333,10 @@ readraster(void) + int status = 1; + + datasize = getc(infile); ++ ++ if (datasize > 12) ++ return 0; ++ + clear = 1 << datasize; + eoi = clear + 1; + avail = clear + 2; diff --git a/libtiff-CVE-2013-4232.patch b/libtiff-CVE-2013-4232.patch new file mode 100644 index 0000000..5e8612c --- /dev/null +++ b/libtiff-CVE-2013-4232.patch @@ -0,0 +1,12 @@ +diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c +index 92a1a3d..26a1acb 100644 +--- a/tools/tiff2pdf.c ++++ b/tools/tiff2pdf.c +@@ -2462,6 +2462,7 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ + TIFFFileName(input)); + t2p->t2p_error = T2P_ERR_ERROR; + _TIFFfree(buffer); ++ return(0); + } else { + buffer=samplebuffer; + t2p->tiff_datasize *= t2p->tiff_samplesperpixel; diff --git a/libtiff-CVE-2013-4243.patch b/libtiff-CVE-2013-4243.patch new file mode 100644 index 0000000..20944b0 --- /dev/null +++ b/libtiff-CVE-2013-4243.patch @@ -0,0 +1,37 @@ +diff --git a/tools/gif2tiff.c b/tools/gif2tiff.c +index 2786974..9262573 100644 +--- a/tools/gif2tiff.c ++++ b/tools/gif2tiff.c +@@ -276,6 +276,10 @@ readgifimage(char* mode) + fprintf(stderr, "no colormap present for image\n"); + return (0); + } ++ if (width == 0 || height == 0) { ++ fprintf(stderr, "Invalid value of width or height\n"); ++ return(0); ++ } + if ((raster = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) { + fprintf(stderr, "not enough memory for image\n"); + return (0); +@@ -402,6 +406,10 @@ process(register int code, unsigned char** fill) + fprintf(stderr, "bad input: code=%d is larger than clear=%d\n",code, clear); + return 0; + } ++ if (*fill >= raster + width*height) { ++ fprintf(stderr, "raster full before eoi code\n"); ++ return 0; ++ } + *(*fill)++ = suffix[code]; + firstchar = oldcode = code; + return 1; +@@ -432,6 +440,10 @@ process(register int code, unsigned char** fill) + } + oldcode = incode; + do { ++ if (*fill >= raster + width*height) { ++ fprintf(stderr, "raster full before eoi code\n"); ++ return 0; ++ } + *(*fill)++ = *--stackp; + } while (stackp > stack); + return 1; diff --git a/libtiff-CVE-2013-4244.patch b/libtiff-CVE-2013-4244.patch new file mode 100644 index 0000000..792e076 --- /dev/null +++ b/libtiff-CVE-2013-4244.patch @@ -0,0 +1,15 @@ +diff --git a/tools/gif2tiff.c b/tools/gif2tiff.c +index 375b152..2731273 100644 +--- a/tools/gif2tiff.c ++++ b/tools/gif2tiff.c +@@ -402,6 +402,10 @@ process(register int code, unsigned char** fill) + } + + if (oldcode == -1) { ++ if (code >= clear) { ++ fprintf(stderr, "bad input: code=%d is larger than clear=%d\n",code, clear); ++ return 0; ++ } + *(*fill)++ = suffix[code]; + firstchar = oldcode = code; + return 1; diff --git a/libtiff-CVE-2018-7456.patch b/libtiff-CVE-2018-7456.patch new file mode 100644 index 0000000..c52bb56 --- /dev/null +++ b/libtiff-CVE-2018-7456.patch @@ -0,0 +1,196 @@ +From f1c2759436a0ee5181cae7176114f57e45f0eb16 Mon Sep 17 00:00:00 2001 +From: Hugo Lefeuvre +Date: Sun, 8 Apr 2018 14:07:08 -0400 +Subject: [PATCH] Fix NULL pointer dereference in TIFFPrintDirectory + +The TIFFPrintDirectory function relies on the following assumptions, +supposed to be guaranteed by the specification: + +(a) A Transfer Function field is only present if the TIFF file has + photometric type < 3. + +(b) If SamplesPerPixel > Color Channels, then the ExtraSamples field + has count SamplesPerPixel - (Color Channels) and contains + information about supplementary channels. + +While respect of (a) and (b) are essential for the well functioning of +TIFFPrintDirectory, no checks are realized neither by the callee nor +by TIFFPrintDirectory itself. Hence, following scenarios might happen +and trigger the NULL pointer dereference: + +(1) TIFF File of photometric type 4 or more has illegal Transfer + Function field. + +(2) TIFF File has photometric type 3 or less and defines a + SamplesPerPixel field such that SamplesPerPixel > Color Channels + without defining all extra samples in the ExtraSamples fields. + +In this patch, we address both issues with respect of the following +principles: + +(A) In the case of (1), the defined transfer table should be printed + safely even if it isn't 'legal'. This allows us to avoid expensive + checks in TIFFPrintDirectory. Also, it is quite possible that + an alternative photometric type would be developed (not part of the + standard) and would allow definition of Transfer Table. We want + libtiff to be able to handle this scenario out of the box. + +(B) In the case of (2), the transfer table should be printed at its + right size, that is if TIFF file has photometric type Palette + then the transfer table should have one row and not three, even + if two extra samples are declared. + +In order to fulfill (A) we simply add a new 'i < 3' end condition to +the broken TIFFPrintDirectory loop. This makes sure that in any case +where (b) would be respected but not (a), everything stays fine. + +(B) is fulfilled by the loop condition +'i < td->td_samplesperpixel - td->td_extrasamples'. This is enough as +long as (b) is respected. + +Naturally, we also make sure (b) is respected. This is done in the +TIFFReadDirectory function by making sure any non-color channel is +counted in ExtraSamples. + +This commit addresses CVE-2018-7456. +--- + libtiff/tif_dirread.c | 61 +++++++++++++++++++++++++++++++++++++++++++ + libtiff/tif_print.c | 2 +- + libtiff/tif_unix.c | 9 +++++++ + libtiff/tiffio.h | 1 + + 4 files changed, 72 insertions(+), 1 deletion(-) + +diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c +index 0a9484d..8dc40b5 100644 +--- a/libtiff/tif_dirread.c ++++ b/libtiff/tif_dirread.c +@@ -65,6 +65,35 @@ static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*); + static int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*); + static int TIFFFetchShortPair(TIFF*, TIFFDirEntry*); + static void ChopUpSingleUncompressedStrip(TIFF*); ++static int _TIFFGetMaxColorChannels(uint16 photometric); ++ ++/* ++ * Return the maximum number of color channels specified for a given photometric ++ * type. 0 is returned if photometric type isn't supported or no default value ++ * is defined by the specification. ++ */ ++static int _TIFFGetMaxColorChannels( uint16 photometric ) ++{ ++ switch (photometric) { ++ case PHOTOMETRIC_PALETTE: ++ case PHOTOMETRIC_MINISWHITE: ++ case PHOTOMETRIC_MINISBLACK: ++ return 1; ++ case PHOTOMETRIC_YCBCR: ++ case PHOTOMETRIC_RGB: ++ case PHOTOMETRIC_CIELAB: ++ return 3; ++ case PHOTOMETRIC_SEPARATED: ++ case PHOTOMETRIC_MASK: ++ return 4; ++ case PHOTOMETRIC_LOGL: ++ case PHOTOMETRIC_LOGLUV: ++ case PHOTOMETRIC_ITULAB: ++ case PHOTOMETRIC_ICCLAB: ++ default: ++ return 0; ++ } ++} + + /* + * Read the next TIFF directory from a file and convert it to the internal +@@ -86,6 +115,7 @@ TIFFReadDirectory(TIFF* tif) + uint16 previous_tag = 0; + int diroutoforderwarning = 0, compressionknown = 0; + int haveunknowntags = 0; ++ int color_channels; + + tif->tif_diroff = tif->tif_nextdiroff; + /* +@@ -617,6 +647,37 @@ TIFFReadDirectory(TIFF* tif) + } + } + } ++ ++ /* ++ * Make sure all non-color channels are extrasamples. ++ * If it's not the case, define them as such. ++ */ ++ color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); ++ if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) { ++ uint16 old_extrasamples; ++ uint16 *new_sampleinfo; ++ ++ TIFFWarningExt(tif->tif_clientdata,module, "Sum of Photometric type-related " ++ "color channels and ExtraSamples doesn't match SamplesPerPixel. " ++ "Defining non-color channels as ExtraSamples."); ++ ++ old_extrasamples = tif->tif_dir.td_extrasamples; ++ tif->tif_dir.td_extrasamples = (tif->tif_dir.td_samplesperpixel - color_channels); ++ ++ // sampleinfo should contain information relative to these new extra samples ++ new_sampleinfo = (uint16*) _TIFFcalloc(tif->tif_dir.td_extrasamples, sizeof(uint16)); ++ if (!new_sampleinfo) { ++ TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate memory for " ++ "temporary new sampleinfo array (%d 16 bit elements)", ++ tif->tif_dir.td_extrasamples); ++ goto bad; ++ } ++ ++ memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16)); ++ _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); ++ _TIFFfree(new_sampleinfo); ++ } ++ + /* + * Verify Palette image has a Colormap. + */ +diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c +index 0f6ea01..1ec4f26 100644 +--- a/libtiff/tif_print.c ++++ b/libtiff/tif_print.c +@@ -503,7 +503,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) + for (l = 0; l < n; l++) { + fprintf(fd, " %2lu: %5u", + l, td->td_transferfunction[0][l]); +- for (i = 1; i < td->td_samplesperpixel; i++) ++ for (i = 1; i < td->td_samplesperpixel - td->td_extrasamples && i < 3; i++) + fprintf(fd, " %5u", + td->td_transferfunction[i][l]); + fputc('\n', fd); +diff --git a/libtiff/tif_unix.c b/libtiff/tif_unix.c +index b73e80d..5d29040 100644 +--- a/libtiff/tif_unix.c ++++ b/libtiff/tif_unix.c +@@ -241,6 +241,15 @@ _TIFFmalloc(tsize_t s) + return (malloc((size_t) s)); + } + ++void* ++_TIFFcalloc(tsize_t nmemb, tsize_t siz) ++{ ++ if( nmemb == 0 || siz == 0 ) ++ return ((void *) NULL); ++ ++ return calloc((size_t) nmemb, (size_t)siz); ++} ++ + void + _TIFFfree(tdata_t p) + { +diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h +index 06ec25c..3cf8e75 100644 +--- a/libtiff/tiffio.h ++++ b/libtiff/tiffio.h +@@ -281,6 +281,7 @@ extern TIFFCodec* TIFFGetConfiguredCODECs(void); + */ + + extern tdata_t _TIFFmalloc(tsize_t); ++extern tdata_t _TIFFcalloc(tsize_t, tsize_t); + extern tdata_t _TIFFrealloc(tdata_t, tsize_t); + extern void _TIFFmemset(tdata_t, int, tsize_t); + extern void _TIFFmemcpy(tdata_t, const tdata_t, tsize_t); +-- +2.17.0 + diff --git a/libtiff-acversion.patch b/libtiff-acversion.patch new file mode 100644 index 0000000..fc3a136 --- /dev/null +++ b/libtiff-acversion.patch @@ -0,0 +1,16 @@ +This patch is needed for building the package as of F-11. It can be +dropped whenever autoconf 2.63 is no longer used on any live branch. + + +diff -Naur tiff-3.9.4.orig/configure.ac tiff-3.9.4/configure.ac +--- tiff-3.9.4.orig/configure.ac 2010-06-15 14:58:12.000000000 -0400 ++++ tiff-3.9.4/configure.ac 2010-06-15 17:13:11.000000000 -0400 +@@ -24,7 +24,7 @@ + + dnl Process this file with autoconf to produce a configure script. + +-AC_PREREQ(2.64) ++AC_PREREQ(2.63) + AC_INIT([LibTIFF Software],[3.9.4],[tiff@lists.maptools.org],[tiff]) + AC_CONFIG_AUX_DIR(config) + AC_CONFIG_MACRO_DIR(m4) diff --git a/libtiff-checkbytecount.patch b/libtiff-checkbytecount.patch new file mode 100644 index 0000000..ecd8a9f --- /dev/null +++ b/libtiff-checkbytecount.patch @@ -0,0 +1,48 @@ +Upstream fix for bug #603024 is incomplete, tif_ojpeg.c should guard against +missing strip byte counts too. Testing shows that tiffsplit.c has an issue +too. + +Filed upstream at http://bugzilla.maptools.org/show_bug.cgi?id=1996 + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_ojpeg.c tiff-3.9.4/libtiff/tif_ojpeg.c +--- tiff-3.9.4.orig/libtiff/tif_ojpeg.c 2010-06-08 19:29:51.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_ojpeg.c 2010-06-22 11:25:17.579807706 -0400 +@@ -1920,6 +1920,10 @@ + sp->in_buffer_file_pos=0; + else + { ++ if (sp->tif->tif_dir.td_stripbytecount == 0) { ++ TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing"); ++ return(0); ++ } + sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile]; + if (sp->in_buffer_file_togo==0) + sp->in_buffer_file_pos=0; +diff -Naur tiff-3.9.4.orig/tools/tiffsplit.c tiff-3.9.4/tools/tiffsplit.c +--- tiff-3.9.4.orig/tools/tiffsplit.c 2010-06-08 14:50:44.000000000 -0400 ++++ tiff-3.9.4/tools/tiffsplit.c 2010-06-22 12:23:23.258823151 -0400 +@@ -237,7 +237,10 @@ + tstrip_t s, ns = TIFFNumberOfStrips(in); + uint32 *bytecounts; + +- TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); ++ if (!TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts)) { ++ fprintf(stderr, "tiffsplit: strip byte counts are missing\n"); ++ return (0); ++ } + for (s = 0; s < ns; s++) { + if (bytecounts[s] > (uint32)bufsize) { + buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); +@@ -267,7 +270,10 @@ + ttile_t t, nt = TIFFNumberOfTiles(in); + uint32 *bytecounts; + +- TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); ++ if (!TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts)) { ++ fprintf(stderr, "tiffsplit: tile byte counts are missing\n"); ++ return (0); ++ } + for (t = 0; t < nt; t++) { + if (bytecounts[t] > (uint32) bufsize) { + buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); diff --git a/libtiff-coverity.patch b/libtiff-coverity.patch new file mode 100644 index 0000000..f636b87 --- /dev/null +++ b/libtiff-coverity.patch @@ -0,0 +1,262 @@ +From 7704f4b45c7808a6ea73d4b6684f36124ba37c11 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Wed, 12 Jun 2019 13:57:49 +0200 +Subject: [PATCH] Fix important Covscan defects + +--- + contrib/addtiffo/tif_ovrcache.c | 1 + + contrib/iptcutil/iptcutil.c | 4 +++- + libtiff/tif_ojpeg.c | 10 ++++++++++ + libtiff/tif_open.c | 1 + + test/ascii_tag.c | 2 +- + test/long_tag.c | 2 +- + test/short_tag.c | 2 +- + test/strip.c | 2 +- + tools/tiff2pdf.c | 2 ++ + tools/tiffcp.c | 6 +++++- + tools/tiffcrop.c | 1 + + tools/tiffdither.c | 3 ++- + tools/tiffsplit.c | 2 ++ + 13 files changed, 31 insertions(+), 7 deletions(-) + +diff --git a/contrib/addtiffo/tif_ovrcache.c b/contrib/addtiffo/tif_ovrcache.c +index 646b534..1d183ab 100644 +--- a/contrib/addtiffo/tif_ovrcache.c ++++ b/contrib/addtiffo/tif_ovrcache.c +@@ -110,6 +110,7 @@ TIFFOvrCache *TIFFCreateOvrCache( TIFF *hTIFF, int nDirOffset ) + TIFFErrorExt( hTIFF->tif_clientdata, hTIFF->tif_name, + "Can't allocate memory for overview cache." ); + /* TODO: use of TIFFError is inconsistent with use of fprintf in addtiffo.c, sort out */ ++ _TIFFfree( psCache ); + return NULL; + } + +diff --git a/contrib/iptcutil/iptcutil.c b/contrib/iptcutil/iptcutil.c +index 557a67e..b6be247 100644 +--- a/contrib/iptcutil/iptcutil.c ++++ b/contrib/iptcutil/iptcutil.c +@@ -293,8 +293,10 @@ int formatIPTC(FILE *ifile, FILE *ofile) + for (tagindx=0; tagindxtif_clientdata,module,"Corrupt DQT marker in JPEG data"); ++ _TIFFfree(nb); + return(0); + } + if (sp->qtable[o]!=0) +@@ -1446,13 +1450,17 @@ OJPEGReadHeaderInfoSecStreamDht(TIFF* tif) + nb[sizeof(uint32)+2]=(m>>8); + nb[sizeof(uint32)+3]=(m&255); + if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0) ++ { ++ _TIFFfree(nb); + return(0); ++ } + o=nb[sizeof(uint32)+4]; + if ((o&240)==0) + { + if (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); ++ _TIFFfree(nb); + return(0); + } + if (sp->dctable[o]!=0) +@@ -1464,12 +1472,14 @@ OJPEGReadHeaderInfoSecStreamDht(TIFF* tif) + if ((o&240)!=16) + { + TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data"); ++ _TIFFfree(nb); + return(0); + } + o&=15; + if (3tif_clientdata,module,"Corrupt DHT marker in JPEG data"); ++ _TIFFfree(nb); + return(0); + } + if (sp->actable[o]!=0) +diff --git a/libtiff/tif_open.c b/libtiff/tif_open.c +index 3b3b2ce..7578275 100644 +--- a/libtiff/tif_open.c ++++ b/libtiff/tif_open.c +@@ -175,6 +175,7 @@ TIFFClientOpen( + if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { + TIFFErrorExt(clientdata, module, + "One of the client procedures is NULL pointer."); ++ _TIFFfree(tif); + goto bad2; + } + tif->tif_readproc = readproc; +diff --git a/test/ascii_tag.c b/test/ascii_tag.c +index bf81212..0e85c8f 100644 +--- a/test/ascii_tag.c ++++ b/test/ascii_tag.c +@@ -125,7 +125,7 @@ main(int argc, char **argv) + } + + /* Write dummy pixel data. */ +- if (!TIFFWriteScanline(tif, buf, 0, 0) < 0) { ++ if (TIFFWriteScanline(tif, buf, 0, 0) == -1) { + fprintf (stderr, "Can't write image data.\n"); + goto failure; + } +diff --git a/test/long_tag.c b/test/long_tag.c +index 256bc8e..e895ee4 100644 +--- a/test/long_tag.c ++++ b/test/long_tag.c +@@ -109,7 +109,7 @@ main(int argc, char **argv) + } + + /* Write dummy pixel data. */ +- if (!TIFFWriteScanline(tif, buf, 0, 0) < 0) { ++ if (TIFFWriteScanline(tif, buf, 0, 0) == -1) { + fprintf (stderr, "Can't write image data.\n"); + goto failure; + } +diff --git a/test/short_tag.c b/test/short_tag.c +index 45214e1..c9e0c21 100644 +--- a/test/short_tag.c ++++ b/test/short_tag.c +@@ -123,7 +123,7 @@ main(int argc, char **argv) + } + + /* Write dummy pixel data. */ +- if (!TIFFWriteScanline(tif, buf, 0, 0) < 0) { ++ if (TIFFWriteScanline(tif, buf, 0, 0) == -1) { + fprintf (stderr, "Can't write image data.\n"); + goto failure; + } +diff --git a/test/strip.c b/test/strip.c +index df6406e..ab7f5ef 100644 +--- a/test/strip.c ++++ b/test/strip.c +@@ -278,7 +278,7 @@ write_scanlines(TIFF *tif, const tdata_t array, const tsize_t size) + } + + for (offset = 0, row = 0; row < length; offset+=scanlinesize, row++) { +- if (TIFFWriteScanline(tif, (char *)array + offset, row, 0) < 0) { ++ if (TIFFWriteScanline(tif, (char *)array + offset, row, 0) == -1) { + fprintf (stderr, + "Can't write image data at row %u.\n", row); + return -1; +diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c +index ac5d70d..a4ce325 100644 +--- a/tools/tiff2pdf.c ++++ b/tools/tiff2pdf.c +@@ -2440,6 +2440,7 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ + t2p->tiff_datasize, + TIFFFileName(input)); + t2p->t2p_error = T2P_ERR_ERROR; ++ _TIFFfree(buffer); + return(0); + } + for(i=0;itiff_datasize, + TIFFFileName(input)); + t2p->t2p_error = T2P_ERR_ERROR; ++ _TIFFfree(buffer); + return(0); + } + samplebufferoffset=0; +diff --git a/tools/tiffcp.c b/tools/tiffcp.c +index 48319fa..a54e65d 100644 +--- a/tools/tiffcp.c ++++ b/tools/tiffcp.c +@@ -1191,10 +1191,14 @@ DECLAREreadFunc(readSeparateStripsIntoBuffer) + { + int status = 1; + tsize_t scanlinesize = TIFFScanlineSize(in); +- tdata_t scanline = _TIFFmalloc(scanlinesize); ++ tdata_t scanline; + if (!scanlinesize) + return 0; + ++ scanline = _TIFFmalloc(scanlinesize); ++ if (!scanline) ++ return 0; ++ + (void) imagewidth; + if (scanline) { + uint8* bufp = (uint8*) buf; +diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c +index 7684318..a5d0231 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -2576,6 +2576,7 @@ static void dump_info(FILE *dumpfile, int format, char *prefix, char *msg, ...) + fprintf(dumpfile, "%s ", prefix); + vfprintf(dumpfile, msg, ap); + fprintf(dumpfile, "\n"); ++ va_end(ap); + } + } + +diff --git a/tools/tiffdither.c b/tools/tiffdither.c +index 86160f2..5ceb314 100644 +--- a/tools/tiffdither.c ++++ b/tools/tiffdither.c +@@ -77,7 +77,7 @@ fsdither(TIFF* in, TIFF* out) + * Get first line + */ + if (TIFFReadScanline(in, inputline, 0, 0) <= 0) +- return; ++ goto skip_on_error; + inptr = inputline; + nextptr = nextline; + for (j = 0; j < imagewidth; ++j) +@@ -128,6 +128,7 @@ fsdither(TIFF* in, TIFF* out) + if (TIFFWriteScanline(out, outline, i-1, 0) < 0) + break; + } ++skip_on_error: + _TIFFfree(inputline); + _TIFFfree(thisline); + _TIFFfree(nextline); +diff --git a/tools/tiffsplit.c b/tools/tiffsplit.c +index 135de2e..03b5558 100644 +--- a/tools/tiffsplit.c ++++ b/tools/tiffsplit.c +@@ -239,6 +239,7 @@ cpStrips(TIFF* in, TIFF* out) + + if (!TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts)) { + fprintf(stderr, "tiffsplit: strip byte counts are missing\n"); ++ _TIFFfree(buf); + return (0); + } + for (s = 0; s < ns; s++) { +@@ -272,6 +273,7 @@ cpTiles(TIFF* in, TIFF* out) + + if (!TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts)) { + fprintf(stderr, "tiffsplit: tile byte counts are missing\n"); ++ _TIFFfree(buf); + return (0); + } + for (t = 0; t < nt; t++) { +-- +2.21.0 + diff --git a/libtiff-getimage-64bit.patch b/libtiff-getimage-64bit.patch new file mode 100644 index 0000000..2f3d68e --- /dev/null +++ b/libtiff-getimage-64bit.patch @@ -0,0 +1,48 @@ +Fix misbehavior on 64-bit machines when trying to flip a downsampled image +vertically: unsigned ints will be widened to 64 bits the wrong way. +See RH bug #583081. + +Filed upstream at http://bugzilla.maptools.org/show_bug.cgi?id=2207 + + +diff -Naur tiff-3.9.2.orig/libtiff/tif_getimage.c tiff-3.9.2/libtiff/tif_getimage.c +--- tiff-3.9.2.orig/libtiff/tif_getimage.c 2009-08-30 12:21:46.000000000 -0400 ++++ tiff-3.9.2/libtiff/tif_getimage.c 2010-06-10 15:07:28.000000000 -0400 +@@ -1846,6 +1846,7 @@ + DECLAREContigPutFunc(putcontig8bitYCbCr22tile) + { + uint32* cp2; ++ int32 incr = 2*toskew+w; + (void) y; + fromskew = (fromskew / 2) * 6; + cp2 = cp+w+toskew; +@@ -1872,8 +1873,8 @@ + cp2 ++ ; + pp += 6; + } +- cp += toskew*2+w; +- cp2 += toskew*2+w; ++ cp += incr; ++ cp2 += incr; + pp += fromskew; + h-=2; + } +@@ -1939,6 +1940,7 @@ + DECLAREContigPutFunc(putcontig8bitYCbCr12tile) + { + uint32* cp2; ++ int32 incr = 2*toskew+w; + (void) y; + fromskew = (fromskew / 2) * 4; + cp2 = cp+w+toskew; +@@ -1953,8 +1955,8 @@ + cp2 ++; + pp += 4; + } while (--x); +- cp += toskew*2+w; +- cp2 += toskew*2+w; ++ cp += incr; ++ cp2 += incr; + pp += fromskew; + h-=2; + } diff --git a/libtiff-mantypo.patch b/libtiff-mantypo.patch new file mode 100644 index 0000000..c7e91b4 --- /dev/null +++ b/libtiff-mantypo.patch @@ -0,0 +1,17 @@ +Minor typo, reported upstream at +http://bugzilla.maptools.org/show_bug.cgi?id=2129 +This patch should not be needed as of libtiff 4.0. + + +diff -Naur tiff-3.9.2.orig/man/tiffset.1 tiff-3.9.2/man/tiffset.1 +--- tiff-3.9.2.orig/man/tiffset.1 2006-04-20 08:17:19.000000000 -0400 ++++ tiff-3.9.2/man/tiffset.1 2009-12-03 12:11:58.000000000 -0500 +@@ -60,7 +60,7 @@ + ``Anonymous'': + .RS + .nf +-tiffset \-s 305 Anonymous a.tif ++tiffset \-s 315 Anonymous a.tif + .fi + .RE + .PP diff --git a/libtiff-printdir-width.patch b/libtiff-printdir-width.patch new file mode 100644 index 0000000..6ad7534 --- /dev/null +++ b/libtiff-printdir-width.patch @@ -0,0 +1,36 @@ +Make TIFFPrintDirectory cope with both TIFF_VARIABLE and TIFF_VARIABLE2 +conventions for field_passcount fields, ie, either 16- or 32-bit counts. +This patch is taken from upstream commits dated 2012-05-23 ("fix crash +with odd 16bit count types for some custom fields") and 2012-12-12 ("Fix +TIFF_VARIABLE/TIFF_VARIABLE2 confusion in TIFFPrintDirectory"). + +This doesn't qualify as a security issue in itself, mainly because +TIFFPrintDirectory is unlikely to be used in any security-exposed +scenarios; but we need to fix it so that our test case for CVE-2012-5581 +works on all platforms. + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_print.c tiff-3.9.4/libtiff/tif_print.c +--- tiff-3.9.4.orig/libtiff/tif_print.c 2010-06-08 14:50:42.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_print.c 2012-12-13 12:17:33.726765771 -0500 +@@ -518,8 +518,19 @@ + continue; + + if(fip->field_passcount) { +- if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) ++ if (fip->field_readcount == TIFF_VARIABLE2 ) { ++ if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) ++ continue; ++ } else if (fip->field_readcount == TIFF_VARIABLE ) { ++ uint16 small_value_count; ++ if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1) ++ continue; ++ value_count = small_value_count; ++ } else { ++ assert (fip->field_readcount == TIFF_VARIABLE ++ || fip->field_readcount == TIFF_VARIABLE2); + continue; ++ } + } else { + if (fip->field_readcount == TIFF_VARIABLE + || fip->field_readcount == TIFF_VARIABLE2) diff --git a/libtiff-scanlinesize.patch b/libtiff-scanlinesize.patch new file mode 100644 index 0000000..57fe809 --- /dev/null +++ b/libtiff-scanlinesize.patch @@ -0,0 +1,72 @@ +Partial fix for issues filed upstream at +http://bugzilla.maptools.org/show_bug.cgi?id=2140 +This stops the tiffcmp core dump noted in bug #460322, but isn't enough +to make tiffcmp return the right answer (it emits a bunch of error +messages instead). + + +diff -Naur tiff-3.9.2.orig/libtiff/tif_jpeg.c tiff-3.9.2/libtiff/tif_jpeg.c +--- tiff-3.9.2.orig/libtiff/tif_jpeg.c 2009-08-30 12:21:46.000000000 -0400 ++++ tiff-3.9.2/libtiff/tif_jpeg.c 2010-01-05 22:40:40.000000000 -0500 +@@ -988,8 +988,15 @@ + tsize_t nrows; + (void) s; + +- /* data is expected to be read in multiples of a scanline */ +- if ( (nrows = sp->cinfo.d.image_height) ) { ++ nrows = cc / sp->bytesperline; ++ if (cc % sp->bytesperline) ++ TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read"); ++ ++ if( nrows > (int) sp->cinfo.d.image_height ) ++ nrows = sp->cinfo.d.image_height; ++ ++ /* data is expected to be read in multiples of a scanline */ ++ if (nrows) { + /* Cb,Cr both have sampling factors 1, so this is correct */ + JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; + int samples_per_clump = sp->samplesperclump; +@@ -1087,8 +1094,7 @@ + * TODO: resolve this */ + buf += sp->bytesperline; + cc -= sp->bytesperline; +- nrows -= sp->v_sampling; +- } while (nrows > 0); ++ } while (--nrows > 0); + + #ifdef JPEG_LIB_MK1 + _TIFFfree(tmpbuf); +diff -Naur tiff-3.9.2.orig/libtiff/tif_strip.c tiff-3.9.2/libtiff/tif_strip.c +--- tiff-3.9.2.orig/libtiff/tif_strip.c 2006-03-25 13:04:35.000000000 -0500 ++++ tiff-3.9.2/libtiff/tif_strip.c 2010-01-05 21:39:20.000000000 -0500 +@@ -238,23 +238,19 @@ + ycbcrsubsampling + 0, + ycbcrsubsampling + 1); + +- if (ycbcrsubsampling[0] == 0) { ++ if (ycbcrsubsampling[0]*ycbcrsubsampling[1] == 0) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, + "Invalid YCbCr subsampling"); + return 0; + } + +- scanline = TIFFroundup(td->td_imagewidth, ++ /* number of sample clumps per line */ ++ scanline = TIFFhowmany(td->td_imagewidth, + ycbcrsubsampling[0]); +- scanline = TIFFhowmany8(multiply(tif, scanline, +- td->td_bitspersample, +- "TIFFScanlineSize")); +- return ((tsize_t) +- summarize(tif, scanline, +- multiply(tif, 2, +- scanline / ycbcrsubsampling[0], +- "TIFFVStripSize"), +- "TIFFVStripSize")); ++ /* number of samples per line */ ++ scanline = multiply(tif, scanline, ++ ycbcrsubsampling[0]*ycbcrsubsampling[1] + 2, ++ "TIFFScanlineSize"); + } else { + scanline = multiply(tif, td->td_imagewidth, + td->td_samplesperpixel, diff --git a/libtiff-subsampling.patch b/libtiff-subsampling.patch new file mode 100644 index 0000000..a44406b --- /dev/null +++ b/libtiff-subsampling.patch @@ -0,0 +1,51 @@ +Use the spec-mandated default YCbCrSubSampling values in strip size +calculations, if the YCBCRSUBSAMPLING tag hasn't been provided. +See bug #603703. + +Filed upstream at http://bugzilla.maptools.org/show_bug.cgi?id=2215 + +NB: must be applied after libtiff-scanlinesize.patch to avoid fuzz issues. + + +diff -Naur tiff-3.9.2.orig/libtiff/tif_strip.c tiff-3.9.2/libtiff/tif_strip.c +--- tiff-3.9.2.orig/libtiff/tif_strip.c 2006-03-25 13:04:35.000000000 -0500 ++++ tiff-3.9.2/libtiff/tif_strip.c 2010-06-14 12:00:49.000000000 -0400 +@@ -124,9 +124,9 @@ + uint16 ycbcrsubsampling[2]; + tsize_t w, scanline, samplingarea; + +- TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, +- ycbcrsubsampling + 0, +- ycbcrsubsampling + 1 ); ++ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, ++ ycbcrsubsampling + 0, ++ ycbcrsubsampling + 1); + + samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1]; + if (samplingarea == 0) { +@@ -234,9 +234,9 @@ + && !isUpSampled(tif)) { + uint16 ycbcrsubsampling[2]; + +- TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING, +- ycbcrsubsampling + 0, +- ycbcrsubsampling + 1); ++ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, ++ ycbcrsubsampling + 0, ++ ycbcrsubsampling + 1); + + if (ycbcrsubsampling[0]*ycbcrsubsampling[1] == 0) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, +@@ -308,9 +308,9 @@ + && !isUpSampled(tif)) { + uint16 ycbcrsubsampling[2]; + +- TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING, +- ycbcrsubsampling + 0, +- ycbcrsubsampling + 1); ++ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, ++ ycbcrsubsampling + 0, ++ ycbcrsubsampling + 1); + + if (ycbcrsubsampling[0]*ycbcrsubsampling[1] == 0) { + TIFFErrorExt(tif->tif_clientdata, tif->tif_name, diff --git a/libtiff-tiffdump.patch b/libtiff-tiffdump.patch new file mode 100644 index 0000000..cb77796 --- /dev/null +++ b/libtiff-tiffdump.patch @@ -0,0 +1,35 @@ +Make tiffdump more paranoid about checking the count field of a directory +entry. + +Filed upstream at http://bugzilla.maptools.org/show_bug.cgi?id=2218 + + +diff -Naur tiff-3.9.4.orig/tools/tiffdump.c tiff-3.9.4/tools/tiffdump.c +--- tiff-3.9.4.orig/tools/tiffdump.c 2010-06-08 14:50:44.000000000 -0400 ++++ tiff-3.9.4/tools/tiffdump.c 2010-06-22 12:51:42.207932477 -0400 +@@ -46,6 +46,7 @@ + # include + #endif + ++#include "tiffiop.h" + #include "tiffio.h" + + #ifndef O_BINARY +@@ -317,7 +318,7 @@ + printf(">\n"); + continue; + } +- space = dp->tdir_count * datawidth[dp->tdir_type]; ++ space = TIFFSafeMultiply(int, dp->tdir_count, datawidth[dp->tdir_type]); + if (space <= 0) { + printf(">\n"); + Error("Invalid count for tag %u", dp->tdir_tag); +@@ -709,7 +710,7 @@ + w = (dir->tdir_type < NWIDTHS ? datawidth[dir->tdir_type] : 0); + cc = dir->tdir_count * w; + if (lseek(fd, (off_t)dir->tdir_offset, 0) != (off_t)-1 +- && read(fd, cp, cc) != -1) { ++ && read(fd, cp, cc) == cc) { + if (swabflag) { + switch (dir->tdir_type) { + case TIFF_SHORT: diff --git a/libtiff-tiffinfo-exif.patch b/libtiff-tiffinfo-exif.patch new file mode 100644 index 0000000..a326e21 --- /dev/null +++ b/libtiff-tiffinfo-exif.patch @@ -0,0 +1,59 @@ +Teach "tiffinfo -D" to not try to print image data inside an EXIF subdirectory, +because there isn't any. Back-patched from an upstream 4.0.2 fix. + +This is not a security issue in itself (it crashes, but with a simple NULL +pointer dereference). However, our test case for CVE-2012-5581 tickles this +bug, so it seems easier to fix this than make a new test case. + + +diff -Naur tiff-3.9.4.orig/tools/tiffinfo.c tiff-3.9.4/tools/tiffinfo.c +--- tiff-3.9.4.orig/tools/tiffinfo.c 2010-06-08 14:50:44.000000000 -0400 ++++ tiff-3.9.4/tools/tiffinfo.c 2012-12-11 16:33:17.062228558 -0500 +@@ -49,7 +49,7 @@ + int stoponerr = 1; /* stop on first read error */ + + static void usage(void); +-static void tiffinfo(TIFF*, uint16, long); ++static void tiffinfo(TIFF*, uint16, long, int); + + int + main(int argc, char* argv[]) +@@ -124,19 +124,20 @@ + if (tif != NULL) { + if (dirnum != -1) { + if (TIFFSetDirectory(tif, (tdir_t) dirnum)) +- tiffinfo(tif, order, flags); ++ tiffinfo(tif, order, flags, 1); + } else if (diroff != 0) { + if (TIFFSetSubDirectory(tif, diroff)) +- tiffinfo(tif, order, flags); ++ tiffinfo(tif, order, flags, 1); + } else { + do { + uint32 offset; + +- tiffinfo(tif, order, flags); ++ tiffinfo(tif, order, flags, 1); + if (TIFFGetField(tif, TIFFTAG_EXIFIFD, + &offset)) { +- if (TIFFReadEXIFDirectory(tif, offset)) +- tiffinfo(tif, order, flags); ++ if (TIFFReadEXIFDirectory(tif, offset)) { ++ tiffinfo(tif, order, flags, 0); ++ } + } + } while (TIFFReadDirectory(tif)); + } +@@ -426,10 +427,10 @@ + } + + static void +-tiffinfo(TIFF* tif, uint16 order, long flags) ++tiffinfo(TIFF* tif, uint16 order, long flags, int is_image) + { + TIFFPrintDirectory(tif, stdout, flags); +- if (!readdata) ++ if (!readdata || !is_image) + return; + if (rawdata) { + if (order) { diff --git a/libtiff-unknown-fix.patch b/libtiff-unknown-fix.patch new file mode 100644 index 0000000..5c3b32e --- /dev/null +++ b/libtiff-unknown-fix.patch @@ -0,0 +1,47 @@ +Ooops, previous fix to unknown-tag handling caused TIFFReadDirectory to +sometimes complain about out-of-order tags when there weren't really any. +Fix by decoupling that logic from the tag search logic. + +Filed upstream at http://bugzilla.maptools.org/show_bug.cgi?id=2210 + + +diff -Naur tiff-3.9.4.orig/libtiff/tif_dirread.c tiff-3.9.4/libtiff/tif_dirread.c +--- tiff-3.9.4.orig/libtiff/tif_dirread.c 2010-06-14 10:27:51.000000000 -0400 ++++ tiff-3.9.4/libtiff/tif_dirread.c 2010-06-16 01:27:03.000000000 -0400 +@@ -83,6 +83,7 @@ + const TIFFFieldInfo* fip; + size_t fix; + uint16 dircount; ++ uint16 previous_tag = 0; + int diroutoforderwarning = 0, compressionknown = 0; + int haveunknowntags = 0; + +@@ -163,23 +164,24 @@ + + if (dp->tdir_tag == IGNORE) + continue; +- if (fix >= tif->tif_nfields) +- fix = 0; + + /* + * Silicon Beach (at least) writes unordered + * directory tags (violating the spec). Handle + * it here, but be obnoxious (maybe they'll fix it?). + */ +- if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) { ++ if (dp->tdir_tag < previous_tag) { + if (!diroutoforderwarning) { + TIFFWarningExt(tif->tif_clientdata, module, + "%s: invalid TIFF directory; tags are not sorted in ascending order", + tif->tif_name); + diroutoforderwarning = 1; + } +- fix = 0; /* O(n^2) */ + } ++ previous_tag = dp->tdir_tag; ++ if (fix >= tif->tif_nfields || ++ dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) ++ fix = 0; /* O(n^2) */ + while (fix < tif->tif_nfields && + tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) + fix++; diff --git a/libtiff-ycbcr-clamp.patch b/libtiff-ycbcr-clamp.patch new file mode 100644 index 0000000..fbd10bb --- /dev/null +++ b/libtiff-ycbcr-clamp.patch @@ -0,0 +1,35 @@ +Using an array to clamp translated YCbCr values is insecure, because if the +TIFF file contains bogus ReferenceBlackWhite parameters, the computed RGB +values could be very far out of range (much further than the current array +size, anyway), possibly resulting in SIGSEGV. Just drop the whole idea in +favor of using a comparison-based macro to clamp. See RH bug #583081. + +Filed upstream at http://bugzilla.maptools.org/show_bug.cgi?id=2208 + + +diff -Naur tiff-3.9.2.orig/libtiff/tif_color.c tiff-3.9.2/libtiff/tif_color.c +--- tiff-3.9.2.orig/libtiff/tif_color.c 2006-02-09 10:42:20.000000000 -0500 ++++ tiff-3.9.2/libtiff/tif_color.c 2010-06-10 15:53:24.000000000 -0400 +@@ -183,13 +183,18 @@ + TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, + uint32 *r, uint32 *g, uint32 *b) + { ++ int32 i; ++ + /* XXX: Only 8-bit YCbCr input supported for now */ + Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255); + +- *r = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]]; +- *g = ycbcr->clamptab[ycbcr->Y_tab[Y] +- + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT)]; +- *b = ycbcr->clamptab[ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]]; ++ i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; ++ *r = CLAMP(i, 0, 255); ++ i = ycbcr->Y_tab[Y] ++ + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); ++ *g = CLAMP(i, 0, 255); ++ i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; ++ *b = CLAMP(i, 0, 255); + } + + /* diff --git a/sources b/sources new file mode 100644 index 0000000..ddb660b --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (tiff-3.9.4.tar.gz) = 928502edaf67a6565b0cc451d5105e4de17978f35aed6b95d21765c2a47102560ca38cd2f91f475e1073141172a0aa616e17000e78e14eb79a8ef9ba4a55b756