mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-06-13 17:39:57 +00:00
xterm: Security fix for CVE-2023-40359
CVE fixed: - CVE-2023-40359 xterm: ReGIS reporting for character-set names containing characters other than alphanumerics or underscore Upstream-Status: Backport from https://github.com/ThomasDickey/xterm-snapshots/commit/41ba5cf31da5e43477811b28009d64d3f643fd29 Note: The CVE patch is part of minor version-up and is extracted from the snapshot of xterm-379c. Documentation of the commit shows 2 different overflows being fixed and hence the fix was extracted from the commit. Signed-off-by: Rohini Sangam <rsangam@mvista.com> Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
This commit is contained in:
committed by
Armin Kuster
parent
717462f811
commit
7a49f1e016
@@ -0,0 +1,388 @@
|
||||
From 41ba5cf31da5e43477811b28009d64d3f643fd29 Mon Sep 17 00:00:00 2001
|
||||
From: "Thomas E. Dickey" <dickey@invisible-island.net>
|
||||
Date: Wed, 8 Mar 2023 01:06:03 +0000
|
||||
Subject: [PATCH] snapshot of project "xterm", label xterm-379c
|
||||
|
||||
Upstream-Status: Backport from https://github.com/ThomasDickey/xterm-snapshots/commit/41ba5cf31da5e43477811b28009d64d3f643fd29
|
||||
CVE: CVE-2023-40359
|
||||
|
||||
Signed-off-by: Rohini Sangam <rsangam@mvista.com>
|
||||
|
||||
---
|
||||
graphics_regis.c | 235 +++++++++++++++++++++++++++--------------------
|
||||
1 file changed, 133 insertions(+), 102 deletions(-)
|
||||
|
||||
diff --git a/graphics_regis.c b/graphics_regis.c
|
||||
index 479bb79..cf14437 100644
|
||||
--- a/graphics_regis.c
|
||||
+++ b/graphics_regis.c
|
||||
@@ -1,8 +1,8 @@
|
||||
-/* $XTermId: graphics_regis.c,v 1.129 2022/02/21 13:33:08 tom Exp $ */
|
||||
+/* $XTermId: graphics_regis.c,v 1.139 2023/03/08 01:06:03 tom Exp $ */
|
||||
|
||||
/*
|
||||
- * Copyright 2014-2021,2022 by Ross Combs
|
||||
- * Copyright 2014-2021,2022 by Thomas E. Dickey
|
||||
+ * Copyright 2014-2022,2023 by Ross Combs
|
||||
+ * Copyright 2014-2022,2023 by Thomas E. Dickeiy
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -119,6 +119,14 @@ typedef struct RegisTextControls {
|
||||
int slant; /* for italic/oblique */
|
||||
} RegisTextControls;
|
||||
|
||||
+#define S_QUOTE '\''
|
||||
+#define D_QUOTE '"'
|
||||
+
|
||||
+#define isQuote(ch) ((ch) == S_QUOTE || (ch) == D_QUOTE)
|
||||
+#define PickQuote(ch) ((ch) == S_QUOTE ? D_QUOTE : S_QUOTE)
|
||||
+
|
||||
+#define isName(c) ((c) == '_' || isalnum(CharOf(c)))
|
||||
+
|
||||
#define FixedCopy(dst, src, len) strncpy(dst, src, len - 1)[len - 1] = '\0'
|
||||
#define CopyFontname(dst, src) FixedCopy(dst, src, (size_t) REGIS_FONTNAME_LEN)
|
||||
|
||||
@@ -538,8 +546,8 @@ draw_or_save_patterned_pixel(RegisGraphicsContext *context, int x, int y)
|
||||
static int
|
||||
sort_points(void const *l, void const *r)
|
||||
{
|
||||
- RegisPoint const *const lp = l;
|
||||
- RegisPoint const *const rp = r;
|
||||
+ RegisPoint const *const lp = (RegisPoint const *) l;
|
||||
+ RegisPoint const *const rp = (RegisPoint const *) r;
|
||||
|
||||
if (lp->y < rp->y)
|
||||
return -1;
|
||||
@@ -3151,6 +3159,37 @@ extract_regis_command(RegisDataFragment *input, char *command)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * * Check a ReGIS alphabet name before reporting it, to pick an appropriate
|
||||
+ * * delimiter. If the string is empty, or contains nonreportable characters,
|
||||
+ * * just return NUL.
|
||||
+ * */
|
||||
+static int
|
||||
+pick_quote(const char *value)
|
||||
+{
|
||||
+ Bool s_quote = False;
|
||||
+ Bool d_quote = False;
|
||||
+
|
||||
+ if (*value != '\0') {
|
||||
+ while (*value != '\0') {
|
||||
+ int ch = CharOf(*value++);
|
||||
+ if (ch == D_QUOTE)
|
||||
+ d_quote = True;
|
||||
+ else if (ch == S_QUOTE)
|
||||
+ s_quote = True;
|
||||
+ else if (!isName(ch))
|
||||
+ s_quote = d_quote = True;
|
||||
+ }
|
||||
+ } else {
|
||||
+ s_quote = d_quote = True;
|
||||
+ }
|
||||
+ return ((s_quote && d_quote)
|
||||
+ ? 0
|
||||
+ : (s_quote
|
||||
+ ? D_QUOTE
|
||||
+ : S_QUOTE));
|
||||
+}
|
||||
+
|
||||
static int
|
||||
extract_regis_string(RegisDataFragment *input, char *out, unsigned maxlen)
|
||||
{
|
||||
@@ -3166,7 +3205,7 @@ extract_regis_string(RegisDataFragment *input, char *out, unsigned maxlen)
|
||||
return 0;
|
||||
|
||||
ch = peek_fragment(input);
|
||||
- if (ch != '\'' && ch != '"')
|
||||
+ if (!isQuote(ch))
|
||||
return 0;
|
||||
open_quote_ch = ch;
|
||||
outlen = 0U;
|
||||
@@ -3246,7 +3285,7 @@ extract_regis_parenthesized_data(RegisDataFragment *input,
|
||||
for (; input->pos < input->len; input->pos++, output->len++) {
|
||||
char prev_ch = ch;
|
||||
ch = input->start[input->pos];
|
||||
- if (ch == '\'' || ch == '"') {
|
||||
+ if (isQuote(ch)) {
|
||||
if (open_quote_ch == '\0') {
|
||||
open_quote_ch = ch;
|
||||
} else {
|
||||
@@ -3314,7 +3353,7 @@ extract_regis_option(RegisDataFragment *input,
|
||||
if (ch == ';' || ch == ',' ||
|
||||
ch == '(' || ch == ')' ||
|
||||
ch == '[' || ch == ']' ||
|
||||
- ch == '"' || ch == '\'' ||
|
||||
+ isQuote(ch) ||
|
||||
isdigit(CharOf(ch))) {
|
||||
return 0;
|
||||
}
|
||||
@@ -3330,7 +3369,7 @@ extract_regis_option(RegisDataFragment *input,
|
||||
TRACE(("looking at char '%c' in option '%c'\n", ch, *option));
|
||||
/* FIXME: any special rules for commas? */
|
||||
/* FIXME: handle escaped quotes */
|
||||
- if (ch == '\'' || ch == '"') {
|
||||
+ if (isQuote(ch)) {
|
||||
if (open_quote_ch == ch) {
|
||||
open_quote_ch = '\0';
|
||||
} else {
|
||||
@@ -5008,6 +5047,7 @@ parse_regis_command(RegisParseState *state)
|
||||
static int
|
||||
parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
{
|
||||
+ XtermWidget xw = context->display_graphic->xw;
|
||||
RegisDataFragment optionarg;
|
||||
|
||||
if (!extract_regis_option(&state->input, &state->option, &optionarg))
|
||||
@@ -5586,13 +5626,18 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
state->option, fragment_to_tempstr(&optionarg)));
|
||||
break;
|
||||
} {
|
||||
- char reply[64];
|
||||
+ unsigned err_code = 0U;
|
||||
+ unsigned err_char = 0U;
|
||||
|
||||
TRACE(("got report last error condition\n"));
|
||||
/* FIXME: implement after adding error tracking */
|
||||
- sprintf(reply, "\"%u,%u\"\r", 0U, 0U);
|
||||
- unparseputs(context->display_graphic->xw, reply);
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
+ unparseputc(xw, D_QUOTE);
|
||||
+ unparseputn(xw, err_code);
|
||||
+ unparseputc(xw, ',');
|
||||
+ unparseputn(xw, err_char);
|
||||
+ unparseputc(xw, D_QUOTE);
|
||||
+ unparseputc(xw, '\r');
|
||||
+ unparse_end(xw);
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
@@ -5639,8 +5684,8 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
/* FIXME: implement arrow key movement */
|
||||
/* FIXME: implement button/key collection */
|
||||
|
||||
- unparseputs(context->display_graphic->xw, "\r");
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
+ unparseputc(xw, '\r');
|
||||
+ unparse_end(xw);
|
||||
|
||||
skip_regis_whitespace(&optionarg);
|
||||
if (!fragment_consumed(&optionarg)) {
|
||||
@@ -5657,25 +5702,22 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
if (!fragment_consumed(&optionarg)) {
|
||||
TRACE(("DATA_ERROR: unexpected arguments to ReGIS report command option '%c' arg \"%s\"\n",
|
||||
state->option, fragment_to_tempstr(&optionarg)));
|
||||
- break;
|
||||
- } {
|
||||
- char buffer[32];
|
||||
-
|
||||
- if (state->load_index == MAX_REGIS_ALPHABETS) {
|
||||
- /* If this happens something went wrong elsewhere. */
|
||||
- TRACE(("DATA_ERROR: unable to report current load alphabet\n"));
|
||||
- unparseputs(context->display_graphic->xw, "A0\"\"\r");
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
- break;
|
||||
+ } else if (state->load_index == MAX_REGIS_ALPHABETS) {
|
||||
+ /* If this happens something went wrong elsewhere. */
|
||||
+ TRACE(("DATA_ERROR: unable to report current load alphabet\n"));
|
||||
+ unparseputs(xw, "A0\"\"\r");
|
||||
+ unparse_end(xw);
|
||||
+ } else {
|
||||
+ int delim = pick_quote(state->load_name);
|
||||
+ if (delim != '\0') {
|
||||
+ unparseputs(xw, "A");
|
||||
+ unparseputn(xw, state->load_alphabet);
|
||||
+ unparseputc(xw, delim);
|
||||
+ unparseputs(xw, state->load_name);
|
||||
+ unparseputc(xw, delim);
|
||||
}
|
||||
-
|
||||
- unparseputs(context->display_graphic->xw, "A");
|
||||
- sprintf(buffer, "%u", state->load_alphabet);
|
||||
- unparseputs(context->display_graphic->xw, buffer);
|
||||
- unparseputs(context->display_graphic->xw, "\"");
|
||||
- unparseputs(context->display_graphic->xw, state->load_name);
|
||||
- unparseputs(context->display_graphic->xw, "\"\r");
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
+ unparseputc(xw, '\r');
|
||||
+ unparse_end(xw);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
@@ -5717,13 +5759,18 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
}
|
||||
|
||||
if (name == '=') {
|
||||
- char reply[64];
|
||||
+ unsigned max_available = 1000U;
|
||||
+ unsigned cur_available = max_available;
|
||||
|
||||
TRACE(("got report macrograph storage request\n"));
|
||||
/* FIXME: Implement when macrographs are supported. */
|
||||
- sprintf(reply, "\"%u,%u\"\r", 1000U, 1000U);
|
||||
- unparseputs(context->display_graphic->xw, reply);
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
+ unparseputc(xw, D_QUOTE);
|
||||
+ unparseputn(xw, cur_available);
|
||||
+ unparseputc(xw, ',');
|
||||
+ unparseputn(xw, max_available);
|
||||
+ unparseputc(xw, D_QUOTE);
|
||||
+ unparseputc(xw, '\r');
|
||||
+ unparse_end(xw);
|
||||
} else if (name < 'A' || name > 'Z') {
|
||||
TRACE(("DATA_ERROR: invalid macrograph name: \"%c\"\n", name));
|
||||
/* FIXME: what should happen? */
|
||||
@@ -5732,12 +5779,13 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
char temp[8];
|
||||
|
||||
TRACE(("got report macrograph request for name '%c'\n", name));
|
||||
- sprintf(temp, "@=%c", name);
|
||||
- unparseputs(context->display_graphic->xw, temp);
|
||||
+ unparseputs(xw, "@=");
|
||||
+ unparseputc(xw, name);
|
||||
/* FIXME: Allow this to be disabled for security reasons. */
|
||||
/* FIXME: implement when macrographs are supported. */
|
||||
- unparseputs(context->display_graphic->xw, "@;\r");
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
+ unparseputs(xw, "@;");
|
||||
+ unparseputc(xw, '\r');
|
||||
+ unparse_end(xw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -5785,78 +5833,61 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
TRACE(("got report cursor position (output=%d)\n", output));
|
||||
|
||||
/* FIXME: look into supporting ANSI locator reports (DECLRP) */
|
||||
+ unparseputc(xw, L_BLOK);
|
||||
if (output == 1) {
|
||||
- char reply[64];
|
||||
+ /* FIXME: verify in absolute, not user, coordinates */
|
||||
+ unparseputn(xw, (unsigned) context->graphics_output_cursor_x);
|
||||
+ unparseputc(xw, ',');
|
||||
+ unparseputn(xw, (unsigned) context->graphics_output_cursor_y);
|
||||
+ } else if (context->multi_input_mode) {
|
||||
+ /* FIXME: track input coordinates */
|
||||
+ unsigned x = 0, y = 0; /* placeholders */
|
||||
+
|
||||
+ /* send CSI240~[x,y]\r with current input cursor location */
|
||||
+
|
||||
+ /* FIXME: verify no leading char or button sequence */
|
||||
+ /* FIXME: should we ever send an eight-bit CSI? */
|
||||
|
||||
/* FIXME: verify in absolute, not user, coordinates */
|
||||
- sprintf(reply, "[%d,%d]\r",
|
||||
- context->graphics_output_cursor_x,
|
||||
- context->graphics_output_cursor_y);
|
||||
- unparseputs(context->display_graphic->xw, reply);
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
+ TRACE(("sending multi-mode input report at %u,%u\n", x, y));
|
||||
+ unparseputn(xw, x);
|
||||
+ unparseputc(xw, ',');
|
||||
+ unparseputn(xw, y);
|
||||
} else {
|
||||
- char reply[64];
|
||||
- int x, y;
|
||||
-
|
||||
- if (context->multi_input_mode) {
|
||||
- /* FIXME: track input coordinates */
|
||||
- x = y = 0; /* placeholders */
|
||||
-
|
||||
- /* send CSI240~[x,y]\r with current input cursor location */
|
||||
-
|
||||
- /* FIXME: verify no leading char or button sequence */
|
||||
- /* FIXME: should we ever send an eight-bit CSI? */
|
||||
- /* FIXME: verify in absolute, not user, coordinates */
|
||||
- TRACE(("sending multi-mode input report at %d,%d\n",
|
||||
- x, y));
|
||||
- sprintf(reply, "[%d,%d]\r", x, y);
|
||||
- unparseputs(context->display_graphic->xw, reply);
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
- break;
|
||||
- } else {
|
||||
- char ch;
|
||||
-
|
||||
- /* FIXME: wait for first non-arrow keypress or mouse click, and don't update graphics while waiting */
|
||||
- ch = ' '; /* placeholder */
|
||||
- x = y = 0; /* placeholders */
|
||||
-
|
||||
- /* send <key or button>[x,y]\r to report input cursor location */
|
||||
-
|
||||
- /* null button: CSI240~ */
|
||||
- /* left button: CSI241~ */
|
||||
- /* middle button: CSI243~ */
|
||||
- /* right button: CSI245~ */
|
||||
- /* extra button: CSI247~ */
|
||||
- /* FIXME: support DECLBD to change button assignments */
|
||||
- /* FIXME: verify no leading char or button sequence */
|
||||
- TRACE(("sending one-shot input report with %c at %d,%d\n",
|
||||
- ch, x, y));
|
||||
-#if 0 /* FIXME - dead code */
|
||||
- if (ch == '\r') {
|
||||
- /* Return only reports the location. */
|
||||
- sprintf(reply, "[%d,%d]\r", x, y);
|
||||
- } else if (ch == '\177') {
|
||||
- /* DEL exits locator mode reporting nothing. */
|
||||
- sprintf(reply, "\r");
|
||||
- } else
|
||||
-#endif
|
||||
- {
|
||||
- sprintf(reply, "%c[%d,%d]\r", ch, x, y);
|
||||
- }
|
||||
- unparseputs(context->display_graphic->xw, reply);
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
- /* FIXME: exit one-shot mode and disable input cursor */
|
||||
- break;
|
||||
+
|
||||
+ char ch = ' '; /* placeholder */
|
||||
+ unsigned x = 0, y = 0; /* placeholders */
|
||||
+
|
||||
+ /* FIXME: wait for first non-arrow keypress or mouse click, and don't update graphics while waiting */
|
||||
+ /* send <key or button>[x,y]\r to report input cursor location */
|
||||
+
|
||||
+ /* null button: CSI240~ */
|
||||
+ /* left button: CSI241~ */
|
||||
+ /* middle button: CSI243~ */
|
||||
+ /* right button: CSI245~ */
|
||||
+ /* extra button: CSI247~ */
|
||||
+ /* FIXME: support DECLBD to change button assignments */
|
||||
+ /* FIXME: verify no leading char or button sequence */
|
||||
+ TRACE(("sending one-shot input report with %c at %u,%u\n",
|
||||
+ ch, x, y));
|
||||
+ if (ch != '\177') {
|
||||
+ unparseputn(xw, x);
|
||||
+ unparseputc(xw, ',');
|
||||
+ unparseputn(xw, y);
|
||||
}
|
||||
+ /* FIXME: exit one-shot mode and disable input cursor */
|
||||
}
|
||||
+ unparseputc(xw, R_BLOK);
|
||||
+ unparseputc(xw, '\r');
|
||||
+ unparse_end(xw);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
TRACE(("DATA_ERROR: sending empty report for unknown ReGIS report command option '%c' arg \"%s\"\n",
|
||||
state->option, fragment_to_tempstr(&optionarg)));
|
||||
/* Unknown report request types must receive empty reports. */
|
||||
- unparseputs(context->display_graphic->xw, "\r");
|
||||
- unparse_end(context->display_graphic->xw);
|
||||
+ unparseputs(xw, "\r");
|
||||
+ unparse_end(xw);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -6154,7 +6185,7 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
|
||||
|
||||
TRACE(("using display page number: %d\n", page));
|
||||
context->display_page = (unsigned) page;
|
||||
- map_regis_graphics_pages(context->display_graphic->xw, context);
|
||||
+ map_regis_graphics_pages(xw, context);
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
--
|
||||
2.35.7
|
||||
|
||||
@@ -7,6 +7,7 @@ LIC_FILES_CHKSUM = "file://xterm.h;beginline=3;endline=31;md5=5ec6748ed90e588caa
|
||||
SRC_URI = "http://invisible-mirror.net/archives/${BPN}/${BP}.tgz \
|
||||
file://0001-Add-configure-time-check-for-setsid.patch \
|
||||
file://CVE-2022-45063.patch \
|
||||
file://CVE-2023-40359.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "c6d08127cb2409c3a04bcae559b7025196ed770bb7bf26630abcb45d95f60ab1"
|
||||
|
||||
Reference in New Issue
Block a user