1From f94a29a822f5528d2334592760fbb7938f15eb55 Mon Sep 17 00:00:00 2001
2From: erouault <erouault>
3Date: Sat, 26 Dec 2015 17:32:03 +0000
4Subject: [PATCH] * libtiff/tif_getimage.c: fix out-of-bound reads in
5 TIFFRGBAImage interface in case of unsupported values of
6 SamplesPerPixel/ExtraSamples for LogLUV / CIELab. Add explicit call to
7 TIFFRGBAImageOK() in TIFFRGBAImageBegin(). Fix CVE-2015-8665 reported by
8 limingxing and CVE-2015-8683 reported by zzf of Alibaba.
9
10---
11 ChangeLog              |  8 ++++++++
12 libtiff/tif_getimage.c | 35 ++++++++++++++++++++++-------------
13 2 files changed, 30 insertions(+), 13 deletions(-)
14
15Index: tiff-4.0.3/libtiff/tif_getimage.c
16===================================================================
17--- tiff-4.0.3.orig/libtiff/tif_getimage.c	2016-03-23 10:13:42.728371661 -0400
18+++ tiff-4.0.3/libtiff/tif_getimage.c	2016-03-23 10:13:42.724371614 -0400
19@@ -182,20 +182,22 @@
20 				    "Planarconfiguration", td->td_planarconfig);
21 				return (0);
22 			}
23-			if( td->td_samplesperpixel != 3 )
24+			if( td->td_samplesperpixel != 3 || colorchannels != 3 )
25             {
26                 sprintf(emsg,
27-                        "Sorry, can not handle image with %s=%d",
28-                        "Samples/pixel", td->td_samplesperpixel);
29+                        "Sorry, can not handle image with %s=%d, %s=%d",
30+                        "Samples/pixel", td->td_samplesperpixel,
31+                        "colorchannels", colorchannels);
32                 return 0;
33             }
34 			break;
35 		case PHOTOMETRIC_CIELAB:
36-            if( td->td_samplesperpixel != 3 || td->td_bitspersample != 8 )
37+            if( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 )
38             {
39                 sprintf(emsg,
40-                        "Sorry, can not handle image with %s=%d and %s=%d",
41+                        "Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
42                         "Samples/pixel", td->td_samplesperpixel,
43+                        "colorchannels", colorchannels,
44                         "Bits/sample", td->td_bitspersample);
45                 return 0;
46             }
47@@ -255,6 +257,9 @@
48 	int colorchannels;
49 	uint16 *red_orig, *green_orig, *blue_orig;
50 	int n_color;
51+	
52+	if( !TIFFRGBAImageOK(tif, emsg) )
53+		return 0;
54 
55 	/* Initialize to normal values */
56 	img->row_offset = 0;
57@@ -2470,29 +2475,33 @@
58 		case PHOTOMETRIC_RGB:
59 			switch (img->bitspersample) {
60 				case 8:
61-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
62+					if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
63+						img->samplesperpixel >= 4)
64 						img->put.contig = putRGBAAcontig8bittile;
65-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
66+					else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
67+							 img->samplesperpixel >= 4)
68 					{
69 						if (BuildMapUaToAa(img))
70 							img->put.contig = putRGBUAcontig8bittile;
71 					}
72-					else
73+					else if( img->samplesperpixel >= 3 )
74 						img->put.contig = putRGBcontig8bittile;
75 					break;
76 				case 16:
77-					if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
78+					if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
79+						img->samplesperpixel >=4 )
80 					{
81 						if (BuildMapBitdepth16To8(img))
82 							img->put.contig = putRGBAAcontig16bittile;
83 					}
84-					else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
85+					else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
86+							 img->samplesperpixel >=4 )
87 					{
88 						if (BuildMapBitdepth16To8(img) &&
89 						    BuildMapUaToAa(img))
90 							img->put.contig = putRGBUAcontig16bittile;
91 					}
92-					else
93+					else if( img->samplesperpixel >=3 )
94 					{
95 						if (BuildMapBitdepth16To8(img))
96 							img->put.contig = putRGBcontig16bittile;
97@@ -2501,7 +2510,7 @@
98 			}
99 			break;
100 		case PHOTOMETRIC_SEPARATED:
101-			if (buildMap(img)) {
102+			if (img->samplesperpixel >=4 && buildMap(img)) {
103 				if (img->bitspersample == 8) {
104 					if (!img->Map)
105 						img->put.contig = putRGBcontig8bitCMYKtile;
106@@ -2597,7 +2606,7 @@
107 			}
108 			break;
109 		case PHOTOMETRIC_CIELAB:
110-			if (buildMap(img)) {
111+			if (img->samplesperpixel == 3 && buildMap(img)) {
112 				if (img->bitspersample == 8)
113 					img->put.contig = initCIELabConversion(img);
114 				break;
115