From 92d966a5fcfbdca67957c8c5c47b467aa650b286 Mon Sep 17 00:00:00 2001
From: bfriesen <bfriesen>
Date: Sat, 24 Sep 2016 23:11:55 +0000
Subject: [PATCH] * libtiff/tif_getimage.c (TIFFRGBAImageOK): Reject attempts
 to read floating point images.

* libtiff/tif_predict.c (PredictorSetup): Enforce bits-per-sample
requirements of floating point predictor (3).  Fixes CVE-2016-3622
"Divide By Zero in the tiff2rgba tool."

CVE: CVE-2016-3622
Upstream-Status: Backport
https://github.com/vadz/libtiff/commit/92d966a5fcfbdca67957c8c5c47b467aa650b286

Signed-off-by: Yi Zhao <yi.zhao@windirver.com>
---
 ChangeLog              | 11 ++++++++++-
 libtiff/tif_getimage.c | 38 ++++++++++++++++++++------------------
 libtiff/tif_predict.c  | 11 ++++++++++-
 3 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 26d6f47..a628277 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-09-24  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
+
+	* libtiff/tif_getimage.c (TIFFRGBAImageOK): Reject attempts to
+	read floating point images.
+
+	* libtiff/tif_predict.c (PredictorSetup): Enforce bits-per-sample
+	requirements of floating point predictor (3).  Fixes CVE-2016-3622
+	"Divide By Zero in the tiff2rgba tool."
+
 2016-08-15 Even Rouault <even.rouault at spatialys.com>
 
 	* tools/rgb2ycbcr.c: validate values of -v and -h parameters to
diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
index 386cee0..3e689ee 100644
--- a/libtiff/tif_getimage.c
+++ b/libtiff/tif_getimage.c
@@ -95,6 +95,10 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 			    td->td_bitspersample);
 			return (0);
 	}
+        if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) {
+                sprintf(emsg, "Sorry, can not handle images with IEEE floating-point samples");
+                return (0);
+        }
 	colorchannels = td->td_samplesperpixel - td->td_extrasamples;
 	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
 		switch (colorchannels) {
@@ -182,27 +186,25 @@ TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
 				    "Planarconfiguration", td->td_planarconfig);
 				return (0);
 			}
-			if( td->td_samplesperpixel != 3 || colorchannels != 3 )
-            {
-                sprintf(emsg,
-                        "Sorry, can not handle image with %s=%d, %s=%d",
-                        "Samples/pixel", td->td_samplesperpixel,
-                        "colorchannels", colorchannels);
-                return 0;
-            }
+			if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) {
+                                sprintf(emsg,
+                                        "Sorry, can not handle image with %s=%d, %s=%d",
+                                        "Samples/pixel", td->td_samplesperpixel,
+                                        "colorchannels", colorchannels);
+                                return 0;
+                        }
 			break;
 		case PHOTOMETRIC_CIELAB:
-            if( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 )
-            {
-                sprintf(emsg,
-                        "Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
-                        "Samples/pixel", td->td_samplesperpixel,
-                        "colorchannels", colorchannels,
-                        "Bits/sample", td->td_bitspersample);
-                return 0;
-            }
+                        if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) {
+                                sprintf(emsg,
+                                        "Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
+                                        "Samples/pixel", td->td_samplesperpixel,
+                                        "colorchannels", colorchannels,
+                                        "Bits/sample", td->td_bitspersample);
+                                return 0;
+                        }
 			break;
-		default:
+                default:
 			sprintf(emsg, "Sorry, can not handle image with %s=%d",
 			    photoTag, photometric);
 			return (0);
diff --git a/libtiff/tif_predict.c b/libtiff/tif_predict.c
index 081eb11..555f2f9 100644
--- a/libtiff/tif_predict.c
+++ b/libtiff/tif_predict.c
@@ -80,6 +80,15 @@ PredictorSetup(TIFF* tif)
 				    td->td_sampleformat);
 				return 0;
 			}
+                        if (td->td_bitspersample != 16
+                            && td->td_bitspersample != 24
+                            && td->td_bitspersample != 32
+                            && td->td_bitspersample != 64) { /* Should 64 be allowed? */
+                                TIFFErrorExt(tif->tif_clientdata, module,
+                                             "Floating point \"Predictor\" not supported with %d-bit samples",
+                                             td->td_bitspersample);
+				return 0;
+                            }
 			break;
 		default:
 			TIFFErrorExt(tif->tif_clientdata, module,
@@ -174,7 +183,7 @@ PredictorSetupDecode(TIFF* tif)
 		}
 		/*
 		 * Allocate buffer to keep the decoded bytes before
-		 * rearranging in the ight order
+		 * rearranging in the right order
 		 */
 	}
 
-- 
2.7.4

