diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-03-07 18:05:55 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-07 18:05:55 +0800 |
commit | 3e569d440b8e5a2b190a7013081d29cb7e04af01 (patch) | |
tree | eaac727f12d66cddf09bc45abbc83e6c6e1a360d | |
parent | 04232a19ccf0e49a3a19d0ef48221249d982b0d4 (diff) | |
download | rneovim-3e569d440b8e5a2b190a7013081d29cb7e04af01.tar.gz rneovim-3e569d440b8e5a2b190a7013081d29cb7e04af01.tar.bz2 rneovim-3e569d440b8e5a2b190a7013081d29cb7e04af01.zip |
fix(process): close handles and timer in pty_process_close() (#27760)
This should prevent use-after-free on exit on Windows.
-rw-r--r-- | src/nvim/os/pty_process_win.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index fdc06f9804..cce27c31b4 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -34,8 +34,6 @@ static void start_wait_eof_timer(void **argv) PtyProcess *ptyproc = (PtyProcess *)argv[0]; Process *proc = (Process *)ptyproc; - uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); - ptyproc->wait_eof_timer.data = (void *)ptyproc; uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200); } @@ -117,6 +115,8 @@ int pty_process_spawn(PtyProcess *ptyproc) } proc->pid = (int)GetProcessId(process_handle); + uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); + ptyproc->wait_eof_timer.data = (void *)ptyproc; if (!RegisterWaitForSingleObject(&ptyproc->finish_wait, process_handle, pty_process_finish1, @@ -176,6 +176,16 @@ void pty_process_close(PtyProcess *ptyproc) pty_process_close_master(ptyproc); + if (ptyproc->finish_wait != NULL) { + UnregisterWaitEx(ptyproc->finish_wait, NULL); + ptyproc->finish_wait = NULL; + uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL); + } + if (ptyproc->process_handle != NULL) { + CloseHandle(ptyproc->process_handle); + ptyproc->process_handle = NULL; + } + if (proc->internal_close_cb) { proc->internal_close_cb(proc); } @@ -215,16 +225,10 @@ static void pty_process_finish2(PtyProcess *ptyproc) { Process *proc = (Process *)ptyproc; - UnregisterWaitEx(ptyproc->finish_wait, NULL); - uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL); - DWORD exit_code = 0; GetExitCodeProcess(ptyproc->process_handle, &exit_code); proc->status = proc->exit_signal ? 128 + proc->exit_signal : (int)exit_code; - CloseHandle(ptyproc->process_handle); - ptyproc->process_handle = NULL; - proc->internal_exit_cb(proc); } |