Skip to content
This repository has been archived by the owner on Dec 1, 2017. It is now read-only.
Permalink
Browse files Browse the repository at this point in the history
* libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() to
instanciate compute ntrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip),
instead of a logic based on the total size of data. Which is faulty is
the total size of data is not sufficient to fill the whole image, and thus
results in reading outside of the StripByCounts/StripOffsets arrays when
using TIFFReadScanline().
Reported by Agostino Sarubbo.
Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2608.

* libtiff/tif_strip.c: revert the change in TIFFNumberOfStrips() done
for http://bugzilla.maptools.org/show_bug.cgi?id=2587 / CVE-2016-9273 since
the above change is a better fix that makes it unnecessary.
  • Loading branch information
erouault committed Dec 3, 2016
1 parent 1044b43 commit 9a72a69
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 21 deletions.
15 changes: 15 additions & 0 deletions ChangeLog
@@ -1,3 +1,18 @@
2016-12-03 Even Rouault <even.rouault at spatialys.com>

* libtiff/tif_dirread.c: modify ChopUpSingleUncompressedStrip() to
instanciate compute ntrips as TIFFhowmany_32(td->td_imagelength, rowsperstrip),
instead of a logic based on the total size of data. Which is faulty is
the total size of data is not sufficient to fill the whole image, and thus
results in reading outside of the StripByCounts/StripOffsets arrays when
using TIFFReadScanline().
Reported by Agostino Sarubbo.
Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2608.

* libtiff/tif_strip.c: revert the change in TIFFNumberOfStrips() done
for http://bugzilla.maptools.org/show_bug.cgi?id=2587 / CVE-2016-9273 since
the above change is a better fix that makes it unnecessary.

2016-12-03 Even Rouault <even.rouault at spatialys.com>

* libtiff/tif_pixarlog.c, libtiff/tif_luv.c: fix heap-based buffer
Expand Down
22 changes: 10 additions & 12 deletions libtiff/tif_dirread.c
Expand Up @@ -5502,8 +5502,7 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
uint64 rowblockbytes;
uint64 stripbytes;
uint32 strip;
uint64 nstrips64;
uint32 nstrips32;
uint32 nstrips;
uint32 rowsperstrip;
uint64* newcounts;
uint64* newoffsets;
Expand Down Expand Up @@ -5534,18 +5533,17 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
return;

/*
* never increase the number of strips in an image
* never increase the number of rows per strip
*/
if (rowsperstrip >= td->td_rowsperstrip)
return;
nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
return;
nstrips32 = (uint32)nstrips64;
nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
if( nstrips == 0 )
return;

newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripByteCounts\" array");
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
"for chopped \"StripOffsets\" array");
if (newcounts == NULL || newoffsets == NULL) {
/*
Expand All @@ -5562,18 +5560,18 @@ ChopUpSingleUncompressedStrip(TIFF* tif)
* Fill the strip information arrays with new bytecounts and offsets
* that reflect the broken-up format.
*/
for (strip = 0; strip < nstrips32; strip++) {
for (strip = 0; strip < nstrips; strip++) {
if (stripbytes > bytecount)
stripbytes = bytecount;
newcounts[strip] = stripbytes;
newoffsets[strip] = offset;
newoffsets[strip] = stripbytes ? offset : 0;
offset += stripbytes;
bytecount -= stripbytes;
}
/*
* Replace old single strip info with multi-strip info.
*/
td->td_stripsperimage = td->td_nstrips = nstrips32;
td->td_stripsperimage = td->td_nstrips = nstrips;
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);

_TIFFfree(td->td_stripbytecount);
Expand Down
9 changes: 0 additions & 9 deletions libtiff/tif_strip.c
Expand Up @@ -63,15 +63,6 @@ TIFFNumberOfStrips(TIFF* tif)
TIFFDirectory *td = &tif->tif_dir;
uint32 nstrips;

/* If the value was already computed and store in td_nstrips, then return it,
since ChopUpSingleUncompressedStrip might have altered and resized the
since the td_stripbytecount and td_stripoffset arrays to the new value
after the initial affectation of td_nstrips = TIFFNumberOfStrips() in
tif_dirread.c ~line 3612.
See http://bugzilla.maptools.org/show_bug.cgi?id=2587 */
if( td->td_nstrips )
return td->td_nstrips;

nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
Expand Down

0 comments on commit 9a72a69

Please sign in to comment.