diff --git a/patches/0004-init_ntproc-Use-SetHandleInformation-to-set-NOINHERI.patch b/patches/0004-init_ntproc-Use-SetHandleInformation-to-set-NOINHERI.patch new file mode 100644 index 0000000..7e34ebf --- /dev/null +++ b/patches/0004-init_ntproc-Use-SetHandleInformation-to-set-NOINHERI.patch @@ -0,0 +1,164 @@ +From 6932da3096f8149e0fffe2aba0ab8c444a598476 Mon Sep 17 00:00:00 2001 +From: Kien Nguyen +Date: Sun, 4 Aug 2024 04:29:35 -0700 +Subject: [PATCH 4/6] init_ntproc: Use SetHandleInformation to set NOINHERIT + when possible + +--- + src/w32.c | 123 ++++++++++++++++++++++++++++++------------------------ + 1 file changed, 68 insertions(+), 55 deletions(-) + +diff --git a/src/w32.c b/src/w32.c +index 31ffa301c2f..f531274ce92 100644 +--- a/src/w32.c ++++ b/src/w32.c +@@ -7783,10 +7783,6 @@ init_winsock (int load_now) + if (winsock_lib != NULL) + return TRUE; + +- pfn_SetHandleInformation +- = (void *) get_proc_addr (GetModuleHandle ("kernel32.dll"), +- "SetHandleInformation"); +- + winsock_lib = LoadLibrary ("Ws2_32.dll"); + + if (winsock_lib != NULL) +@@ -10471,6 +10467,10 @@ init_ntproc (int dumping) + Conveniently, init_environment is called before us, so + PRELOAD_WINSOCK can be set in the registry. */ + ++ pfn_SetHandleInformation ++ = (void *) get_proc_addr (GetModuleHandle ("kernel32.dll"), ++ "SetHandleInformation"); ++ + /* Always initialize this correctly. */ + winsock_lib = NULL; + +@@ -10480,60 +10480,73 @@ init_ntproc (int dumping) + /* Initial preparation for subprocess support: replace our standard + handles with non-inheritable versions. */ + { +- HANDLE parent; +- HANDLE stdin_save = INVALID_HANDLE_VALUE; +- HANDLE stdout_save = INVALID_HANDLE_VALUE; +- HANDLE stderr_save = INVALID_HANDLE_VALUE; +- +- parent = GetCurrentProcess (); +- +- /* ignore errors when duplicating and closing; typically the +- handles will be invalid when running as a gui program. */ +- DuplicateHandle (parent, +- GetStdHandle (STD_INPUT_HANDLE), +- parent, +- &stdin_save, +- 0, +- FALSE, +- DUPLICATE_SAME_ACCESS); +- +- DuplicateHandle (parent, +- GetStdHandle (STD_OUTPUT_HANDLE), +- parent, +- &stdout_save, +- 0, +- FALSE, +- DUPLICATE_SAME_ACCESS); +- +- DuplicateHandle (parent, +- GetStdHandle (STD_ERROR_HANDLE), +- parent, +- &stderr_save, +- 0, +- FALSE, +- DUPLICATE_SAME_ACCESS); +- +- fclose (stdin); +- fclose (stdout); +- fclose (stderr); +- +- if (stdin_save != INVALID_HANDLE_VALUE) +- _open_osfhandle ((intptr_t) stdin_save, O_TEXT); ++ /* For UCRT, the _fdopen will try to find free stream from ++ _IOB_ENTRIES (= 3), thus we can't reopen the standard handles ++ with it. Using SetHandleInformation to make the handle not ++ inheritable to child process is a better way. */ ++ if (pfn_SetHandleInformation) ++ { ++ pfn_SetHandleInformation (GetStdHandle(STD_INPUT_HANDLE), HANDLE_FLAG_INHERIT, 0); ++ pfn_SetHandleInformation (GetStdHandle(STD_OUTPUT_HANDLE), HANDLE_FLAG_INHERIT, 0); ++ pfn_SetHandleInformation (GetStdHandle(STD_ERROR_HANDLE), HANDLE_FLAG_INHERIT, 0); ++ } + else +- _open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY); +- _fdopen (0, "r"); ++ { ++ HANDLE parent; ++ HANDLE stdin_save = INVALID_HANDLE_VALUE; ++ HANDLE stdout_save = INVALID_HANDLE_VALUE; ++ HANDLE stderr_save = INVALID_HANDLE_VALUE; ++ ++ parent = GetCurrentProcess (); ++ ++ /* ignore errors when duplicating and closing; typically the ++ handles will be invalid when running as a gui program. */ ++ DuplicateHandle (parent, ++ GetStdHandle (STD_INPUT_HANDLE), ++ parent, ++ &stdin_save, ++ 0, ++ FALSE, ++ DUPLICATE_SAME_ACCESS); ++ ++ DuplicateHandle (parent, ++ GetStdHandle (STD_OUTPUT_HANDLE), ++ parent, ++ &stdout_save, ++ 0, ++ FALSE, ++ DUPLICATE_SAME_ACCESS); ++ ++ DuplicateHandle (parent, ++ GetStdHandle (STD_ERROR_HANDLE), ++ parent, ++ &stderr_save, ++ 0, ++ FALSE, ++ DUPLICATE_SAME_ACCESS); ++ ++ fclose (stdin); ++ fclose (stdout); ++ fclose (stderr); ++ ++ if (stdin_save != INVALID_HANDLE_VALUE) ++ _open_osfhandle ((intptr_t) stdin_save, O_TEXT); ++ else ++ _open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY); ++ _fdopen (0, "r"); + +- if (stdout_save != INVALID_HANDLE_VALUE) +- _open_osfhandle ((intptr_t) stdout_save, O_TEXT); +- else +- _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY); +- _fdopen (1, "w"); ++ if (stdout_save != INVALID_HANDLE_VALUE) ++ _open_osfhandle ((intptr_t) stdout_save, O_TEXT); ++ else ++ _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY); ++ _fdopen (1, "w"); + +- if (stderr_save != INVALID_HANDLE_VALUE) +- _open_osfhandle ((intptr_t) stderr_save, O_TEXT); +- else +- _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY); +- _fdopen (2, "w"); ++ if (stderr_save != INVALID_HANDLE_VALUE) ++ _open_osfhandle ((intptr_t) stderr_save, O_TEXT); ++ else ++ _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY); ++ _fdopen (2, "w"); ++ } + } + + /* unfortunately, atexit depends on implementation of malloc */ +-- +2.46.0.windows.1 +