Skip to content

Commit 2377443

Browse files
zeertzjqchrisbra
andauthored
vim-patch:9.1.0764: [security]: use-after-free when closing a buffer (neovim#30705)
Problem: [security]: use-after-free when closing a buffer Solution: When splitting the window and editing a new buffer, check whether the newly to be edited buffer has been marked for deletion and abort in this case Github Advisory: GHSA-rj48-v4mq-j4vg vim/vim@51b6238 Co-authored-by: Christian Brabandt <[email protected]>
1 parent bf868e7 commit 2377443

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

src/nvim/buffer.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,11 @@ static bool can_unload_buffer(buf_T *buf)
478478
return can_unload;
479479
}
480480

481+
bool buf_locked(buf_T *buf)
482+
{
483+
return buf->b_locked || buf->b_locked_split;
484+
}
485+
481486
/// Close the link to a buffer.
482487
///
483488
/// @param win If not NULL, set b_last_cursor.

src/nvim/ex_cmds.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,6 +2261,16 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
22612261
if (buf == NULL) {
22622262
goto theend;
22632263
}
2264+
// autocommands try to edit a file that is goind to be removed, abort
2265+
if (buf_locked(buf)) {
2266+
// window was split, but not editing the new buffer, reset b_nwindows again
2267+
if (oldwin == NULL
2268+
&& curwin->w_buffer != NULL
2269+
&& curwin->w_buffer->b_nwindows > 1) {
2270+
curwin->w_buffer->b_nwindows--;
2271+
}
2272+
goto theend;
2273+
}
22642274
if (curwin->w_alt_fnum == buf->b_fnum && prev_alt_fnum != 0) {
22652275
// reusing the buffer, keep the old alternate file
22662276
curwin->w_alt_fnum = prev_alt_fnum;

test/old/testdir/test_autocmd.vim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ func s:cleanup_buffers() abort
1515
endfor
1616
endfunc
1717

18+
func CleanUpTestAuGroup()
19+
augroup testing
20+
au!
21+
augroup END
22+
augroup! testing
23+
endfunc
24+
1825
func Test_vim_did_enter()
1926
call assert_false(v:vim_did_enter)
2027

@@ -4152,4 +4159,23 @@ func Test_BufEnter_botline()
41524159
set hidden&vim
41534160
endfunc
41544161

4162+
" This was using freed memory
4163+
func Test_autocmd_BufWinLeave_with_vsp()
4164+
new
4165+
let fname = 'XXXBufWinLeaveUAF.txt'
4166+
let dummy = 'XXXDummy.txt'
4167+
call writefile([], fname)
4168+
call writefile([], dummy)
4169+
defer delete(fname)
4170+
defer delete(dummy)
4171+
exe "e " fname
4172+
vsp
4173+
augroup testing
4174+
exe "au BufWinLeave " .. fname .. " :e " dummy .. "| vsp " .. fname
4175+
augroup END
4176+
bw
4177+
call CleanUpTestAuGroup()
4178+
exe "bw! " .. dummy
4179+
endfunc
4180+
41554181
" vim: shiftwidth=2 sts=2 expandtab

0 commit comments

Comments
 (0)