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