GHSA-47gw-8gc3-mgcm on CTRL-OS 26.05
Aliases: GHSA-47gw-8gc3-mgcm, CVE-2026-52859
Packages: vim
Status: Plausible
Advisory Information
Out-of-bounds Read in Terminal Screen Snapshot in Vim < 9.2.565
Date: 30.05.2026 Severity: Medium CVE: CVE-2026-52859 CWE: Out-of-bounds Read (CWE-125)
Summary
The
update_snapshot()function insrc/terminal.ccopies the visible terminal screen into the scrollback buffer when a snapshot is taken. For each screen cell it walks the cell'schars[]array with no upper bound, stopping only when it encounters a NUL terminator. When a cell legitimately fills allVTERM_MAX_CHARS_PER_CELL(6) slots — a base character plus five combining marks — the bundled libvterm returns the array without a terminating NUL, so the loop reads past the fixed six-element array and appends the out-of-bounds values to a buffer reserved for only six characters. A program whose output is rendered inside a:terminalwindow can trigger this with a short byte sequence and no Vim scripting, leading to a crash.Description
update_snapshot()is invoked whenever the terminal's visible screen is snapshotted into the scrollback buffer, for example when the user enters Terminal-Normal mode withCTRL-W N, or when the terminal job exits. For each cell it retrieves the cell withvterm_screen_get_cell()and emits its characters with:for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i) ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c, (char_u *)ga.ga_data + ga.ga_len);
The loop has no
i < VTERM_MAX_CHARS_PER_CELLguard and relies on the array being NUL-terminated. The bundled libvterm fillscell.chars[]with up toVTERM_MAX_CHARS_PER_CELLentries and only writes a terminator when fewer than that many characters are present. A cell holding a base glyph plus five combining marks therefore fills all six slots and is returned unterminated, so the loop readscell.chars[6]and beyond — past the end of the array — and appends each out-of-bounds value to the snapshot buffer, which was grown for onlyVTERM_MAX_CHARS_PER_CELLcharacters.Impact
A program running inside a
:terminalwindow normally controls only its own output and cannot affect the parent Vim process's memory. By emitting a single cell that fills all six character slots, such a program causes Vim to read past a fixed-size array and append attacker-influenced, out-of-bounds values to a buffer sized for only six characters. The reliably reproduced outcome is an out-of-bounds read leading to a crash (denial of service) of the editor.Mitigation
The issue is fixed as of Vim patch v9.2.0565, which bounds the loop in
update_snapshot()withi < VTERM_MAX_CHARS_PER_CELL, mirroring the existing bound inhandle_pushline().Acknowledgements
The Vim project would like to thank github user andrejtomci for reporting and analyzing the issue and suggesting a fix.
References
The issue has been fixed as of Vim patch v9.2.565. - Commit - Github Security Advisory
Updates
2026-07-10 22:53 CEST
Metadata changes:
- Status for package
vim: “Plausible”
2026-06-26 14:33 CEST
Metadata changes:
- Status for package
vim: “New”
(Amended on: 2026-07-10 22:53 CEST)