-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Description
In Foundation/src/Process_WIN32U.cpp, the PROCESS_CLOSE_STDIN, PROCESS_CLOSE_STDOUT, and PROCESS_CLOSE_STDERR options incorrectly close the parent process's standard handles using GetStdHandle(), instead of closing the duplicated handles in startupInfo that are about to be inherited by the child process.
Current behavior
if (options & PROCESS_CLOSE_STDOUT)
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOut) CloseHandle(hStdOut);
}This calls GetStdHandle(STD_OUTPUT_HANDLE) which returns the calling (parent) process's stdout handle, then closes it. After this, any write to std::cout or std::cerr in the parent process crashes or fails silently.
The same issue affects PROCESS_CLOSE_STDIN and PROCESS_CLOSE_STDERR.
Expected behavior
The flags should close the duplicated handles in startupInfo that were prepared for the child process, preventing the child from inheriting them — without affecting the parent:
if (options & PROCESS_CLOSE_STDOUT)
{
if (startupInfo.hStdOutput) CloseHandle(startupInfo.hStdOutput);
startupInfo.hStdOutput = 0;
}Comparison with POSIX implementation
The POSIX implementation (Process_UNIX.cpp) handles this correctly. The close(STDOUT_FILENO) etc. calls happen inside the child process after fork() (in the else branch of fork()), so they only affect the child:
// Process_UNIX.cpp — runs in child process after fork()
if (options & PROCESS_CLOSE_STDIN) close(STDIN_FILENO);
// ...
if (options & PROCESS_CLOSE_STDOUT) close(STDOUT_FILENO);
// ...
if (options & PROCESS_CLOSE_STDERR) close(STDERR_FILENO);On Windows there is no fork(), so the equivalent is to close the duplicated startupInfo handles before calling CreateProcessW() — these are the handles that will be inherited by the child. Using GetStdHandle() instead erroneously targets the parent's own handles.
Reproduction
Launch a child process with PROCESS_CLOSE_STDOUT | PROCESS_CLOSE_STDERR flags, then write to std::cerr in the parent process — the parent crashes.
Environment
- Windows (affects
Process_WIN32U.cpponly; POSIX code paths are not affected) - Discovered in POCO 1.14.2-based fork, but the code appears unchanged in current main