diff options
author | Ron Yorston <rmy@pobox.com> | 2022-02-12 12:59:04 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-02-12 12:59:04 +0000 |
commit | c5270ab0c1bfe1f79bc57650da1091cd7358c689 (patch) | |
tree | 45bce329c790b92ce22f8be9beeb1b547c698426 | |
parent | e6238530e486d3c4bfe5cab7df5545869ab139ad (diff) | |
download | busybox-w32-c5270ab0c1bfe1f79bc57650da1091cd7358c689.tar.gz busybox-w32-c5270ab0c1bfe1f79bc57650da1091cd7358c689.tar.bz2 busybox-w32-c5270ab0c1bfe1f79bc57650da1091cd7358c689.zip |
ash: workaround for UCRT bug
There seems to be a bug in UCRT such that if a process has been
started by passing a non-NULL environment block to CreateProcess()
any subsequent call to spawnve() with a non-NULL environment pointer
results in a crash.
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 to allow
spawnve() to be passed a NULL environment pointer. Do this for
UCRT builds only.
(GitHub issue #234)
-rw-r--r-- | shell/ash.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/shell/ash.c b/shell/ash.c index 46c4f1675..c9122b291 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -8899,9 +8899,13 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c | |||
8899 | # else | 8899 | # else |
8900 | if (APPLET_IS_NOEXEC(applet_no)) { | 8900 | if (APPLET_IS_NOEXEC(applet_no)) { |
8901 | # endif | 8901 | # endif |
8902 | #if ENABLE_PLATFORM_MINGW32 && !defined(_UCRT) | ||
8903 | /* If building for UCRT move this up into shellexec() to | ||
8904 | * work around a bug. */ | ||
8902 | clearenv(); | 8905 | clearenv(); |
8903 | while (*envp) | 8906 | while (*envp) |
8904 | putenv(*envp++); | 8907 | putenv(*envp++); |
8908 | #endif | ||
8905 | popredir(/*drop:*/ 1); | 8909 | popredir(/*drop:*/ 1); |
8906 | run_noexec_applet_and_exit(applet_no, cmd, argv); | 8910 | run_noexec_applet_and_exit(applet_no, cmd, argv); |
8907 | } | 8911 | } |
@@ -8971,6 +8975,14 @@ static void shellexec(char *prog, char **argv, const char *path, int idx) | |||
8971 | int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ | 8975 | int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ |
8972 | 8976 | ||
8973 | envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL); | 8977 | envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL); |
8978 | #if ENABLE_PLATFORM_MINGW32 && defined(_UCRT) | ||
8979 | /* Avoid UCRT bug by updating parent's environment and passing a | ||
8980 | * NULL environment pointer to execve(). */ | ||
8981 | clearenv(); | ||
8982 | while (*envp) | ||
8983 | putenv(*envp++); | ||
8984 | envp = NULL; | ||
8985 | #endif | ||
8974 | #if !ENABLE_PLATFORM_MINGW32 | 8986 | #if !ENABLE_PLATFORM_MINGW32 |
8975 | if (strchr(prog, '/') != NULL | 8987 | if (strchr(prog, '/') != NULL |
8976 | #else | 8988 | #else |