changeset 33772:7624df087ebf v9.0.2106

patch 9.0.2106: [security]: Use-after-free in win_close() Commit: https://github.com/vim/vim/commit/25aabc2b8ee1e19ced6f4da9d866cf9378fc4c5a Author: Christian Brabandt <cb@256bit.org> Date: Tue Nov 14 19:31:34 2023 +0100 patch 9.0.2106: [security]: Use-after-free in win_close() Problem: [security]: Use-after-free in win_close() Solution: Check window is valid, before accessing it If the current window structure is no longer valid (because a previous autocommand has already freed this window), fail and return before attempting to set win->w_closing variable. Add a test to trigger ASAN in CI Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Thu, 16 Nov 2023 22:15:05 +0100
parents 9968a3af7e7b
children 087539ab4b70
files src/testdir/crash/poc1 src/testdir/test_crash.vim src/version.c src/window.c
diffstat 4 files changed, 37 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ec223f16b8803b676e4c47620190a77f13a18e93
GIT binary patch
literal 3264
zc%1E4O-vI(6rLJ-;1zU~r2Yis&=?9>$fn^S1qqsnCXIhIh9*LA=}t?{{=n`c#7J5X
z#8@zJH0aGlf?ho6)x?utIB@Xp-NeLb0^zd0+2yAoplG8U{F3gxnfcz#`(}2(R5!Ak
zH7HrSA)V-g@vJK8hN&CXQ&L_6oB$U(vZOBQ@Cq~HGE;`8$$CwrE}NM%4J^q=2Tj(d
z8H&}e^3gUNwc0@*wheY}INil%<*Lb91LLDSWXU1cv`x-ik<-LScgCQsD|MkZxqmp_
z9;#=MzR8keuau_rr3Pd@!_}-cAe;4&l2tZhW;=K~tMa-V;iSziTg1^=bF4WWi-eQh
zG{g147+11Pbil1EoJ7`)%i3A$KH>oBUjTzHy%Kndzc;Tu)YjI<7HGw%bT_Y|h|l7|
zMtm=()SjM>udVTxP=s@f&VQVrpYQnr)3lo3q7@=ZqO@-LeI=zwa3lYfNEmQSMwc#Q
z#0XxIsl{aERnUV>@ad)XxWOHu5g+xY=n$p2QiaIbdhhb`s(dh0F1VFm%5l1U0Gs^@
z7gi$iMPYGfOTBqUYMui%suY4{bjHD+C{v%PD&Tw+A2}i-uq82j4cm+49&sn4z%Ove
z$C;{wsyC?voFz`OVt8p|opGxTEY7U4>q=puP$<k53TKazMrb7GUFCj%Q1hP(K5h*L
z{VI7l3Ehz4#Q<djSjPuS6cZFP;6UEF%Y8r{7zStB!9MFyu=6eD^!Ok%14x^QLN`kI
z;#J?frg5q>PJGyoPn7WouFe)ur!7Gra%YP`2%)oo9atsV4S$)C<x=haZc~45J;bWm
zPqImVt@5X(s>sDlmRZ_7_I6h*JStf&yTD}0S9IUzu3qMTwF$5T|4pPMCb9@aU~0Za
zIJ+8TRk5n6oxUSEIVa$PkTMb|!qGs$CPb(gst*bEcp3z_!yPkMq=}&>=R^a_@dTSI
zf^Dhz-0(g{J|0(;;OMO9T-e=kxaeLhM3;ov;_mOyiVxPeD<4_KYxntX)9BoWUT(8T
zZSShTQ^NbzU||h;=l1seXTP-Sp0V@CJMs69ofly*+d0YoX+8f8d)v;p{;TyFJo77o
Goqq?k=Ec<j
--- a/src/testdir/test_crash.vim
+++ b/src/testdir/test_crash.vim
@@ -110,6 +110,39 @@ func Test_crash1()
   call delete('X_crash1_result.txt')
 endfunc
 
+func Test_crash1_2()
+  CheckNotBSD
+  CheckExecutable dash
+
+  " The following used to crash Vim
+  let opts = #{cmd: 'sh'}
+  let vim  = GetVimProg()
+  let result = 'X_crash1_1_result.txt'
+
+  let buf = RunVimInTerminal('sh', opts)
+
+  let file = 'crash/poc1'
+  let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'"
+  let args = printf(cmn_args, vim, file)
+  call term_sendkeys(buf, args ..
+    \ '  && echo "crash 1: [OK]" > '.. result .. "\<cr>")
+  call TermWait(buf, 150)
+
+  " clean up
+  exe buf .. "bw!"
+
+  exe "sp " .. result
+
+  let expected = [
+      \ 'crash 1: [OK]',
+      \ ]
+
+  call assert_equal(expected, getline(1, '$'))
+  bw!
+
+  call delete(result)
+endfunc
+
 func Test_crash2()
   " The following used to crash Vim
   let opts = #{wait_for_ruler: 0, rows: 20}
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2106,
+/**/
     2105,
 /**/
     2104,
--- a/src/window.c
+++ b/src/window.c
@@ -2682,6 +2682,8 @@ win_close(win_T *win, int free_buf)
 	    reset_VIsual_and_resel();	// stop Visual mode
 
 	    other_buffer = TRUE;
+	    if (!win_valid(win))
+		return FAIL;
 	    win->w_closing = TRUE;
 	    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
 	    if (!win_valid(win))