diff options
author | Even Rouault <even.rouault@spatialys.com> | 2018-10-14 15:57:45 +0000 |
---|---|---|
committer | Even Rouault <even.rouault@spatialys.com> | 2018-10-14 15:57:45 +0000 |
commit | 183102bc2610eb589f808b889e043fef7734d128 (patch) | |
tree | e824bb9773a16f9fd54d3abcc253180851bf2cf6 | |
parent | d438fab328c0e6180f27610df532340a73694023 (diff) | |
parent | 681748ec2f5ce88da5f9fa6831e1653e46af8a66 (diff) | |
download | libtiff-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.c | 32 | ||||
-rw-r--r-- | libtiff/tif_read.c | 3 |
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 */ |