macvim-dev / macvim-dev/macvim
[Security] MacVim affected by GHSA-q4jv-r9gj-6cwv — heap buffer overflow in spellfile.c read_compound() (vim < 9.2.0450)
Nobody has claimed this yet.
- Dominant language
- Vim Script
- Stars
- 7.9k
- Forks
- 691
- PR merge metrics
- No merged PRs in 30d
Description
Summary
MacVim's src/spellfile.c contains a heap buffer overflow in read_compound() when loading specially crafted spell files. An integer overflow in the allocation size computation allows a malicious .spl file to cause out-of-bounds writes. The fix from vim 9.2.0450 (92993329) has not been applied to macvim r183.
Vulnerability Details
- GHSA: GHSA-q4jv-r9gj-6cwv
- CVE: CVE-2026-45130
- Upstream fix (vim): 9.2.0450 (commit
929933294a5c56ef8e9dab03e0b8c61bbb1dc3cd, 2026-05-07) - Affected code:
src/spellfile.c—read_compound()function - Vulnerability type: CWE-122 — Heap-based Buffer Overflow
Root Cause
In read_compound(), the todo variable (derived from the SN_COMPOUND section length in the spell file) is used directly in buffer size calculations without an upper bound check:
/* src/spellfile.c line 1278 (macvim r183) */
c = todo * 2 + 7;
A malicious spell file can set todo to a large value (e.g., 0x40000000), causing todo * 2 to overflow a 32-bit integer to 7, resulting in an undersized allocation. Subsequent writes to the buffer cause a heap overflow.
Attack Scenario
- Attacker provides a malicious
.splspell file (e.g., in a project's spell directory) - Victim loads the spell file in MacVim (
:setlocal spelllang=...or via modeline) read_compound()allocates an undersized buffer and writes beyond it, potentially enabling arbitrary code execution
Verification
$ grep -n 'todo.*2.*7\|read_compound\|COMPOUND_MAX_LEN' src/spellfile.c
1278: c = todo * 2 + 7;
Missing the COMPOUND_MAX_LEN guard and safe size computation. Patch 9.2.0450 not present:
$ git log --all --oneline | grep -i '9.2.0450\|spellfile\|q4jv'
(no output)
Suggested Fix
Merge vim patches up to at least 9.2.0450. The fix adds an upper bound check and uses size_t arithmetic:
/* Fixed (vim 9.2.0450): */
#define COMPOUND_MAX_LEN 100000
if ((size_t)todo > COMPOUND_MAX_LEN)
return SP_FORMERROR;
size_t patsize = (size_t)todo * 2 + 7;
size_t flagsize = (size_t)todo + 1;
pat = alloc(patsize);
cp = alloc(flagsize);
ap = alloc(flagsize);
crp = alloc(flagsize);
References
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/spellfile.c at read_compound(), especially the todo-based allocation around line 1278, and compare it with Vim commit 929933294a5c56ef8e9dab03e0b8c61bbb1dc3cd. Apply the upstream fix for bounded, safe size calculations and verify that the vulnerable allocation is no longer present in MacVim r183.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, vim
- Domain
- desktop, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100