summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-10-14 15:57:45 +0000
committerEven Rouault <even.rouault@spatialys.com>2018-10-14 15:57:45 +0000
commit183102bc2610eb589f808b889e043fef7734d128 (patch)
treee824bb9773a16f9fd54d3abcc253180851bf2cf6
parentd438fab328c0e6180f27610df532340a73694023 (diff)
parent681748ec2f5ce88da5f9fa6831e1653e46af8a66 (diff)
downloadlibtiff-git-183102bc2610eb589f808b889e043fef7734d128.tar.gz
Merge branch 'jbig_decode_overflow' into 'master'
JBIG: fix potential out-of-bounds write in JBIGDecode() See merge request libtiff/libtiff!38
-rw-r--r--libtiff/tif_jbig.c32
-rw-r--r--libtiff/tif_read.c3
2 files changed, 28 insertions, 7 deletions
diff --git a/libtiff/tif_jbig.c b/libtiff/tif_jbig.c
index 0befdf32..7ffe8851 100644
--- a/libtiff/tif_jbig.c
+++ b/libtiff/tif_jbig.c
@@ -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;
}
diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c
index 518363bb..e63810cc 100644
--- a/libtiff/tif_read.c
+++ b/libtiff/tif_read.c
@@ -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 */