CVE: CVE-2023-6277 Upstream-Status: Backport [upstream : https://gitlab.com/libtiff/libtiff/-/commit/0b025324711213a75e38b52f7e7ba60235f108aa ubuntu : http://archive.ubuntu.com/ubuntu/pool/main/t/tiff/tiff_4.3.0-6ubuntu0.8.debian.tar.xz ] Signed-off-by: Lee Chee Yang [Ubuntu note: Backport of the following patch from upstream, with a few changes to match the current version of the file in the present Ubuntu release: . using TIFFWarningExt instead of TIFFWarningExtR (the latter did not exist yet); -- Rodrigo Figueiredo Zaiden] Backport of: From 0b025324711213a75e38b52f7e7ba60235f108aa Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 31 Oct 2023 19:47:22 +0100 Subject: [PATCH] tif_dirread.c: only issue TIFFGetFileSize() for large enough RAM requests Ammends 5320c9d89c054fa805d037d84c57da874470b01a This fixes a performance regression caught by the GDAL regression test suite. --- libtiff/tif_dirread.c | 83 +++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 35 deletions(-) --- tiff-4.3.0.orig/libtiff/tif_dirread.c +++ tiff-4.3.0/libtiff/tif_dirread.c @@ -866,19 +866,22 @@ static enum TIFFReadDirEntryErr TIFFRead datasize=(*count)*typesize; assert((tmsize_t)datasize>0); - /* Before allocating a huge amount of memory for corrupted files, check if - * size of requested memory is not greater than file size. - */ - uint64_t filesize = TIFFGetFileSize(tif); - if (datasize > filesize) + if (datasize > 100 * 1024 * 1024) { - TIFFWarningExt(tif->tif_clientdata, "ReadDirEntryArray", - "Requested memory size for tag %d (0x%x) %" PRIu32 - " is greather than filesize %" PRIu64 - ". Memory not allocated, tag not read", - direntry->tdir_tag, direntry->tdir_tag, datasize, - filesize); - return (TIFFReadDirEntryErrAlloc); + /* Before allocating a huge amount of memory for corrupted files, check + * if size of requested memory is not greater than file size. + */ + const uint64_t filesize = TIFFGetFileSize(tif); + if (datasize > filesize) + { + TIFFWarningExt(tif->tif_clientdata, "ReadDirEntryArray", + "Requested memory size for tag %d (0x%x) %" PRIu32 + " is greater than filesize %" PRIu64 + ". Memory not allocated, tag not read", + direntry->tdir_tag, direntry->tdir_tag, datasize, + filesize); + return (TIFFReadDirEntryErrAlloc); + } } if( isMapped(tif) && datasize > (uint64_t)tif->tif_size ) @@ -4608,18 +4611,22 @@ EstimateStripByteCounts(TIFF* tif, TIFFD if( !_TIFFFillStrilesInternal( tif, 0 ) ) return -1; - /* Before allocating a huge amount of memory for corrupted files, check if - * size of requested memory is not greater than file size. */ - uint64_t filesize = TIFFGetFileSize(tif); - uint64_t allocsize = (uint64_t)td->td_nstrips * sizeof(uint64_t); - if (allocsize > filesize) + const uint64_t allocsize = (uint64_t)td->td_nstrips * sizeof(uint64_t); + uint64_t filesize = 0; + if (allocsize > 100 * 1024 * 1024) { - TIFFWarningExt(tif->tif_clientdata, module, - "Requested memory size for StripByteCounts of %" PRIu64 - " is greather than filesize %" PRIu64 - ". Memory not allocated", - allocsize, filesize); - return -1; + /* Before allocating a huge amount of memory for corrupted files, check + * if size of requested memory is not greater than file size. */ + filesize = TIFFGetFileSize(tif); + if (allocsize > filesize) + { + TIFFWarningExt( + tif->tif_clientdata, module, + "Requested memory size for StripByteCounts of %" PRIu64 + " is greater than filesize %" PRIu64 ". Memory not allocated", + allocsize, filesize); + return -1; + } } if (td->td_stripbytecount_p) @@ -4666,11 +4673,13 @@ EstimateStripByteCounts(TIFF* tif, TIFFD return -1; space+=datasize; } + if (filesize == 0) + filesize = TIFFGetFileSize(tif); if( filesize < space ) - /* we should perhaps return in error ? */ - space = filesize; - else - space = filesize - space; + /* we should perhaps return in error ? */ + space = filesize; + else + space = filesize - space; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) space /= td->td_samplesperpixel; for (strip = 0; strip < td->td_nstrips; strip++) @@ -4940,19 +4949,23 @@ TIFFFetchDirectory(TIFF* tif, uint64_t d dircount16 = (uint16_t)dircount64; dirsize = 20; } - /* Before allocating a huge amount of memory for corrupted files, check - * if size of requested memory is not greater than file size. */ - uint64_t filesize = TIFFGetFileSize(tif); - uint64_t allocsize = (uint64_t)dircount16 * dirsize; - if (allocsize > filesize) + const uint64_t allocsize = (uint64_t)dircount16 * dirsize; + if (allocsize > 100 * 1024 * 1024) { - TIFFWarningExt( - tif->tif_clientdata, module, - "Requested memory size for TIFF directory of %" PRIu64 - " is greather than filesize %" PRIu64 - ". Memory not allocated, TIFF directory not read", - allocsize, filesize); - return 0; + /* Before allocating a huge amount of memory for corrupted files, + * check if size of requested memory is not greater than file size. + */ + const uint64_t filesize = TIFFGetFileSize(tif); + if (allocsize > filesize) + { + TIFFWarningExt( + tif->tif_clientdata, module, + "Requested memory size for TIFF directory of %" PRIu64 + " is greater than filesize %" PRIu64 + ". Memory not allocated, TIFF directory not read", + allocsize, filesize); + return 0; + } } origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, "to read TIFF directory");