diff --git a/SOURCES/libtiff-CVE-2015-8870.patch b/SOURCES/libtiff-CVE-2015-8870.patch new file mode 100644 index 0000000..f83d10f --- /dev/null +++ b/SOURCES/libtiff-CVE-2015-8870.patch @@ -0,0 +1,33 @@ +From fb0bc75826b860609c59848d85daa43beb7838d6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Thu, 12 Jan 2017 15:34:59 +0100 +Subject: [PATCH 5/5] Fix CVE-2015-8870 + +--- + tools/bmp2tiff.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/tools/bmp2tiff.c b/tools/bmp2tiff.c +index c747c13..384cf96 100644 +--- a/tools/bmp2tiff.c ++++ b/tools/bmp2tiff.c +@@ -634,7 +634,16 @@ main(int argc, char* argv[]) + } + } + else ++ { + uncompr_size = width * length; ++ /* Detect int overflow */ ++ if (uncompr_size / width != length) { ++ TIFFError(infilename, ++ "Invalid dimensions of BMP file"); ++ close(fd); ++ return -1; ++ } ++ } + comprbuf = (unsigned char *) _TIFFmalloc( compr_size ); + if (!comprbuf) { + TIFFError(infilename, +-- +2.7.4 + diff --git a/SOURCES/libtiff-CVE-2016-5652.patch b/SOURCES/libtiff-CVE-2016-5652.patch new file mode 100644 index 0000000..a50d1e6 --- /dev/null +++ b/SOURCES/libtiff-CVE-2016-5652.patch @@ -0,0 +1,48 @@ +From bb2505b3d099104a296823fc3a456680417475b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Thu, 12 Jan 2017 11:30:40 +0100 +Subject: [PATCH 4/5] Fix CVE-2016-5652 + +--- + tools/tiff2pdf.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c +index fbca305..9df5b16 100644 +--- a/tools/tiff2pdf.c ++++ b/tools/tiff2pdf.c +@@ -2826,21 +2826,24 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ + return(0); + } + if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { +- if (count > 0) { +- _TIFFmemcpy(buffer, jpt, count); ++ if (count >= 4) { ++ /* Ignore EOI marker of JpegTables */ ++ _TIFFmemcpy(buffer, jpt, count - 2); + bufferoffset += count - 2; ++ /* Store last 2 bytes of the JpegTables */ + table_end[0] = buffer[bufferoffset-2]; + table_end[1] = buffer[bufferoffset-1]; +- } +- if (count > 0) { + xuint32 = bufferoffset; ++ bufferoffset -= 2; + bufferoffset += TIFFReadRawTile( + input, + tile, +- (tdata_t) &(((unsigned char*)buffer)[bufferoffset-2]), ++ (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), + -1); +- buffer[xuint32-2]=table_end[0]; +- buffer[xuint32-1]=table_end[1]; ++ /* Overwrite SOI marker of image scan with previously */ ++ /* saved end of JpegTables */ ++ buffer[xuint32-2]=table_end[0]; ++ buffer[xuint32-1]=table_end[1]; + } else { + bufferoffset += TIFFReadRawTile( + input, +-- +2.7.4 + diff --git a/SOURCES/libtiff-CVE-2016-9533_9534_9536_9537.patch b/SOURCES/libtiff-CVE-2016-9533_9534_9536_9537.patch new file mode 100644 index 0000000..445f5ad --- /dev/null +++ b/SOURCES/libtiff-CVE-2016-9533_9534_9536_9537.patch @@ -0,0 +1,300 @@ +From 6c4480d2980dc61f3fcd4f43a499e69764133f1a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Wed, 11 Jan 2017 12:50:33 +0100 +Subject: [PATCH 1/5] Fix CVE-2016-9533, CVE-2016-9534, CVE-2016-9536, + CVE-2016-9537 + +--- + libtiff/tif_pixarlog.c | 55 +++++++++++++++++++++----------------------------- + libtiff/tif_write.c | 7 +++++++ + tools/thumbnail.c | 7 ++++++- + tools/tiff2pdf.c | 22 ++++++++++++++++++-- + tools/tiffcrop.c | 31 ++++++++++++++++++++++++---- + 5 files changed, 83 insertions(+), 39 deletions(-) + +diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c +index c961529..6128f2f 100644 +--- a/libtiff/tif_pixarlog.c ++++ b/libtiff/tif_pixarlog.c +@@ -981,17 +981,14 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) + 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; ++ } + } + } + } +@@ -1034,17 +1031,14 @@ horizontalDifference16(unsigned short *ip, int n, int stride, + 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; ++ } + } + } + } +@@ -1087,18 +1081,15 @@ horizontalDifference8(unsigned char *ip, int n, int stride, + 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 --git a/libtiff/tif_write.c b/libtiff/tif_write.c +index 8792123..ce671af 100644 +--- a/libtiff/tif_write.c ++++ b/libtiff/tif_write.c +@@ -742,7 +742,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 --git a/tools/thumbnail.c b/tools/thumbnail.c +index e14d290..9a9c439 100644 +--- a/tools/thumbnail.c ++++ b/tools/thumbnail.c +@@ -587,12 +587,17 @@ generateThumbnail(TIFF* in, TIFF* out) + rowsize = TIFFScanlineSize(in); + rastersize = sh * rowsize; + fprintf(stderr, "rastersize=%u\n", (unsigned int)rastersize); +- raster = (unsigned char*)_TIFFmalloc(rastersize + 3); ++ /* +3 : add a few guard bytes since setrow() can read a bit */ ++ /* outside buffer */ ++ raster = (unsigned char*)_TIFFmalloc(rastersize+3); + if (!raster) { + TIFFError(TIFFFileName(in), + "Can't allocate space for raster buffer."); + return 0; + } ++ raster[rastersize] = 0; ++ raster[rastersize+1] = 0; ++ raster[rastersize+2] = 0; + rp = raster; + for (s = 0; s < ns; s++) { + (void) TIFFReadEncodedStrip(in, s, rp, -1); +diff --git a/tools/tiff2pdf.c b/tools/tiff2pdf.c +index 2a64ec3..fbca305 100644 +--- a/tools/tiff2pdf.c ++++ b/tools/tiff2pdf.c +@@ -285,7 +285,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P*, TIFF*, TIFF*, ttile_t); + 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*); +@@ -2348,7 +2348,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ + if(!t2p_process_jpeg_strip( + stripbuffer, + &striplength, +- buffer, ++ buffer, ++ t2p->tiff_datasize, + &bufferoffset, + i, + t2p->tiff_length)){ +@@ -3378,6 +3379,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){ +@@ -3412,6 +3414,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; +@@ -3421,12 +3425,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>4) > h_samp) +@@ -3458,20 +3468,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 --git a/tools/tiffcrop.c b/tools/tiffcrop.c +index f04e2eb..02c53cd 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -5744,7 +5744,8 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c + { + 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; +@@ -6049,17 +6050,31 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c + } + + read_buff = *read_ptr; ++ /* +3 : add a few guard bytes since reverseSamples16bits() can read a bit */ ++ /* outside buffer */ + if (!read_buff) +- read_buff = (unsigned char *)_TIFFmalloc(buffsize); ++ { ++ 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 ) + { +- new_buff = _TIFFrealloc(read_buff, buffsize); ++ TIFFError("loadImage", "Unable to allocate/reallocate read buffer"); ++ return (-1); ++ } ++ new_buff = _TIFFrealloc(read_buff, buffsize+3); + if (!new_buff) + { + free (read_buff); +- read_buff = (unsigned char *)_TIFFmalloc(buffsize); ++ read_buff = (unsigned char *)_TIFFmalloc(buffsize+3); + } + else + read_buff = new_buff; +@@ -6071,6 +6086,9 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c + TIFFError("loadImage", "Unable to allocate/reallocate read buffer"); + return (-1); + } ++ read_buff[buffsize] = 0; ++ read_buff[buffsize+1] = 0; ++ read_buff[buffsize+2] = 0; + + prev_readsize = buffsize; + *read_ptr = read_buff; +@@ -8877,6 +8895,11 @@ reverseSamplesBytes (uint16 spp, uint16 bps, uint32 width, + } + + 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 */ +-- +2.7.4 + diff --git a/SOURCES/libtiff-CVE-2016-9535.patch b/SOURCES/libtiff-CVE-2016-9535.patch new file mode 100644 index 0000000..7ec32cf --- /dev/null +++ b/SOURCES/libtiff-CVE-2016-9535.patch @@ -0,0 +1,613 @@ +From f42765c206cc2e4a77f5e3c107a9a258d981c98e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Mon, 16 Jan 2017 18:13:13 +0100 +Subject: [PATCH 2/5] Fix CVE-2016-9535 + +--- + libtiff/tif_fax3.c | 3 +- + libtiff/tif_lzw.c | 9 +- + libtiff/tif_predict.c | 285 +++++++++++++++++++++++++++++++++----------------- + libtiff/tif_predict.h | 6 +- + 4 files changed, 203 insertions(+), 100 deletions(-) + +diff --git a/libtiff/tif_fax3.c b/libtiff/tif_fax3.c +index 2b2dccd..777ef8f 100644 +--- a/libtiff/tif_fax3.c ++++ b/libtiff/tif_fax3.c +@@ -442,8 +442,9 @@ _TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx) + FILL(n, cp); + run &= 7; + } ++ /* Explicit 0xff masking to make icc -check=conversions happy */ + if (run) +- cp[0] |= 0xff00 >> run; ++ cp[0] = (unsigned char)((cp[0] | (0xff00 >> run))&0xff); + } else + cp[0] |= _fillmasks[run]>>bx; + x += runs[1]; +diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c +index fd9c7a0..d7fbe74 100644 +--- a/libtiff/tif_lzw.c ++++ b/libtiff/tif_lzw.c +@@ -830,13 +830,15 @@ LZWPreEncode(TIFF* tif, uint16 s) + } else \ + rat = (incount<<8) / outcount; \ + } ++ ++/* Explicit 0xff masking to make icc -check=conversions happy */ + #define PutNextCode(op, c) { \ + nextdata = (nextdata << nbits) | c; \ + nextbits += nbits; \ +- *op++ = (unsigned char)(nextdata >> (nextbits-8)); \ ++ *op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \ + nextbits -= 8; \ + if (nextbits >= 8) { \ +- *op++ = (unsigned char)(nextdata >> (nextbits-8)); \ ++ *op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \ + nextbits -= 8; \ + } \ + outcount += nbits; \ +@@ -1042,8 +1044,9 @@ LZWPostEncode(TIFF* tif) + sp->enc_oldcode = (hcode_t) -1; + } + PutNextCode(op, CODE_EOI); ++ /* Explicit 0xff masking to make icc -check=conversions happy */ + if (nextbits > 0) +- *op++ = (unsigned char)(nextdata << (8-nextbits)); ++ *op++ = (unsigned char)((nextdata << (8-nextbits))&0xff); + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + return (1); + } +diff --git a/libtiff/tif_predict.c b/libtiff/tif_predict.c +index f93c664..39d764f 100644 +--- a/libtiff/tif_predict.c ++++ b/libtiff/tif_predict.c +@@ -34,16 +34,18 @@ + + #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 swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); ++static int swabHorDiff32(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); +@@ -207,7 +209,24 @@ PredictorSetupEncode(TIFF* tif) + sp->encodetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } +- } ++ ++ /* ++ * If the data is horizontally differenced 16-bit data that ++ * requires byte-swapping, then it must be byte swapped after ++ * the differenciation step. We do this with a special-purpose ++ * routine and override the normal post decoding logic that ++ * the library setup when the directory was read. ++ */ ++ if (tif->tif_flags & TIFF_SWAB) { ++ if (sp->encodepfunc == horDiff16) { ++ sp->encodepfunc = swabHorDiff16; ++ tif->tif_postdecode = _TIFFNoPostDecode; ++ } else if (sp->encodepfunc == horDiff32) { ++ sp->encodepfunc = swabHorDiff32; ++ tif->tif_postdecode = _TIFFNoPostDecode; ++ } ++ } ++ } + + else if (sp->predictor == 3) { + sp->encodepfunc = fpDiff; +@@ -239,13 +258,25 @@ PredictorSetupEncode(TIFF* tif) + case 0: ; \ + } + +-static void ++/* Remarks related to C standard compliance in all below functions : */ ++/* - to avoid any undefined behaviour, we only operate on unsigned types */ ++/* since the behaviour of "overflows" is defined (wrap over) */ ++/* - when storing into the byte stream, we explicitly mask with 0xff so */ ++/* as to make icc -check=conversions happy (not necessary by the standard) */ ++ ++static int + horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) + { + tmsize_t stride = PredictorState(tif)->stride; + +- char* cp = (char*) cp0; +- assert((cc%stride)==0); ++ unsigned char* cp = (unsigned char*) cp0; ++ if((cc%stride)!=0) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "horAcc8", ++ "%s", "(cc%stride)!=0"); ++ return 0; ++ } ++ + if (cc > stride) { + /* + * Pipeline the most common cases. +@@ -257,9 +288,9 @@ horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) + cc -= 3; + cp += 3; + while (cc>0) { +- cp[0] = (char) (cr += cp[0]); +- cp[1] = (char) (cg += cp[1]); +- cp[2] = (char) (cb += cp[2]); ++ cp[0] = (unsigned char) ((cr += cp[0]) & 0xff); ++ cp[1] = (unsigned char) ((cg += cp[1]) & 0xff); ++ cp[2] = (unsigned char) ((cb += cp[2]) & 0xff); + cc -= 3; + cp += 3; + } +@@ -271,10 +302,10 @@ horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) + cc -= 4; + cp += 4; + while (cc>0) { +- cp[0] = (char) (cr += cp[0]); +- cp[1] = (char) (cg += cp[1]); +- cp[2] = (char) (cb += cp[2]); +- cp[3] = (char) (ca += cp[3]); ++ cp[0] = (unsigned char) ((cr += cp[0]) & 0xff); ++ cp[1] = (unsigned char) ((cg += cp[1]) & 0xff); ++ cp[2] = (unsigned char) ((cb += cp[2]) & 0xff); ++ cp[3] = (unsigned char) ((ca += cp[3]) & 0xff); + cc -= 4; + cp += 4; + } +@@ -282,77 +313,71 @@ horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) + cc -= stride; + do { + REPEAT4(stride, cp[stride] = +- (char) (cp[stride] + *cp); cp++) ++ (unsigned char) ((cp[stride] + *cp) & 0xff); cp++) + cc -= stride; + } 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; + do { +- REPEAT4(stride, wp[stride] += wp[0]; wp++) ++ REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++) + 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 +386,13 @@ horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) + 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,15 +400,22 @@ 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++) ++ REPEAT4(stride, cp[stride] = ++ (unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++) + count -= stride; + } + +@@ -400,6 +433,7 @@ fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) + } + } + _TIFFfree(tmp); ++ return 1; + } + + /* +@@ -415,8 +449,7 @@ PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) + 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 +472,16 @@ PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) + 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 +490,19 @@ PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) + 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; ++ unsigned char* cp = (unsigned 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; +@@ -466,67 +510,92 @@ horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) + * Pipeline the most common cases. + */ + if (stride == 3) { +- int r1, g1, b1; +- int r2 = cp[0]; +- int g2 = cp[1]; +- int b2 = cp[2]; ++ unsigned int r1, g1, b1; ++ unsigned int r2 = cp[0]; ++ unsigned int g2 = cp[1]; ++ unsigned int b2 = cp[2]; + do { +- r1 = cp[3]; cp[3] = r1-r2; r2 = r1; +- g1 = cp[4]; cp[4] = g1-g2; g2 = g1; +- b1 = cp[5]; cp[5] = b1-b2; b2 = b1; ++ r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1; ++ g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1; ++ b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1; + cp += 3; + } while ((cc -= 3) > 0); + } else if (stride == 4) { +- int r1, g1, b1, a1; +- int r2 = cp[0]; +- int g2 = cp[1]; +- int b2 = cp[2]; +- int a2 = cp[3]; ++ unsigned int r1, g1, b1, a1; ++ unsigned int r2 = cp[0]; ++ unsigned int g2 = cp[1]; ++ unsigned int b2 = cp[2]; ++ unsigned int a2 = cp[3]; + do { +- r1 = cp[4]; cp[4] = r1-r2; r2 = r1; +- g1 = cp[5]; cp[5] = g1-g2; g2 = g1; +- b1 = cp[6]; cp[6] = b1-b2; b2 = b1; +- a1 = cp[7]; cp[7] = a1-a2; a2 = a1; ++ r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1; ++ g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1; ++ b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1; ++ a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1; + cp += 4; + } while ((cc -= 4) > 0); + } else { + cp += cc - 1; + do { +- REPEAT4(stride, cp[stride] -= cp[0]; cp--) ++ REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--) + } while ((cc -= stride) > 0); + } + } ++ return 1; + } + +-static void ++static int + horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) + { + TIFFPredictorState* sp = PredictorState(tif); + tmsize_t stride = sp->stride; +- int16 *wp = (int16*) cp0; ++ uint16 *wp = (uint16*) 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; + wp += wc - 1; + do { +- REPEAT4(stride, wp[stride] -= wp[0]; wp--) ++ REPEAT4(stride, wp[stride] = (uint16)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--) + wc -= stride; + } while (wc > 0); + } ++ return 1; + } + +-static void ++static int ++swabHorDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) ++{ ++ uint16* wp = (uint16*) cp0; ++ tmsize_t wc = cc / 2; ++ ++ if( !horDiff16(tif, cp0, cc) ) ++ return 0; ++ ++ TIFFSwabArrayOfShort(wp, wc); ++ return 1; ++} ++ ++static int + horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) + { + TIFFPredictorState* sp = PredictorState(tif); + tmsize_t stride = sp->stride; +- int32 *wp = (int32*) cp0; ++ uint32 *wp = (uint32*) 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 +605,26 @@ horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) + wc -= stride; + } while (wc > 0); + } ++ return 1; ++} ++ ++static int ++swabHorDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) ++{ ++ uint32* wp = (uint32*) cp0; ++ tmsize_t wc = cc / 4; ++ ++ if( !horDiff32(tif, cp0, cc) ) ++ return 0; ++ ++ TIFFSwabArrayOfLong(wp, wc); ++ 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 +632,18 @@ fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) + 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++) { +@@ -573,7 +662,8 @@ fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) + cp = (uint8 *) cp0; + cp += cc - stride - 1; + for (count = cc; count > stride; count -= stride) +- REPEAT4(stride, cp[stride] -= cp[0]; cp--) ++ REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--) ++ return 1; + } + + static int +@@ -586,7 +676,8 @@ PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) + 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 +712,13 @@ PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s) + + 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; +diff --git a/libtiff/tif_predict.h b/libtiff/tif_predict.h +index dc7144c..1585a58 100644 +--- 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 */ +-- +2.7.4 + diff --git a/SOURCES/libtiff-CVE-2016-9540.patch b/SOURCES/libtiff-CVE-2016-9540.patch new file mode 100644 index 0000000..b473d86 --- /dev/null +++ b/SOURCES/libtiff-CVE-2016-9540.patch @@ -0,0 +1,34 @@ +From aa6829cda019f56ed882b2db2d1e84c994412f9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Wed, 11 Jan 2017 12:58:22 +0100 +Subject: [PATCH 3/5] Fix CVE-2016-9540 + +--- + tools/tiffcp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/tiffcp.c b/tools/tiffcp.c +index 8c696db..2903461 100644 +--- a/tools/tiffcp.c ++++ b/tools/tiffcp.c +@@ -1330,7 +1330,7 @@ DECLAREreadFunc(readContigTilesIntoBuffer) + 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), +@@ -1515,7 +1515,7 @@ DECLAREwriteFunc(writeBufferToContigTiles) + 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. +-- +2.7.4 + diff --git a/SPECS/libtiff.spec b/SPECS/libtiff.spec index 141e1ee..3777273 100644 --- a/SPECS/libtiff.spec +++ b/SPECS/libtiff.spec @@ -1,7 +1,7 @@ Summary: Library of functions for manipulating TIFF format image files Name: libtiff Version: 4.0.3 -Release: 25%{?dist} +Release: 27%{?dist} License: libtiff Group: System Environment/Libraries @@ -37,6 +37,11 @@ Patch24: libtiff-CVE-2016-3945.patch Patch25: libtiff-CVE-2016-3990.patch Patch26: libtiff-CVE-2016-3991.patch Patch27: libtiff-CVE-2016-5320.patch +Patch28: libtiff-CVE-2016-9533_9534_9536_9537.patch +Patch29: libtiff-CVE-2016-9535.patch +Patch30: libtiff-CVE-2016-9540.patch +Patch31: libtiff-CVE-2016-5652.patch +Patch32: libtiff-CVE-2015-8870.patch BuildRequires: zlib-devel libjpeg-devel jbigkit-devel BuildRequires: libtool automake autoconf pkgconfig @@ -115,6 +120,11 @@ image files using the libtiff library. %patch25 -p1 %patch26 -p1 %patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 # Use build system's libtool.m4, not the one in the package. rm -f libtool.m4 @@ -219,27 +229,38 @@ find html -name 'Makefile*' | xargs rm %{_mandir}/man1/* %changelog +* Wed Jan 18 2017 Nikola Forró - 4.0.3-27 +- Fix CWE-476 defect found by covscan +- Related: #1412080 + +* Wed Jan 11 2017 Nikola Forró - 4.0.3-26 +- Add patches for CVEs: + CVE-2016-9533, CVE-2016-9534, CVE-2016-9535, + CVE-2016-9536, CVE-2016-9537, CVE-2016-9540, + CVE-2016-5652, CVE-2015-8870 +- Resolves: #1412080 + * Wed Jul 27 2016 Nikola Forró - 4.0.3-25 - Add patches for CVEs: CVE-2015-7554, CVE-2015-8683, CVE-2015-8665, CVE-2015-8781, CVE-2015-8782, CVE-2015-8783, CVE-2015-8784 -- Related: #1299920 +- Related: #1299921 * Tue Jul 26 2016 Nikola Forró - 4.0.3-24 - Update patches for CVEs: CVE-2014-8127, CVE-2014-8130 -- Related: #1299920 +- Related: #1299921 -* Tue Jul 26 2016 Petr Hracek - 4.0.3-23 +* Mon Jul 25 2016 Petr Hracek - 4.0.3-23 - Update patches: CVE-2014-9330, CVE-2014-8127, CVE-2014-8129 CVE-2014-8130 -- Related: #1299920 +- Related: #1299921 * Tue Jul 19 2016 Nikola Forró - 4.0.3-22 - Update patch for CVE-2015-8668 -- Related: #1299920 +- Related: #1299921 * Mon Jul 11 2016 Nikola Forró - 4.0.3-21 - Remove patches for CVEs: @@ -251,27 +272,27 @@ find html -name 'Makefile*' | xargs rm CVE-2016-3991, CVE-2016-5320 - Update patches for CVEs: CVE-2014-9655, CVE-2015-1547, CVE-2015-8668 -- Related: #1299920 +- Related: #1299921 * Tue Apr 19 2016 Petr Hracek - 4.0.3-20 - CVE-2014-8127 should contain only two fixes -- Related: #1299920 +- Related: #1299921 -* Fri Apr 15 2016 Petr Hracek - 4.0.3-19 +* Fri Apr 01 2016 Petr Hracek - 4.0.3-19 - Revert previous patch CVE-2014-8127 -- Related: #1299920 +- Related: #1299921 * Thu Mar 31 2016 Petr Hracek - 4.0.3-18 -- Fix patch CVE-2014-8127. Wrongly applied -- Related: #1299920 +- Fixed wrongly applied patch CVE-2014-8127 +- Related: #1299921 * Tue Mar 15 2016 Petr Hracek - 4.0.3-17 -- Fix patch CVE-2015-8668. Wrongly applied by me -- Related: #1299920 +- Fixed patch CVE-2015-8668. Wrongly applied by me +- Related: #1299921 * Tue Mar 08 2016 Petr Hracek - 4.0.3-16 - Fixed patches on preview CVEs -- Related: #1299920 +- Related: #1299921 * Wed Feb 03 2016 Petr Hracek - 4.0.3-15 - This resolves several CVEs @@ -279,7 +300,7 @@ find html -name 'Makefile*' | xargs rm - CVE-2014-9330, CVE-2014-9655, CVE-2015-8781 - CVE-2015-8784, CVE-2015-1547, CVE-2015-8683 - CVE-2015-8665, CVE-2015-7554, CVE-2015-8668 -- Resolves: #1299920 +- Resolves: #1299921 * Thu Feb 13 2014 Petr Hracek - 4.0.3-14 - Resolves: #996827 CVE-2013-4243 libtiff various flaws