mirror of
https://github.com/neovim/neovim.git
synced 2026-05-04 21:15:09 +00:00
fix(terminal): heap UAF from autocmds when entering #38316
Problem: heap-use-after-free possible when entering Terminal mode if autocommands close the terminal. Solution: set the refcount. Skip to the end if we must close the terminal.
This commit is contained in:
@@ -943,12 +943,18 @@ bool terminal_enter(void)
|
|||||||
// Don't fire TextChangedT from changes in Normal mode.
|
// Don't fire TextChangedT from changes in Normal mode.
|
||||||
curbuf->b_last_changedtick_i = buf_get_changedtick(curbuf);
|
curbuf->b_last_changedtick_i = buf_get_changedtick(curbuf);
|
||||||
|
|
||||||
|
// Don't let autocommands free the terminal now!
|
||||||
|
s->term->refcount++;
|
||||||
apply_autocmds(EVENT_TERMENTER, NULL, NULL, false, curbuf);
|
apply_autocmds(EVENT_TERMENTER, NULL, NULL, false, curbuf);
|
||||||
may_trigger_modechanged();
|
may_trigger_modechanged();
|
||||||
|
s->term->refcount--;
|
||||||
s->state.execute = terminal_execute;
|
if (s->term->buf_handle == 0) {
|
||||||
s->state.check = terminal_check;
|
s->close = true; // skip entering and close
|
||||||
state_enter(&s->state);
|
} else {
|
||||||
|
s->state.execute = terminal_execute;
|
||||||
|
s->state.check = terminal_check;
|
||||||
|
state_enter(&s->state);
|
||||||
|
}
|
||||||
|
|
||||||
if (!s->got_bsl_o) {
|
if (!s->got_bsl_o) {
|
||||||
restart_edit = 0;
|
restart_edit = 0;
|
||||||
|
|||||||
@@ -1146,6 +1146,16 @@ describe(':terminal buffer', function()
|
|||||||
eq(false, api.nvim_buf_is_valid(term_buf))
|
eq(false, api.nvim_buf_is_valid(term_buf))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('no heap-use-after-free from autocmds when entering terminal mode', function()
|
||||||
|
local chans = api.nvim_list_chans()
|
||||||
|
local buf = api.nvim_get_current_buf()
|
||||||
|
api.nvim_open_term(0, {})
|
||||||
|
command('autocmd TermEnter,ModeChanged * ++once bwipeout!')
|
||||||
|
feed('i')
|
||||||
|
eq(false, api.nvim_buf_is_valid(buf))
|
||||||
|
eq(chans, api.nvim_list_chans())
|
||||||
|
end)
|
||||||
|
|
||||||
local enew_screen = [[
|
local enew_screen = [[
|
||||||
^ |
|
^ |
|
||||||
{1:~ }|*5
|
{1:~ }|*5
|
||||||
|
|||||||
Reference in New Issue
Block a user