Memory-safety bugs in libtsm's VTE terminal escape-sequence parser
fixed
Details
libtsm kmscon kmscon/libtsm ≤ 4.7.0 (through 8a40f0b; also the Aetf/libtsm fork); fixed in 4.7.1 CWE-125 medium fixed Timeline
6 Aug 2026 7 Aug 2026 14 Aug 2026 17 Aug 2026 References
Notes
Fuzzing libtsm’s terminal state machine (AFL++ with AddressSanitizer/UBSan)
surfaced three memory-safety bugs in the VTE escape-sequence parser, all
reachable directly from tsm_vte_input() — i.e. from untrusted terminal
output. A terminal built on libtsm (e.g. kmscon) runs a program’s stdout, or a
file cat’d to it, straight through this parser, so a crafted byte sequence a
few bytes long is enough to reach each bug.
- Heap out-of-bounds read — cursor backward tab.
tsm_screen_tab_left()(src/tsm/tsm-screen.c) indexestab_ruler[cursor_x - 1]without clampingcursor_xto the screen width, so a cursor-forward-tab (CHT) followed by a wide glyph at the last column and then a cursor-backward-tab (CBT,ESC [ Z) reads past the tab-ruler allocation. (CWE-125.) - Out-of-bounds array read — SGR extended color.
csi_attribute()(src/tsm/tsm-vte.c) readscsi_argv[i + 1]before checkingi + 1against the parsed argument count, so an SGR sequence whose38/48introducer is the sixteenth argument reads one past the fixedint[16]argument array. (CWE-125.) - Out-of-bounds read / SIGSEGV — OSC 4 color palette.
do_osc_4()parses the colour index as an unboundedunsigned intand passes it tolookup_color(int color); a large value wraps negative, passes thecolor < 16test, and wild-reads the palette table inpalette_rgb(). The read colour is echoed in the OSC-4 query reply, so a surviving read is also an information leak. (CWE-125.)
Each was reduced to a minimal PoC (11–196 bytes), confirmed on a clean non-AFL ASan/UBSan build, and came with a one-line fix (verified: PoCs clean, no regression on the escape-sequence seed corpus). A follow-up static variant analysis of the three bug classes across the parser found no further siblings — the parser’s bounds handling is otherwise consistent.
The maintainer (Jocelyn Falempe) merged all three patches and released libtsm 4.7.1 on 2026-08-14, crediting the reporter as the commit author. Rebuilding at 4.7.1 and replaying every PoC confirms each parses cleanly under ASan/UBSan.