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

Commit: 
https://github.com/vim/vim/commit/bb6de2105b160e729c340631435cd62f3e69bd32
Author: Christian Brabandt <[email protected]>
Date:   Mon Feb 23 20:29:43 2026 +0000

    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 <[email protected]>

diff --git a/src/terminal.c b/src/terminal.c
index 0753c2892..02ca5d6d9 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -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]);
diff --git a/src/testdir/samples/terminal_max_combining_chars.txt 
b/src/testdir/samples/terminal_max_combining_chars.txt
new file mode 100644
index 000000000..a4f508d54
--- /dev/null
+++ b/src/testdir/samples/terminal_max_combining_chars.txt
@@ -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𐀀󠄀󠄁󠄂󠄃󠄄
diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim
index b637a6652..7deb0eaaf 100644
--- a/src/testdir/test_terminal3.vim
+++ b/src/testdir/test_terminal3.vim
@@ -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
")
+  exe buf . "bwipe!"
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index f2809216a..21a1f3207 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    76,
 /**/
     75,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vw5Ay-00GEsw-I8%40256bit.org.

Raspunde prin e-mail lui