From 3528ecaa5c78613af92d6b4887afbbc14e3ce945 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 06 2019 09:47:03 +0000 Subject: import libtiff-4.0.3-32.el7 --- diff --git a/SOURCES/libtiff-CVE-2016-3186.patch b/SOURCES/libtiff-CVE-2016-3186.patch new file mode 100644 index 0000000..303f446 --- /dev/null +++ b/SOURCES/libtiff-CVE-2016-3186.patch @@ -0,0 +1,25 @@ +From 4c5f309925e568f3ccd4bacc1907c082401c13cd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Thu, 6 Dec 2018 14:42:00 +0100 +Subject: [PATCH 01/10] Fix CVE-2016-3186 + +--- + tools/gif2tiff.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/gif2tiff.c b/tools/gif2tiff.c +index 1e9b4b9..e89ac5b 100644 +--- a/tools/gif2tiff.c ++++ b/tools/gif2tiff.c +@@ -316,7 +316,7 @@ readextension(void) + char buf[255]; + + (void) getc(infile); +- while ((count = getc(infile))) ++ while ((count = getc(infile)) && count >= 0 && count <= 255) + fread(buf, 1, count, infile); + } + +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-10779.patch b/SOURCES/libtiff-CVE-2018-10779.patch new file mode 100644 index 0000000..3241375 --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-10779.patch @@ -0,0 +1,32 @@ +From 12f57b64abecdb610aee44b70d2379c301ce5b09 Mon Sep 17 00:00:00 2001 +From: Even Rouault +Date: Wed, 15 Aug 2018 16:34:40 +0200 +Subject: [PATCH 04/10] TIFFSetupStrips(): avoid potential uint32 overflow on + 32-bit systems with large number of strips. Probably relates to + http://bugzilla.maptools.org/show_bug.cgi?id=2788 / CVE-2018-10779 + +--- + libtiff/tif_write.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c +index ce671af..c7c29a5 100644 +--- a/libtiff/tif_write.c ++++ b/libtiff/tif_write.c +@@ -484,9 +484,11 @@ TIFFSetupStrips(TIFF* tif) + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + td->td_stripsperimage /= td->td_samplesperpixel; + td->td_stripoffset = (uint64 *) +- _TIFFmalloc(td->td_nstrips * sizeof (uint64)); ++ _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), ++ "for \"StripOffsets\" array"); + td->td_stripbytecount = (uint64 *) +- _TIFFmalloc(td->td_nstrips * sizeof (uint64)); ++ _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64), ++ "for \"StripByteCounts\" array"); + if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) + return (0); + /* +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-10963.patch b/SOURCES/libtiff-CVE-2018-10963.patch new file mode 100644 index 0000000..21ff7f1 --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-10963.patch @@ -0,0 +1,31 @@ +From db1b2741b413714c69f67842d40d78d793ef47e8 Mon Sep 17 00:00:00 2001 +From: Even Rouault +Date: Sat, 12 May 2018 14:24:15 +0200 +Subject: [PATCH 05/10] TIFFWriteDirectorySec: avoid assertion. Fixes + http://bugzilla.maptools.org/show_bug.cgi?id=2795. CVE-2018-10963 + +--- + libtiff/tif_dirwrite.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c +index fa68d1c..fd0d31c 100644 +--- a/libtiff/tif_dirwrite.c ++++ b/libtiff/tif_dirwrite.c +@@ -688,8 +688,11 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff) + } + break; + default: +- assert(0); /* we should never get here */ +- break; ++ TIFFErrorExt(tif->tif_clientdata,module, ++ "Cannot write tag %d (%s)", ++ TIFFFieldTag(o), ++ o->field_name ? o->field_name : "unknown"); ++ goto bad; + } + } + } +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-12900.patch b/SOURCES/libtiff-CVE-2018-12900.patch new file mode 100644 index 0000000..a437365 --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-12900.patch @@ -0,0 +1,29 @@ +From 38e3984b95ed5dc9820cba7af13c9a000eba9742 Mon Sep 17 00:00:00 2001 +From: pgajdos +Date: Tue, 13 Nov 2018 09:03:31 +0100 +Subject: [PATCH 06/10] prevent integer overflow + +--- + tools/tiffcp.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/tools/tiffcp.c b/tools/tiffcp.c +index 2903461..754ee9f 100644 +--- a/tools/tiffcp.c ++++ b/tools/tiffcp.c +@@ -1402,6 +1402,12 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer) + status = 0; + goto done; + } ++ if (0xFFFFFFFF / tilew < spp) ++ { ++ TIFFError(TIFFFileName(in), "Error, either TileWidth (%u) or BitsPerSample (%u) is too large", tilew, bps); ++ status = 0; ++ goto done; ++ } + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-17100.patch b/SOURCES/libtiff-CVE-2018-17100.patch new file mode 100644 index 0000000..524bc78 --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-17100.patch @@ -0,0 +1,39 @@ +From b103d539e2421a66db911f069885ffbd5760bffd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Thu, 6 Dec 2018 14:58:16 +0100 +Subject: [PATCH 07/10] Fix CVE-2018-17100 + +--- + tools/ppm2tiff.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/tools/ppm2tiff.c b/tools/ppm2tiff.c +index 8e168ad..fc97983 100644 +--- a/tools/ppm2tiff.c ++++ b/tools/ppm2tiff.c +@@ -72,15 +72,16 @@ BadPPM(char* file) + exit(-2); + } + ++ ++#define TIFF_SIZE_T_MAX ((size_t) ~ ((size_t)0)) ++#define TIFF_TMSIZE_T_MAX (tmsize_t)(TIFF_SIZE_T_MAX >> 1) ++ + static tmsize_t + multiply_ms(tmsize_t m1, tmsize_t m2) + { +- tmsize_t bytes = m1 * m2; +- +- if (m1 && bytes / m1 != m2) +- bytes = 0; +- +- return bytes; ++ if( m1 == 0 || m2 > TIFF_TMSIZE_T_MAX / m1 ) ++ return 0; ++ return m1 * m2; + } + + int +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-17101.patch b/SOURCES/libtiff-CVE-2018-17101.patch new file mode 100644 index 0000000..f6c0bd9 --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-17101.patch @@ -0,0 +1,71 @@ +From 666a205254d095947de95670f014fe30137c0014 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Thu, 6 Dec 2018 14:59:10 +0100 +Subject: [PATCH 08/10] Fix CVE-2018-17101 + +--- + tools/pal2rgb.c | 18 +++++++++++++++++- + tools/tiff2bw.c | 18 +++++++++++++++++- + 2 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/tools/pal2rgb.c b/tools/pal2rgb.c +index 426bbc0..994757a 100644 +--- a/tools/pal2rgb.c ++++ b/tools/pal2rgb.c +@@ -389,7 +389,23 @@ cpTags(TIFF* in, TIFF* out) + { + struct cpTag *p; + for (p = tags; p < &tags[NTAGS]; p++) +- cpTag(in, out, p->tag, p->count, p->type); ++ { ++ if( p->tag == TIFFTAG_GROUP3OPTIONS ) ++ { ++ uint16 compression; ++ if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || ++ compression != COMPRESSION_CCITTFAX3 ) ++ continue; ++ } ++ if( p->tag == TIFFTAG_GROUP4OPTIONS ) ++ { ++ uint16 compression; ++ if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || ++ compression != COMPRESSION_CCITTFAX4 ) ++ continue; ++ } ++ cpTag(in, out, p->tag, p->count, p->type); ++ } + } + #undef NTAGS + +diff --git a/tools/tiff2bw.c b/tools/tiff2bw.c +index 02605df..53067e7 100644 +--- a/tools/tiff2bw.c ++++ b/tools/tiff2bw.c +@@ -427,7 +427,23 @@ cpTags(TIFF* in, TIFF* out) + { + struct cpTag *p; + for (p = tags; p < &tags[NTAGS]; p++) +- cpTag(in, out, p->tag, p->count, p->type); ++ { ++ if( p->tag == TIFFTAG_GROUP3OPTIONS ) ++ { ++ uint16 compression; ++ if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || ++ compression != COMPRESSION_CCITTFAX3 ) ++ continue; ++ } ++ if( p->tag == TIFFTAG_GROUP4OPTIONS ) ++ { ++ uint16 compression; ++ if( !TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) || ++ compression != COMPRESSION_CCITTFAX4 ) ++ continue; ++ } ++ cpTag(in, out, p->tag, p->count, p->type); ++ } + } + #undef NTAGS + +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-18557.patch b/SOURCES/libtiff-CVE-2018-18557.patch new file mode 100644 index 0000000..27d476c --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-18557.patch @@ -0,0 +1,89 @@ +From ac1ad5a48fe981a8a9b6911886894520bbe0c71e Mon Sep 17 00:00:00 2001 +From: Even Rouault +Date: Sun, 14 Oct 2018 16:38:29 +0200 +Subject: [PATCH 09/10] JBIG: fix potential out-of-bounds write in JBIGDecode() + +JBIGDecode doesn't check if the user provided buffer is large enough +to store the JBIG decoded image, which can potentially cause out-of-bounds +write in the buffer. +This issue was reported and analyzed by Thomas Dullien. + +Also fixes a (harmless) potential use of uninitialized memory when +tif->tif_rawsize > tif->tif_rawcc + +And in case libtiff is compiled with CHUNKY_STRIP_READ_SUPPORT, make sure +that whole strip data is provided to JBIGDecode() +--- + libtiff/tif_jbig.c | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/libtiff/tif_jbig.c b/libtiff/tif_jbig.c +index 37878f6..667f3ff 100644 +--- a/libtiff/tif_jbig.c ++++ b/libtiff/tif_jbig.c +@@ -53,17 +53,18 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) + struct jbg_dec_state decoder; + int decodeStatus = 0; + unsigned char* pImage = NULL; +- (void) size, (void) s; ++ unsigned long decodedSize; ++ (void) s; + + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { +- TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize); ++ TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); + } + + jbg_dec_init(&decoder); + + #if defined(HAVE_JBG_NEWLEN) +- jbg_newlen(tif->tif_rawdata, (size_t)tif->tif_rawdatasize); ++ jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); + /* + * I do not check the return status of jbg_newlen because even if this + * function fails it does not necessarily mean that decoding the image +@@ -76,8 +77,8 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) + */ + #endif /* HAVE_JBG_NEWLEN */ + +- decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawdata, +- (size_t)tif->tif_rawdatasize, NULL); ++ decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp, ++ (size_t)tif->tif_rawcc, NULL); + if (JBG_EOK != decodeStatus) + { + /* +@@ -97,9 +98,28 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) + return 0; + } + ++ decodedSize = jbg_dec_getsize(&decoder); ++ if( (tmsize_t)decodedSize < size ) ++ { ++ TIFFWarningExt(tif->tif_clientdata, "JBIG", ++ "Only decoded %lu bytes, whereas %lu requested", ++ decodedSize, (unsigned long)size); ++ } ++ else if( (tmsize_t)decodedSize > size ) ++ { ++ TIFFErrorExt(tif->tif_clientdata, "JBIG", ++ "Decoded %lu bytes, whereas %lu were requested", ++ decodedSize, (unsigned long)size); ++ jbg_dec_free(&decoder); ++ return 0; ++ } + pImage = jbg_dec_getimage(&decoder, 0); +- _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder)); ++ _TIFFmemcpy(buffer, pImage, decodedSize); + jbg_dec_free(&decoder); ++ ++ tif->tif_rawcp += tif->tif_rawcc; ++ tif->tif_rawcc = 0; ++ + return 1; + } + +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-18661.patch b/SOURCES/libtiff-CVE-2018-18661.patch new file mode 100644 index 0000000..dc7014f --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-18661.patch @@ -0,0 +1,196 @@ +From c188f95bd865b1428f88c193b895fe9b3f6767e9 Mon Sep 17 00:00:00 2001 +From: Even Rouault +Date: Tue, 30 Oct 2018 18:50:27 +0100 +Subject: [PATCH] tiff2bw: avoid null pointer dereference in case of out of + memory situation. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2819 / + CVE-2018-18661 + +--- + libtiff/tiffiop.h | 1 + + tools/tiff2bw.c | 63 +++++++++++++++++++++++++++++++++++++++-------- + tools/tiffcrop.c | 5 ---- + 3 files changed, 54 insertions(+), 15 deletions(-) + +diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h +index 53357d8..8d1357b 100644 +--- a/libtiff/tiffiop.h ++++ b/libtiff/tiffiop.h +@@ -66,6 +66,7 @@ extern void *lfind(const void *, const void *, size_t *, size_t, + #endif + + #define streq(a,b) (strcmp(a,b) == 0) ++#define strneq(a,b,n) (strncmp(a,b,n) == 0) + + #ifndef TRUE + #define TRUE 1 +diff --git a/tools/tiff2bw.c b/tools/tiff2bw.c +index 53067e7..ad797b2 100644 +--- a/tools/tiff2bw.c ++++ b/tools/tiff2bw.c +@@ -40,9 +40,7 @@ + #endif + + #include "tiffio.h" +- +-#define streq(a,b) (strcmp((a),(b)) == 0) +-#define strneq(a,b,n) (strncmp(a,b,n) == 0) ++#include "tiffiop.h" + + /* x% weighting -> fraction of full color */ + #define PCT(x) (((x)*255+127)/100) +@@ -130,6 +128,11 @@ main(int argc, char* argv[]) + extern int optind; + extern char *optarg; + ++ in = (TIFF *) NULL; ++ out = (TIFF *) NULL; ++ inbuf = (unsigned char *) NULL; ++ outbuf = (unsigned char *) NULL; ++ + while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1) + switch (c) { + case 'c': /* compression scheme */ +@@ -163,24 +166,24 @@ main(int argc, char* argv[]) + fprintf(stderr, + "%s: Bad photometric; can only handle RGB and Palette images.\n", + argv[optind]); +- return (-1); ++ goto tiff2bw_error; + } + TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if (samplesperpixel != 1 && samplesperpixel != 3) { + fprintf(stderr, "%s: Bad samples/pixel %u.\n", + argv[optind], samplesperpixel); +- return (-1); ++ goto tiff2bw_error; + } + if( photometric == PHOTOMETRIC_RGB && samplesperpixel != 3) { + fprintf(stderr, "%s: Bad samples/pixel %u for PHOTOMETRIC_RGB.\n", + argv[optind], samplesperpixel); +- return (-1); ++ goto tiff2bw_error; + } + TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + if (bitspersample != 8) { + fprintf(stderr, + " %s: Sorry, only handle 8-bit samples.\n", argv[optind]); +- return (-1); ++ goto tiff2bw_error; + } + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h); +@@ -188,7 +191,7 @@ main(int argc, char* argv[]) + + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) +- return (-1); ++ goto tiff2bw_error; + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, w); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, h); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); +@@ -214,6 +217,11 @@ main(int argc, char* argv[]) + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); + TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw"); + outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); ++ if( !outbuf ) ++ { ++ fprintf(stderr, "Out of memory\n"); ++ goto tiff2bw_error; ++ } + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); + +@@ -237,6 +245,11 @@ main(int argc, char* argv[]) + #undef CVT + } + inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); ++ if( !inbuf ) ++ { ++ fprintf(stderr, "Out of memory\n"); ++ goto tiff2bw_error; ++ } + for (row = 0; row < h; row++) { + if (TIFFReadScanline(in, inbuf, row, 0) < 0) + break; +@@ -247,6 +260,11 @@ main(int argc, char* argv[]) + break; + case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG): + inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); ++ if( !inbuf ) ++ { ++ fprintf(stderr, "Out of memory\n"); ++ goto tiff2bw_error; ++ } + for (row = 0; row < h; row++) { + if (TIFFReadScanline(in, inbuf, row, 0) < 0) + break; +@@ -256,23 +274,48 @@ main(int argc, char* argv[]) + } + break; + case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE): ++ { ++ tmsize_t inbufsize; + rowsize = TIFFScanlineSize(in); +- inbuf = (unsigned char *)_TIFFmalloc(3*rowsize); ++ inbufsize = TIFFSafeMultiply(tmsize_t, 3, rowsize); ++ inbuf = (unsigned char *)_TIFFmalloc(inbufsize); ++ if( !inbuf ) ++ { ++ fprintf(stderr, "Out of memory\n"); ++ goto tiff2bw_error; ++ } + for (row = 0; row < h; row++) { + for (s = 0; s < 3; s++) + if (TIFFReadScanline(in, + inbuf+s*rowsize, row, s) < 0) +- return (-1); ++ goto tiff2bw_error; + compresssep(outbuf, + inbuf, inbuf+rowsize, inbuf+2*rowsize, w); + if (TIFFWriteScanline(out, outbuf, row, 0) < 0) + break; + } + break; ++ } + } + #undef pack ++ if (inbuf) ++ _TIFFfree(inbuf); ++ if (outbuf) ++ _TIFFfree(outbuf); ++ TIFFClose(in); + TIFFClose(out); + return (0); ++ ++ tiff2bw_error: ++ if (inbuf) ++ _TIFFfree(inbuf); ++ if (outbuf) ++ _TIFFfree(outbuf); ++ if (out) ++ TIFFClose(out); ++ if (in) ++ TIFFClose(in); ++ return (-1); + } + + static int +diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c +index 02c53cd..0192f3f 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -148,11 +148,6 @@ extern int getopt(int, char**, char*); + #define PATH_MAX 1024 + #endif + +-#ifndef streq +-#define streq(a,b) (strcmp((a),(b)) == 0) +-#endif +-#define strneq(a,b,n) (strncmp((a),(b),(n)) == 0) +- + #define TRUE 1 + #define FALSE 0 + +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-7456.patch b/SOURCES/libtiff-CVE-2018-7456.patch new file mode 100644 index 0000000..5ae9a50 --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-7456.patch @@ -0,0 +1,222 @@ +From 52dcdc1d89925fe7e362b2cc9cae699773f9618e Mon Sep 17 00:00:00 2001 +From: Hugo Lefeuvre +Date: Sun, 8 Apr 2018 14:07:08 -0400 +Subject: [PATCH] Fix NULL pointer dereference in TIFFPrintDirectory + +The TIFFPrintDirectory function relies on the following assumptions, +supposed to be guaranteed by the specification: + +(a) A Transfer Function field is only present if the TIFF file has + photometric type < 3. + +(b) If SamplesPerPixel > Color Channels, then the ExtraSamples field + has count SamplesPerPixel - (Color Channels) and contains + information about supplementary channels. + +While respect of (a) and (b) are essential for the well functioning of +TIFFPrintDirectory, no checks are realized neither by the callee nor +by TIFFPrintDirectory itself. Hence, following scenarios might happen +and trigger the NULL pointer dereference: + +(1) TIFF File of photometric type 4 or more has illegal Transfer + Function field. + +(2) TIFF File has photometric type 3 or less and defines a + SamplesPerPixel field such that SamplesPerPixel > Color Channels + without defining all extra samples in the ExtraSamples fields. + +In this patch, we address both issues with respect of the following +principles: + +(A) In the case of (1), the defined transfer table should be printed + safely even if it isn't 'legal'. This allows us to avoid expensive + checks in TIFFPrintDirectory. Also, it is quite possible that + an alternative photometric type would be developed (not part of the + standard) and would allow definition of Transfer Table. We want + libtiff to be able to handle this scenario out of the box. + +(B) In the case of (2), the transfer table should be printed at its + right size, that is if TIFF file has photometric type Palette + then the transfer table should have one row and not three, even + if two extra samples are declared. + +In order to fulfill (A) we simply add a new 'i < 3' end condition to +the broken TIFFPrintDirectory loop. This makes sure that in any case +where (b) would be respected but not (a), everything stays fine. + +(B) is fulfilled by the loop condition +'i < td->td_samplesperpixel - td->td_extrasamples'. This is enough as +long as (b) is respected. + +Naturally, we also make sure (b) is respected. This is done in the +TIFFReadDirectory function by making sure any non-color channel is +counted in ExtraSamples. + +This commit addresses CVE-2018-7456. +--- + libtiff/tif_dirread.c | 61 +++++++++++++++++++++++++++++++++++++++++++ + libtiff/tif_print.c | 2 +- + libtiff/tif_unix.c | 8 ++++++ + libtiff/tif_win32.c | 8 ++++++ + libtiff/tiffio.h | 1 + + 5 files changed, 79 insertions(+), 1 deletion(-) + +diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c +index 6667228..4f07bc8 100644 +--- a/libtiff/tif_dirread.c ++++ b/libtiff/tif_dirread.c +@@ -165,6 +165,7 @@ static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uin + static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); + static void ChopUpSingleUncompressedStrip(TIFF*); + static uint64 TIFFReadUInt64(const uint8 *value); ++static int _TIFFGetMaxColorChannels(uint16 photometric); + + typedef union _UInt64Aligned_t + { +@@ -3415,6 +3416,34 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c + } + } + ++/* ++ * Return the maximum number of color channels specified for a given photometric ++ * type. 0 is returned if photometric type isn't supported or no default value ++ * is defined by the specification. ++ */ ++static int _TIFFGetMaxColorChannels( uint16 photometric ) ++{ ++ switch (photometric) { ++ case PHOTOMETRIC_PALETTE: ++ case PHOTOMETRIC_MINISWHITE: ++ case PHOTOMETRIC_MINISBLACK: ++ return 1; ++ case PHOTOMETRIC_YCBCR: ++ case PHOTOMETRIC_RGB: ++ case PHOTOMETRIC_CIELAB: ++ return 3; ++ case PHOTOMETRIC_SEPARATED: ++ case PHOTOMETRIC_MASK: ++ return 4; ++ case PHOTOMETRIC_LOGL: ++ case PHOTOMETRIC_LOGLUV: ++ case PHOTOMETRIC_ITULAB: ++ case PHOTOMETRIC_ICCLAB: ++ default: ++ return 0; ++ } ++} ++ + /* + * Read the next TIFF directory from a file and convert it to the internal + * format. We read directories sequentially. +@@ -3430,6 +3459,7 @@ TIFFReadDirectory(TIFF* tif) + const TIFFField* fip; + uint32 fii=FAILED_FII; + toff_t nextdiroff; ++ int color_channels; + tif->tif_diroff=tif->tif_nextdiroff; + if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff)) + return 0; /* last offset or bad offset (IFD looping) */ +@@ -3909,6 +3939,37 @@ TIFFReadDirectory(TIFF* tif) + } + } + } ++ ++ /* ++ * Make sure all non-color channels are extrasamples. ++ * If it's not the case, define them as such. ++ */ ++ color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); ++ if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) { ++ uint16 old_extrasamples; ++ uint16 *new_sampleinfo; ++ ++ TIFFWarningExt(tif->tif_clientdata,module, "Sum of Photometric type-related " ++ "color channels and ExtraSamples doesn't match SamplesPerPixel. " ++ "Defining non-color channels as ExtraSamples."); ++ ++ old_extrasamples = tif->tif_dir.td_extrasamples; ++ tif->tif_dir.td_extrasamples = (tif->tif_dir.td_samplesperpixel - color_channels); ++ ++ // sampleinfo should contain information relative to these new extra samples ++ new_sampleinfo = (uint16*) _TIFFcalloc(tif->tif_dir.td_extrasamples, sizeof(uint16)); ++ if (!new_sampleinfo) { ++ TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate memory for " ++ "temporary new sampleinfo array (%d 16 bit elements)", ++ tif->tif_dir.td_extrasamples); ++ goto bad; ++ } ++ ++ memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16)); ++ _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); ++ _TIFFfree(new_sampleinfo); ++ } ++ + /* + * Verify Palette image has a Colormap. + */ +diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c +index b323ef1..8c075e5 100644 +--- a/libtiff/tif_print.c ++++ b/libtiff/tif_print.c +@@ -541,7 +541,7 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) + for (l = 0; l < n; l++) { + fprintf(fd, " %2lu: %5u", + l, td->td_transferfunction[0][l]); +- for (i = 1; i < td->td_samplesperpixel; i++) ++ for (i = 1; i < td->td_samplesperpixel - td->td_extrasamples && i < 3; i++) + fprintf(fd, " %5u", + td->td_transferfunction[i][l]); + fputc('\n', fd); +diff --git a/libtiff/tif_unix.c b/libtiff/tif_unix.c +index 0a3a4a8..5c00917 100644 +--- a/libtiff/tif_unix.c ++++ b/libtiff/tif_unix.c +@@ -262,6 +262,14 @@ _TIFFmalloc(tmsize_t s) + return (malloc((size_t) s)); + } + ++void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) ++{ ++ if( nmemb == 0 || siz == 0 ) ++ return ((void *) NULL); ++ ++ return calloc((size_t) nmemb, (size_t)siz); ++} ++ + void + _TIFFfree(void* p) + { +diff --git a/libtiff/tif_win32.c b/libtiff/tif_win32.c +index 4a2466f..ef6be08 100644 +--- a/libtiff/tif_win32.c ++++ b/libtiff/tif_win32.c +@@ -334,6 +334,14 @@ _TIFFmalloc(tmsize_t s) + return (malloc((size_t) s)); + } + ++void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) ++{ ++ if( nmemb == 0 || siz == 0 ) ++ return ((void *) NULL); ++ ++ return calloc((size_t) nmemb, (size_t)siz); ++} ++ + void + _TIFFfree(void* p) + { +diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h +index 038b670..9b39392 100644 +--- a/libtiff/tiffio.h ++++ b/libtiff/tiffio.h +@@ -293,6 +293,7 @@ extern TIFFCodec* TIFFGetConfiguredCODECs(void); + */ + + extern void* _TIFFmalloc(tmsize_t s); ++extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz); + extern void* _TIFFrealloc(void* p, tmsize_t s); + extern void _TIFFmemset(void* p, int v, tmsize_t c); + extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c); +-- +2.17.2 + diff --git a/SOURCES/libtiff-CVE-2018-8905.patch b/SOURCES/libtiff-CVE-2018-8905.patch new file mode 100644 index 0000000..6b16f2b --- /dev/null +++ b/SOURCES/libtiff-CVE-2018-8905.patch @@ -0,0 +1,52 @@ +From ba8ce45d1eda9c6291af38f41f09a5c9d238f707 Mon Sep 17 00:00:00 2001 +From: Even Rouault +Date: Sat, 12 May 2018 15:32:31 +0200 +Subject: [PATCH 03/10] LZWDecodeCompat(): fix potential index-out-of-bounds + write. Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2780 / + CVE-2018-8905 + +The fix consists in using the similar code LZWDecode() to validate we +don't write outside of the output buffer. +--- + libtiff/tif_lzw.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c +index d7fbe74..af35c2a 100644 +--- a/libtiff/tif_lzw.c ++++ b/libtiff/tif_lzw.c +@@ -589,6 +589,7 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) + char *tp; + unsigned char *bp; + int code, nbits; ++ int len; + long nextbits, nextdata, nbitsmask; + code_t *codep, *free_entp, *maxcodep, *oldcodep; + +@@ -733,12 +734,18 @@ LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) + } while (--occ); + break; + } +- assert(occ >= codep->length); +- op += codep->length, occ -= codep->length; +- tp = op; ++ len = codep->length; ++ tp = op + len; + do { +- *--tp = codep->value; +- } while( (codep = codep->next) != NULL ); ++ int t; ++ --tp; ++ t = codep->value; ++ codep = codep->next; ++ *tp = (char)t; ++ } while (codep && tp > op); ++ assert(occ >= len); ++ op += len; ++ occ -= len; + } else + *op++ = code, occ--; + } +-- +2.17.2 + diff --git a/SOURCES/libtiff-coverity.patch b/SOURCES/libtiff-coverity.patch new file mode 100644 index 0000000..39c84e3 --- /dev/null +++ b/SOURCES/libtiff-coverity.patch @@ -0,0 +1,215 @@ +From f4ee7a53cc422490986225c49f92935b3ba52866 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Thu, 13 Dec 2018 17:06:44 +0100 +Subject: [PATCH] Fix Covscan defects + +--- + contrib/addtiffo/addtiffo.c | 3 ++- + libtiff/tif_dir.c | 2 +- + libtiff/tif_ojpeg.c | 7 ++++++- + tools/gif2tiff.c | 21 +++++++++++++++------ + tools/ras2tiff.c | 22 +++++++++++++++++++++- + tools/rasterfile.h | 16 +++++++++------- + tools/tiffcrop.c | 4 ++++ + 7 files changed, 58 insertions(+), 17 deletions(-) + +diff --git a/contrib/addtiffo/addtiffo.c b/contrib/addtiffo/addtiffo.c +index d3920e2..47f5fa8 100644 +--- a/contrib/addtiffo/addtiffo.c ++++ b/contrib/addtiffo/addtiffo.c +@@ -120,7 +120,8 @@ int main( int argc, char ** argv ) + while( nOverviewCount < argc - 2 && nOverviewCount < 100 ) + { + anOverviews[nOverviewCount] = atoi(argv[nOverviewCount+2]); +- if( anOverviews[nOverviewCount] <= 0) ++ if( (anOverviews[nOverviewCount] <= 0) || ++ ((anOverviews[nOverviewCount] > 1024))) + { + fprintf( stderr, "Incorrect parameters\n" ); + return(1); +diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c +index f812fa2..9c613da 100644 +--- a/libtiff/tif_dir.c ++++ b/libtiff/tif_dir.c +@@ -706,7 +706,7 @@ badvaluedouble: + TIFFErrorExt(tif->tif_clientdata, module, + "%s: Bad value %f for \"%s\" tag", + tif->tif_name, dblval, +- fip->field_name); ++ fip ? fip->field_name : "Unknown"); + va_end(ap); + } + return (0); +diff --git a/libtiff/tif_ojpeg.c b/libtiff/tif_ojpeg.c +index 6ea3c38..1d9c77c 100644 +--- a/libtiff/tif_ojpeg.c ++++ b/libtiff/tif_ojpeg.c +@@ -528,6 +528,8 @@ OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap) + uint32 ma; + uint64* mb; + uint32 n; ++ const TIFFField* fip; ++ + switch(tag) + { + case TIFFTAG_JPEGIFOFFSET: +@@ -597,7 +599,10 @@ OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap) + default: + return (*sp->vsetparent)(tif,tag,ap); + } +- TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit); ++ fip = TIFFFieldWithTag(tif,tag); ++ if( fip == NULL ) /* shouldn't happen */ ++ return(0); ++ TIFFSetFieldBit(tif,fip->field_bit); + tif->tif_flags|=TIFF_DIRTYDIRECT; + return(1); + } +diff --git a/tools/gif2tiff.c b/tools/gif2tiff.c +index e89ac5b..012345d 100644 +--- a/tools/gif2tiff.c ++++ b/tools/gif2tiff.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include + + #ifdef HAVE_UNISTD_H +@@ -266,13 +267,15 @@ readgifimage(char* mode) + unsigned char localmap[256][3]; + int localbits; + int status; ++ size_t raster_size; + +- if (fread(buf, 1, 9, infile) == 0) { +- perror(filename); ++ if (fread(buf, 1, 9, infile) != 9) { ++ fprintf(stderr, "short read from file %s (%s)\n", ++ filename, strerror(errno)); + return (0); + } +- width = buf[4] + (buf[5] << 8); +- height = buf[6] + (buf[7] << 8); ++ width = (buf[4] + (buf[5] << 8)) & 0xffff; /* 16 bit */ ++ height = (buf[6] + (buf[7] << 8)) & 0xffff; /* 16 bit */ + local = buf[8] & 0x80; + interleaved = buf[8] & 0x40; + +@@ -280,11 +283,17 @@ readgifimage(char* mode) + fprintf(stderr, "no colormap present for image\n"); + return (0); + } +- if (width == 0 || height == 0) { ++ if (width == 0UL || height == 0UL || (width > 2000000000UL / height)) { + fprintf(stderr, "Invalid value of width or height\n"); + return(0); + } +- if ((raster = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) { ++ raster_size=width*height; ++ if ((raster_size/width) == height) { ++ raster_size += EXTRAFUDGE; /* Add elbow room */ ++ } else { ++ raster_size=0; ++ } ++ if ((raster = (unsigned char*) _TIFFmalloc(raster_size)) == NULL) { + fprintf(stderr, "not enough memory for image\n"); + return (0); + } +diff --git a/tools/ras2tiff.c b/tools/ras2tiff.c +index ec8a071..007dd8c 100644 +--- a/tools/ras2tiff.c ++++ b/tools/ras2tiff.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #ifdef HAVE_UNISTD_H + # include +@@ -122,6 +123,25 @@ main(int argc, char* argv[]) + fclose(in); + return (-3); + } ++ if ((h.ras_width <= 0) || (h.ras_width >= INT_MAX) || ++ (h.ras_height <= 0) || (h.ras_height >= INT_MAX) || ++ (h.ras_depth <= 0) || (h.ras_depth >= INT_MAX) || ++ (h.ras_length <= 0) || (h.ras_length >= INT_MAX) || ++ (h.ras_type < 0) || ++ (h.ras_maptype < 0) || ++ (h.ras_maplength < 0) || (h.ras_maplength >= INT_MAX)) { ++ fprintf(stderr, "%s: Improper image header.\n", argv[optind]); ++ fclose(in); ++ return (-2); ++ } ++ if ((h.ras_depth != 1) && ++ (h.ras_depth != 8) && ++ (h.ras_depth != 24)) { ++ fprintf(stderr, "%s: Improper image depth (%d).\n", ++ argv[optind], h.ras_depth); ++ fclose(in); ++ return (-2); ++ } + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + { +@@ -153,7 +173,7 @@ main(int argc, char* argv[]) + mapsize = 1< mapsize*3) { + fprintf(stderr, +- "%s: Huh, %ld colormap entries, should be %d?\n", ++ "%s: Huh, %d colormap entries, should be %d?\n", + argv[optind], h.ras_maplength, mapsize*3); + return (-7); + } +diff --git a/tools/rasterfile.h b/tools/rasterfile.h +index 833e095..33da707 100644 +--- a/tools/rasterfile.h ++++ b/tools/rasterfile.h +@@ -1,17 +1,19 @@ + /* $Header: /cvs/libtiff/tools/rasterfile.h,v 1.3 2003/11/12 19:14:33 dron Exp $ */ + ++#include "tiff.h" ++ + /* + * Description of header for files containing raster images + */ + struct rasterfile { + char ras_magic[4]; /* magic number */ +- long ras_width; /* width (pixels) of image */ +- long ras_height; /* height (pixels) of image */ +- long ras_depth; /* depth (1, 8, or 24 bits) of pixel */ +- long ras_length; /* length (bytes) of image */ +- long ras_type; /* type of file; see RT_* below */ +- long ras_maptype; /* type of colormap; see RMT_* below */ +- long ras_maplength; /* length (bytes) of following map */ ++ int32 ras_width; /* width (pixels) of image */ ++ int32 ras_height; /* height (pixels) of image */ ++ int32 ras_depth; /* depth (1, 8, or 24 bits) of pixel */ ++ int32 ras_length; /* length (bytes) of image */ ++ int32 ras_type; /* type of file; see RT_* below */ ++ int32 ras_maptype; /* type of colormap; see RMT_* below */ ++ int32 ras_maplength; /* length (bytes) of following map */ + /* color map follows for ras_maplength bytes, followed by image */ + }; + #define RAS_MAGIC "\x59\xa6\x6a\x95" +diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c +index 0192f3f..ae6ec1a 100644 +--- a/tools/tiffcrop.c ++++ b/tools/tiffcrop.c +@@ -2029,6 +2029,10 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32 + { + crop_data->zones++; + opt_offset = strchr(opt_ptr, ':'); ++ if (!opt_offset) { ++ TIFFError("Wrong parameter syntax for -Z", "tiffcrop -h"); ++ exit(-1); ++ } + *opt_offset = '\0'; + crop_data->zonelist[i].position = atoi(opt_ptr); + crop_data->zonelist[i].total = atoi(opt_offset + 1); +-- +2.21.0 + diff --git a/SPECS/libtiff.spec b/SPECS/libtiff.spec index 3777273..59cbd7b 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: 27%{?dist} +Release: 32%{?dist} License: libtiff Group: System Environment/Libraries @@ -42,6 +42,17 @@ Patch29: libtiff-CVE-2016-9535.patch Patch30: libtiff-CVE-2016-9540.patch Patch31: libtiff-CVE-2016-5652.patch Patch32: libtiff-CVE-2015-8870.patch +Patch33: libtiff-CVE-2016-3186.patch +Patch34: libtiff-CVE-2018-7456.patch +Patch35: libtiff-CVE-2018-8905.patch +Patch36: libtiff-CVE-2018-10779.patch +Patch37: libtiff-CVE-2018-10963.patch +Patch38: libtiff-CVE-2018-12900.patch +Patch39: libtiff-CVE-2018-17100.patch +Patch40: libtiff-CVE-2018-17101.patch +Patch41: libtiff-CVE-2018-18557.patch +Patch42: libtiff-CVE-2018-18661.patch +Patch43: libtiff-coverity.patch BuildRequires: zlib-devel libjpeg-devel jbigkit-devel BuildRequires: libtool automake autoconf pkgconfig @@ -125,6 +136,17 @@ image files using the libtiff library. %patch30 -p1 %patch31 -p1 %patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 # Use build system's libtool.m4, not the one in the package. rm -f libtool.m4 @@ -229,16 +251,54 @@ find html -name 'Makefile*' | xargs rm %{_mandir}/man1/* %changelog +* Tue Apr 30 2019 Nikola Forró - 4.0.3-32 +- Fix one more Covscan defect +- Related: #1647965 + +* Tue Apr 30 2019 Nikola Forró - 4.0.3-31 +- Fix processing of RAS files without colormap +- Related: #1647965 + +* Thu Dec 13 2018 Nikola Forró - 4.0.3-30 +- Fix various Covscan defects +- Related: #1647965 + +* Thu Dec 13 2018 Nikola Forró - 4.0.3-29 +- Fix compiler warning introduced by patch for CVE-2018-18661 +- Related: #1647965 + +* Thu Dec 06 2018 Nikola Forró - 4.0.3-28 +- Fix CVE-2016-3186 +- Resolves: #1319503 +- Fix CVE-2018-7456 +- Resolves: #1561318 +- Fix CVE-2018-8905 +- Resolves: #1574548 +- Fix CVE-2018-10779 +- Resolves: #1598503 +- Fix CVE-2018-10963 +- Resolves: #1598726 +- Fix CVE-2018-12900 +- Resolves: #1600430 +- Fix CVE-2018-17100 +- Resolves: #1632578 +- Fix CVE-2018-17101 +- Resolves: #1632579 +- Fix CVE-2018-18557 +- Resolves: #1647737 +- Fix CVE-2018-18661 +- Resolves: #1647965 + * Wed Jan 18 2017 Nikola Forró - 4.0.3-27 - Fix CWE-476 defect found by covscan -- Related: #1412080 +- Related: #1412081 * 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 +- Resolves: #1412081 * Wed Jul 27 2016 Nikola Forró - 4.0.3-25 - Add patches for CVEs: