diff options
-rw-r--r-- | meta/recipes-multimedia/libtiff/files/Fix_several_CVE_issues.patch | 281 | ||||
-rw-r--r-- | meta/recipes-multimedia/libtiff/tiff_4.0.6.bb | 1 |
2 files changed, 282 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/libtiff/files/Fix_several_CVE_issues.patch b/meta/recipes-multimedia/libtiff/files/Fix_several_CVE_issues.patch new file mode 100644 index 0000000000..bd587e6d07 --- /dev/null +++ b/meta/recipes-multimedia/libtiff/files/Fix_several_CVE_issues.patch @@ -0,0 +1,281 @@ +From 83a4b92815ea04969d494416eaae3d4c6b338e4a Mon Sep 17 00:00:00 2001 +From: erouault <erouault> +Date: Fri, 23 Sep 2016 22:12:18 +0000 +Subject: [PATCH] Fix several CVE issues + +Fix CVE-2016-9533, CVE-2016-9534, CVE-2016-9536 and CVE-2016-9537 + +* 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. + +CVE: CVE-2016-9533, CVE-2016-9534, CVE-2016-9536, CVE-2016-9537 +Upstream-Status: Backport +https://github.com/vadz/libtiff/commit/83a4b92815ea04969d494416eaae3d4c6b338e4a#diff-bdc795f6afeb9558c1012b3cfae729ef + +Signed-off-by: Mingli Yu <Mingli.Yu@windriver.com> + +--- + libtiff/tif_pixarlog.c | 55 +++++++++++++++++++++----------------------------- + libtiff/tif_write.c | 7 +++++++ + tools/tiff2pdf.c | 22 ++++++++++++++++++-- + tools/tiffcrop.c | 20 +++++++++++++++++- + 4 files changed, 92 insertions(+), 35 deletions(-) + +diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c +index 1fb8f3b..d1246c3 100644 +--- a/libtiff/tif_pixarlog.c ++++ b/libtiff/tif_pixarlog.c +@@ -983,17 +983,14 @@ horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) + a1 = (int32) CLAMP(ip[3]); wp[3] = (uint16)((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; ++ } + } + } + } +@@ -1036,17 +1033,14 @@ horizontalDifference16(unsigned short *ip, int n, int stride, + a1 = CLAMP(ip[3]); wp[3] = (uint16)((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; ++ } + } + } + } +@@ -1089,18 +1083,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 f9a3fc0..d8fa802 100644 +--- a/libtiff/tif_write.c ++++ b/libtiff/tif_write.c +@@ -798,7 +798,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/tiff2pdf.c b/tools/tiff2pdf.c +index dcd5a7e..f8df6b5 100644 +--- a/tools/tiff2pdf.c ++++ b/tools/tiff2pdf.c +@@ -286,7 +286,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*); +@@ -2408,7 +2408,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)){ +@@ -3439,6 +3440,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){ +@@ -3473,6 +3475,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; +@@ -3482,12 +3486,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) +@@ -3519,20 +3529,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 ebc4aba..7685566 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -5758,7 +5758,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; +@@ -6066,11 +6067,23 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c + /* +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+3); + if (!new_buff) + { +@@ -8912,6 +8925,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.9.3 + diff --git a/meta/recipes-multimedia/libtiff/tiff_4.0.6.bb b/meta/recipes-multimedia/libtiff/tiff_4.0.6.bb index e0f91b8390..450927d93c 100644 --- a/meta/recipes-multimedia/libtiff/tiff_4.0.6.bb +++ b/meta/recipes-multimedia/libtiff/tiff_4.0.6.bb @@ -24,6 +24,7 @@ SRC_URI = "http://download.osgeo.org/libtiff/tiff-${PV}.tar.gz \ file://CVE-2016-9535-1.patch \ file://CVE-2016-9535-2.patch \ file://CVE-2016-9538.patch \ + file://Fix_several_CVE_issues.patch \ " SRC_URI[md5sum] = "d1d2e940dea0b5ad435f21f03d96dd72" |