From 3d660bd84208ffc797f9d41423a8951123b3e46e Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 12 Nov 2021 13:56:22 +0000 Subject: win32: another attempt at a UCRT hack The problem with UCRT seems to be that if a process has been started with a non-NULL environment block passed to CreateProcess() any subsequent call to spawnve() with a non-NULL environment pointer fails. Commit 5b48ca53b (win32: pass NULL to spawnve, not environ) fixed the problem in busybox-w32 for those cases where a NULL environment pointer was sufficient. It didn't handle the case where the shell passes a modified environment to its child. All calls to spawnve() in the shell occur in a process which will terminate whether or not the call succeeds. It therefore doesn't matter if we mess with the environment of this process such that spawnve() can be passed a NULL environment pointer. (I think.) --- shell/ash.c | 10 ++++++++++ win32/process.c | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index ad1e5ba7e..6d7066a1b 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -8898,9 +8898,11 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c # else if (APPLET_IS_NOEXEC(applet_no)) { # endif +#if !defined(_UCRT) clearenv(); while (*envp) putenv(*envp++); +#endif popredir(/*drop:*/ 1); run_noexec_applet_and_exit(applet_no, cmd, argv); } @@ -8973,6 +8975,14 @@ static void shellexec(char *prog, char **argv, const char *path, int idx) #if !ENABLE_PLATFORM_MINGW32 if (strchr(prog, '/') != NULL #else +#if defined(_UCRT) + /* Avoid UCRT bug by updating parent's environment and passing a + * NULL environment pointer to execve(). */ + clearenv(); + while (*envp) + putenv(*envp++); + envp = NULL; +#endif if (has_path(prog) #endif #if ENABLE_FEATURE_SH_STANDALONE diff --git a/win32/process.c b/win32/process.c index 137cb6a39..812e259f4 100644 --- a/win32/process.c +++ b/win32/process.c @@ -268,14 +268,6 @@ spawnveq(int mode, const char *path, char *const *argv, char *const *env) new_path = xasprintf("%s.", path); } -#if defined(_UCRT) - if (env) { - char buffer[64]; - - sprintf(buffer, "BB_HELLO_%d", getpid()); - SetEnvironmentVariable(buffer, "1"); - } -#endif errno = 0; ret = spawnve(mode, new_path ? new_path : path, new_argv, env); -- cgit v1.2.3-55-g6feb