xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunFrom 281fa3cf0e0e8a44b93478c63d90dbfb64359e88 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Even Rouault <even.rouault@spatialys.com>
3*4882a593SmuzhiyunDate: Sun, 5 Dec 2021 14:37:46 +0100
4*4882a593SmuzhiyunSubject: [PATCH] TIFFReadDirectory: fix OJPEG hack (fixes #319)
5*4882a593Smuzhiyun
6*4882a593Smuzhiyunto avoid having the size of the strip arrays inconsistent with the
7*4882a593Smuzhiyunnumber of strips returned by TIFFNumberOfStrips(), which may cause
8*4882a593Smuzhiyunout-ouf-bounds array read afterwards.
9*4882a593Smuzhiyun
10*4882a593SmuzhiyunOne of the OJPEG hack that alters SamplesPerPixel may influence the
11*4882a593Smuzhiyunnumber of strips. Hence compute tif_dir.td_nstrips only afterwards.
12*4882a593Smuzhiyun
13*4882a593SmuzhiyunCVE: CVE-2022-1354
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunUpstream-Status: Backport
16*4882a593Smuzhiyun[https://gitlab.com/libtiff/libtiff/-/commit/87f580f39011109b3bb5f6eca13fac543a542798]
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunSigned-off-by: Yi Zhao <yi.zhao@windriver.com>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun---
21*4882a593Smuzhiyun libtiff/tif_dirread.c | 162 ++++++++++++++++++++++--------------------
22*4882a593Smuzhiyun 1 file changed, 83 insertions(+), 79 deletions(-)
23*4882a593Smuzhiyun
24*4882a593Smuzhiyundiff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
25*4882a593Smuzhiyunindex a31109a..d7cccbe 100644
26*4882a593Smuzhiyun--- a/libtiff/tif_dirread.c
27*4882a593Smuzhiyun+++ b/libtiff/tif_dirread.c
28*4882a593Smuzhiyun@@ -3794,50 +3794,7 @@ TIFFReadDirectory(TIFF* tif)
29*4882a593Smuzhiyun 		MissingRequired(tif,"ImageLength");
30*4882a593Smuzhiyun 		goto bad;
31*4882a593Smuzhiyun 	}
32*4882a593Smuzhiyun-	/*
33*4882a593Smuzhiyun-	 * Setup appropriate structures (by strip or by tile)
34*4882a593Smuzhiyun-	 */
35*4882a593Smuzhiyun-	if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
36*4882a593Smuzhiyun-		tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
37*4882a593Smuzhiyun-		tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
38*4882a593Smuzhiyun-		tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
39*4882a593Smuzhiyun-		tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
40*4882a593Smuzhiyun-		tif->tif_flags &= ~TIFF_ISTILED;
41*4882a593Smuzhiyun-	} else {
42*4882a593Smuzhiyun-		tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
43*4882a593Smuzhiyun-		tif->tif_flags |= TIFF_ISTILED;
44*4882a593Smuzhiyun-	}
45*4882a593Smuzhiyun-	if (!tif->tif_dir.td_nstrips) {
46*4882a593Smuzhiyun-		TIFFErrorExt(tif->tif_clientdata, module,
47*4882a593Smuzhiyun-		    "Cannot handle zero number of %s",
48*4882a593Smuzhiyun-		    isTiled(tif) ? "tiles" : "strips");
49*4882a593Smuzhiyun-		goto bad;
50*4882a593Smuzhiyun-	}
51*4882a593Smuzhiyun-	tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
52*4882a593Smuzhiyun-	if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
53*4882a593Smuzhiyun-		tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
54*4882a593Smuzhiyun-	if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
55*4882a593Smuzhiyun-#ifdef OJPEG_SUPPORT
56*4882a593Smuzhiyun-		if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
57*4882a593Smuzhiyun-		    (isTiled(tif)==0) &&
58*4882a593Smuzhiyun-		    (tif->tif_dir.td_nstrips==1)) {
59*4882a593Smuzhiyun-			/*
60*4882a593Smuzhiyun-			 * XXX: OJPEG hack.
61*4882a593Smuzhiyun-			 * If a) compression is OJPEG, b) it's not a tiled TIFF,
62*4882a593Smuzhiyun-			 * and c) the number of strips is 1,
63*4882a593Smuzhiyun-			 * then we tolerate the absence of stripoffsets tag,
64*4882a593Smuzhiyun-			 * because, presumably, all required data is in the
65*4882a593Smuzhiyun-			 * JpegInterchangeFormat stream.
66*4882a593Smuzhiyun-			 */
67*4882a593Smuzhiyun-			TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
68*4882a593Smuzhiyun-		} else
69*4882a593Smuzhiyun-#endif
70*4882a593Smuzhiyun-        {
71*4882a593Smuzhiyun-			MissingRequired(tif,
72*4882a593Smuzhiyun-				isTiled(tif) ? "TileOffsets" : "StripOffsets");
73*4882a593Smuzhiyun-			goto bad;
74*4882a593Smuzhiyun-		}
75*4882a593Smuzhiyun-	}
76*4882a593Smuzhiyun+
77*4882a593Smuzhiyun 	/*
78*4882a593Smuzhiyun 	 * Second pass: extract other information.
79*4882a593Smuzhiyun 	 */
80*4882a593Smuzhiyun@@ -4042,41 +3999,6 @@ TIFFReadDirectory(TIFF* tif)
81*4882a593Smuzhiyun 			} /* -- if (!dp->tdir_ignore) */
82*4882a593Smuzhiyun 		} /* -- for-loop -- */
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun-        if( tif->tif_mode == O_RDWR &&
85*4882a593Smuzhiyun-            tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
86*4882a593Smuzhiyun-            tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
87*4882a593Smuzhiyun-            tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
88*4882a593Smuzhiyun-            tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
89*4882a593Smuzhiyun-            tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
90*4882a593Smuzhiyun-            tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
91*4882a593Smuzhiyun-            tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
92*4882a593Smuzhiyun-            tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
93*4882a593Smuzhiyun-        {
94*4882a593Smuzhiyun-            /* Directory typically created with TIFFDeferStrileArrayWriting() */
95*4882a593Smuzhiyun-            TIFFSetupStrips(tif);
96*4882a593Smuzhiyun-        }
97*4882a593Smuzhiyun-        else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
98*4882a593Smuzhiyun-        {
99*4882a593Smuzhiyun-            if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
100*4882a593Smuzhiyun-            {
101*4882a593Smuzhiyun-                if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
102*4882a593Smuzhiyun-                                         tif->tif_dir.td_nstrips,
103*4882a593Smuzhiyun-                                         &tif->tif_dir.td_stripoffset_p))
104*4882a593Smuzhiyun-                {
105*4882a593Smuzhiyun-                    goto bad;
106*4882a593Smuzhiyun-                }
107*4882a593Smuzhiyun-            }
108*4882a593Smuzhiyun-            if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
109*4882a593Smuzhiyun-            {
110*4882a593Smuzhiyun-                if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
111*4882a593Smuzhiyun-                                         tif->tif_dir.td_nstrips,
112*4882a593Smuzhiyun-                                         &tif->tif_dir.td_stripbytecount_p))
113*4882a593Smuzhiyun-                {
114*4882a593Smuzhiyun-                    goto bad;
115*4882a593Smuzhiyun-                }
116*4882a593Smuzhiyun-            }
117*4882a593Smuzhiyun-        }
118*4882a593Smuzhiyun-
119*4882a593Smuzhiyun 	/*
120*4882a593Smuzhiyun 	 * OJPEG hack:
121*4882a593Smuzhiyun 	 * - If a) compression is OJPEG, and b) photometric tag is missing,
122*4882a593Smuzhiyun@@ -4147,6 +4069,88 @@ TIFFReadDirectory(TIFF* tif)
123*4882a593Smuzhiyun 		}
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun+	/*
127*4882a593Smuzhiyun+	 * Setup appropriate structures (by strip or by tile)
128*4882a593Smuzhiyun+	 * We do that only after the above OJPEG hack which alters SamplesPerPixel
129*4882a593Smuzhiyun+	 * and thus influences the number of strips in the separate planarconfig.
130*4882a593Smuzhiyun+	 */
131*4882a593Smuzhiyun+	if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
132*4882a593Smuzhiyun+		tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
133*4882a593Smuzhiyun+		tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
134*4882a593Smuzhiyun+		tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
135*4882a593Smuzhiyun+		tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
136*4882a593Smuzhiyun+		tif->tif_flags &= ~TIFF_ISTILED;
137*4882a593Smuzhiyun+	} else {
138*4882a593Smuzhiyun+		tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
139*4882a593Smuzhiyun+		tif->tif_flags |= TIFF_ISTILED;
140*4882a593Smuzhiyun+	}
141*4882a593Smuzhiyun+	if (!tif->tif_dir.td_nstrips) {
142*4882a593Smuzhiyun+		TIFFErrorExt(tif->tif_clientdata, module,
143*4882a593Smuzhiyun+		    "Cannot handle zero number of %s",
144*4882a593Smuzhiyun+		    isTiled(tif) ? "tiles" : "strips");
145*4882a593Smuzhiyun+		goto bad;
146*4882a593Smuzhiyun+	}
147*4882a593Smuzhiyun+	tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
148*4882a593Smuzhiyun+	if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
149*4882a593Smuzhiyun+		tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
150*4882a593Smuzhiyun+	if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
151*4882a593Smuzhiyun+#ifdef OJPEG_SUPPORT
152*4882a593Smuzhiyun+		if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
153*4882a593Smuzhiyun+		    (isTiled(tif)==0) &&
154*4882a593Smuzhiyun+		    (tif->tif_dir.td_nstrips==1)) {
155*4882a593Smuzhiyun+			/*
156*4882a593Smuzhiyun+			 * XXX: OJPEG hack.
157*4882a593Smuzhiyun+			 * If a) compression is OJPEG, b) it's not a tiled TIFF,
158*4882a593Smuzhiyun+			 * and c) the number of strips is 1,
159*4882a593Smuzhiyun+			 * then we tolerate the absence of stripoffsets tag,
160*4882a593Smuzhiyun+			 * because, presumably, all required data is in the
161*4882a593Smuzhiyun+			 * JpegInterchangeFormat stream.
162*4882a593Smuzhiyun+			 */
163*4882a593Smuzhiyun+			TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
164*4882a593Smuzhiyun+		} else
165*4882a593Smuzhiyun+#endif
166*4882a593Smuzhiyun+        {
167*4882a593Smuzhiyun+			MissingRequired(tif,
168*4882a593Smuzhiyun+				isTiled(tif) ? "TileOffsets" : "StripOffsets");
169*4882a593Smuzhiyun+			goto bad;
170*4882a593Smuzhiyun+		}
171*4882a593Smuzhiyun+	}
172*4882a593Smuzhiyun+
173*4882a593Smuzhiyun+        if( tif->tif_mode == O_RDWR &&
174*4882a593Smuzhiyun+            tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
175*4882a593Smuzhiyun+            tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
176*4882a593Smuzhiyun+            tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
177*4882a593Smuzhiyun+            tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
178*4882a593Smuzhiyun+            tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
179*4882a593Smuzhiyun+            tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
180*4882a593Smuzhiyun+            tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
181*4882a593Smuzhiyun+            tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
182*4882a593Smuzhiyun+        {
183*4882a593Smuzhiyun+            /* Directory typically created with TIFFDeferStrileArrayWriting() */
184*4882a593Smuzhiyun+            TIFFSetupStrips(tif);
185*4882a593Smuzhiyun+        }
186*4882a593Smuzhiyun+        else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
187*4882a593Smuzhiyun+        {
188*4882a593Smuzhiyun+            if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
189*4882a593Smuzhiyun+            {
190*4882a593Smuzhiyun+                if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
191*4882a593Smuzhiyun+                                         tif->tif_dir.td_nstrips,
192*4882a593Smuzhiyun+                                         &tif->tif_dir.td_stripoffset_p))
193*4882a593Smuzhiyun+                {
194*4882a593Smuzhiyun+                    goto bad;
195*4882a593Smuzhiyun+                }
196*4882a593Smuzhiyun+            }
197*4882a593Smuzhiyun+            if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
198*4882a593Smuzhiyun+            {
199*4882a593Smuzhiyun+                if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
200*4882a593Smuzhiyun+                                         tif->tif_dir.td_nstrips,
201*4882a593Smuzhiyun+                                         &tif->tif_dir.td_stripbytecount_p))
202*4882a593Smuzhiyun+                {
203*4882a593Smuzhiyun+                    goto bad;
204*4882a593Smuzhiyun+                }
205*4882a593Smuzhiyun+            }
206*4882a593Smuzhiyun+        }
207*4882a593Smuzhiyun+
208*4882a593Smuzhiyun 	/*
209*4882a593Smuzhiyun 	 * Make sure all non-color channels are extrasamples.
210*4882a593Smuzhiyun 	 * If it's not the case, define them as such.
211