Use After Free in vim/vim
Description
Use after free in Vim's substitute command (prior to 9.0.0046) can lead to crash or arbitrary code execution via a crafted recursive substitute expression.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Use after free in Vim's substitute command (prior to 9.0.0046) can lead to crash or arbitrary code execution via a crafted recursive substitute expression.
Vulnerability
A use-after-free vulnerability exists in Vim's ex_substitute function (file src/ex_docmd.c) prior to version 9.0.0046. The issue occurs when a recursive substitute expression is used, causing the regtilde() function to allocate new memory and free the previous reg_prev_sub pointer. However, the sub variable in ex_substitute is not updated to point to the newly allocated string, leading to a use-after-free when the freed memory is subsequently accessed.
Exploitation
An attacker must be able to craft a specially crafted substitute command that includes a recursive expression (e.g., :s/pattern/\=Repl()/). The attacker does not require authentication or special privileges beyond the ability to open and edit a file in Vim. By triggering the recursive substitute, the attacker can cause Vim to read from freed heap memory, potentially leading to a crash or allowing further memory corruption.
Impact
Successful exploitation results in a use-after-free condition, which can cause Vim to crash (denial of service) or potentially allow arbitrary code execution within the context of the Vim process. The scope of compromise is limited to the Vim session, but if Vim runs with elevated privileges, further system compromise may be possible.
Mitigation
The vulnerability is fixed in Vim version 9.0.0047 [1]. Users should upgrade to at least 9.0.0047 or later. Distributions have backported the fix: Gentoo advises upgrading to >=app-editors/vim-9.0.0060 (GLSA 202208-32) or >=app-editors/vim-9.0.1157 (GLSA 202305-16) [3][4]. No workarounds are available if upgrading is not possible.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
39- osv-coords37 versionspkg:rpm/opensuse/vim&distro=openSUSE%20Leap%2015.3pkg:rpm/opensuse/vim&distro=openSUSE%20Leap%2015.4pkg:rpm/opensuse/vim&distro=openSUSE%20Leap%20Micro%205.2pkg:rpm/opensuse/vim&distro=openSUSE%20Tumbleweedpkg:rpm/suse/vim&distro=SUSE%20Enterprise%20Storage%206pkg:rpm/suse/vim&distro=SUSE%20Enterprise%20Storage%207pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-ESPOSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-LTSSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP2-ESPOSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP2-LTSSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Micro%205.1pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Micro%205.2pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Basesystem%2015%20SP3pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Basesystem%2015%20SP4pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Desktop%20Applications%2015%20SP3pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Desktop%20Applications%2015%20SP4pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP2-BCLpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP3-BCLpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP4-LTSSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP5pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-BCLpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-LTSSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP2-BCLpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP2-LTSSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP4pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP5pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP1pkg:rpm/suse/vim&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP2pkg:rpm/suse/vim&distro=SUSE%20Manager%20Proxy%204.1pkg:rpm/suse/vim&distro=SUSE%20Manager%20Retail%20Branch%20Server%204.1pkg:rpm/suse/vim&distro=SUSE%20Manager%20Server%204.1pkg:rpm/suse/vim&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/vim&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209
< 9.0.0313-150000.5.25.1+ 36 more
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0453-2.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0814-17.9.1
- (no CPE)range: < 9.0.0814-17.9.1
- (no CPE)range: < 9.0.0814-17.9.1
- (no CPE)range: < 9.0.0814-17.9.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0814-17.9.1
- (no CPE)range: < 9.0.0814-17.9.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0313-150000.5.25.1
- (no CPE)range: < 9.0.0814-17.9.1
- (no CPE)range: < 9.0.0814-17.9.1
Patches
0No patches discovered yet.
Vulnerability mechanics
Root cause
"Use-after-free in `ex_substitute()` when `regtilde()` frees and reallocates `reg_prev_sub` during recursive substitute expression evaluation, but the caller continues using the old freed pointer."
Attack vector
An attacker can trigger a use-after-free by crafting a recursive substitute expression (e.g., `s/\%')/~\=Repl()` where `Repl()` itself calls `:s`). When `regtilde()` is called, it may free and reallocate `reg_prev_sub`, but the caller `ex_substitute()` continues to use the old `sub` pointer, which now points to freed memory [ref_id=1]. The attack requires the ability to supply a substitute command with a recursive expression.
Affected code
The vulnerability is in the `ex_substitute()` function in `src/ex_cmds.c` and the `regtilde()` function in `src/regexp.c`. The patch modifies the logic around `regtilde()` calls and how `reg_prev_sub` is managed [ref_id=1].
What the fix does
The patch fixes the use-after-free by ensuring that when `regtilde()` returns a newly allocated string (different from the input `sub`), the caller `ex_substitute()` updates `sub` to point to the new allocation and stores it in `sub_copy` for later freeing [ref_id=1]. Additionally, `regtilde()` is changed to always store a copy of the result in `reg_prev_sub` via `vim_strsave()`, rather than conditionally keeping the returned pointer, because recursive calls may invalidate the previously stored pointer [ref_id=1].
Preconditions
- inputAttacker must be able to supply a substitute command with a recursive expression (e.g., via a crafted file or command input)
- inputThe substitute expression must trigger a recursive call to :substitute within the expression evaluation
Reproduction
The test case added in the patch demonstrates reproduction: create a new buffer, define a function `Repl()` that calls `:s`, then run `silent! s/\%')/~\=Repl()` [ref_id=1].
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/43Y3VJPOTTY3NTREDIFUPITM2POG4ZLP/mitrevendor-advisory
- security.gentoo.org/glsa/202208-32mitrevendor-advisory
- security.gentoo.org/glsa/202305-16mitrevendor-advisory
- github.com/vim/vim/commit/32acf1f1a72ebb9d8942b9c9d80023bf1bb668eamitre
- huntr.dev/bounties/1eed7009-db6d-487b-bc41-8f2fd260483fmitre
News mentions
0No linked articles in our index yet.