From 4b8e4e2c4e007e26d5fd3f7e2bbf7ed71bca53bf Mon Sep 17 00:00:00 2001 From: erouault Date: Sat, 15 Jul 2017 12:33:25 +0000 Subject: * libtiff/tif_read.c: TIFFFillStrip() / TIFFFillTile(). Complementary fix for http://bugzilla.maptools.org/show_bug.cgi?id=2708 in the isMapped() case, so as to avoid excessive memory allocation when we need a temporary buffer but the file is truncated. --- ChangeLog | 7 +++++ libtiff/tif_read.c | 77 +++++++++++++++++++++++++++++------------------------- 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b5490f3..b467ec8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2017-07-15 Even Rouault + + * libtiff/tif_read.c: TIFFFillStrip() / TIFFFillTile(). + Complementary fix for http://bugzilla.maptools.org/show_bug.cgi?id=2708 + in the isMapped() case, so as to avoid excessive memory allocation + when we need a temporary buffer but the file is truncated. + 2017-07-15 Even Rouault * tools/tiff2pdf.c: prevent heap buffer overflow write in "Raw" diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c index eb5b7d5c..d5ce8377 100644 --- a/libtiff/tif_read.c +++ b/libtiff/tif_read.c @@ -1,4 +1,4 @@ -/* $Id: tif_read.c,v 1.64 2017-07-04 13:28:42 erouault Exp $ */ +/* $Id: tif_read.c,v 1.65 2017-07-15 12:33:25 erouault Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -816,26 +816,7 @@ TIFFFillStrip(TIFF* tif, uint32 strip) } } - if (isMapped(tif) && - (isFillOrder(tif, td->td_fillorder) - || (tif->tif_flags & TIFF_NOBITREV))) { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfree(tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~TIFF_MYBUFFER; + if (isMapped(tif)) { /* * We must check for overflow, potentially causing * an OOB read. Instead of simple @@ -872,6 +853,28 @@ TIFFFillStrip(TIFF* tif, uint32 strip) tif->tif_curstrip = NOSTRIP; return (0); } + } + + if (isMapped(tif) && + (isFillOrder(tif, td->td_fillorder) + || (tif->tif_flags & TIFF_NOBITREV))) { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; tif->tif_rawdatasize = (tmsize_t)bytecount; tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip]; tif->tif_rawdataoff = 0; @@ -1260,6 +1263,23 @@ TIFFFillTile(TIFF* tif, uint32 tile) } } + if (isMapped(tif)) { + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * td->td_stripoffset[tile]+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64)tif->tif_size || + td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) { + tif->tif_curtile = NOTILE; + return (0); + } + } + if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { @@ -1280,20 +1300,7 @@ TIFFFillTile(TIFF* tif, uint32 tile) tif->tif_rawdatasize = 0; } tif->tif_flags &= ~TIFF_MYBUFFER; - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * td->td_stripoffset[tile]+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64)tif->tif_size || - td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) { - tif->tif_curtile = NOTILE; - return (0); - } + tif->tif_rawdatasize = (tmsize_t)bytecount; tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[tile]; -- cgit v1.2.1