From 760ecced1ea9b01fb2893af15ed1e31f3d64b259 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 1 Sep 2019 15:57:17 +0200 Subject: [PATCH] tif_dirread.c: allocChoppedUpStripArrays(). avoid unsigned integer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16846 --- libtiff/tif_dirread.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c index c5584fe6..94af0c96 100644 --- a/libtiff/tif_dirread.c +++ b/libtiff/tif_dirread.c @@ -5745,10 +5745,22 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips, TIFFDirectory *td = &tif->tif_dir; uint64 bytecount; uint64 offset; + uint64 last_offset; + uint64 last_bytecount; uint32 i; uint64 *newcounts; uint64 *newoffsets; + offset = TIFFGetStrileOffset(tif, 0); + last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1); + last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1); + if( last_offset > TIFF_UINT64_MAX - last_bytecount || + last_offset + last_bytecount < offset ) + { + return; + } + bytecount = last_offset + last_bytecount - offset; + newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), "for chopped \"StripByteCounts\" array"); newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64), @@ -5769,9 +5781,6 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips, * Fill the strip information arrays with new bytecounts and offsets * that reflect the broken-up format. */ - offset = TIFFGetStrileOffset(tif, 0); - bytecount = TIFFGetStrileOffset(tif, td->td_nstrips-1) + - TIFFGetStrileByteCount(tif, td->td_nstrips-1) - offset; for (i = 0; i < nstrips; i++) { if (stripbytes > bytecount) @@ -5953,12 +5962,16 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif ) /* If we are going to allocate a lot of memory, make sure that the */ /* file is as big as needed */ if( tif->tif_mode == O_RDONLY && - nstrips > 1000000 && - (TIFFGetStrileOffset(tif, td->td_nstrips-1) > TIFFGetFileSize(tif) || - TIFFGetStrileOffset(tif, td->td_nstrips-1) + - TIFFGetStrileByteCount(tif, td->td_nstrips-1) > TIFFGetFileSize(tif)) ) + nstrips > 1000000 ) { - return; + uint64 last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1); + uint64 filesize = TIFFGetFileSize(tif); + uint64 last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1); + if( last_offset > filesize || + last_bytecount > filesize - last_offset ) + { + return; + } } allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);