Bug 2014661 (CVE-2021-3875) - CVE-2021-3875 vim: heap-based buffer overflow
Summary: CVE-2021-3875 vim: heap-based buffer overflow
Status: NEW
Alias: CVE-2021-3875
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
Depends On: 2015193 2015194 2014662
Blocks: 2014663
TreeView+ depends on / blocked
Reported: 2021-10-15 18:28 UTC by Guilherme de Almeida Suckevicz
Modified: 2021-10-26 17:27 UTC (History)
18 users (show)

Fixed In Version: vim 8.2.3489
Doc Type: If docs needed, set a value
Doc Text:
There's an out-of-bounds read flaw in Vim's ex_docmd.c. An attacker who is capable of tricking a user into opening a specially crafted file could trigger an out-of-bounds read on a memmove operation, potentially causing an impact to application availability.
Clone Of:
Last Closed:

Attachments (Terms of Use)

Description Guilherme de Almeida Suckevicz 2021-10-15 18:28:04 UTC
vim is vulnerable to Heap-based Buffer Overflow


Upstream patch:

Comment 1 Guilherme de Almeida Suckevicz 2021-10-15 18:28:24 UTC
Created vim tracking bugs for this issue:

Affects: fedora-all [bug 2014662]

Comment 2 juneau 2021-10-18 15:31:42 UTC
marking hosted services affected (low) / delegated solely for presence of affected code.

Comment 6 Todd Cullum 2021-10-21 19:52:18 UTC
Flaw summary:

In vim's undo.c, u_save_line() looks like:

u_save_line(undoline_T *ul, linenr_T lnum)
    char_u *line = ml_get(lnum);

    if (curbuf->b_ml.ml_line_len == 0)
	ul->ul_len = 1;
	ul->ul_line = vim_strsave((char_u *)"");
	// This uses the length in the memline, thus text properties are
	// included.
	ul->ul_len = curbuf->b_ml.ml_line_len;
	ul->ul_line = vim_memsave(line, ul->ul_len);
    return ul->ul_line == NULL ? FAIL : OK;

This flaw involves the line ul->ul_line = vim_memsave(line, ul->ul_len); . Specifically, ul->ul_len can be an incorrect length of `line` if `lnum` is out of range. This causes an out-of-bounds read in vim_memsave() -> mch_memmove() because although the new allocation size is ok, the memory read operation can be an out-of-bounds read of memory pointed to by `p` in:

vim_memsave(char_u *p, size_t len)
    char_u *ret = alloc(len);

    if (ret != NULL)
	mch_memmove(ret, p, len);
    return ret;

because the `len` parameter (ul->ul_len) doesn't match the proper `len` for `lnum`.

This does not reproduce, nor does it affect versions of vim shipped in any Red Hat Enterprise Linux version because the vulnerable code was introduced in a newer version of vim than those shipped.

Note You need to log in before you can comment on or make changes to this bug.