patch 9.2.0076: [security]: buffer-overflow in terminal handling

Problem:  When processing terminal output with many combining characters
          from supplementary planes (4-byte UTF-8), a heap-buffer
          overflow occurs. Additionally, the loop iterating over
          cell characters can read past the end of the vterm array
          (ehdgks0627, un3xploitable).
Solution: Use VTERM_MAX_CHARS_PER_CELL * 4 for ga_grow() to ensure
          sufficient space. Add a boundary check to the character
          loop to prevent index out-of-bounds access.

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-rvj2-jrf9-2phg

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt
2026-02-23 20:29:43 +00:00
parent 9b7dfa2948
commit bb6de2105b
4 changed files with 99 additions and 2 deletions
+3 -2
View File
@@ -3570,12 +3570,13 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user)
{
for (col = 0; col < len; col += cells[col].width)
{
if (ga_grow(&ga, MB_MAXBYTES) == FAIL)
if (ga_grow(&ga, VTERM_MAX_CHARS_PER_CELL * 4) == FAIL)
{
ga.ga_len = 0;
break;
}
for (i = 0; (c = cells[col].chars[i]) > 0 || i == 0; ++i)
for (i = 0; i < VTERM_MAX_CHARS_PER_CELL &&
((c = cells[col].chars[i]) > 0 || i == 0); ++i)
ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c,
(char_u *)ga.ga_data + ga.ga_len);
cell2cellattr(&cells[col], &p[col]);
@@ -0,0 +1,80 @@
padding line 000
padding line 001
padding line 002
padding line 003
padding line 004
padding line 005
padding line 006
padding line 007
padding line 008
padding line 009
padding line 010
padding line 011
padding line 012
padding line 013
padding line 014
padding line 015
padding line 016
padding line 017
padding line 018
padding line 019
padding line 020
padding line 021
padding line 022
padding line 023
padding line 024
padding line 025
padding line 026
padding line 027
padding line 028
padding line 029
padding line 030
padding line 031
padding line 032
padding line 033
padding line 034
padding line 035
padding line 036
padding line 037
padding line 038
padding line 039
padding line 040
padding line 041
padding line 042
padding line 043
padding line 044
padding line 045
padding line 046
padding line 047
padding line 048
padding line 049
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
AAAAAAAAAAAAAAAAAAAAAAAAAAAA𐀀󠄀󠄁󠄂󠄃󠄄
+14
View File
@@ -1148,4 +1148,18 @@ func Test_terminal_split_utf8()
exe buf .. "bwipe!"
endfunc
func Test_terminal_max_combining_chars()
" somehow doesn't work on MS-Windows
CheckUnix
let cmd = "cat samples/terminal_max_combining_chars.txt\<CR>"
let buf = Run_shell_in_terminal({'term_rows': 15, 'term_cols': 35})
call TermWait(buf)
call term_sendkeys(buf, cmd)
" last char is a space with many combining chars
call WaitForAssert({-> assert_match("AAAAAAAAAAAAAAAAAAAAAAAAAAAA.", term_getline(buf, 14))})
call term_sendkeys(buf, "exit\r")
exe buf . "bwipe!"
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
76,
/**/
75,
/**/