mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
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>
This commit is contained in:
BIN
src/testdir/crash/poc1
Normal file
BIN
src/testdir/crash/poc1
Normal file
Binary file not shown.
@@ -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}
|
||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2106,
|
||||
/**/
|
||||
2105,
|
||||
/**/
|
||||
|
@@ -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))
|
||||
|
Reference in New Issue
Block a user