aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-09-03 11:15:43 +0800
committerGitHub <noreply@github.com>2023-09-03 11:15:43 +0800
commit087ef5299789123aa40e44937ef9bc31d49fd085 (patch)
tree04ec7c0c1ef429853e6ae9398647df2e8808f5be
parentf32a69630d0360cd73db6e7507bceb4104ec790d (diff)
downloadrneovim-087ef5299789123aa40e44937ef9bc31d49fd085.tar.gz
rneovim-087ef5299789123aa40e44937ef9bc31d49fd085.tar.bz2
rneovim-087ef5299789123aa40e44937ef9bc31d49fd085.zip
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>
-rw-r--r--src/nvim/ex_cmds.c8
-rw-r--r--test/functional/legacy/crash_spec.lua16
-rw-r--r--test/old/testdir/test_crash.vim25
3 files changed, 49 insertions, 0 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 494ebce370..82ebf1871a 100644
--- 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
new file mode 100644
index 0000000000..5094f81847
--- /dev/null
+++ 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
new file mode 100644
index 0000000000..0dea3c2cb1
--- /dev/null
+++ 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