neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 087ef5299789123aa40e44937ef9bc31d49fd085
parent f32a69630d0360cd73db6e7507bceb4104ec790d
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Sun,  3 Sep 2023 11:15:43 +0800

vim-patch:9.0.1840: [security] use-after-free in do_ecmd (#24993)

Problem:  use-after-free in do_ecmd
Solution: Verify oldwin pointer after reset_VIsual()

https://github.com/vim/vim/commit/e1dc9a627536304bc4f738c21e909ad9fcf3974c

N/A patches for version.c:
vim-patch:9.0.1841: style: trailing whitespace in ex_cmds.c

Co-authored-by: Christian Brabandt <cb@256bit.org>
Diffstat:
Msrc/nvim/ex_cmds.c | 8++++++++
Atest/functional/legacy/crash_spec.lua | 16++++++++++++++++
Atest/old/testdir/test_crash.vim | 25+++++++++++++++++++++++++
3 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c @@ -2230,8 +2230,16 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum // End Visual mode before switching to another buffer, so the text can be // copied into the GUI selection buffer. + // Careful: may trigger ModeChanged() autocommand + + // Should we block autocommands here? reset_VIsual(); + // autocommands freed window :( + if (oldwin != NULL && !win_valid(oldwin)) { + oldwin = NULL; + } + if ((command != NULL || newlnum > (linenr_T)0) && *get_vim_var_str(VV_SWAPCOMMAND) == NUL) { // Set v:swapcommand for the SwapExists autocommands. diff --git a/test/functional/legacy/crash_spec.lua b/test/functional/legacy/crash_spec.lua @@ -0,0 +1,16 @@ +local helpers = require('test.functional.helpers')(after_each) +local assert_alive = helpers.assert_alive +local clear = helpers.clear +local command = helpers.command +local feed = helpers.feed + +before_each(clear) + +-- oldtest: Test_crash1() +it('no crash when ending Visual mode while editing buffer closes window', function() + command('new') + command('autocmd ModeChanged v:n ++once close') + feed('v') + command('enew') + assert_alive() +end) diff --git a/test/old/testdir/test_crash.vim b/test/old/testdir/test_crash.vim @@ -0,0 +1,25 @@ +" Some tests, that used to crash Vim +source check.vim +source screendump.vim + +CheckScreendump + +func Test_crash1() + " The following used to crash Vim + let opts = #{wait_for_ruler: 0} + let args = ' -u NONE -i NONE -n -e -s -S ' + let buf = RunVimInTerminal(args .. ' crash/poc_huaf1', opts) + call VerifyScreenDump(buf, 'Test_crash_01', {}) + exe buf .. "bw!" + + let buf = RunVimInTerminal(args .. ' crash/poc_huaf2', opts) + call VerifyScreenDump(buf, 'Test_crash_01', {}) + exe buf .. "bw!" + + let buf = RunVimInTerminal(args .. ' crash/poc_huaf3', opts) + call VerifyScreenDump(buf, 'Test_crash_01', {}) + exe buf .. "bw!" + +endfunc + +" vim: shiftwidth=2 sts=2 expandtab