Bug 2014661 (CVE-2021-3875)

Summary: CVE-2021-3875 vim: heap-based buffer overflow
Product: [Other] Security Response Reporter: Guilherme de Almeida Suckevicz <gsuckevi>
Component: vulnerabilityAssignee: Nobody <nobody>
Status: NEW --- QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: bdettelb, caswilli, fjansen, gchamoul, gparvin, jburrell, jwong, karsten, kaycoth, pahickey, psegedy, stcannon, vkumar, vmugicag, zdohnal
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
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.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 2014662, 2015193, 2015194    
Bug Blocks: 2014663    

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

Reference:
https://huntr.dev/bounties/5cdbc168-6ba1-4bc2-ba6c-28be12166a53

Upstream patch:
https://github.com/vim/vim/commit/35a319b77f897744eec1155b736e9372c9c5575f

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 *)"");
    }
    else
    {
	// 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.