* libtiff/tif_dirread.c: TIFFFetchStripThing(): limit the number of items
read in StripOffsets/StripByteCounts tags to the number of strips to avoid excessive memory allocation. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2215 Credit to OSS Fuzz
This commit is contained in:
parent
56d802d409
commit
7057734d98
@ -1,3 +1,11 @@
|
||||
2017-06-12 Even Rouault <even.rouault at spatialys.com>
|
||||
|
||||
* libtiff/tif_dirread.c: TIFFFetchStripThing(): limit the number of items
|
||||
read in StripOffsets/StripByteCounts tags to the number of strips to avoid
|
||||
excessive memory allocation.
|
||||
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2215
|
||||
Credit to OSS Fuzz
|
||||
|
||||
2017-06-12 Even Rouault <even.rouault at spatialys.com>
|
||||
|
||||
* libtiff/tif_dirread.c: fix regression of libtiff 4.0.8 in
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tif_dirread.c,v 1.210 2017-06-12 10:45:35 erouault Exp $ */
|
||||
/* $Id: tif_dirread.c,v 1.211 2017-06-12 19:13:49 erouault Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
@ -765,13 +765,20 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* di
|
||||
}
|
||||
}
|
||||
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit(
|
||||
TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize,
|
||||
void** value, uint64 maxcount)
|
||||
{
|
||||
int typesize;
|
||||
uint32 datasize;
|
||||
void* data;
|
||||
uint64 target_count64;
|
||||
typesize=TIFFDataWidth(direntry->tdir_type);
|
||||
if ((direntry->tdir_count==0)||(typesize==0))
|
||||
|
||||
target_count64 = (direntry->tdir_count > maxcount) ?
|
||||
maxcount : direntry->tdir_count;
|
||||
|
||||
if ((target_count64==0)||(typesize==0))
|
||||
{
|
||||
*value=0;
|
||||
return(TIFFReadDirEntryErrOk);
|
||||
@ -783,12 +790,12 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
|
||||
* in either the current data type or the dest data type. This also
|
||||
* avoids problems with overflow of tmsize_t on 32bit systems.
|
||||
*/
|
||||
if ((uint64)(2147483647/typesize)<direntry->tdir_count)
|
||||
if ((uint64)(2147483647/typesize)<target_count64)
|
||||
return(TIFFReadDirEntryErrSizesan);
|
||||
if ((uint64)(2147483647/desttypesize)<direntry->tdir_count)
|
||||
if ((uint64)(2147483647/desttypesize)<target_count64)
|
||||
return(TIFFReadDirEntryErrSizesan);
|
||||
|
||||
*count=(uint32)direntry->tdir_count;
|
||||
*count=(uint32)target_count64;
|
||||
datasize=(*count)*typesize;
|
||||
assert((tmsize_t)datasize>0);
|
||||
data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
|
||||
@ -834,6 +841,12 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* d
|
||||
return(TIFFReadDirEntryErrOk);
|
||||
}
|
||||
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
|
||||
{
|
||||
return TIFFReadDirEntryArrayWithLimit(tif, direntry, count,
|
||||
desttypesize, value, ~((uint64)0));
|
||||
}
|
||||
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value)
|
||||
{
|
||||
enum TIFFReadDirEntryErr err;
|
||||
@ -1863,7 +1876,8 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEnt
|
||||
return(TIFFReadDirEntryErrOk);
|
||||
}
|
||||
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8ArrayWithLimit(
|
||||
TIFF* tif, TIFFDirEntry* direntry, uint64** value, uint64 maxcount)
|
||||
{
|
||||
enum TIFFReadDirEntryErr err;
|
||||
uint32 count;
|
||||
@ -1883,7 +1897,7 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt
|
||||
default:
|
||||
return(TIFFReadDirEntryErrType);
|
||||
}
|
||||
err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
|
||||
err=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount);
|
||||
if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
|
||||
{
|
||||
*value=0;
|
||||
@ -2029,6 +2043,11 @@ static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEnt
|
||||
return(TIFFReadDirEntryErrOk);
|
||||
}
|
||||
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
|
||||
{
|
||||
return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64)0));
|
||||
}
|
||||
|
||||
static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value)
|
||||
{
|
||||
enum TIFFReadDirEntryErr err;
|
||||
@ -3989,6 +4008,7 @@ TIFFReadDirectory(TIFF* tif)
|
||||
tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
|
||||
|
||||
} else if (tif->tif_dir.td_nstrips == 1
|
||||
&& !(tif->tif_flags&TIFF_ISTILED)
|
||||
&& _TIFFFillStriles(tif)
|
||||
&& tif->tif_dir.td_stripoffset[0] != 0
|
||||
&& BYTECOUNTLOOKSBAD) {
|
||||
@ -5433,14 +5453,14 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
|
||||
static const char module[] = "TIFFFetchStripThing";
|
||||
enum TIFFReadDirEntryErr err;
|
||||
uint64* data;
|
||||
err=TIFFReadDirEntryLong8Array(tif,dir,&data);
|
||||
err=TIFFReadDirEntryLong8ArrayWithLimit(tif,dir,&data,nstrips);
|
||||
if (err!=TIFFReadDirEntryErrOk)
|
||||
{
|
||||
const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag);
|
||||
TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
|
||||
return(0);
|
||||
}
|
||||
if (dir->tdir_count!=(uint64)nstrips)
|
||||
if (dir->tdir_count<(uint64)nstrips)
|
||||
{
|
||||
uint64* resizeddata;
|
||||
resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
|
||||
@ -5448,13 +5468,8 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
|
||||
_TIFFfree(data);
|
||||
return(0);
|
||||
}
|
||||
if (dir->tdir_count<(uint64)nstrips)
|
||||
{
|
||||
_TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
|
||||
_TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
|
||||
}
|
||||
else
|
||||
_TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));
|
||||
_TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
|
||||
_TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
|
||||
_TIFFfree(data);
|
||||
data=resizeddata;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user