patch 9.1.1361: [security]: possible use-after-free when closing a buffer
Problem: [security]: Possible to open more windows into a closing
buffer without splitting, bypassing existing "b_locked_split"
checks and triggering use-after-free
Solution: Disallow switching to a closing buffer. Editing a closing
buffer (via ":edit", etc.) was fixed in v9.1.0764, but add an
error message and check just "b_locked_split", as "b_locked"
is necessary only when the buffer shouldn't be wiped, and may
be set for buffers that are in-use but not actually closing.
(Sean Dewar)
closes: #17246
Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_buffer.vim b/src/testdir/test_buffer.vim
index 757ba05..36a6ef5 100644
--- a/src/testdir/test_buffer.vim
+++ b/src/testdir/test_buffer.vim
@@ -569,4 +569,39 @@
call assert_fails('cexpr "XallocFail6:10:Line10"', 'E342:')
endfunc
+func Test_closed_buffer_still_in_window()
+ %bw!
+
+ let s:w = win_getid()
+ new
+ let s:b = bufnr()
+ setl bufhidden=wipe
+
+ augroup ViewClosedBuffer
+ autocmd!
+ autocmd BufUnload * ++once call assert_fails(
+ \ 'call win_execute(s:w, "' .. s:b .. 'b")', 'E1546:')
+ augroup END
+ quit!
+ " Previously resulted in s:b being curbuf while unloaded (no memfile).
+ call assert_equal(1, bufloaded(bufnr()))
+ call assert_equal(0, bufexists(s:b))
+
+ let s:w = win_getid()
+ split
+ new
+ let s:b = bufnr()
+
+ augroup ViewClosedBuffer
+ autocmd!
+ autocmd BufWipeout * ++once call win_gotoid(s:w)
+ \| call assert_fails(s:b .. 'b', 'E1546:') | wincmd p
+ augroup END
+ bw! " Close only this buffer first; used to be a heap UAF.
+
+ unlet! s:w s:b
+ autocmd! ViewClosedBuffer
+ %bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab