From e596d4e27c5afb7960dc360fdd3afd90ba0fb8ba Mon Sep 17 00:00:00 2001 From: erouault Date: Mon, 15 Aug 2016 21:05:40 +0000 Subject: [PATCH 2/2] * tools/tiffcrop.c: Fix out-of-bounds write in loadImage(). From patch libtiff-CVE-2016-3991.patch from libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro (bugzilla #2543) CVE: CVE-2016-3991 Upstream-Status: Backport https://github.com/vadz/libtiff/commit/e596d4e27c5afb7960dc360fdd3afd90ba0fb8ba Signed-off-by: Yi Zhao --- ChangeLog | 6 ++++++ tools/tiffcrop.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index db4ea18..5d60608 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2016-08-15 Even Rouault + * tools/tiffcrop.c: Fix out-of-bounds write in loadImage(). + From patch libtiff-CVE-2016-3991.patch from + libtiff-4.0.3-25.el7_2.src.rpm by Nikola Forro (bugzilla #2543) + +2016-08-15 Even Rouault + * 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 diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c index 27abc0b..ddba7b9 100644 --- a/tools/tiffcrop.c +++ b/tools/tiffcrop.c @@ -798,6 +798,11 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, } tile_buffsize = tilesize; + if (tilesize == 0 || tile_rowsize == 0) + { + TIFFError("readContigTilesIntoBuffer", "Tile size or tile rowsize is zero"); + exit(-1); + } if (tilesize < (tsize_t)(tl * tile_rowsize)) { @@ -807,7 +812,12 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8* buf, tilesize, tl * tile_rowsize); #endif tile_buffsize = tl * tile_rowsize; - } + if (tl != (tile_buffsize / tile_rowsize)) + { + TIFFError("readContigTilesIntoBuffer", "Integer overflow when calculating buffer size."); + exit(-1); + } + } tilebuf = _TIFFmalloc(tile_buffsize); if (tilebuf == 0) @@ -1210,6 +1220,12 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength, !TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps) ) return 1; + if (tilesize == 0 || tile_rowsize == 0 || tl == 0 || tw == 0) + { + TIFFError("writeBufferToContigTiles", "Tile size, tile row size, tile width, or tile length is zero"); + exit(-1); + } + tile_buffsize = tilesize; if (tilesize < (tsize_t)(tl * tile_rowsize)) { @@ -1219,6 +1235,11 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength, tilesize, tl * tile_rowsize); #endif tile_buffsize = tl * tile_rowsize; + if (tl != tile_buffsize / tile_rowsize) + { + TIFFError("writeBufferToContigTiles", "Integer overflow when calculating buffer size"); + exit(-1); + } } tilebuf = _TIFFmalloc(tile_buffsize); @@ -5945,12 +5966,27 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c TIFFGetField(in, TIFFTAG_TILELENGTH, &tl); tile_rowsize = TIFFTileRowSize(in); + if (ntiles == 0 || tlsize == 0 || tile_rowsize == 0) + { + TIFFError("loadImage", "File appears to be tiled, but the number of tiles, tile size, or tile rowsize is zero."); + exit(-1); + } buffsize = tlsize * ntiles; + if (tlsize != (buffsize / ntiles)) + { + TIFFError("loadImage", "Integer overflow when calculating buffer size"); + exit(-1); + } - if (buffsize < (uint32)(ntiles * tl * tile_rowsize)) { buffsize = ntiles * tl * tile_rowsize; + if (ntiles != (buffsize / tl / tile_rowsize)) + { + TIFFError("loadImage", "Integer overflow when calculating buffer size"); + exit(-1); + } + #ifdef DEBUG2 TIFFError("loadImage", "Tilesize %u is too small, using ntiles * tilelength * tilerowsize %lu", @@ -5969,8 +6005,25 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); stsize = TIFFStripSize(in); nstrips = TIFFNumberOfStrips(in); + if (nstrips == 0 || stsize == 0) + { + TIFFError("loadImage", "File appears to be striped, but the number of stipes or stripe size is zero."); + exit(-1); + } + buffsize = stsize * nstrips; - + if (stsize != (buffsize / nstrips)) + { + TIFFError("loadImage", "Integer overflow when calculating buffer size"); + exit(-1); + } + uint32 buffsize_check; + buffsize_check = ((length * width * spp * bps) + 7); + if (length != ((buffsize_check - 7) / width / spp / bps)) + { + TIFFError("loadImage", "Integer overflow detected."); + exit(-1); + } if (buffsize < (uint32) (((length * width * spp * bps) + 7) / 8)) { buffsize = ((length * width * spp * bps) + 7) / 8; -- 2.7.4