From e1dc9a627536304bc4f738c21e909ad9fcf3974c Mon Sep 17 00:00:00 2001 From: Christian Brabandt Date: Sat, 2 Sep 2023 14:40:13 +0200 Subject: [PATCH] patch 9.0.1840: [security] use-after-free in do_ecmd Problem: use-after-free in do_ecmd Solution: Verify oldwin pointer after reset_VIsual() Signed-off-by: Christian Brabandt --- src/ex_cmds.c | 14 ++++++++++---- src/testdir/Make_all.mak | 2 ++ src/testdir/crash/poc_huaf1 | Bin 0 -> 1541 bytes src/testdir/crash/poc_huaf2 | Bin 0 -> 3238 bytes src/testdir/crash/poc_huaf3 | Bin 0 -> 4053 bytes src/testdir/dumps/Test_crash_01.dump | 20 ++++++++++++++++++++ src/testdir/test_crash.vim | 25 +++++++++++++++++++++++++ src/version.c | 2 ++ 8 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/testdir/crash/poc_huaf1 create mode 100644 src/testdir/crash/poc_huaf2 create mode 100644 src/testdir/crash/poc_huaf3 create mode 100644 src/testdir/dumps/Test_crash_01.dump create mode 100644 src/testdir/test_crash.vim 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 0000000000000000000000000000000000000000..0d0ea475c1062a4df89ee505a078ecc578d57f22 GIT binary patch literal 1541 zc-qxdO=uHA6n>H9kVhIv3qeG2QY40&YRIk8Lq&|jQbmL0k}B36x5_rbWYvQ$ji6{Z ziUn`#*~J{Bhv=zz)ypD9diO2}6%VzS@y%`$o3zDJ^xy|O^XC1`n{U3^9Uu|L7qQG% znhNvH=BxKjABjXFyU6@8^7UFl#F;{b?c(g4viO~VHaw6LqRQMauIm=pVUFz+H>iS; zW-Ph-v5&Dm)GTx^bqJ{~XDesP;((=cWiorEy}iQdZ+p;luvCC?c9SvMB%;#0+fKFS zaJat~Gs3E%&#&9hR(H}A&3mZkPcG|R<5qgC#v$H7R_@nCj`$Qzzh73l05z`N zzH35U-OFxOL-l|{wpjl=9gADmF~1!hbN{=J*SmE5v@o;q=)!s()7a5*Qw`gUxyN|0 z&GbzNp{e% z(jLWn6AaZ$5A`Z|vX>lk@a|oR6g`Ao#<#mQZep}X;xGANcjnE!H*dZ-v)^t5iEyQk zdDdLBu}aU&H5cRKT$qazA!g^nf!umC%66CnJ@hbXMlwj=1#He zjL}L#JEnK;Kw#7gWdpYFh#Rt>wRTXmJ?WsBOm65r!A&h=aTt4sEI+CPZ6lsQv*I%z z8wS#RgkB}EduVF*?0ITW!yRxYA}CG?sR(Z5(8wJ#W(7|k;$FC6^YKLSI2Hvj&R^8a zv*mJmrCdI-7bbBMPCCr}{?MHNXlOYa3i%Cquz)Gd3NKKvAdkIapchats1hxCTPVmR z-axq|$>uSgjE`4kTEXliB)3WgQ$%6I-F>FbaWS3%h1$CnpSbVvoN{@Z8eSsbss{kT zs=pnyOX$bH1<)E)?$=%RN=GsH7SUj}cm8CcC0XU!X7|{uzE*fx{V(9$<_j6_e6>k5 z)uD(CPDC20ejfln@Y;J+)daBF+pKrl?5P@nLJCqh5k z$5Xi?K%-SxxybA&E~(e1qvJ&AarXC|4_1MnxnnQ3QUXG$PmSt{_0OGp8H6zD~(XDTle&8!C8@gq}`^LS7vnE@B4rvJJUrj4jK~KL&ncIu8O0e}7ofb6msZ+B zm$pF!{%S37q;`ZmZGE-{l&U9zf)l9rPjK$Kvuj2>Ii}IH?b&$@_;1w>g~hH!a5&!- zS?Trv26eOghX4SoZZ_Hg?Lql^x5QfWN60F)OFxQ +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 @@ -699,6 +699,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1840, /**/ 1839, /**/ -- 2.47.3