Commit: patch 9.1.2148: [security]: Buffer overflow in netbeans interface

1 view
Skip to first unread message

Christian Brabandt

unread,
Feb 13, 2026, 2:16:39 PM (yesterday) Feb 13
to vim...@googlegroups.com
patch 9.1.2148: [security]: Buffer overflow in netbeans interface

Commit: https://github.com/vim/vim/commit/c5f312aad8e4179e437f81ad39a860cd0ef11970
Author: Christian Brabandt <c...@256bit.org>
Date: Fri Feb 13 10:27:12 2026 +0100

patch 9.1.2148: [security]: Buffer overflow in netbeans interface

Problem: [security]: Buffer overflow in netbeans special_keys() handling
Solution: Limit writing to max KEYBUFLEN bytes to prevent writing out of
bounds.

Github Advisory:
https://github.com/vim/vim/security/advisories/GHSA-9w5c-hwr9-hc68

Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index a34d6c872..4c673bf97 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -52561,4 +52561,9 @@ Patch 9.1.2147
Problem: Compile warning in strings.c
Solution: Use const qualifier (John Marriott).

+Patch 9.1.2148
+Problem: [security]: Buffer overflow in netbeans special_keys() handling
+Solution: Limit writing to max KEYBUFLEN bytes to prevent writing out of
+ bounds.
+
vim:tw=78:ts=8:noet:ft=help:norl:fdm=manual:nofoldenable
diff --git a/src/netbeans.c b/src/netbeans.c
index 0f17c1b00..a098adc30 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -2302,7 +2302,7 @@ special_keys(char_u *args)
if ((sep = strchr(tok, '-')) != NULL)
{
*sep = NUL;
- while (*tok)
+ while (*tok && i + 2 < KEYBUFLEN)
{
switch (*tok)
{
diff --git a/src/testdir/test_netbeans.py b/src/testdir/test_netbeans.py
index 0d6b09680..585886fb4 100644
--- a/src/testdir/test_netbeans.py
+++ b/src/testdir/test_netbeans.py
@@ -112,7 +112,9 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
'startAtomic_Test' : '0:startAtomic!94
',
'endAtomic_Test' : '0:endAtomic!95
',
'AnnoScale_Test' : "".join(['2:defineAnnoType!60 ' + str(i) + ' "s' + str(i) + '" "x" "=>" blue none
' for i in range(2, 26)]),
- 'detach_Test' : '2:close!96
1:close!97
DETACH
'
+ 'detach_Test' : '2:close!96
1:close!97
DETACH
',
+ 'specialKeys_overflow_Test' : '0:specialKeys!200 "' + 'A'*80 + '-X"
'
+
}
# execute the specified test
if cmd not in testmap:
diff --git a/src/testdir/test_netbeans.vim b/src/testdir/test_netbeans.vim
index d3d5e8baf..d1be5066e 100644
--- a/src/testdir/test_netbeans.vim
+++ b/src/testdir/test_netbeans.vim
@@ -958,6 +958,58 @@ func Nb_bwipe_buffer(port)
sleep 10m
endfunc

+func Nb_specialKeys_overflow(port)
+ call delete("Xnetbeans")
+ call writefile([], "Xnetbeans")
+
+ " Last line number in the Xnetbeans file. Used to verify the result of the
+ " communication with the netbeans server
+ let g:last = 0
+
+ " Establish the connection with the netbeans server
+ exe 'nbstart :localhost:' .. a:port .. ':bunny'
+ call WaitFor('len(ReadXnetbeans()) > (g:last + 2)')
+ let l = ReadXnetbeans()
+ call assert_equal(['AUTH bunny',
+ \ '0:version=0 "2.5"',
+ \ '0:startupDone=0'], l[-3:])
+ let g:last += 3
+
+ " Open the command buffer to communicate with the server
+ split Xcmdbuf
+ let cmdbufnr = bufnr()
+ call WaitFor('len(ReadXnetbeans()) > (g:last + 2)')
+ let l = ReadXnetbeans()
+ call assert_equal('0:fileOpened=0 "Xcmdbuf" T F',
+ \ substitute(l[-3], '".*/', '"', ''))
+ call assert_equal('send: 1:putBufferNumber!15 "Xcmdbuf"',
+ \ substitute(l[-2], '".*/', '"', ''))
+ call assert_equal('1:startDocumentListen!16', l[-1])
+ let g:last += 3
+
+ " Keep the command buffer loaded for communication
+ hide
+
+ sleep 1m
+
+ " Open the command buffer to communicate with the server
+ split Xcmdbuf
+ let cmdbufnr = bufnr()
+ call appendbufline(cmdbufnr, '$', 'specialKeys_overflow_Test')
+ call WaitFor('len(ReadXnetbeans()) >= (g:last + 6)')
+ call WaitForAssert({-> assert_match('send: 0:specialKeys!200 "A\{80}-X"',
+ \ ReadXnetbeans()[-1])})
+
+ " Verify that specialKeys test, still works after the previous junk
+ call appendbufline(cmdbufnr, '$', 'specialKeys_Test')
+ call WaitFor('len(ReadXnetbeans()) >= (g:last + 1)')
+ call WaitForAssert({-> assert_match('^send: 0:specialKeys!91 "F12 F13 C-F13"$',
+ \ ReadXnetbeans()[-1])})
+ let g:last += 1
+
+ sleep 10m
+endfunc
+
" This test used to reference a buffer after it was freed leading to an ASAN
" error.
func Test_nb_bwipe_buffer()
@@ -967,4 +1019,9 @@ func Test_nb_bwipe_buffer()
nbclose
endfunc

+" Verify that the specialKeys argument does not overflow
+func Test_nb_specialKeys_overflow()
+ call s:run_server('Nb_specialKeys_overflow')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index b521788dd..bd45d0216 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 */
+/**/
+ 2148,
/**/
2147,
/**/
Reply all
Reply to author
Forward
0 new messages