fix(process): close handles and timer in pty_process_close() (#27760)

This should prevent use-after-free on exit on Windows.
This commit is contained in:
zeertzjq 2024-03-07 18:05:55 +08:00 committed by GitHub
parent 04232a19cc
commit 3e569d440b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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);
}