Hi, I've built an update for the tiff package for all the pending issues in the security tracker, including some issues that were marked "no-dsa" for various reasons. I believe some of those were actually misfiled, as arbitrary code execution seems serious enough, in my opinion, to warrant an upload.
I closed a bunch of issues I couldn't reproduce with the provided POC (with or without valgrind) in a wheezy VM as well. Those are CVE-2016-3625, CVE-2016-10094 and CVE-2016-10095. Since there are so many changes, I figured it was a good idea to submit the package for testing. In the usual location: https://people.debian.org/~anarcat/debian/wheezy-lts/ Debdiff attached. I did some quick smoke tests but didn't test all the 16+ (!) proof of concepts. If someone had the patience to go through that, it would be useful... I also wonder if there's a test suite, or where did it go if there were any before, because it doesn't seem to run on build right now. Thanks for any feedback, A. -- Il faut tout un village pour élever un enfant. - Proverbe africain
diff -Nru tiff-4.0.2/debian/changelog tiff-4.0.2/debian/changelog --- tiff-4.0.2/debian/changelog 2016-11-22 06:03:09.000000000 -0500 +++ tiff-4.0.2/debian/changelog 2017-01-17 15:05:14.000000000 -0500 @@ -1,3 +1,61 @@ +tiff (4.0.2-6+deb7u9) UNRELEASED; urgency=high + + * Non-maintainer upload by the Security Team. + * CVE-2016-3622: The fpAcc function in tif_predict.c in the tiff2rgba + tool in LibTIFF 4.0.6 and earlier allows remote attackers to cause a + denial of service (divide-by-zero error) via a crafted TIFF image. + * CVE-2016-3623: The rgb2ycbcr tool in LibTIFF 4.0.6 and earlier allows + remote attackers to cause a denial of service (divide-by-zero) by + setting the (1) v or (2) h parameter to 0. (Fixed along with CVE-2016-3624.) + * CVE-2016-3624: The cvtClump function in the rgb2ycbcr tool in + LibTIFF 4.0.6 and earlier allows remote attackers to cause a denial + of service (out-of-bounds write) by setting the "-v" option to -1. + * CVE-2016-3945: Multiple integer overflows in the (1) cvt_by_strip + and (2) cvt_by_tile functions in the tiff2rgba tool in LibTIFF 4.0.6 + and earlier, when -b mode is enabled, allow remote attackers to + cause a denial of service (crash) or execute arbitrary code via a + crafted TIFF image, which triggers an out-of-bounds write. + * CVE-2016-3990: Heap-based buffer overflow in the + horizontalDifference8 function in tif_pixarlog.c in LibTIFF 4.0.6 + and earlier allows remote attackers to cause a denial of service + (crash) or execute arbitrary code via a crafted TIFF image to + tiffcp. + * CVE-2016-9533: tif_pixarlog.c in libtiff 4.0.6 has out-of-bounds write + vulnerabilities in heap allocated buffers. Reported as MSVR 35094, aka + "PixarLog horizontalDifference heap-buffer-overflow." + * CVE-2016-9534: tif_write.c in libtiff 4.0.6 has an issue in the error + code path of TIFFFlushData1() that didn't reset the tif_rawcc and + tif_rawcp members. Reported as MSVR 35095, aka "TIFFFlushData1 + heap-buffer-overflow." + * CVE-2016-9535: tif_predict.h and tif_predict.c in libtiff 4.0.6 have + assertions that can lead to assertion failures in debug mode, or + buffer overflows in release mode, when dealing with unusual tile size + like YCbCr with subsampling. Reported as MSVR 35105, aka "Predictor + heap-buffer-overflow." + * CVE-2016-9536: tools/tiff2pdf.c in libtiff 4.0.6 has out-of-bounds + write vulnerabilities in heap allocated buffers in + t2p_process_jpeg_strip(). Reported as MSVR 35098, aka + "t2p_process_jpeg_strip heap-buffer-overflow." + * CVE-2016-9537: tools/tiffcrop.c in libtiff 4.0.6 has out-of-bounds + write vulnerabilities in buffers. Reported as MSVR 35093, MSVR 35096, + and MSVR 35097. + * CVE-2016-9538: tools/tiffcrop.c in libtiff 4.0.6 reads an undefined + buffer in readContigStripsIntoBuffer() because of a uint16 integer + overflow. Reported as MSVR 35100. + * CVE-2016-9540: tools/tiffcp.c in libtiff 4.0.6 has an out-of-bounds + write on tiled images with odd tile width versus image width. + Reported as MSVR 35103, aka cpStripToTile heap-buffer-overflow. + * CVE-2016-10092: heap-buffer-overflow in tiffcrop + * CVE-2016-10093: uint32 underflow/overflow that can cause heap-based + buffer overflow in tiffcp + * CVE-2017-5225: LibTIFF version 4.0.7 is vulnerable to a heap buffer + overflow in the tools/tiffcp resulting in DoS or code execution via + a crafted BitsPerSample value. + * heap-based buffer overflow in TIFFFillStrip (tif_read.c) (Closes: + 846837) + + -- Antoine Beaupré <anar...@debian.org> Tue, 17 Jan 2017 15:05:14 -0500 + tiff (4.0.2-6+deb7u8) wheezy-security; urgency=high * Non-maintainer upload by the Debian Long Term Support Team. diff -Nru tiff-4.0.2/debian/patches/0047-CVE-2016-9532.patch tiff-4.0.2/debian/patches/0047-CVE-2016-9532.patch --- tiff-4.0.2/debian/patches/0047-CVE-2016-9532.patch 2016-11-22 06:03:09.000000000 -0500 +++ tiff-4.0.2/debian/patches/0047-CVE-2016-9532.patch 2017-01-17 15:05:14.000000000 -0500 @@ -15,8 +15,6 @@ tools/tiffcrop.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) -diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c -index 6244385..9680ba0 100644 --- a/tools/tiffcrop.c +++ b/tools/tiffcrop.c @@ -148,6 +148,8 @@ extern int getopt(int, char**, char*); @@ -28,7 +26,7 @@ #ifndef streq #define streq(a,b) (strcmp((a),(b)) == 0) #endif -@@ -1155,7 +1157,24 @@ writeBufferToSeparateStrips (TIFF* out, uint8* buf, +@@ -1155,7 +1157,24 @@ writeBufferToSeparateStrips (TIFF* out, (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps); bytes_per_sample = (bps + 7) / 8; @@ -54,7 +52,7 @@ rowstripsize = rowsperstrip * bytes_per_sample * (width + 1); obuf = _TIFFmalloc (rowstripsize); -@@ -1242,11 +1261,19 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength, +@@ -1242,11 +1261,19 @@ static int writeBufferToContigTiles (TIF } } @@ -76,7 +74,7 @@ for (row = 0; row < imagelength; row += tl) { nrow = (row + tl > imagelength) ? imagelength - row : tl; -@@ -1306,7 +1333,16 @@ static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength +@@ -1306,7 +1333,16 @@ static int writeBufferToSeparateTiles (T TIFFGetField(out, TIFFTAG_TILELENGTH, &tl); TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps); diff -Nru tiff-4.0.2/debian/patches/0048-CVE-2016-9533.patch tiff-4.0.2/debian/patches/0048-CVE-2016-9533.patch --- tiff-4.0.2/debian/patches/0048-CVE-2016-9533.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0048-CVE-2016-9533.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,110 @@ +From 83a4b92815ea04969d494416eaae3d4c6b338e4a Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Fri, 23 Sep 2016 22:12:18 +0000 +Subject: [PATCH] * tools/tiffcrop.c: fix various out-of-bounds write + vulnerabilities in heap or stack allocated buffers. Reported as MSVR 35093, + MSVR 35096 and MSVR 35097. Discovered by Axel Souchet and Vishal Chauhan from + the MSRC Vulnerabilities & Mitigations team. * tools/tiff2pdf.c: fix + out-of-bounds write vulnerabilities in heap allocate buffer in + t2p_process_jpeg_strip(). Reported as MSVR 35098. Discovered by Axel Souchet + and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_pixarlog.c: fix out-of-bounds write vulnerabilities in heap + allocated buffers. Reported as MSVR 35094. Discovered by Axel Souchet and + Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_write.c: fix issue in error code path of TIFFFlushData1() that + didn't reset the tif_rawcc and tif_rawcp members. I'm not completely sure if + that could happen in practice outside of the odd behaviour of t2p_seekproc() + of tiff2pdf). The report points that a better fix could be to check the + return value of TIFFFlushData1() in places where it isn't done currently, but + it seems this patch is enough. Reported as MSVR 35095. Discovered by Axel + Souchet & Vishal Chauhan & Suha Can from the MSRC Vulnerabilities & + Mitigations team. + +--- + ChangeLog | 23 +++++++++++++++++++++ + libtiff/tif_pixarlog.c | 55 +++++++++++++++++++++----------------------------- + libtiff/tif_write.c | 7 +++++++ + tools/tiff2pdf.c | 22 ++++++++++++++++++-- + tools/tiffcrop.c | 20 +++++++++++++++++- + 5 files changed, 92 insertions(+), 35 deletions(-) + +--- a/libtiff/tif_pixarlog.c ++++ b/libtiff/tif_pixarlog.c +@@ -965,17 +965,14 @@ horizontalDifferenceF(float *ip, int n, + a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1; + } + } else { +- ip += n - 1; /* point to last one */ +- wp += n - 1; /* point to last one */ +- n -= stride; +- while (n > 0) { +- REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); +- wp[stride] -= wp[0]; +- wp[stride] &= mask; +- wp--; ip--) +- n -= stride; +- } +- REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--) ++ REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp++; ip++) ++ n -= stride; ++ while (n > 0) { ++ REPEAT(stride, ++ wp[0] = (uint16)(((int32)CLAMP(ip[0])-(int32)CLAMP(ip[-stride])) & mask); ++ wp++; ip++) ++ n -= stride; ++ } + } + } + } +@@ -1018,17 +1015,14 @@ horizontalDifference16(unsigned short *i + a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1; + } + } else { +- ip += n - 1; /* point to last one */ +- wp += n - 1; /* point to last one */ ++ REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) + n -= stride; + while (n > 0) { +- REPEAT(stride, wp[0] = CLAMP(ip[0]); +- wp[stride] -= wp[0]; +- wp[stride] &= mask; +- wp--; ip--) +- n -= stride; +- } +- REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--) ++ REPEAT(stride, ++ wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); ++ wp++; ip++) ++ n -= stride; ++ } + } + } + } +@@ -1071,18 +1065,15 @@ horizontalDifference8(unsigned char *ip, + ip += 4; + } + } else { +- wp += n + stride - 1; /* point to last one */ +- ip += n + stride - 1; /* point to last one */ +- n -= stride; +- while (n > 0) { +- REPEAT(stride, wp[0] = CLAMP(ip[0]); +- wp[stride] -= wp[0]; +- wp[stride] &= mask; +- wp--; ip--) +- n -= stride; +- } +- REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--) +- } ++ REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) ++ n -= stride; ++ while (n > 0) { ++ REPEAT(stride, ++ wp[0] = (uint16)((CLAMP(ip[0])-CLAMP(ip[-stride])) & mask); ++ wp++; ip++) ++ n -= stride; ++ } ++ } + } + } + diff -Nru tiff-4.0.2/debian/patches/0049-CVE-2016-9534.patch tiff-4.0.2/debian/patches/0049-CVE-2016-9534.patch --- tiff-4.0.2/debian/patches/0049-CVE-2016-9534.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0049-CVE-2016-9534.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,47 @@ +From 83a4b92815ea04969d494416eaae3d4c6b338e4a Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Fri, 23 Sep 2016 22:12:18 +0000 +Subject: [PATCH] * tools/tiffcrop.c: fix various out-of-bounds write + vulnerabilities in heap or stack allocated buffers. Reported as MSVR 35093, + MSVR 35096 and MSVR 35097. Discovered by Axel Souchet and Vishal Chauhan from + the MSRC Vulnerabilities & Mitigations team. * tools/tiff2pdf.c: fix + out-of-bounds write vulnerabilities in heap allocate buffer in + t2p_process_jpeg_strip(). Reported as MSVR 35098. Discovered by Axel Souchet + and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_pixarlog.c: fix out-of-bounds write vulnerabilities in heap + allocated buffers. Reported as MSVR 35094. Discovered by Axel Souchet and + Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_write.c: fix issue in error code path of TIFFFlushData1() that + didn't reset the tif_rawcc and tif_rawcp members. I'm not completely sure if + that could happen in practice outside of the odd behaviour of t2p_seekproc() + of tiff2pdf). The report points that a better fix could be to check the + return value of TIFFFlushData1() in places where it isn't done currently, but + it seems this patch is enough. Reported as MSVR 35095. Discovered by Axel + Souchet & Vishal Chauhan & Suha Can from the MSRC Vulnerabilities & + Mitigations team. + +--- + ChangeLog | 23 +++++++++++++++++++++ + libtiff/tif_pixarlog.c | 55 +++++++++++++++++++++----------------------------- + libtiff/tif_write.c | 7 +++++++ + tools/tiff2pdf.c | 22 ++++++++++++++++++-- + tools/tiffcrop.c | 20 +++++++++++++++++- + 5 files changed, 92 insertions(+), 35 deletions(-) + +--- a/libtiff/tif_write.c ++++ b/libtiff/tif_write.c +@@ -720,7 +720,14 @@ TIFFFlushData1(TIFF* tif) + if (!TIFFAppendToStrip(tif, + isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, + tif->tif_rawdata, tif->tif_rawcc)) ++ { ++ /* We update those variables even in case of error since there's */ ++ /* code that doesn't really check the return code of this */ ++ /* function */ ++ tif->tif_rawcc = 0; ++ tif->tif_rawcp = tif->tif_rawdata; + return (0); ++ } + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + } diff -Nru tiff-4.0.2/debian/patches/0050-CVE-2016-9536.patch tiff-4.0.2/debian/patches/0050-CVE-2016-9536.patch --- tiff-4.0.2/debian/patches/0050-CVE-2016-9536.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0050-CVE-2016-9536.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,116 @@ +From 83a4b92815ea04969d494416eaae3d4c6b338e4a Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Fri, 23 Sep 2016 22:12:18 +0000 +Subject: [PATCH] * tools/tiffcrop.c: fix various out-of-bounds write + vulnerabilities in heap or stack allocated buffers. Reported as MSVR 35093, + MSVR 35096 and MSVR 35097. Discovered by Axel Souchet and Vishal Chauhan from + the MSRC Vulnerabilities & Mitigations team. * tools/tiff2pdf.c: fix + out-of-bounds write vulnerabilities in heap allocate buffer in + t2p_process_jpeg_strip(). Reported as MSVR 35098. Discovered by Axel Souchet + and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_pixarlog.c: fix out-of-bounds write vulnerabilities in heap + allocated buffers. Reported as MSVR 35094. Discovered by Axel Souchet and + Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_write.c: fix issue in error code path of TIFFFlushData1() that + didn't reset the tif_rawcc and tif_rawcp members. I'm not completely sure if + that could happen in practice outside of the odd behaviour of t2p_seekproc() + of tiff2pdf). The report points that a better fix could be to check the + return value of TIFFFlushData1() in places where it isn't done currently, but + it seems this patch is enough. Reported as MSVR 35095. Discovered by Axel + Souchet & Vishal Chauhan & Suha Can from the MSRC Vulnerabilities & + Mitigations team. + +--- + ChangeLog | 23 +++++++++++++++++++++ + libtiff/tif_pixarlog.c | 55 +++++++++++++++++++++----------------------------- + libtiff/tif_write.c | 7 +++++++ + tools/tiff2pdf.c | 22 ++++++++++++++++++-- + tools/tiffcrop.c | 20 +++++++++++++++++- + 5 files changed, 92 insertions(+), 35 deletions(-) + +--- a/tools/tiff2pdf.c ++++ b/tools/tiff2pdf.c +@@ -286,7 +286,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P + int t2p_process_ojpeg_tables(T2P*, TIFF*); + #endif + #ifdef JPEG_SUPPORT +-int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t*, tstrip_t, uint32); ++int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t, tsize_t*, tstrip_t, uint32); + #endif + void t2p_tile_collapse_left(tdata_t, tsize_t, uint32, uint32, uint32); + void t2p_write_advance_directory(T2P*, TIFF*); +@@ -2375,7 +2375,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p + if(!t2p_process_jpeg_strip( + stripbuffer, + &striplength, +- buffer, ++ buffer, ++ t2p->tiff_datasize, + &bufferoffset, + i, + t2p->tiff_length)){ +@@ -3407,6 +3408,7 @@ int t2p_process_jpeg_strip( + unsigned char* strip, + tsize_t* striplength, + unsigned char* buffer, ++ tsize_t buffersize, + tsize_t* bufferoffset, + tstrip_t no, + uint32 height){ +@@ -3441,6 +3443,8 @@ int t2p_process_jpeg_strip( + } + switch( strip[i] ){ + case 0xd8: /* SOI - start of image */ ++ if( *bufferoffset + 2 > buffersize ) ++ return(0); + _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), 2); + *bufferoffset+=2; + break; +@@ -3450,12 +3454,18 @@ int t2p_process_jpeg_strip( + case 0xc9: /* SOF9 */ + case 0xca: /* SOF10 */ + if(no==0){ ++ if( *bufferoffset + datalen + 2 + 6 > buffersize ) ++ return(0); + _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2); ++ if( *bufferoffset + 9 >= buffersize ) ++ return(0); + ncomp = buffer[*bufferoffset+9]; + if (ncomp < 1 || ncomp > 4) + return(0); + v_samp=1; + h_samp=1; ++ if( *bufferoffset + 11 + 3*(ncomp-1) >= buffersize ) ++ return(0); + for(j=0;j<ncomp;j++){ + uint16 samp = buffer[*bufferoffset+11+(3*j)]; + if( (samp>>4) > h_samp) +@@ -3487,20 +3497,28 @@ int t2p_process_jpeg_strip( + break; + case 0xc4: /* DHT */ + case 0xdb: /* DQT */ ++ if( *bufferoffset + datalen + 2 > buffersize ) ++ return(0); + _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2); + *bufferoffset+=datalen+2; + break; + case 0xda: /* SOS */ + if(no==0){ ++ if( *bufferoffset + datalen + 2 > buffersize ) ++ return(0); + _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2); + *bufferoffset+=datalen+2; + } else { ++ if( *bufferoffset + 2 > buffersize ) ++ return(0); + buffer[(*bufferoffset)++]=0xff; + buffer[(*bufferoffset)++]= + (unsigned char)(0xd0 | ((no-1)%8)); + } + i += datalen + 1; + /* copy remainder of strip */ ++ if( *bufferoffset + *striplength - i > buffersize ) ++ return(0); + _TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i]), *striplength - i); + *bufferoffset+= *striplength - i; + return(1); diff -Nru tiff-4.0.2/debian/patches/0051-CVE-2016-9537.patch tiff-4.0.2/debian/patches/0051-CVE-2016-9537.patch --- tiff-4.0.2/debian/patches/0051-CVE-2016-9537.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0051-CVE-2016-9537.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,78 @@ +From 83a4b92815ea04969d494416eaae3d4c6b338e4a Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Fri, 23 Sep 2016 22:12:18 +0000 +Subject: [PATCH] * tools/tiffcrop.c: fix various out-of-bounds write + vulnerabilities in heap or stack allocated buffers. Reported as MSVR 35093, + MSVR 35096 and MSVR 35097. Discovered by Axel Souchet and Vishal Chauhan from + the MSRC Vulnerabilities & Mitigations team. * tools/tiff2pdf.c: fix + out-of-bounds write vulnerabilities in heap allocate buffer in + t2p_process_jpeg_strip(). Reported as MSVR 35098. Discovered by Axel Souchet + and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_pixarlog.c: fix out-of-bounds write vulnerabilities in heap + allocated buffers. Reported as MSVR 35094. Discovered by Axel Souchet and + Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. * + libtiff/tif_write.c: fix issue in error code path of TIFFFlushData1() that + didn't reset the tif_rawcc and tif_rawcp members. I'm not completely sure if + that could happen in practice outside of the odd behaviour of t2p_seekproc() + of tiff2pdf). The report points that a better fix could be to check the + return value of TIFFFlushData1() in places where it isn't done currently, but + it seems this patch is enough. Reported as MSVR 35095. Discovered by Axel + Souchet & Vishal Chauhan & Suha Can from the MSRC Vulnerabilities & + Mitigations team. + +--- + ChangeLog | 23 +++++++++++++++++++++ + libtiff/tif_pixarlog.c | 55 +++++++++++++++++++++----------------------------- + libtiff/tif_write.c | 7 +++++++ + tools/tiff2pdf.c | 22 ++++++++++++++++++-- + tools/tiffcrop.c | 20 +++++++++++++++++- + 5 files changed, 92 insertions(+), 35 deletions(-) + +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -5785,7 +5785,8 @@ loadImage(TIFF* in, struct image_data *i + { + uint32 i; + float xres = 0.0, yres = 0.0; +- uint16 nstrips = 0, ntiles = 0, planar = 0; ++ uint32 nstrips = 0, ntiles = 0; ++ uint16 planar = 0; + uint16 bps = 0, spp = 0, res_unit = 0; + uint16 orientation = 0; + uint16 input_compression = 0, input_photometric = 0; +@@ -6093,11 +6094,23 @@ loadImage(TIFF* in, struct image_data *i + /* +3 : add a few guard bytes since reverseSamples16bits() can read a bit */ + /* outside buffer */ + if (!read_buff) ++ { ++ if( buffsize > 0xFFFFFFFFU - 3 ) ++ { ++ TIFFError("loadImage", "Unable to allocate/reallocate read buffer"); ++ return (-1); ++ } + read_buff = (unsigned char *)_TIFFmalloc(buffsize+3); ++ } + else + { + if (prev_readsize < buffsize) ++ { ++ if( buffsize > 0xFFFFFFFFU - 3 ) + { ++ TIFFError("loadImage", "Unable to allocate/reallocate read buffer"); ++ return (-1); ++ } + new_buff = _TIFFrealloc(read_buff, buffsize); + if (!new_buff) + { +@@ -8923,6 +8936,11 @@ reverseSamplesBytes (uint16 spp, uint16 + } + + bytes_per_pixel = ((bps * spp) + 7) / 8; ++ if( bytes_per_pixel > sizeof(swapbuff) ) ++ { ++ TIFFError("reverseSamplesBytes","bytes_per_pixel too large"); ++ return (1); ++ } + switch (bps / 8) + { + case 8: /* Use memcpy for multiple bytes per sample data */ diff -Nru tiff-4.0.2/debian/patches/0052-CVE-2016-9535.patch tiff-4.0.2/debian/patches/0052-CVE-2016-9535.patch --- tiff-4.0.2/debian/patches/0052-CVE-2016-9535.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0052-CVE-2016-9535.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,402 @@ +Description: fix for CVE-2016-9535, a merge of 3ca657a8793dd011bf869695d72ad31c779c3cc1 and 6a984bf7905c6621281588431f384e79d11a2e33 upstream + +Subject: [PATCH] * libtiff/tif_predict.h, libtiff/tif_predict.c: Replace + assertions by runtime checks to avoid assertions in debug mode, or buffer + overflows in release mode. Can happen when dealing with unusual tile size + like YCbCr with subsampling. Reported as MSVR 35105 by Axel Souchet & + Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. +Subject: [PATCH] * libtiff/tif_predic.c: fix memory leaks in error code paths + added in previous commit (fix for MSVR 35105) + +Note that the swab* functions were refactored to follow upstream to +simplify the patch and ease possible future fixes. + +--- a/libtiff/tif_predict.c ++++ b/libtiff/tif_predict.c +@@ -34,16 +34,16 @@ + + #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) + +-static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc); +-static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc); + static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); + static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); + static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); +@@ -239,13 +239,19 @@ PredictorSetupEncode(TIFF* tif) + case 0: ; \ + } + +-static void ++static int + horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) + { + tmsize_t stride = PredictorState(tif)->stride; + + char* cp = (char*) cp0; +- assert((cc%stride)==0); ++ if((cc%stride)!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "horAcc8", ++ "%s", "(cc%stride)!=0"); ++ return 0; ++ } ++ + if (cc > stride) { + /* + * Pipeline the most common cases. +@@ -287,35 +293,32 @@ horAcc8(TIFF* tif, uint8* cp0, tmsize_t + } while (cc>0); + } + } ++ return 1; + } + +-static void ++static int + swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) + { +- tmsize_t stride = PredictorState(tif)->stride; + uint16* wp = (uint16*) cp0; + tmsize_t wc = cc / 2; + +- assert((cc%(2*stride))==0); +- +- if (wc > stride) { +- TIFFSwabArrayOfShort(wp, wc); +- wc -= stride; +- do { +- REPEAT4(stride, wp[stride] += wp[0]; wp++) +- wc -= stride; +- } while (wc > 0); +- } ++ TIFFSwabArrayOfShort(wp, wc); ++ return horAcc16(tif, cp0, cc); + } + +-static void ++static int + horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) + { + tmsize_t stride = PredictorState(tif)->stride; + uint16* wp = (uint16*) cp0; + tmsize_t wc = cc / 2; + +- assert((cc%(2*stride))==0); ++ if((cc%(2*stride))!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "horAcc16", ++ "%s", "cc%(2*stride))!=0"); ++ return 0; ++ } + + if (wc > stride) { + wc -= stride; +@@ -324,35 +327,32 @@ horAcc16(TIFF* tif, uint8* cp0, tmsize_t + wc -= stride; + } while (wc > 0); + } ++ return 1; + } + +-static void ++static int + swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) + { +- tmsize_t stride = PredictorState(tif)->stride; + uint32* wp = (uint32*) cp0; + tmsize_t wc = cc / 4; + +- assert((cc%(4*stride))==0); +- +- if (wc > stride) { +- TIFFSwabArrayOfLong(wp, wc); +- wc -= stride; +- do { +- REPEAT4(stride, wp[stride] += wp[0]; wp++) +- wc -= stride; +- } while (wc > 0); +- } ++ TIFFSwabArrayOfLong(wp, wc); ++ return horAcc32(tif, cp0, cc); + } + +-static void ++static int + horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) + { + tmsize_t stride = PredictorState(tif)->stride; + uint32* wp = (uint32*) cp0; + tmsize_t wc = cc / 4; + +- assert((cc%(4*stride))==0); ++ if((cc%(4*stride))!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "horAcc32", ++ "%s", "cc%(4*stride))!=0"); ++ return 0; ++ } + + if (wc > stride) { + wc -= stride; +@@ -361,12 +361,13 @@ horAcc32(TIFF* tif, uint8* cp0, tmsize_t + wc -= stride; + } while (wc > 0); + } ++ return 1; + } + + /* + * Floating point predictor accumulation routine. + */ +-static void ++static int + fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) + { + tmsize_t stride = PredictorState(tif)->stride; +@@ -374,12 +375,18 @@ fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc + tmsize_t wc = cc / bps; + tmsize_t count = cc; + uint8 *cp = (uint8 *) cp0; +- uint8 *tmp = (uint8 *)_TIFFmalloc(cc); ++ uint8 *tmp; + +- assert((cc%(bps*stride))==0); ++ if(cc%(bps*stride)!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "fpAcc", ++ "%s", "cc%(bps*stride))!=0"); ++ return 0; ++ } + ++ tmp = (uint8 *)_TIFFmalloc(cc); + if (!tmp) +- return; ++ return 0; + + while (count > stride) { + REPEAT4(stride, cp[stride] += cp[0]; cp++) +@@ -400,6 +407,7 @@ fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc + } + } + _TIFFfree(tmp); ++ return 1; + } + + /* +@@ -415,8 +423,7 @@ PredictorDecodeRow(TIFF* tif, uint8* op0 + assert(sp->decodepfunc != NULL); + + if ((*sp->decoderow)(tif, op0, occ0, s)) { +- (*sp->decodepfunc)(tif, op0, occ0); +- return 1; ++ return (*sp->decodepfunc)(tif, op0, occ0); + } else + return 0; + } +@@ -439,10 +446,16 @@ PredictorDecodeTile(TIFF* tif, uint8* op + if ((*sp->decodetile)(tif, op0, occ0, s)) { + tmsize_t rowsize = sp->rowsize; + assert(rowsize > 0); +- assert((occ0%rowsize)==0); ++ if((occ0%rowsize) !=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "PredictorDecodeTile", ++ "%s", "occ0%rowsize != 0"); ++ return 0; ++ } + assert(sp->decodepfunc != NULL); + while (occ0 > 0) { +- (*sp->decodepfunc)(tif, op0, rowsize); ++ if( !(*sp->decodepfunc)(tif, op0, rowsize) ) ++ return 0; + occ0 -= rowsize; + op0 += rowsize; + } +@@ -451,14 +464,19 @@ PredictorDecodeTile(TIFF* tif, uint8* op + return 0; + } + +-static void ++static int + horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) + { + TIFFPredictorState* sp = PredictorState(tif); + tmsize_t stride = sp->stride; + char* cp = (char*) cp0; + +- assert((cc%stride)==0); ++ if((cc%stride)!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "horDiff8", ++ "%s", "(cc%stride)!=0"); ++ return 0; ++ } + + if (cc > stride) { + cc -= stride; +@@ -496,9 +514,10 @@ horDiff8(TIFF* tif, uint8* cp0, tmsize_t + } while ((cc -= stride) > 0); + } + } ++ return 1; + } + +-static void ++static int + horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) + { + TIFFPredictorState* sp = PredictorState(tif); +@@ -506,7 +525,12 @@ horDiff16(TIFF* tif, uint8* cp0, tmsize_ + int16 *wp = (int16*) cp0; + tmsize_t wc = cc/2; + +- assert((cc%(2*stride))==0); ++ if((cc%(2*stride))!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "horDiff8", ++ "%s", "(cc%(2*stride))!=0"); ++ return 0; ++ } + + if (wc > stride) { + wc -= stride; +@@ -516,9 +540,10 @@ horDiff16(TIFF* tif, uint8* cp0, tmsize_ + wc -= stride; + } while (wc > 0); + } ++ return 1; + } + +-static void ++static int + horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) + { + TIFFPredictorState* sp = PredictorState(tif); +@@ -526,7 +551,12 @@ horDiff32(TIFF* tif, uint8* cp0, tmsize_ + int32 *wp = (int32*) cp0; + tmsize_t wc = cc/4; + +- assert((cc%(4*stride))==0); ++ if((cc%(4*stride))!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "horDiff32", ++ "%s", "(cc%(4*stride))!=0"); ++ return 0; ++ } + + if (wc > stride) { + wc -= stride; +@@ -536,12 +566,13 @@ horDiff32(TIFF* tif, uint8* cp0, tmsize_ + wc -= stride; + } while (wc > 0); + } ++ return 1; + } + + /* + * Floating point predictor differencing routine. + */ +-static void ++static int + fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) + { + tmsize_t stride = PredictorState(tif)->stride; +@@ -549,12 +580,18 @@ fpDiff(TIFF* tif, uint8* cp0, tmsize_t c + tmsize_t wc = cc / bps; + tmsize_t count; + uint8 *cp = (uint8 *) cp0; +- uint8 *tmp = (uint8 *)_TIFFmalloc(cc); ++ uint8 *tmp; + +- assert((cc%(bps*stride))==0); ++ if((cc%(bps*stride))!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "fpDiff", ++ "%s", "(cc%(bps*stride))!=0"); ++ return 0; ++ } + ++ tmp = (uint8 *)_TIFFmalloc(cc); + if (!tmp) +- return; ++ return 0; + + _TIFFmemcpy(tmp, cp0, cc); + for (count = 0; count < wc; count++) { +@@ -574,6 +611,7 @@ fpDiff(TIFF* tif, uint8* cp0, tmsize_t c + cp += cc - stride - 1; + for (count = cc; count > stride; count -= stride) + REPEAT4(stride, cp[stride] -= cp[0]; cp--) ++ return 1; + } + + static int +@@ -586,7 +624,8 @@ PredictorEncodeRow(TIFF* tif, uint8* bp, + assert(sp->encoderow != NULL); + + /* XXX horizontal differencing alters user's data XXX */ +- (*sp->encodepfunc)(tif, bp, cc); ++ if( !(*sp->encodepfunc)(tif, bp, cc) ) ++ return 0; + return (*sp->encoderow)(tif, bp, cc, s); + } + +@@ -621,7 +660,13 @@ PredictorEncodeTile(TIFF* tif, uint8* bp + + rowsize = sp->rowsize; + assert(rowsize > 0); +- assert((cc0%rowsize)==0); ++ if((cc0%rowsize)!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "PredictorEncodeTile", ++ "%s", "(cc0%rowsize)!=0"); ++ _TIFFfree( working_copy ); ++ return 0; ++ } + while (cc > 0) { + (*sp->encodepfunc)(tif, bp, rowsize); + cc -= rowsize; +--- a/libtiff/tif_predict.h ++++ b/libtiff/tif_predict.h +@@ -30,6 +30,8 @@ + * ``Library-private'' Support for the Predictor Tag + */ + ++typedef int (*TIFFEncodeDecodeMethod)(TIFF* tif, uint8* buf, tmsize_t size); ++ + /* + * Codecs that want to support the Predictor tag must place + * this structure first in their private state block so that +@@ -43,12 +45,12 @@ typedef struct { + TIFFCodeMethod encoderow; /* parent codec encode/decode row */ + TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod encodetile; /* parent codec encode/decode tile */ +- TIFFPostMethod encodepfunc; /* horizontal differencer */ ++ TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */ + + TIFFCodeMethod decoderow; /* parent codec encode/decode row */ + TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod decodetile; /* parent codec encode/decode tile */ +- TIFFPostMethod decodepfunc; /* horizontal accumulator */ ++ TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ diff -Nru tiff-4.0.2/debian/patches/0053-CVE-2016-9538.patch tiff-4.0.2/debian/patches/0053-CVE-2016-9538.patch --- tiff-4.0.2/debian/patches/0053-CVE-2016-9538.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0053-CVE-2016-9538.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,54 @@ +From 43c0b81a818640429317c80fea1e66771e85024b Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Sat, 8 Oct 2016 15:04:31 +0000 +Subject: [PATCH] * tools/tiffcp.c: fix read of undefined variable in case of + missing required tags. Found on test case of MSVR 35100. * tools/tiffcrop.c: + fix read of undefined buffer in readContigStripsIntoBuffer() due to uint16 + overflow. Probably not a security issue but I can be wrong. Reported as MSVR + 35100 by Axel Souchet from the MSRC Vulnerabilities & Mitigations team. + +--- + ChangeLog | 9 +++++++++ + tools/tiffcp.c | 4 ++-- + tools/tiffcrop.c | 9 ++++++--- + 3 files changed, 17 insertions(+), 5 deletions(-) + +--- a/tools/tiffcp.c ++++ b/tools/tiffcp.c +@@ -586,8 +586,8 @@ static copyFunc pickCopyFunc(TIFF*, TIFF + static int + tiffcp(TIFF* in, TIFF* out) + { +- uint16 bitspersample, samplesperpixel; +- uint16 input_compression, input_photometric; ++ uint16 bitspersample, samplesperpixel = 1; ++ uint16 input_compression, input_photometric = PHOTOMETRIC_MINISBLACK; + copyFunc cf; + uint32 width, length; + struct cpTag* p; +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -3659,7 +3659,7 @@ static int readContigStripsIntoBuffer (T + { + uint8* bufp = buf; + int32 bytes_read = 0; +- uint16 strip, nstrips = TIFFNumberOfStrips(in); ++ uint32 strip, nstrips = TIFFNumberOfStrips(in); + uint32 stripsize = TIFFStripSize(in); + uint32 rows = 0; + uint32 rps = TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps); +@@ -4738,9 +4738,12 @@ static int readSeparateStripsIntoBuffer + uint32 width, uint16 spp, + struct dump_opts *dump) + { +- int i, j, bytes_per_sample, bytes_per_pixel, shift_width, result = 1; ++ int i, bytes_per_sample, bytes_per_pixel, shift_width, result = 1; ++ uint32 j; + int32 bytes_read = 0; +- uint16 bps, nstrips, planar, strips_per_sample; ++ uint16 bps, planar; ++ uint32 nstrips; ++ uint32 strips_per_sample; + uint32 src_rowsize, dst_rowsize, rows_processed, rps; + uint32 rows_this_strip = 0; + tsample_t s; diff -Nru tiff-4.0.2/debian/patches/0054-CVE-2016-9540.patch tiff-4.0.2/debian/patches/0054-CVE-2016-9540.patch --- tiff-4.0.2/debian/patches/0054-CVE-2016-9540.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0054-CVE-2016-9540.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,32 @@ +From 5ad9d8016fbb60109302d558f7edb2cb2a3bb8e3 Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Sat, 8 Oct 2016 15:54:56 +0000 +Subject: [PATCH] * tools/tiffcp.c: fix out-of-bounds write on tiled images + with odd tile width vs image width. Reported as MSVR 35103 by Axel Souchet + and Vishal Chauhan from the MSRC Vulnerabilities & Mitigations team. + +--- + ChangeLog | 7 +++++++ + tools/tiffcp.c | 4 ++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/tools/tiffcp.c ++++ b/tools/tiffcp.c +@@ -1332,7 +1332,7 @@ DECLAREreadFunc(readContigTilesIntoBuffe + uint32 colb = 0; + uint32 col; + +- for (col = 0; col < imagewidth; col += tw) { ++ for (col = 0; col < imagewidth && colb < imagew; col += tw) { + if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0 + && !ignore) { + TIFFError(TIFFFileName(in), +@@ -1517,7 +1517,7 @@ DECLAREwriteFunc(writeBufferToContigTile + uint32 colb = 0; + uint32 col; + +- for (col = 0; col < imagewidth; col += tw) { ++ for (col = 0; col < imagewidth && colb < imagew; col += tw) { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. diff -Nru tiff-4.0.2/debian/patches/0055-CVE-2016-10092.patch tiff-4.0.2/debian/patches/0055-CVE-2016-10092.patch --- tiff-4.0.2/debian/patches/0055-CVE-2016-10092.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0055-CVE-2016-10092.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,24 @@ +From 9657bbe3cdce4aaa90e07d50c1c70ae52da0ba6a Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Sat, 3 Dec 2016 11:35:56 +0000 +Subject: [PATCH] * tools/tiffcrop.c: fix readContigStripsIntoBuffer() in -i + (ignore) mode so that the output buffer is correctly incremented to avoid + write outside bounds. Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2620 + +--- + ChangeLog | 7 +++++++ + tools/tiffcrop.c | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -3679,7 +3679,7 @@ static int readContigStripsIntoBuffer (T + (unsigned long) strip, (unsigned long)rows); + return 0; + } +- bufp += bytes_read; ++ bufp += stripsize; + } + + return 1; diff -Nru tiff-4.0.2/debian/patches/0056-CVE-2016-10093.patch tiff-4.0.2/debian/patches/0056-CVE-2016-10093.patch --- tiff-4.0.2/debian/patches/0056-CVE-2016-10093.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0056-CVE-2016-10093.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,41 @@ +From 787c0ee906430b772f33ca50b97b8b5ca070faec Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Sat, 3 Dec 2016 16:40:01 +0000 +Subject: [PATCH] * tools/tiffcp.c: fix uint32 underflow/overflow that can + cause heap-based buffer overflow. Reported by Agostino Sarubbo. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2610 + +--- + ChangeLog | 7 +++++++ + tools/tiffcp.c | 6 +++--- + 2 files changed, 10 insertions(+), 3 deletions(-) + +--- a/tools/tiffcp.c ++++ b/tools/tiffcp.c +@@ -1157,7 +1157,7 @@ bad: + + static void + cpStripToTile(uint8* out, uint8* in, +- uint32 rows, uint32 cols, int outskew, int inskew) ++ uint32 rows, uint32 cols, int outskew, int64 inskew) + { + while (rows-- > 0) { + uint32 j = cols; +@@ -1314,7 +1314,7 @@ DECLAREreadFunc(readContigTilesIntoBuffe + tdata_t tilebuf; + uint32 imagew = TIFFScanlineSize(in); + uint32 tilew = TIFFTileRowSize(in); +- int iskew = imagew - tilew; ++ int64 iskew = (int64)imagew - (int64)tilew; + uint8* bufp = (uint8*) buf; + uint32 tw, tl; + uint32 row; +@@ -1342,7 +1342,7 @@ DECLAREreadFunc(readContigTilesIntoBuffe + status = 0; + goto done; + } +- if (colb + tilew > imagew) { ++ if (colb > iskew) { + uint32 width = imagew - colb; + uint32 oskew = tilew - width; + cpStripToTile(bufp + colb, diff -Nru tiff-4.0.2/debian/patches/0057-CVE-2017-5225.patch tiff-4.0.2/debian/patches/0057-CVE-2017-5225.patch --- tiff-4.0.2/debian/patches/0057-CVE-2017-5225.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0057-CVE-2017-5225.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,67 @@ +From 5c080298d59efa53264d7248bbe3a04660db6ef7 Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Wed, 11 Jan 2017 19:25:44 +0000 +Subject: [PATCH] * tools/tiffcp.c: error out cleanly in cpContig2SeparateByRow + and cpSeparate2ContigByRow if BitsPerSample != 8 to avoid heap based + overflow. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2656 and + http://bugzilla.maptools.org/show_bug.cgi?id=2657 + +--- + ChangeLog | 7 +++++++ + tools/tiffcp.c | 24 ++++++++++++++++++++++-- + 2 files changed, 29 insertions(+), 2 deletions(-) + +--- a/tools/tiffcp.c ++++ b/tools/tiffcp.c +@@ -586,7 +586,7 @@ static copyFunc pickCopyFunc(TIFF*, TIFF + static int + tiffcp(TIFF* in, TIFF* out) + { +- uint16 bitspersample, samplesperpixel = 1; ++ uint16 bitspersample = 1, samplesperpixel = 1; + uint16 input_compression, input_photometric = PHOTOMETRIC_MINISBLACK; + copyFunc cf; + uint32 width, length; +@@ -1062,6 +1062,16 @@ DECLAREcpFunc(cpContig2SeparateByRow) + register uint32 n; + uint32 row; + tsample_t s; ++ uint16 bps = 0; ++ ++ (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps); ++ if( bps != 8 ) ++ { ++ TIFFError(TIFFFileName(in), ++ "Error, can only handle BitsPerSample=8 in %s", ++ "cpContig2SeparateByRow"); ++ return 0; ++ } + + inbuf = _TIFFmalloc(scanlinesizein); + outbuf = _TIFFmalloc(scanlinesizeout); +@@ -1115,6 +1125,16 @@ DECLAREcpFunc(cpSeparate2ContigByRow) + register uint32 n; + uint32 row; + tsample_t s; ++ uint16 bps = 0; ++ ++ (void) TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bps); ++ if( bps != 8 ) ++ { ++ TIFFError(TIFFFileName(in), ++ "Error, can only handle BitsPerSample=8 in %s", ++ "cpSeparate2ContigByRow"); ++ return 0; ++ } + + inbuf = _TIFFmalloc(scanlinesizein); + outbuf = _TIFFmalloc(scanlinesizeout); +@@ -1757,7 +1777,7 @@ pickCopyFunc(TIFF* in, TIFF* out, uint16 + uint32 w, l, tw, tl; + int bychunk; + +- (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv); ++ (void) TIFFGetFieldDefaulted(in, TIFFTAG_PLANARCONFIG, &shortv); + if (shortv != config && bitspersample != 8 && samplesperpixel > 1) { + fprintf(stderr, + "%s: Cannot handle different planar configuration w/ bits/sample != 8\n", diff -Nru tiff-4.0.2/debian/patches/0058-CVE-2016-3622.patch tiff-4.0.2/debian/patches/0058-CVE-2016-3622.patch --- tiff-4.0.2/debian/patches/0058-CVE-2016-3622.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0058-CVE-2016-3622.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,101 @@ +From 92d966a5fcfbdca67957c8c5c47b467aa650b286 Mon Sep 17 00:00:00 2001 +From: bfriesen <bfriesen> +Date: Sat, 24 Sep 2016 23:11:55 +0000 +Subject: [PATCH] * libtiff/tif_getimage.c (TIFFRGBAImageOK): Reject attempts + to read floating point images. + +* libtiff/tif_predict.c (PredictorSetup): Enforce bits-per-sample +requirements of floating point predictor (3). Fixes CVE-2016-3622 +"Divide By Zero in the tiff2rgba tool." + +places where it isn't done currently, but it seems this patch is enough. +--- + ChangeLog | 11 ++++++++++- + libtiff/tif_getimage.c | 38 ++++++++++++++++++++------------------ + libtiff/tif_predict.c | 11 ++++++++++- + 3 files changed, 40 insertions(+), 20 deletions(-) + +--- a/libtiff/tif_getimage.c ++++ b/libtiff/tif_getimage.c +@@ -95,6 +95,10 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[102 + td->td_bitspersample); + return (0); + } ++ if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) { ++ sprintf(emsg, "Sorry, can not handle images with IEEE floating-point samples"); ++ return (0); ++ } + colorchannels = td->td_samplesperpixel - td->td_extrasamples; + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { + switch (colorchannels) { +@@ -182,27 +186,25 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[102 + "Planarconfiguration", td->td_planarconfig); + return (0); + } +- if( td->td_samplesperpixel != 3 || colorchannels != 3 ) +- { +- sprintf(emsg, +- "Sorry, can not handle image with %s=%d, %s=%d", +- "Samples/pixel", td->td_samplesperpixel, +- "colorchannels", colorchannels); +- return 0; +- } ++ if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) { ++ sprintf(emsg, ++ "Sorry, can not handle image with %s=%d, %s=%d", ++ "Samples/pixel", td->td_samplesperpixel, ++ "colorchannels", colorchannels); ++ return 0; ++ } + break; + case PHOTOMETRIC_CIELAB: +- if( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) +- { +- sprintf(emsg, +- "Sorry, can not handle image with %s=%d, %s=%d and %s=%d", +- "Samples/pixel", td->td_samplesperpixel, +- "colorchannels", colorchannels, +- "Bits/sample", td->td_bitspersample); +- return 0; +- } ++ if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) { ++ sprintf(emsg, ++ "Sorry, can not handle image with %s=%d, %s=%d and %s=%d", ++ "Samples/pixel", td->td_samplesperpixel, ++ "colorchannels", colorchannels, ++ "Bits/sample", td->td_bitspersample); ++ return 0; ++ } + break; +- default: ++ default: + sprintf(emsg, "Sorry, can not handle image with %s=%d", + photoTag, photometric); + return (0); +--- a/libtiff/tif_predict.c ++++ b/libtiff/tif_predict.c +@@ -78,6 +78,15 @@ PredictorSetup(TIFF* tif) + td->td_sampleformat); + return 0; + } ++ if (td->td_bitspersample != 16 ++ && td->td_bitspersample != 24 ++ && td->td_bitspersample != 32 ++ && td->td_bitspersample != 64) { /* Should 64 be allowed? */ ++ TIFFErrorExt(tif->tif_clientdata, module, ++ "Floating point \"Predictor\" not supported with %d-bit samples", ++ td->td_bitspersample); ++ return 0; ++ } + break; + default: + TIFFErrorExt(tif->tif_clientdata, module, +@@ -172,7 +181,7 @@ PredictorSetupDecode(TIFF* tif) + } + /* + * Allocate buffer to keep the decoded bytes before +- * rearranging in the ight order ++ * rearranging in the right order + */ + } + diff -Nru tiff-4.0.2/debian/patches/0059-CVE-2016-3624.patch tiff-4.0.2/debian/patches/0059-CVE-2016-3624.patch --- tiff-4.0.2/debian/patches/0059-CVE-2016-3624.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0059-CVE-2016-3624.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,27 @@ +From bd024f07019f5d9fea236675607a69f74a66bc7b Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Mon, 15 Aug 2016 21:26:56 +0000 +Subject: [PATCH] * tools/rgb2ycbcr.c: validate values of -v and -h parameters + to avoid potential divide by zero. Fixes CVE-2016-3623 (bugzilla #2569) + +--- + ChangeLog | 5 +++++ + tools/rgb2ycbcr.c | 4 ++++ + 2 files changed, 9 insertions(+) + +--- a/tools/rgb2ycbcr.c ++++ b/tools/rgb2ycbcr.c +@@ -93,9 +93,13 @@ main(int argc, char* argv[]) + break; + case 'h': + horizSubSampling = atoi(optarg); ++ if( horizSubSampling != 1 && horizSubSampling != 2 && horizSubSampling != 4 ) ++ usage(-1); + break; + case 'v': + vertSubSampling = atoi(optarg); ++ if( vertSubSampling != 1 && vertSubSampling != 2 && vertSubSampling != 4 ) ++ usage(-1); + break; + case 'r': + rowsperstrip = atoi(optarg); diff -Nru tiff-4.0.2/debian/patches/0060-CVE-2016-3990.patch tiff-4.0.2/debian/patches/0060-CVE-2016-3990.patch --- tiff-4.0.2/debian/patches/0060-CVE-2016-3990.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0060-CVE-2016-3990.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,33 @@ +From 6a4dbb07ccf92836bb4adac7be4575672d0ac5f1 Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Mon, 15 Aug 2016 20:49:48 +0000 +Subject: [PATCH] * libtiff/tif_pixarlog.c: Fix write buffer overflow in + PixarLogEncode if more input samples are provided than expected by + PixarLogSetupEncode. Idea based on libtiff-CVE-2016-3990.patch from + libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro, but with different and + simpler check. (bugzilla #2544) + +invalid tests that rejected valid files. (bugzilla #2545) +--- + ChangeLog | 10 +++++++++- + libtiff/tif_pixarlog.c | 7 +++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c +index e78f788..28329d1 100644 +--- a/libtiff/tif_pixarlog.c ++++ b/libtiff/tif_pixarlog.c +@@ -1141,6 +1141,13 @@ PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) + } + + llen = sp->stride * td->td_imagewidth; ++ /* Check against the number of elements (of size uint16) of sp->tbuf */ ++ if( n > td->td_rowsperstrip * llen ) ++ { ++ TIFFErrorExt(tif->tif_clientdata, module, ++ "Too many input bytes provided"); ++ return 0; ++ } + + for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) { + switch (sp->user_datafmt) { diff -Nru tiff-4.0.2/debian/patches/0061-bug-846837.patch tiff-4.0.2/debian/patches/0061-bug-846837.patch --- tiff-4.0.2/debian/patches/0061-bug-846837.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0061-bug-846837.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,97 @@ +From 9a72a69e035ee70ff5c41541c8c61cd97990d018 Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Sat, 3 Dec 2016 11:02:15 +0000 +Subject: [PATCH] * libtiff/tif_dirread.c: modify + ChopUpSingleUncompressedStrip() to instanciate compute ntrips as + TIFFhowmany_32(td->td_imagelength, rowsperstrip), instead of a logic based on + the total size of data. Which is faulty is the total size of data is not + sufficient to fill the whole image, and thus results in reading outside of + the StripByCounts/StripOffsets arrays when using TIFFReadScanline(). Reported + by Agostino Sarubbo. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2608. + +* libtiff/tif_strip.c: revert the change in TIFFNumberOfStrips() done +for http://bugzilla.maptools.org/show_bug.cgi?id=2587 / CVE-2016-9273 since +the above change is a better fix that makes it unnecessary. +--- + ChangeLog | 15 +++++++++++++++ + libtiff/tif_dirread.c | 22 ++++++++++------------ + libtiff/tif_strip.c | 9 --------- + 3 files changed, 25 insertions(+), 21 deletions(-) + +--- a/libtiff/tif_dirread.c ++++ b/libtiff/tif_dirread.c +@@ -5498,8 +5498,7 @@ ChopUpSingleUncompressedStrip(TIFF* tif) + uint64 rowblockbytes; + uint64 stripbytes; + uint32 strip; +- uint64 nstrips64; +- uint32 nstrips32; ++ uint32 nstrips; + uint32 rowsperstrip; + uint64* newcounts; + uint64* newoffsets; +@@ -5530,18 +5529,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif) + return; + + /* +- * never increase the number of strips in an image ++ * never increase the number of rows per strip + */ + if (rowsperstrip >= td->td_rowsperstrip) + return; +- nstrips64 = TIFFhowmany_64(bytecount, stripbytes); +- if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */ +- return; +- nstrips32 = (uint32)nstrips64; ++ nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); ++ if( nstrips == 0 ) ++ return; + +- newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), ++ newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), + "for chopped \"StripByteCounts\" array"); +- newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64), ++ newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), + "for chopped \"StripOffsets\" array"); + if (newcounts == NULL || newoffsets == NULL) { + /* +@@ -5558,18 +5556,18 @@ ChopUpSingleUncompressedStrip(TIFF* tif) + * Fill the strip information arrays with new bytecounts and offsets + * that reflect the broken-up format. + */ +- for (strip = 0; strip < nstrips32; strip++) { ++ for (strip = 0; strip < nstrips; strip++) { + if (stripbytes > bytecount) + stripbytes = bytecount; + newcounts[strip] = stripbytes; +- newoffsets[strip] = offset; ++ newoffsets[strip] = stripbytes ? offset : 0; + offset += stripbytes; + bytecount -= stripbytes; + } + /* + * Replace old single strip info with multi-strip info. + */ +- td->td_stripsperimage = td->td_nstrips = nstrips32; ++ td->td_stripsperimage = td->td_nstrips = nstrips; + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + + _TIFFfree(td->td_stripbytecount); +--- a/libtiff/tif_strip.c ++++ b/libtiff/tif_strip.c +@@ -63,15 +63,6 @@ TIFFNumberOfStrips(TIFF* tif) + TIFFDirectory *td = &tif->tif_dir; + uint32 nstrips; + +- /* If the value was already computed and store in td_nstrips, then return it, +- since ChopUpSingleUncompressedStrip might have altered and resized the +- since the td_stripbytecount and td_stripoffset arrays to the new value +- after the initial affectation of td_nstrips = TIFFNumberOfStrips() in +- tif_dirread.c ~line 3612. +- See http://bugzilla.maptools.org/show_bug.cgi?id=2587 */ +- if( td->td_nstrips ) +- return td->td_nstrips; +- + nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 : + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) diff -Nru tiff-4.0.2/debian/patches/0062-CVE-2016-3945.patch tiff-4.0.2/debian/patches/0062-CVE-2016-3945.patch --- tiff-4.0.2/debian/patches/0062-CVE-2016-3945.patch 1969-12-31 19:00:00.000000000 -0500 +++ tiff-4.0.2/debian/patches/0062-CVE-2016-3945.patch 2017-01-17 15:05:14.000000000 -0500 @@ -0,0 +1,92 @@ +From a9bb0f1406e9da35da4da13eabacb00d9cc2efcb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nfo...@redhat.com> +Date: Mon, 11 Jul 2016 16:05:49 +0200 +Subject: [PATCH 5/8] Fix CVE-2016-3945 + +--- + tools/tiff2rgba.c | 34 ++++++++++++++++++++++++++++++---- + 1 file changed, 30 insertions(+), 4 deletions(-) + +diff --git a/tools/tiff2rgba.c b/tools/tiff2rgba.c +index 737167c..5228966 100644 +--- a/tools/tiff2rgba.c ++++ b/tools/tiff2rgba.c +@@ -145,6 +145,7 @@ cvt_by_tile( TIFF *in, TIFF *out ) + uint32 row, col; + uint32 *wrk_line; + int ok = 1; ++ uint32 rastersize, wrk_linesize; + + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); +@@ -161,7 +162,13 @@ cvt_by_tile( TIFF *in, TIFF *out ) + /* + * Allocate tile buffer + */ +- raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32)); ++ rastersize = tile_width * tile_height * sizeof (uint32); ++ if (width != (tile_width / tile_height) / sizeof( uint32)) ++ { ++ TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer"); ++ exit(-1); ++ } ++ raster = (uint32*)_TIFFmalloc(rastersize); + if (raster == 0) { + TIFFError(TIFFFileName(in), "No space for raster buffer"); + return (0); +@@ -171,7 +178,13 @@ cvt_by_tile( TIFF *in, TIFF *out ) + * Allocate a scanline buffer for swapping during the vertical + * mirroring pass. + */ +- wrk_line = (uint32*)_TIFFmalloc(tile_width * sizeof (uint32)); ++ wrk_linesize = tile_width * sizeof (uint32); ++ if (wrk_linesize != tile_width / sizeof (uint32)) ++ { ++ TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer"); ++ exit(-1); ++ } ++ wrk_line = (uint32*)_TIFFmalloc(wrk_linesize); + if (!wrk_line) { + TIFFError(TIFFFileName(in), "No space for raster scanline buffer"); + ok = 0; +@@ -247,6 +260,7 @@ cvt_by_strip( TIFF *in, TIFF *out ) + uint32 row; + uint32 *wrk_line; + int ok = 1; ++ uint32 rastersize, wrk_linesize; + + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); +@@ -261,7 +275,13 @@ cvt_by_strip( TIFF *in, TIFF *out ) + /* + * Allocate strip buffer + */ +- raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32)); ++ rastersize = width * rowsperstrip * sizeof (uint32); ++ if (width != (rastersize / rowsperstrip) / sizeof( uint32)) ++ { ++ TIFFError(TIFFFileName(in), "Integer overflow when calculating raster buffer"); ++ exit(-1); ++ } ++ raster = (uint32*)_TIFFmalloc(rastersize); + if (raster == 0) { + TIFFError(TIFFFileName(in), "No space for raster buffer"); + return (0); +@@ -271,7 +291,13 @@ cvt_by_strip( TIFF *in, TIFF *out ) + * Allocate a scanline buffer for swapping during the vertical + * mirroring pass. + */ +- wrk_line = (uint32*)_TIFFmalloc(width * sizeof (uint32)); ++ wrk_linesize = width * sizeof (uint32); ++ if (wrk_linesize != width / sizeof (uint32)) ++ { ++ TIFFError(TIFFFileName(in), "Integer overflow when calculating wrk_line buffer"); ++ exit(-1); ++ } ++ wrk_line = (uint32*)_TIFFmalloc(wrk_linesize); + if (!wrk_line) { + TIFFError(TIFFFileName(in), "No space for raster scanline buffer"); + ok = 0; +-- +2.7.4 + diff -Nru tiff-4.0.2/debian/patches/series tiff-4.0.2/debian/patches/series --- tiff-4.0.2/debian/patches/series 2016-11-22 06:03:09.000000000 -0500 +++ tiff-4.0.2/debian/patches/series 2017-01-17 15:05:14.000000000 -0500 @@ -45,3 +45,18 @@ 0045-CVE-2016-9273.patch 0046-CVE-2016-9297.patch 0047-CVE-2016-9532.patch +0048-CVE-2016-9533.patch +0049-CVE-2016-9534.patch +0050-CVE-2016-9536.patch +0051-CVE-2016-9537.patch +0052-CVE-2016-9535.patch +0053-CVE-2016-9538.patch +0054-CVE-2016-9540.patch +0055-CVE-2016-10092.patch +0056-CVE-2016-10093.patch +0057-CVE-2017-5225.patch +0058-CVE-2016-3622.patch +0059-CVE-2016-3624.patch +0060-CVE-2016-3990.patch +0061-bug-846837.patch +0062-CVE-2016-3945.patch