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 20d4d9a2e..9348b4edd 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 e2e29f12d..961718fd6 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 zcmdT^L1+^}6#bFpkWY-Gg&?9hDH20XHRRUlp&~|MsiHx0NfqmkTVSd84y?Yk~#Y5W5_-E6^ZW0j-9(;${|L4CyGk^b^*#;6}Y6Z)z z)l^t&HebH;tY$NjNMu)7dyIU!S`cxj5Metx`>HH{JD`mXr-Z05_p|G|#Xc;uz2Z7$ z5Ymh#*FS7$Y&UHdI-5F(v@K_?Gh}hVQrVixUM8Nmyh@n(WsfMIu~dL@c7rimB%ZQ|9s#=Fttxs|q1n7Ie78DC!y<_cq?IYhW zDK0>jYq##05Lf?Ym&&1hKp{7({&#)si0IFK%x|TSx&OV7*L;2axIDl7@O*zC)7b6f zZ+qBLF87o>(oyc~F3KHnp7o-B+1u&OwVOOio=aJqHn! zN;`^m6Aaa*LtF)?cFEAe-Cc-?4kgR;dv|T}dJWN(A{F{U?!LeGzVGhxd$$iH!rfKO zv$d*{CHj5xv}(1#zkhg@MZb+_L?0ums{?-=`Y>l_v!g#pQbVWWLKIo;YpqtxZjpI* zT-;|-Rb(=Dwz0CGu_Lrl_J+geS1=L0|g-*H0 zeq-B6@dO=aKxychDtd#?SKujlfdq=nLWTslr_i1{Z%+uGKFxLU%chg5;sq=UUYx#V zl_pB1(qgG}@fZx^AYAe$4~Juu;d8NtkytEj!^>IBU{2_QRvG!|7Y0@Vt%4!Zl}|(n znZ$=E=Ox*E)FR{8J(&$*?ln?cIe{4(LCr~Bk2PnUOQs-1vpy^Lh!@_RL;jqOiMJ`Y zq6q*n&HP6yJqhS$sRlr!oBU3>%Yoox%cib)%WA8E+wA;p+l1{pmw0Y1So=BX=xD#{ z82xX8-rIb0jC=puG&;r}M0O4$bu>B)Ko95{M-9UPPzY7%Jgg8(r~wpG$ij>UMowUq zCkF_QJ~a#L)O1W8zVtj*Jux={gyf1(E;98bMX&WlFNt2=HXF!uasy><=f(c$6)gu! zH4;!{rb|WzF6Nsn8{XBXxbo44bL;utR#zJjb+$X8z0jt)rfc^=yV+8uvIlMLX6&50 z2klK?e#?P7tC8g|zA^mbo&9>;4*2zbz@RNaxBs*+Na@l}VbtX;X2l46-?ZrlkzvN2s>CM?nSK@o(}(a~5P1K)0^#Rw7_s^Jej$%*4(Aq=d2t<`Fo4lLjiaR&p4 zVT>T2YJJ*^c#!t+UJIWD+KprLDp8z4p;*etZjsUe?&nH5URk5Z>2Gu$ zh##fq5mOYH5yibu{blx;*^DTNOG1_e*9)K*&gip(r%rG;oMm%~q;U=m!Hv0_nl)=# z)}m!yILyXjoL#gn_j*Hl@9EI%$xz6vv*+`WhMaH%vy`livub?$d4EZxz6i3dA&R~MxNgu5@y65St&5pdJ3p0qj;-2 zZb?J8kaEpGf+X~Dr$OGY_6Wup_Nb!wS~h%uBmd*TNR=Fzm-27Vfyic2hd+N8Z}>l$Us}xv2m#KX()OulR%P+rK+tkbOH` zdqvF*vTtYgGN>RntROlZ$UU+1vafC3d$)~$McXCUjV!lI%iz;tXn=ofIJ8cjs#Gb< a^Z@raUc`65C$U^n#{xRr?JLgYx76 literal 0 HcmV?d00001 diff --git a/src/testdir/dumps/Test_crash_01.dump b/src/testdir/dumps/Test_crash_01.dump new file mode 100644 index 000000000..1f0fd44c0 --- /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 000000000..0dea3c2cb --- /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 5f6995cc6..34878d749 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, /**/