summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2016-08-15 21:05:40 +0000
committerEven Rouault <even.rouault@spatialys.com>2016-08-15 21:05:40 +0000
commit5dd73c2b77798cebe22f8668187e502ad462c588 (patch)
tree37c56adca0d172cdc0d545ac5c152c1bab6c312a
parenta71b62bcff784cb86a8f81878f760cb2bcba66e6 (diff)
downloadlibtiff-git-5dd73c2b77798cebe22f8668187e502ad462c588.tar.gz
* 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)
-rw-r--r--ChangeLog6
-rw-r--r--tools/tiffcrop.c61
2 files changed, 63 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index db4ea186..5d606087 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2016-08-15 Even Rouault <even.rouault at spatialys.com>
+ * 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 <even.rouault at spatialys.com>
+
* 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 1b242717..9e833b77 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -1,4 +1,4 @@
-/* $Id: tiffcrop.c,v 1.37 2016-07-11 21:38:31 erouault Exp $ */
+/* $Id: tiffcrop.c,v 1.38 2016-08-15 21:05:40 erouault Exp $ */
/* tiffcrop.c -- a port of tiffcp.c extended to include manipulations of
* the image data through additional options listed below
@@ -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;