mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +00:00 
			
		
		
		
	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:
		@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user