summaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch')
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch277
1 files changed, 277 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch
new file mode 100644
index 0000000000..b3232d9002
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch
@@ -0,0 +1,277 @@
1From 01bca7e6f608da7696949fca6acda78b9935ba19 Mon Sep 17 00:00:00 2001
2From: Su_Laus <sulau@freenet.de>
3Date: Tue, 30 Aug 2022 16:56:48 +0200
4Subject: [PATCH] Revised handling of TIFFTAG_INKNAMES and related
5
6Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz ]
7CVE: CVE-2022-3599 CVE-2022-4645 CVE-2023-30774
8Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
9
10Origin: https://gitlab.com/libtiff/libtiff/-/commit/e813112545942107551433d61afd16ac094ff246
11Reviewed-by: Sylvain Beucler <beuc@debian.org>
12Last-Update: 2023-01-17
13
14 TIFFTAG_NUMBEROFINKS value
15
16In order to solve the buffer overflow issues related to TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value, a revised handling of those tags within LibTiff is proposed:
17
18Behaviour for writing:
19 `NumberOfInks` MUST fit to the number of inks in the `InkNames` string.
20 `NumberOfInks` is automatically set when `InkNames` is set.
21 If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued.
22 If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued.
23
24Behaviour for reading:
25 When reading `InkNames` from a TIFF file, the `NumberOfInks` will be set automatically to the number of inks in `InkNames` string.
26 If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued.
27 If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued.
28
29This allows the safe use of the NumberOfInks value to read out the InkNames without buffer overflow
30
31This MR will close the following issues: #149, #150, #152, #168 (to be checked), #250, #269, #398 and #456.
32
33It also fixes the old bug at http://bugzilla.maptools.org/show_bug.cgi?id=2599, for which the limitation of `NumberOfInks = SPP` was introduced, which is in my opinion not necessary and does not solve the general issue.
34
35---
36 libtiff/tif_dir.c | 120 ++++++++++++++++++++++++-----------------
37 libtiff/tif_dir.h | 2 +
38 libtiff/tif_dirinfo.c | 2 +-
39 libtiff/tif_dirwrite.c | 5 ++
40 libtiff/tif_print.c | 4 ++
41 5 files changed, 83 insertions(+), 50 deletions(-)
42
43diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
44index 39aeeb4..9d8267a 100644
45--- a/libtiff/tif_dir.c
46+++ b/libtiff/tif_dir.c
47@@ -29,6 +29,7 @@
48 * (and also some miscellaneous stuff)
49 */
50 #include "tiffiop.h"
51+# include <inttypes.h>
52
53 /*
54 * These are used in the backwards compatibility code...
55@@ -137,32 +138,30 @@ setExtraSamples(TIFF* tif, va_list ap, uint32* v)
56 }
57
58 /*
59- * Confirm we have "samplesperpixel" ink names separated by \0. Returns
60+ * Count ink names separated by \0. Returns
61 * zero if the ink names are not as expected.
62 */
63-static uint32
64-checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
65+static uint16
66+countInkNamesString(TIFF *tif, uint32 slen, const char *s)
67 {
68- TIFFDirectory* td = &tif->tif_dir;
69- uint16 i = td->td_samplesperpixel;
70+ uint16 i = 0;
71+ const char *ep = s + slen;
72+ const char *cp = s;
73
74 if (slen > 0) {
75- const char* ep = s+slen;
76- const char* cp = s;
77- for (; i > 0; i--) {
78+ do {
79 for (; cp < ep && *cp != '\0'; cp++) {}
80 if (cp >= ep)
81 goto bad;
82 cp++; /* skip \0 */
83- }
84- return ((uint32)(cp-s));
85+ i++;
86+ } while (cp < ep);
87+ return (i);
88 }
89 bad:
90 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
91- "%s: Invalid InkNames value; expecting %d names, found %d",
92- tif->tif_name,
93- td->td_samplesperpixel,
94- td->td_samplesperpixel-i);
95+ "%s: Invalid InkNames value; no NUL at given buffer end location %"PRIu32", after %"PRIu16" ink",
96+ tif->tif_name, slen, i);
97 return (0);
98 }
99
100@@ -476,13 +475,61 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
101 _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
102 break;
103 case TIFFTAG_INKNAMES:
104- v = (uint16) va_arg(ap, uint16_vap);
105- s = va_arg(ap, char*);
106- v = checkInkNamesString(tif, v, s);
107- status = v > 0;
108- if( v > 0 ) {
109- _TIFFsetNString(&td->td_inknames, s, v);
110- td->td_inknameslen = v;
111+ {
112+ v = (uint16) va_arg(ap, uint16_vap);
113+ s = va_arg(ap, char*);
114+ uint16 ninksinstring;
115+ ninksinstring = countInkNamesString(tif, v, s);
116+ status = ninksinstring > 0;
117+ if(ninksinstring > 0 ) {
118+ _TIFFsetNString(&td->td_inknames, s, v);
119+ td->td_inknameslen = v;
120+ /* Set NumberOfInks to the value ninksinstring */
121+ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
122+ {
123+ if (td->td_numberofinks != ninksinstring) {
124+ TIFFErrorExt(tif->tif_clientdata, module,
125+ "Warning %s; Tag %s:\n Value %"PRIu16" of NumberOfInks is different from the number of inks %"PRIu16".\n -> NumberOfInks value adapted to %"PRIu16"",
126+ tif->tif_name, fip->field_name, td->td_numberofinks, ninksinstring, ninksinstring);
127+ td->td_numberofinks = ninksinstring;
128+ }
129+ } else {
130+ td->td_numberofinks = ninksinstring;
131+ TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
132+ }
133+ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
134+ {
135+ if (td->td_numberofinks != td->td_samplesperpixel) {
136+ TIFFErrorExt(tif->tif_clientdata, module,
137+ "Warning %s; Tag %s:\n Value %"PRIu16" of NumberOfInks is different from the SamplesPerPixel value %"PRIu16"",
138+ tif->tif_name, fip->field_name, td->td_numberofinks, td->td_samplesperpixel);
139+ }
140+ }
141+ }
142+ }
143+ break;
144+ case TIFFTAG_NUMBEROFINKS:
145+ v = (uint16)va_arg(ap, uint16_vap);
146+ /* If InkNames already set also NumberOfInks is set accordingly and should be equal */
147+ if (TIFFFieldSet(tif, FIELD_INKNAMES))
148+ {
149+ if (v != td->td_numberofinks) {
150+ TIFFErrorExt(tif->tif_clientdata, module,
151+ "Error %s; Tag %s:\n It is not possible to set the value %"PRIu32" for NumberOfInks\n which is different from the number of inks in the InkNames tag (%"PRIu16")",
152+ tif->tif_name, fip->field_name, v, td->td_numberofinks);
153+ /* Do not set / overwrite number of inks already set by InkNames case accordingly. */
154+ status = 0;
155+ }
156+ } else {
157+ td->td_numberofinks = (uint16)v;
158+ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
159+ {
160+ if (td->td_numberofinks != td->td_samplesperpixel) {
161+ TIFFErrorExt(tif->tif_clientdata, module,
162+ "Warning %s; Tag %s:\n Value %"PRIu32" of NumberOfInks is different from the SamplesPerPixel value %"PRIu16"",
163+ tif->tif_name, fip->field_name, v, td->td_samplesperpixel);
164+ }
165+ }
166 }
167 break;
168 case TIFFTAG_PERSAMPLE:
169@@ -887,34 +934,6 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
170 if (fip->field_bit == FIELD_CUSTOM) {
171 standard_tag = 0;
172 }
173-
174- if( standard_tag == TIFFTAG_NUMBEROFINKS )
175- {
176- int i;
177- for (i = 0; i < td->td_customValueCount; i++) {
178- uint16 val;
179- TIFFTagValue *tv = td->td_customValues + i;
180- if (tv->info->field_tag != standard_tag)
181- continue;
182- if( tv->value == NULL )
183- return 0;
184- val = *(uint16 *)tv->value;
185- /* Truncate to SamplesPerPixel, since the */
186- /* setting code for INKNAMES assume that there are SamplesPerPixel */
187- /* inknames. */
188- /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
189- if( val > td->td_samplesperpixel )
190- {
191- TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
192- "Truncating NumberOfInks from %u to %u",
193- val, td->td_samplesperpixel);
194- val = td->td_samplesperpixel;
195- }
196- *va_arg(ap, uint16*) = val;
197- return 1;
198- }
199- return 0;
200- }
201
202 switch (standard_tag) {
203 case TIFFTAG_SUBFILETYPE:
204@@ -1092,6 +1111,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
205 case TIFFTAG_INKNAMES:
206 *va_arg(ap, char**) = td->td_inknames;
207 break;
208+ case TIFFTAG_NUMBEROFINKS:
209+ *va_arg(ap, uint16 *) = td->td_numberofinks;
210+ break;
211 default:
212 {
213 int i;
214diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
215index e7f0667..7cad679 100644
216--- a/libtiff/tif_dir.h
217+++ b/libtiff/tif_dir.h
218@@ -117,6 +117,7 @@ typedef struct {
219 /* CMYK parameters */
220 int td_inknameslen;
221 char* td_inknames;
222+ uint16 td_numberofinks; /* number of inks in InkNames string */
223
224 int td_customValueCount;
225 TIFFTagValue *td_customValues;
226@@ -174,6 +175,7 @@ typedef struct {
227 #define FIELD_TRANSFERFUNCTION 44
228 #define FIELD_INKNAMES 46
229 #define FIELD_SUBIFD 49
230+#define FIELD_NUMBEROFINKS 50
231 /* FIELD_CUSTOM (see tiffio.h) 65 */
232 /* end of support for well-known tags; codec-private tags follow */
233 #define FIELD_CODEC 66 /* base of codec-private tags */
234diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
235index fbfaaf0..bf7de70 100644
236--- a/libtiff/tif_dirinfo.c
237+++ b/libtiff/tif_dirinfo.c
238@@ -104,7 +104,7 @@ tiffFields[] = {
239 { TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray*) &tiffFieldArray },
240 { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL },
241 { TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL },
242- { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL },
243+ { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL },
244 { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL },
245 { TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL },
246 { TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL },
247diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
248index 9e4d306..a2dbc3b 100644
249--- a/libtiff/tif_dirwrite.c
250+++ b/libtiff/tif_dirwrite.c
251@@ -677,6 +677,11 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
252 if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
253 goto bad;
254 }
255+ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
256+ {
257+ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, TIFFTAG_NUMBEROFINKS, tif->tif_dir.td_numberofinks))
258+ goto bad;
259+ }
260 if (TIFFFieldSet(tif,FIELD_SUBIFD))
261 {
262 if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
263diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
264index a073794..a9f05a7 100644
265--- a/libtiff/tif_print.c
266+++ b/libtiff/tif_print.c
267@@ -402,6 +402,10 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
268 }
269 fputs("\n", fd);
270 }
271+ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) {
272+ fprintf(fd, " NumberOfInks: %d\n",
273+ td->td_numberofinks);
274+ }
275 if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
276 fprintf(fd, " Thresholding: ");
277 switch (td->td_threshholding) {