JBIG: fix potential out-of-bounds write in JBIGDecode()

JBIGDecode doesn't check if the user provided buffer is large enough
to store the JBIG decoded image, which can potentially cause out-of-bounds
write in the buffer.
This issue was reported and analyzed by Thomas Dullien.

Also fixes a (harmless) potential use of uninitialized memory when
tif->tif_rawsize > tif->tif_rawcc

And in case libtiff is compiled with CHUNKY_STRIP_READ_SUPPORT, make sure
that whole strip data is provided to JBIGDecode()
parent d438fab3
......@@ -51,17 +51,18 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
struct jbg_dec_state decoder;
int decodeStatus = 0;
unsigned char* pImage = NULL;
(void) size, (void) s;
unsigned long decodedSize;
(void) s;
if (isFillOrder(tif, tif->tif_dir.td_fillorder))
{
TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize);
TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc);
}
jbg_dec_init(&decoder);
#if defined(HAVE_JBG_NEWLEN)
jbg_newlen(tif->tif_rawdata, (size_t)tif->tif_rawdatasize);
jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc);
/*
* I do not check the return status of jbg_newlen because even if this
* function fails it does not necessarily mean that decoding the image
......@@ -74,8 +75,8 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
*/
#endif /* HAVE_JBG_NEWLEN */
decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawdata,
(size_t)tif->tif_rawdatasize, NULL);
decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp,
(size_t)tif->tif_rawcc, NULL);
if (JBG_EOK != decodeStatus)
{
/*
......@@ -96,9 +97,28 @@ static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s)
return 0;
}
decodedSize = jbg_dec_getsize(&decoder);
if( (tmsize_t)decodedSize < size )
{
TIFFWarningExt(tif->tif_clientdata, "JBIG",
"Only decoded %lu bytes, whereas %lu requested",
decodedSize, (unsigned long)size);
}
else if( (tmsize_t)decodedSize > size )
{
TIFFErrorExt(tif->tif_clientdata, "JBIG",
"Decoded %lu bytes, whereas %lu were requested",
decodedSize, (unsigned long)size);
jbg_dec_free(&decoder);
return 0;
}
pImage = jbg_dec_getimage(&decoder, 0);
_TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder));
_TIFFmemcpy(buffer, pImage, decodedSize);
jbg_dec_free(&decoder);
tif->tif_rawcp += tif->tif_rawcc;
tif->tif_rawcc = 0;
return 1;
}
......
......@@ -346,7 +346,8 @@ TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
return 0;
whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
|| isMapped(tif);
if( td->td_compression == COMPRESSION_LERC )
if( td->td_compression == COMPRESSION_LERC ||
td->td_compression == COMPRESSION_JBIG )
{
/* Ideally plugins should have a way to declare they don't support
* chunk strip */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment