From 3cc246980b800454dda0603af410c77a8c1926e0 Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Fri, 13 Feb 2026 10:27:12 +0100 Subject: [PATCH] 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 CVE: CVE-2026-26269 Upstream-Status: Backport [https://github.com/vim/vim/commit/c5f312aad8e4179e437f81ad39a860cd0ef11970] Backport Changes: - Excluded changes to src/version.c from this backport. This file only tracks upstream version increments. We are applying a security fix, not a version upgrade. These changes were skipped to maintain current package versioning and avoid merge conflicts. Signed-off-by: Christian Brabandt (cherry picked from commit c5f312aad8e4179e437f81ad39a860cd0ef11970) Signed-off-by: Anil Dongare --- runtime/doc/version9.txt | 5 +++ src/netbeans.c | 2 +- src/testdir/test_netbeans.py | 4 ++- src/testdir/test_netbeans.vim | 57 +++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index b82071757..b32400f17 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -41899,4 +41899,9 @@ features, but does not include runtime file changes (syntax, indent, ftplugin, documentation, etc.) +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 4f5378512..8a341a20b 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\n', 'endAtomic_Test' : '0:endAtomic!95\n', 'AnnoScale_Test' : "".join(['2:defineAnnoType!60 ' + str(i) + ' "s' + str(i) + '" "x" "=>" blue none\n' for i in range(2, 26)]), - 'detach_Test' : '2:close!96\n1:close!97\nDETACH\n' + 'detach_Test' : '2:close!96\n1:close!97\nDETACH\n', + 'specialKeys_overflow_Test' : '0:specialKeys!200 "' + 'A'*80 + '-X"\n' + } # 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 -- 2.43.7