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