GHSA-q8mh-6qm3-25g4 on CTRL-OS 26.05
Aliases: GHSA-q8mh-6qm3-25g4, CVE-2026-57455
Packages: vim
Status: Plausible
Advisory Information
Out-of-bounds Write in SOFO Soundfolding in Vim < 9.2.0698
Date: 21.06.2026 Severity: Medium CVE: CVE-2026-57455 CWE: Out-of-bounds Write (CWE-787)
Summary
The single-byte branch of
spell_soundfold_sofo()insrc/spell.ctranslates a word through a spell file's SOFO (sound-folding) byte map into a caller-owned result buffer. Its copy loop advances the output indexriwith no upper bound and terminates only on the input NUL, writing one byte per input byte into theMAXWLEN-element stack buffer the caller provides. A word longer thanMAXWLEN, passed tosoundfold()(or reached via sound-based spell suggestion) while a SOFO-based spell language is active, therefore writes past the end of that buffer. This is a stack out-of-bounds write that corrupts the call frame and crashes the editor.Description
spell_soundfold_sofo()has two branches. The multibyte branch (taken under multibyte encodings) bounds its output withif (ri + MB_MAXBYTES > MAXWLEN) break;. The single-byte branch, taken for 8-bit encodings such aslatin1, has no equivalent guard:else { // The sl_sal_first[] table contains the translation. for (s = inword; (c = *s) != NUL; ++s) // bound: input NUL only { if (VIM_ISWHITE(c)) c = ' '; else c = slang->sl_sal_first[c]; if (c != NUL && (ri == 0 || res[ri - 1] != c)) res[ri++] = c; // no ri < MAXWLEN guard } } res[ri] = NUL; // trailing OOB write tooThe destination
resis an array of size[MAXWLEN].f_soundfold()passes the user-supplied string straight toeval_soundfold()without length-bounding it, so once the active language carries a SOFO map (sl_sal_first), any input longer than 253 bytes runsripast the end of the buffer. The two sibling walkers do bound their output (spell_soundfold_sal()truncates its input withvim_strncpy(.., MAXWLEN - 1)and guardsreslen < MAXWLEN;spell_soundfold_wsal()guardsreslen < MAXWLEN); the single-byte SOFO branch was the remaining unguarded walker of this class.Impact
This issue is driven by the length of the word handed to the spell_soundfold_sofo() function, not by the contents of the spell file. any loaded spell language with a SOFO sound-folding table is enough. Exploitation is constrained, however. The vulnerable single-byte branch is only reached under a non-multibyte 8-bit encoding (e.g.
set encoding=latin1); under the default UTF-8 encoding the multibyte branch, which is already bounded, is taken instead. Spell checking must be enabled with such a SOFO-based language, andsoundfold()must be invoked on an over-long word - for instance a script or plugin that callssoundfold()on untrusted input. When those conditions hold the out-of-bounds write corrupts theeval_soundfold()stack frame and the process aborts.Acknowledgements
The Vim project would like to thank Cipher / Causal Security (https://causalsecurity.com/) for reporting and analyzing the issue and suggesting a fix.
References
The issue has been fixed as of Vim patch v9.2.0698. - Commit - Github Security Advisory
Updates
2026-07-10 22:53 CEST
Metadata changes:
- Status for package
vim: “Plausible”
2026-07-06 22:42 CEST
Metadata changes:
- Status for package
vim: “New”