summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/ncurses/files/0001-Fix-CVE-2023-29491.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/ncurses/files/0001-Fix-CVE-2023-29491.patch')
-rw-r--r--meta/recipes-core/ncurses/files/0001-Fix-CVE-2023-29491.patch462
1 files changed, 462 insertions, 0 deletions
diff --git a/meta/recipes-core/ncurses/files/0001-Fix-CVE-2023-29491.patch b/meta/recipes-core/ncurses/files/0001-Fix-CVE-2023-29491.patch
new file mode 100644
index 0000000000..1232c8c2a8
--- /dev/null
+++ b/meta/recipes-core/ncurses/files/0001-Fix-CVE-2023-29491.patch
@@ -0,0 +1,462 @@
1From 3d54a41f12e9aa059f06e66e72d872f2283395b6 Mon Sep 17 00:00:00 2001
2From: Chen Qi <Qi.Chen@windriver.com>
3Date: Sun, 30 Jul 2023 21:14:00 -0700
4Subject: [PATCH] Fix CVE-2023-29491
5
6CVE: CVE-2023-29491
7
8Upstream-Status: Backport [http://ncurses.scripts.mit.edu/?p=ncurses.git;a=commitdiff;h=eb51b1ea1f75a0ec17c9c5937cb28df1e8eeec56]
9
10Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
11---
12 ncurses/tinfo/lib_tgoto.c | 10 +++-
13 ncurses/tinfo/lib_tparm.c | 116 ++++++++++++++++++++++++++++++++-----
14 ncurses/tinfo/read_entry.c | 3 +
15 progs/tic.c | 6 ++
16 progs/tparm_type.c | 9 +++
17 progs/tparm_type.h | 2 +
18 progs/tput.c | 61 ++++++++++++++++---
19 7 files changed, 185 insertions(+), 22 deletions(-)
20
21diff --git a/ncurses/tinfo/lib_tgoto.c b/ncurses/tinfo/lib_tgoto.c
22index 9cf5e100..c50ed4df 100644
23--- a/ncurses/tinfo/lib_tgoto.c
24+++ b/ncurses/tinfo/lib_tgoto.c
25@@ -207,6 +207,14 @@ tgoto(const char *string, int x, int y)
26 result = tgoto_internal(string, x, y);
27 else
28 #endif
29- result = TIPARM_2(string, y, x);
30+ if ((result = TIPARM_2(string, y, x)) == NULL) {
31+ /*
32+ * Because termcap did not provide a more general solution such as
33+ * tparm(), it was necessary to handle single-parameter capabilities
34+ * using tgoto(). The internal _nc_tiparm() function returns a NULL
35+ * for that case; retry for the single-parameter case.
36+ */
37+ result = TIPARM_1(string, y);
38+ }
39 returnPtr(result);
40 }
41diff --git a/ncurses/tinfo/lib_tparm.c b/ncurses/tinfo/lib_tparm.c
42index d9bdfd8f..a10a3877 100644
43--- a/ncurses/tinfo/lib_tparm.c
44+++ b/ncurses/tinfo/lib_tparm.c
45@@ -1086,6 +1086,64 @@ tparam_internal(TPARM_STATE *tps, const char *string, TPARM_DATA *data)
46 return (TPS(out_buff));
47 }
48
49+#ifdef CUR
50+/*
51+ * Only a few standard capabilities accept string parameters. The others that
52+ * are parameterized accept only numeric parameters.
53+ */
54+static bool
55+check_string_caps(TPARM_DATA *data, const char *string)
56+{
57+ bool result = FALSE;
58+
59+#define CHECK_CAP(name) (VALID_STRING(name) && !strcmp(name, string))
60+
61+ /*
62+ * Disallow string parameters unless we can check them against a terminal
63+ * description.
64+ */
65+ if (cur_term != NULL) {
66+ int want_type = 0;
67+
68+ if (CHECK_CAP(pkey_key))
69+ want_type = 2; /* function key #1, type string #2 */
70+ else if (CHECK_CAP(pkey_local))
71+ want_type = 2; /* function key #1, execute string #2 */
72+ else if (CHECK_CAP(pkey_xmit))
73+ want_type = 2; /* function key #1, transmit string #2 */
74+ else if (CHECK_CAP(plab_norm))
75+ want_type = 2; /* label #1, show string #2 */
76+ else if (CHECK_CAP(pkey_plab))
77+ want_type = 6; /* function key #1, type string #2, show string #3 */
78+#if NCURSES_XNAMES
79+ else {
80+ char *check;
81+
82+ check = tigetstr("Cs");
83+ if (CHECK_CAP(check))
84+ want_type = 1; /* style #1 */
85+
86+ check = tigetstr("Ms");
87+ if (CHECK_CAP(check))
88+ want_type = 3; /* storage unit #1, content #2 */
89+ }
90+#endif
91+
92+ if (want_type == data->tparm_type) {
93+ result = TRUE;
94+ } else {
95+ T(("unexpected string-parameter"));
96+ }
97+ }
98+ return result;
99+}
100+
101+#define ValidCap() (myData.tparm_type == 0 || \
102+ check_string_caps(&myData, string))
103+#else
104+#define ValidCap() 1
105+#endif
106+
107 #if NCURSES_TPARM_VARARGS
108
109 NCURSES_EXPORT(char *)
110@@ -1100,7 +1158,7 @@ tparm(const char *string, ...)
111 tps->tname = "tparm";
112 #endif /* TRACE */
113
114- if (tparm_setup(cur_term, string, &myData) == OK) {
115+ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
116 va_list ap;
117
118 va_start(ap, string);
119@@ -1135,7 +1193,7 @@ tparm(const char *string,
120 tps->tname = "tparm";
121 #endif /* TRACE */
122
123- if (tparm_setup(cur_term, string, &myData) == OK) {
124+ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
125
126 myData.param[0] = a1;
127 myData.param[1] = a2;
128@@ -1166,7 +1224,7 @@ tiparm(const char *string, ...)
129 tps->tname = "tiparm";
130 #endif /* TRACE */
131
132- if (tparm_setup(cur_term, string, &myData) == OK) {
133+ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
134 va_list ap;
135
136 va_start(ap, string);
137@@ -1179,7 +1237,25 @@ tiparm(const char *string, ...)
138 }
139
140 /*
141- * The internal-use flavor ensures that the parameters are numbers, not strings
142+ * The internal-use flavor ensures that parameters are numbers, not strings.
143+ * In addition to ensuring that they are numbers, it ensures that the parameter
144+ * count is consistent with intended usage.
145+ *
146+ * Unlike the general-purpose tparm/tiparm, these internal calls are fairly
147+ * well defined:
148+ *
149+ * expected == 0 - not applicable
150+ * expected == 1 - set color, or vertical/horizontal addressing
151+ * expected == 2 - cursor addressing
152+ * expected == 4 - initialize color or color pair
153+ * expected == 9 - set attributes
154+ *
155+ * Only for the last case (set attributes) should a parameter be optional.
156+ * Also, a capability which calls for more parameters than expected should be
157+ * ignored.
158+ *
159+ * Return a null if the parameter-checks fail. Otherwise, return a pointer to
160+ * the formatted capability string.
161 */
162 NCURSES_EXPORT(char *)
163 _nc_tiparm(int expected, const char *string, ...)
164@@ -1189,22 +1265,36 @@ _nc_tiparm(int expected, const char *string, ...)
165 char *result = NULL;
166
167 _nc_tparm_err = 0;
168+ T((T_CALLED("_nc_tiparm(%d, %s, ...)"), expected, _nc_visbuf(string)));
169 #ifdef TRACE
170 tps->tname = "_nc_tiparm";
171 #endif /* TRACE */
172
173- if (tparm_setup(cur_term, string, &myData) == OK
174- && myData.num_actual <= expected
175- && myData.tparm_type == 0) {
176- va_list ap;
177+ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
178+ if (myData.num_actual == 0) {
179+ T(("missing parameter%s, expected %s%d",
180+ expected > 1 ? "s" : "",
181+ expected == 9 ? "up to " : "",
182+ expected));
183+ } else if (myData.num_actual > expected) {
184+ T(("too many parameters, have %d, expected %d",
185+ myData.num_actual,
186+ expected));
187+ } else if (expected != 9 && myData.num_actual != expected) {
188+ T(("expected %d parameters, have %d",
189+ myData.num_actual,
190+ expected));
191+ } else {
192+ va_list ap;
193
194- va_start(ap, string);
195- tparm_copy_valist(&myData, FALSE, ap);
196- va_end(ap);
197+ va_start(ap, string);
198+ tparm_copy_valist(&myData, FALSE, ap);
199+ va_end(ap);
200
201- result = tparam_internal(tps, string, &myData);
202+ result = tparam_internal(tps, string, &myData);
203+ }
204 }
205- return result;
206+ returnPtr(result);
207 }
208
209 /*
210diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c
211index 2b1875ed..341337d2 100644
212--- a/ncurses/tinfo/read_entry.c
213+++ b/ncurses/tinfo/read_entry.c
214@@ -323,6 +323,9 @@ _nc_read_termtype(TERMTYPE2 *ptr, char *buffer, int limit)
215 || bool_count < 0
216 || num_count < 0
217 || str_count < 0
218+ || bool_count > BOOLCOUNT
219+ || num_count > NUMCOUNT
220+ || str_count > STRCOUNT
221 || str_size < 0) {
222 returnDB(TGETENT_NO);
223 }
224diff --git a/progs/tic.c b/progs/tic.c
225index 93a0b491..888927e2 100644
226--- a/progs/tic.c
227+++ b/progs/tic.c
228@@ -2270,9 +2270,15 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
229
230 _nc_reset_tparm(NULL);
231 switch (actual) {
232+ case Str:
233+ result = TPARM_1(value, strings[1]);
234+ break;
235 case Num_Str:
236 result = TPARM_2(value, numbers[1], strings[2]);
237 break;
238+ case Str_Str:
239+ result = TPARM_2(value, strings[1], strings[2]);
240+ break;
241 case Num_Str_Str:
242 result = TPARM_3(value, numbers[1], strings[2], strings[3]);
243 break;
244diff --git a/progs/tparm_type.c b/progs/tparm_type.c
245index 3da4a077..644aa62a 100644
246--- a/progs/tparm_type.c
247+++ b/progs/tparm_type.c
248@@ -47,6 +47,7 @@ tparm_type(const char *name)
249 {code, {longname} }, \
250 {code, {ti} }, \
251 {code, {tc} }
252+#define XD(code, onlyname) TD(code, onlyname, onlyname, onlyname)
253 TParams result = Numbers;
254 /* *INDENT-OFF* */
255 static const struct {
256@@ -58,6 +59,10 @@ tparm_type(const char *name)
257 TD(Num_Str, "pkey_xmit", "pfx", "px"),
258 TD(Num_Str, "plab_norm", "pln", "pn"),
259 TD(Num_Str_Str, "pkey_plab", "pfxl", "xl"),
260+#if NCURSES_XNAMES
261+ XD(Str, "Cs"),
262+ XD(Str_Str, "Ms"),
263+#endif
264 };
265 /* *INDENT-ON* */
266
267@@ -80,12 +85,16 @@ guess_tparm_type(int nparam, char **p_is_s)
268 case 1:
269 if (!p_is_s[0])
270 result = Numbers;
271+ if (p_is_s[0])
272+ result = Str;
273 break;
274 case 2:
275 if (!p_is_s[0] && !p_is_s[1])
276 result = Numbers;
277 if (!p_is_s[0] && p_is_s[1])
278 result = Num_Str;
279+ if (p_is_s[0] && p_is_s[1])
280+ result = Str_Str;
281 break;
282 case 3:
283 if (!p_is_s[0] && !p_is_s[1] && !p_is_s[2])
284diff --git a/progs/tparm_type.h b/progs/tparm_type.h
285index 7c102a30..af5bcf0f 100644
286--- a/progs/tparm_type.h
287+++ b/progs/tparm_type.h
288@@ -45,8 +45,10 @@
289 typedef enum {
290 Other = -1
291 ,Numbers = 0
292+ ,Str
293 ,Num_Str
294 ,Num_Str_Str
295+ ,Str_Str
296 } TParams;
297
298 extern TParams tparm_type(const char *name);
299diff --git a/progs/tput.c b/progs/tput.c
300index 4cd0c5ba..41508b72 100644
301--- a/progs/tput.c
302+++ b/progs/tput.c
303@@ -1,5 +1,5 @@
304 /****************************************************************************
305- * Copyright 2018-2021,2022 Thomas E. Dickey *
306+ * Copyright 2018-2022,2023 Thomas E. Dickey *
307 * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
308 * *
309 * Permission is hereby granted, free of charge, to any person obtaining a *
310@@ -47,12 +47,15 @@
311 #include <transform.h>
312 #include <tty_settings.h>
313
314-MODULE_ID("$Id: tput.c,v 1.99 2022/02/26 23:19:31 tom Exp $")
315+MODULE_ID("$Id: tput.c,v 1.102 2023/04/08 16:26:36 tom Exp $")
316
317 #define PUTS(s) fputs(s, stdout)
318
319 const char *_nc_progname = "tput";
320
321+static bool opt_v = FALSE; /* quiet, do not show warnings */
322+static bool opt_x = FALSE; /* clear scrollback if possible */
323+
324 static bool is_init = FALSE;
325 static bool is_reset = FALSE;
326 static bool is_clear = FALSE;
327@@ -81,6 +84,7 @@ usage(const char *optstring)
328 KEEP(" -S << read commands from standard input")
329 KEEP(" -T TERM use this instead of $TERM")
330 KEEP(" -V print curses-version")
331+ KEEP(" -v verbose, show warnings")
332 KEEP(" -x do not try to clear scrollback")
333 KEEP("")
334 KEEP("Commands:")
335@@ -148,7 +152,7 @@ exit_code(int token, int value)
336 * Returns nonzero on error.
337 */
338 static int
339-tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
340+tput_cmd(int fd, TTY * settings, int argc, char **argv, int *used)
341 {
342 NCURSES_CONST char *name;
343 char *s;
344@@ -231,7 +235,9 @@ tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
345 } else if (VALID_STRING(s)) {
346 if (argc > 1) {
347 int k;
348+ int narg;
349 int analyzed;
350+ int provided;
351 int popcount;
352 long numbers[1 + NUM_PARM];
353 char *strings[1 + NUM_PARM];
354@@ -271,14 +277,45 @@ tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
355
356 popcount = 0;
357 _nc_reset_tparm(NULL);
358+ /*
359+ * Count the number of numeric parameters which are provided.
360+ */
361+ provided = 0;
362+ for (narg = 1; narg < argc; ++narg) {
363+ char *ending = NULL;
364+ long check = strtol(argv[narg], &ending, 10);
365+ if (check < 0 || ending == argv[narg] || *ending != '\0')
366+ break;
367+ provided = narg;
368+ }
369 switch (paramType) {
370+ case Str:
371+ s = TPARM_1(s, strings[1]);
372+ analyzed = 1;
373+ if (provided == 0 && argc >= 1)
374+ provided++;
375+ break;
376+ case Str_Str:
377+ s = TPARM_2(s, strings[1], strings[2]);
378+ analyzed = 2;
379+ if (provided == 0 && argc >= 1)
380+ provided++;
381+ if (provided == 1 && argc >= 2)
382+ provided++;
383+ break;
384 case Num_Str:
385 s = TPARM_2(s, numbers[1], strings[2]);
386 analyzed = 2;
387+ if (provided == 1 && argc >= 2)
388+ provided++;
389 break;
390 case Num_Str_Str:
391 s = TPARM_3(s, numbers[1], strings[2], strings[3]);
392 analyzed = 3;
393+ if (provided == 1 && argc >= 2)
394+ provided++;
395+ if (provided == 2 && argc >= 3)
396+ provided++;
397 break;
398 case Numbers:
399 analyzed = _nc_tparm_analyze(NULL, s, p_is_s, &popcount);
400@@ -316,7 +353,13 @@ tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
401 if (analyzed < popcount) {
402 analyzed = popcount;
403 }
404- *used += analyzed;
405+ if (opt_v && (analyzed != provided)) {
406+ fprintf(stderr, "%s: %s parameters for \"%s\"\n",
407+ _nc_progname,
408+ (analyzed < provided ? "extra" : "missing"),
409+ argv[0]);
410+ }
411+ *used += provided;
412 }
413
414 /* use putp() in order to perform padding */
415@@ -339,7 +382,6 @@ main(int argc, char **argv)
416 int used;
417 TTY old_settings;
418 TTY tty_settings;
419- bool opt_x = FALSE; /* clear scrollback if possible */
420 bool is_alias;
421 bool need_tty;
422
423@@ -348,7 +390,7 @@ main(int argc, char **argv)
424
425 term = getenv("TERM");
426
427- while ((c = getopt(argc, argv, is_alias ? "T:Vx" : "ST:Vx")) != -1) {
428+ while ((c = getopt(argc, argv, is_alias ? "T:Vvx" : "ST:Vvx")) != -1) {
429 switch (c) {
430 case 'S':
431 cmdline = FALSE;
432@@ -361,6 +403,9 @@ main(int argc, char **argv)
433 case 'V':
434 puts(curses_version());
435 ExitProgram(EXIT_SUCCESS);
436+ case 'v': /* verbose */
437+ opt_v = TRUE;
438+ break;
439 case 'x': /* do not try to clear scrollback */
440 opt_x = TRUE;
441 break;
442@@ -404,7 +449,7 @@ main(int argc, char **argv)
443 usage(NULL);
444 while (argc > 0) {
445 tty_settings = old_settings;
446- code = tput_cmd(fd, &tty_settings, opt_x, argc, argv, &used);
447+ code = tput_cmd(fd, &tty_settings, argc, argv, &used);
448 if (code != 0)
449 break;
450 argc -= used;
451@@ -439,7 +484,7 @@ main(int argc, char **argv)
452 while (argnum > 0) {
453 int code;
454 tty_settings = old_settings;
455- code = tput_cmd(fd, &tty_settings, opt_x, argnum, argnow, &used);
456+ code = tput_cmd(fd, &tty_settings, argnum, argnow, &used);
457 if (code != 0) {
458 if (result == 0)
459 result = ErrSystem(0); /* will return value >4 */
460--
4612.40.0
462