CVE-2016-9535: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: tif_predict.h and tif_predict.c in libtiff 4.0.6 have assertions that can lead to assertion failures in debug mode, or buffer overflows in release mode, when dealing with unusual tile size like YCbCr with subsampling. Reported as MSVR 35105, aka "Predictor heap-buffer-overflow."
CWE description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
CVSS v3 base score: 9.8
Published: 2016-11-22T19:59Z
Repository: https://github.com/vadz/libtiff
Language: Other
Files changed: ChangeLog, libtiff/tif_predict.c
Commit date: 2016-11-04 09:19:13 +0000
Commit message: * libtiff/tif_predic.c: fix memory leaks in error code paths added in
previous commit (fix for MSVR 35105)

Diff: diff --git a/ChangeLog b/ChangeLog
index 0379c3b7c..48fb75d36 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
+2016-11-04 Even Rouault <even.rouault at spatialys.com>
+
+	* libtiff/tif_predic.c: fix memory leaks in error code paths added in
+	previous commit (fix for MSVR 35105)
+
 2016-10-31 Even Rouault <even.rouault at spatialys.com>
 
 	* libtiff/tif_predict.h, libtiff/tif_predict.c:
 	Replace assertions by runtime checks to avoid assertions in debug mode,
 	or buffer overflows in release mode. Can happen when dealing with
diff --git a/libtiff/tif_predict.c b/libtiff/tif_predict.c
index b829259ae..3f42f3b31 100644
--- a/libtiff/tif_predict.c
+++ b/libtiff/tif_predict.c
@@ -407,19 +407,20 @@ fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
 	tmsize_t stride = PredictorState(tif)->stride;
 	uint32 bps = tif->tif_dir.td_bitspersample / 8;
 	tmsize_t wc = cc / bps;
 	tmsize_t count = cc;
 	uint8 *cp = (uint8 *) cp0;
-	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
+	uint8 *tmp;
 
     if(cc%(bps*stride)!=0)
     {
         TIFFErrorExt(tif->tif_clientdata, "fpAcc",
                      "%s", "cc%(bps*stride))!=0");
         return 0;
     }
 
+    tmp = (uint8 *)_TIFFmalloc(cc);
 	if (!tmp)
 		return 0;
 
 	while (count > stride) {
 		REPEAT4(stride, cp[stride] =
@@ -638,18 +639,20 @@ fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
 	tmsize_t stride = PredictorState(tif)->stride;
 	uint32 bps = tif->tif_dir.td_bitspersample / 8;
 	tmsize_t wc = cc / bps;
 	tmsize_t count;
 	uint8 *cp = (uint8 *) cp0;
-	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
+	uint8 *tmp;
 
     if((cc%(bps*stride))!=0)
     {
         TIFFErrorExt(tif->tif_clientdata, "fpDiff",
                      "%s", "(cc%(bps*stride))!=0");
         return 0;
     }
+
+    tmp = (uint8 *)_TIFFmalloc(cc);
 	if (!tmp)
 		return 0;
 
 	_TIFFmemcpy(tmp, cp0, cc);
 	for (count = 0; count < wc; count++) {
@@ -720,10 +723,11 @@ PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
 	assert(rowsize > 0);
 	if((cc0%rowsize)!=0)
     {
         TIFFErrorExt(tif->tif_clientdata, "PredictorEncodeTile",
                      "%s", "(cc0%rowsize)!=0");
+        _TIFFfree( working_copy );
         return 0;
     }
 	while (cc > 0) {
 		(*sp->encodepfunc)(tif, bp, rowsize);
 		cc -= rowsize;

Vulnerable code: 	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
	uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
Fixed code: 2016-11-04 Even Rouault <even.rouault at spatialys.com>

	* libtiff/tif_predic.c: fix memory leaks in error code paths added in
	previous commit (fix for MSVR 35105)

	uint8 *tmp;
    tmp = (uint8 *)_TIFFmalloc(cc);
	uint8 *tmp;

    tmp = (uint8 *)_TIFFmalloc(cc);
        _TIFFfree( working_copy );