Skip to content

Commit

Permalink
Merge pull request #99108 from RandomShaper/win_less_inheritance_4.3
Browse files Browse the repository at this point in the history
[4.3] Windows: Avoid child processes inheriting all file handles
  • Loading branch information
akien-mga committed Nov 15, 2024
2 parents 305bdbf + ce608dc commit 711c725
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 24 deletions.
89 changes: 66 additions & 23 deletions platform/windows/os_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,18 +840,10 @@ Dictionary OS_Windows::execute_with_pipe(const String &p_path, const List<String
sa.lpSecurityDescriptor = nullptr;

ERR_FAIL_COND_V(!CreatePipe(&pipe_in[0], &pipe_in[1], &sa, 0), ret);
if (!SetHandleInformation(pipe_in[1], HANDLE_FLAG_INHERIT, 0)) {
CLEAN_PIPES
ERR_FAIL_V(ret);
}
if (!CreatePipe(&pipe_out[0], &pipe_out[1], &sa, 0)) {
CLEAN_PIPES
ERR_FAIL_V(ret);
}
if (!SetHandleInformation(pipe_out[0], HANDLE_FLAG_INHERIT, 0)) {
CLEAN_PIPES
ERR_FAIL_V(ret);
}
if (!CreatePipe(&pipe_err[0], &pipe_err[1], &sa, 0)) {
CLEAN_PIPES
ERR_FAIL_V(ret);
Expand All @@ -861,24 +853,47 @@ Dictionary OS_Windows::execute_with_pipe(const String &p_path, const List<String
// Create process.
ProcessInfo pi;
ZeroMemory(&pi.si, sizeof(pi.si));
pi.si.cb = sizeof(pi.si);
pi.si.StartupInfo.cb = sizeof(pi.si);
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si.StartupInfo;

pi.si.dwFlags |= STARTF_USESTDHANDLES;
pi.si.hStdInput = pipe_in[0];
pi.si.hStdOutput = pipe_out[1];
pi.si.hStdError = pipe_err[1];
pi.si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
pi.si.StartupInfo.hStdInput = pipe_in[0];
pi.si.StartupInfo.hStdOutput = pipe_out[1];
pi.si.StartupInfo.hStdError = pipe_err[1];

DWORD creation_flags = NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW;
size_t attr_list_size = 0;
InitializeProcThreadAttributeList(nullptr, 1, 0, &attr_list_size);
pi.si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)alloca(attr_list_size);
if (!InitializeProcThreadAttributeList(pi.si.lpAttributeList, 1, 0, &attr_list_size)) {
CLEAN_PIPES
ERR_FAIL_V(ret);
}
HANDLE handles_to_inherit[] = { pipe_in[0], pipe_out[1], pipe_err[1] };
if (!UpdateProcThreadAttribute(
pi.si.lpAttributeList,
0,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
handles_to_inherit,
sizeof(handles_to_inherit),
nullptr,
nullptr)) {
CLEAN_PIPES
DeleteProcThreadAttributeList(pi.si.lpAttributeList);
ERR_FAIL_V(ret);
}

DWORD creation_flags = NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT;

if (!CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, true, creation_flags, nullptr, nullptr, si_w, &pi.pi)) {
CLEAN_PIPES
DeleteProcThreadAttributeList(pi.si.lpAttributeList);
ERR_FAIL_V_MSG(ret, "Could not create child process: " + command);
}
CloseHandle(pipe_in[0]);
CloseHandle(pipe_out[1]);
CloseHandle(pipe_err[1]);
DeleteProcThreadAttributeList(pi.si.lpAttributeList);

ProcessID pid = pi.pi.dwProcessId;
process_map_mutex.lock();
Expand Down Expand Up @@ -910,9 +925,9 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,

ProcessInfo pi;
ZeroMemory(&pi.si, sizeof(pi.si));
pi.si.cb = sizeof(pi.si);
pi.si.StartupInfo.cb = sizeof(pi.si);
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si.StartupInfo;

bool inherit_handles = false;
HANDLE pipe[2] = { nullptr, nullptr };
Expand All @@ -924,16 +939,40 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
sa.lpSecurityDescriptor = nullptr;

ERR_FAIL_COND_V(!CreatePipe(&pipe[0], &pipe[1], &sa, 0), ERR_CANT_FORK);
ERR_FAIL_COND_V(!SetHandleInformation(pipe[0], HANDLE_FLAG_INHERIT, 0), ERR_CANT_FORK); // Read handle is for host process only and should not be inherited.

pi.si.dwFlags |= STARTF_USESTDHANDLES;
pi.si.hStdOutput = pipe[1];
pi.si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
pi.si.StartupInfo.hStdOutput = pipe[1];
if (read_stderr) {
pi.si.hStdError = pipe[1];
pi.si.StartupInfo.hStdError = pipe[1];
}

size_t attr_list_size = 0;
InitializeProcThreadAttributeList(nullptr, 1, 0, &attr_list_size);
pi.si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)alloca(attr_list_size);
if (!InitializeProcThreadAttributeList(pi.si.lpAttributeList, 1, 0, &attr_list_size)) {
CloseHandle(pipe[0]); // Cleanup pipe handles.
CloseHandle(pipe[1]);
ERR_FAIL_V(ERR_CANT_FORK);
}
if (!UpdateProcThreadAttribute(
pi.si.lpAttributeList,
0,
PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
&pipe[1],
sizeof(HANDLE),
nullptr,
nullptr)) {
CloseHandle(pipe[0]); // Cleanup pipe handles.
CloseHandle(pipe[1]);
DeleteProcThreadAttributeList(pi.si.lpAttributeList);
ERR_FAIL_V(ERR_CANT_FORK);
}
inherit_handles = true;
}
DWORD creation_flags = NORMAL_PRIORITY_CLASS;
if (inherit_handles) {
creation_flags |= EXTENDED_STARTUPINFO_PRESENT;
}
if (p_open_console) {
creation_flags |= CREATE_NEW_CONSOLE;
} else {
Expand All @@ -944,6 +983,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
if (!ret && r_pipe) {
CloseHandle(pipe[0]); // Cleanup pipe handles.
CloseHandle(pipe[1]);
DeleteProcThreadAttributeList(pi.si.lpAttributeList);
}
ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);

Expand Down Expand Up @@ -999,6 +1039,9 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,

CloseHandle(pi.pi.hProcess);
CloseHandle(pi.pi.hThread);
if (r_pipe) {
DeleteProcThreadAttributeList(pi.si.lpAttributeList);
}

return OK;
}
Expand All @@ -1012,9 +1055,9 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg

ProcessInfo pi;
ZeroMemory(&pi.si, sizeof(pi.si));
pi.si.cb = sizeof(pi.si);
pi.si.StartupInfo.cb = sizeof(pi.si.StartupInfo);
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si.StartupInfo;

DWORD creation_flags = NORMAL_PRIORITY_CLASS;
if (p_open_console) {
Expand Down
2 changes: 1 addition & 1 deletion platform/windows/os_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class OS_Windows : public OS {
String _quote_command_line_argument(const String &p_text) const;

struct ProcessInfo {
STARTUPINFO si;
STARTUPINFOEX si;
PROCESS_INFORMATION pi;
mutable bool is_running = true;
mutable int exit_code = -1;
Expand Down

0 comments on commit 711c725

Please sign in to comment.