summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Brabandt <cb@256bit.org>2023-09-02 14:40:13 +0200
committerChristian Brabandt <cb@256bit.org>2023-09-02 14:44:47 +0200
commite1dc9a627536304bc4f738c21e909ad9fcf3974c (patch)
tree03d9e7d48d9db0cfd5321b735c542f642ff84860
parentacb91d3905cfef5eff8edfb76e62a6b6bab1e91e (diff)
patch 9.0.1840: [security] use-after-free in do_ecmdv9.0.1840
Problem: use-after-free in do_ecmd Solution: Verify oldwin pointer after reset_VIsual() Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--src/ex_cmds.c14
-rw-r--r--src/testdir/Make_all.mak2
-rw-r--r--src/testdir/crash/poc_huaf1bin0 -> 1541 bytes
-rw-r--r--src/testdir/crash/poc_huaf2bin0 -> 3238 bytes
-rw-r--r--src/testdir/crash/poc_huaf3bin0 -> 4053 bytes
-rw-r--r--src/testdir/dumps/Test_crash_01.dump20
-rw-r--r--src/testdir/test_crash.vim25
-rw-r--r--src/version.c2
8 files changed, 59 insertions, 4 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 20d4d9a2ea..9348b4edda 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2646,12 +2646,18 @@ do_ecmd(
goto theend;
}
- /*
- * End Visual mode before switching to another buffer, so the text can be
- * copied into the GUI selection buffer.
- */
+
+ // 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 defined(FEAT_EVAL)
if ((command != NULL || newlnum > (linenr_T)0)
&& *get_vim_var_str(VV_SWAPCOMMAND) == NUL)
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index e2e29f12d2..961718fd69 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -105,6 +105,7 @@ NEW_TESTS = \
test_conceal \
test_const \
test_cpoptions \
+ test_crash \
test_crypt \
test_cscope \
test_cursor_func \
@@ -369,6 +370,7 @@ NEW_TESTS_RES = \
test_conceal.res \
test_const.res \
test_cpoptions.res \
+ test_crash.res \
test_crypt.res \
test_cscope.res \
test_cursor_func.res \
diff --git a/src/testdir/crash/poc_huaf1 b/src/testdir/crash/poc_huaf1
new file mode 100644
index 0000000000..0d0ea475c1
--- /dev/null
+++ b/src/testdir/crash/poc_huaf1
Binary files differ
diff --git a/src/testdir/crash/poc_huaf2 b/src/testdir/crash/poc_huaf2
new file mode 100644
index 0000000000..4867e0f956
--- /dev/null
+++ b/src/testdir/crash/poc_huaf2
Binary files differ
diff --git a/src/testdir/crash/poc_huaf3 b/src/testdir/crash/poc_huaf3
new file mode 100644
index 0000000000..7e38a9a17c
--- /dev/null
+++ b/src/testdir/crash/poc_huaf3
Binary files differ
diff --git a/src/testdir/dumps/Test_crash_01.dump b/src/testdir/dumps/Test_crash_01.dump
new file mode 100644
index 0000000000..1f0fd44c05
--- /dev/null
+++ b/src/testdir/dumps/Test_crash_01.dump
@@ -0,0 +1,20 @@
+> +0&#ffffff0@74
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
diff --git a/src/testdir/test_crash.vim b/src/testdir/test_crash.vim
new file mode 100644
index 0000000000..0dea3c2cb1
--- /dev/null
+++ b/src/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
diff --git a/src/version.c b/src/version.c
index 5f6995cc61..34878d7492 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1840,
+/**/
1839,
/**/
1838,