From e7d13399f37716c06d0bab32a2a36021832c2a55 Mon Sep 17 00:00:00 2001 From: gitchfox Date: Fri, 14 Aug 2026 12:18:18 +0200 Subject: [PATCH 1/3] screen: Fix out-of-bounds read in tsm_screen_tab_left() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1) Heap out-of-bounds READ — tsm_screen_tab_left (src/tsm/tsm-screen.c) A cursor-forward-tab (CHT, ESC [ n I) followed by a wide glyph at the last column can leave cursor_x > size_x; a following cursor-backward-tab (CBT, ESC [ Z) then reads tab_ruler[cursor_x - 1], past the size_x-element ruler: ==ERROR: AddressSanitizer: heap-buffer-overflow READ of size 1 in tsm_screen_tab_left src/tsm/tsm-screen.c:1354 in do_csi / do_action / do_trans / tsm_vte_input Reported-by: Benjamin Ali (glitchfox) Signed-off-by: Benjamin Ali (glitchfox) --- src/tsm/tsm-screen.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tsm/tsm-screen.c b/src/tsm/tsm-screen.c index 5f532bb..bf37bad 100644 --- a/src/tsm/tsm-screen.c +++ b/src/tsm/tsm-screen.c @@ -1349,6 +1349,11 @@ void tsm_screen_tab_left(struct tsm_screen *con, unsigned int num) screen_inc_age(con); x = con->cursor_x; + + /* cursor_x may exceed size_x (e.g. CHT then a wide glyph at the last + * column); clamp before indexing tab_ruler[0..size_x-1]. */ + if (x > con->size_x) + x = con->size_x; for (i = 0; i < num; ++i) { for (j = x - 1; j > 0; --j) { if (con->tab_ruler[j]) From cdd725df0e4f3525b730d069125ad6651fec29e4 Mon Sep 17 00:00:00 2001 From: gitchfox Date: Fri, 14 Aug 2026 12:24:06 +0200 Subject: [PATCH 2/3] vte: Fix OSC 4 color index MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Out-of-bounds READ via unbounded OSC 4 color index — lookup_color (src/tsm/tsm-vte.c) do_osc_4 (ESC ] 4 ; ; ? ) parses as an unbounded unsigned int and passes it to lookup_color(int color). A large value wraps to a negative int, passes the `color < 16` test, and reaches palette_rgb() -> vte->palette[color] — a wild read that SIGSEGVs: ==ERROR: AddressSanitizer: SEGV ... READ memory access in palette_rgb src/tsm/tsm-vte.c:1284 in lookup_color src/tsm/tsm-vte.c:1310 in do_osc_4 src/tsm/tsm-vte.c:2237 The read colour is also written back in the OSC-4 query reply, so a non-faulting read is an information leak. Large positive indices additionally mis-index cube_rgb's bval[] and overflow greyscale_rgb — same root cause. Reported-by: Benjamin Ali (glitchfox) Signed-off-by: Benjamin Ali (glitchfox) --- src/tsm/tsm-vte.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tsm/tsm-vte.c b/src/tsm/tsm-vte.c index 44ec5a0..26ba3b1 100644 --- a/src/tsm/tsm-vte.c +++ b/src/tsm/tsm-vte.c @@ -1306,6 +1306,12 @@ static void greyscale_rgb(int code, uint8_t *cr, uint8_t *cg, uint8_t *cb) static void lookup_color(struct tsm_vte *vte, int color, uint8_t *cr, uint8_t *cg, uint8_t *cb) { + /* OSC-4 / SGR color indices are untrusted; an out-of-range (or + * unsigned-overflow-negative) index would wild-read palette[]/bval[]. */ + if (color < 0 || color > 255) { + *cr = *cg = *cb = 0; + return; + } if (color < 16) { palette_rgb(vte, color, cr, cg, cb); } else if (color < 232) { From 60c595dbea8b49ff9896baa2c7fbd1d5de7baef8 Mon Sep 17 00:00:00 2001 From: gitchfox Date: Fri, 14 Aug 2026 12:26:05 +0200 Subject: [PATCH 3/3] vte: Fix Out-of-bounds READ in csi_attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Out-of-bounds READ of csi_argv[16] — csi_attribute (src/tsm/tsm-vte.c) csi_argv is int[CSI_ARG_MAX] with CSI_ARG_MAX == 16. In the SGR 38/48 handling, csi_argv[i + 1] is read before i + 1 is bounds-checked (the i+2 >= csi_argc guard comes after). An SGR whose 38/48 is the 16th argument reads csi_argv[16]: src/tsm/tsm-vte.c:1482: runtime error: index 16 out of bounds for type 'int[16]' in csi_attribute -> do_csi -> ... -> tsm_vte_input Reported-by: Benjamin Ali (glitchfox) Signed-off-by: Benjamin Ali (glitchfox) --- src/tsm/tsm-vte.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tsm/tsm-vte.c b/src/tsm/tsm-vte.c index 26ba3b1..04bbe21 100644 --- a/src/tsm/tsm-vte.c +++ b/src/tsm/tsm-vte.c @@ -1485,6 +1485,10 @@ static void csi_attribute(struct tsm_vte *vte) /* fallthrough */ case 48: val = vte->csi_argv[i]; + /* the 5/2 subcommand + its operands live in later argv slots; + * bail if they would read past the parsed args (csi_argv[16] OOB). */ + if (i + 1 >= vte->csi_argc) + break; if (vte->csi_argv[i + 1] == 5) { // 256color mode if (i + 2 >= vte->csi_argc || vte->csi_argv[i + 2] < 0) {