diff options
| author | Ron Yorston <rmy@pobox.com> | 2024-10-06 13:39:09 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2024-10-06 13:39:09 +0100 |
| commit | 041f1d29671c58b839c8e63fced7aa901fbade45 (patch) | |
| tree | 148d9f0a4829981c491743c158450db9290adb05 /shell | |
| parent | 4c095ae6efd1fa8773a58fb4a1dc79f5810b2369 (diff) | |
| download | busybox-w32-041f1d29671c58b839c8e63fced7aa901fbade45.tar.gz busybox-w32-041f1d29671c58b839c8e63fced7aa901fbade45.tar.bz2 busybox-w32-041f1d29671c58b839c8e63fced7aa901fbade45.zip | |
ash: fix regression with 'exec sh -s'
It was noted this command didn't work properly:
su -t -c 'exec sh -s -c "echo 123"'
The child shell performed the 'echo' but then exited, despite the
'-s' flag. This is a regression introduced by commit 074ebfca21
(ash: code shrink).
This simpler command also failed the same way:
sh -c "exec sh -s"
This regression dates back even further, to commit da7c8cdf63
(ash: run ash_main() directly from a FS_SHELLEXEC shell).
The issue can be avoided if shells invoked by the 'exec' builtin
aren't run by calling ash_main() directly.
Adds 80-96 bytes.
GitHub issue #461.
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c index 8a3659542..3865b72d4 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -9090,11 +9090,14 @@ static struct tblentry **cmdtable; | |||
| 9090 | static int builtinloc = -1; /* index in path of %builtin, or -1 */ | 9090 | static int builtinloc = -1; /* index in path of %builtin, or -1 */ |
| 9091 | 9091 | ||
| 9092 | 9092 | ||
| 9093 | static void | ||
| 9094 | #if ENABLE_PLATFORM_MINGW32 | 9093 | #if ENABLE_PLATFORM_MINGW32 |
| 9095 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no, const char *nfpath,) | 9094 | # define EXEC_FLAG 2 |
| 9095 | |||
| 9096 | static void | ||
| 9097 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no, const char *nfpath, int flags,) | ||
| 9096 | const char *cmd, char **argv, char **envp) | 9098 | const char *cmd, char **argv, char **envp) |
| 9097 | #else | 9099 | #else |
| 9100 | static void | ||
| 9098 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp) | 9101 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp) |
| 9099 | #endif | 9102 | #endif |
| 9100 | { | 9103 | { |
| @@ -9104,9 +9107,10 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c | |||
| 9104 | #endif | 9107 | #endif |
| 9105 | #if ENABLE_FEATURE_SH_STANDALONE | 9108 | #if ENABLE_FEATURE_SH_STANDALONE |
| 9106 | if (applet_no >= 0) { | 9109 | if (applet_no >= 0) { |
| 9107 | if (ENABLE_PLATFORM_MINGW32 || APPLET_IS_NOEXEC(applet_no)) { | ||
| 9108 | # if ENABLE_PLATFORM_MINGW32 | 9110 | # if ENABLE_PLATFORM_MINGW32 |
| 9109 | /* Treat all applets as NOEXEC */ | 9111 | /* Treat all applets as NOEXEC, including the shell itself |
| 9112 | * unless it was invoked by the exec builtin. */ | ||
| 9113 | if (applet_main[applet_no] != ash_main || !(flags & EXEC_FLAG)) { | ||
| 9110 | run_noexec: | 9114 | run_noexec: |
| 9111 | /* mingw-w64's getopt() uses __argv[0] as the program name */ | 9115 | /* mingw-w64's getopt() uses __argv[0] as the program name */ |
| 9112 | __argv[0] = (char *)cmd; | 9116 | __argv[0] = (char *)cmd; |
| @@ -9115,6 +9119,8 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c | |||
| 9115 | if (strcmp(argv[0], "which") == 0) { | 9119 | if (strcmp(argv[0], "which") == 0) { |
| 9116 | argv[0] = (char *)"Which"; | 9120 | argv[0] = (char *)"Which"; |
| 9117 | } | 9121 | } |
| 9122 | # else | ||
| 9123 | if (APPLET_IS_NOEXEC(applet_no)) { | ||
| 9118 | # endif | 9124 | # endif |
| 9119 | #if !ENABLE_PLATFORM_MINGW32 || !defined(_UCRT) | 9125 | #if !ENABLE_PLATFORM_MINGW32 || !defined(_UCRT) |
| 9120 | /* If building for UCRT move this up into shellexec() to | 9126 | /* If building for UCRT move this up into shellexec() to |
| @@ -9237,7 +9243,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx, | |||
| 9237 | int exerrno; | 9243 | int exerrno; |
| 9238 | int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ | 9244 | int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ |
| 9239 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | 9245 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE |
| 9240 | const char *nfpath = nofork ? path : NULL; | 9246 | const char *nfpath = (nofork & ~EXEC_FLAG) ? path : NULL; |
| 9241 | #endif | 9247 | #endif |
| 9242 | 9248 | ||
| 9243 | envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL); | 9249 | envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL); |
| @@ -9260,7 +9266,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx, | |||
| 9260 | ) { | 9266 | ) { |
| 9261 | #if ENABLE_PLATFORM_MINGW32 | 9267 | #if ENABLE_PLATFORM_MINGW32 |
| 9262 | char *progext = stack_add_ext_space(prog); | 9268 | char *progext = stack_add_ext_space(prog); |
| 9263 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no, nfpath,) | 9269 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no, nfpath, nofork,) |
| 9264 | progext, argv, envp); | 9270 | progext, argv, envp); |
| 9265 | #else | 9271 | #else |
| 9266 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); | 9272 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); |
| @@ -9278,7 +9284,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx, | |||
| 9278 | const char *name = bb_basename(prog); | 9284 | const char *name = bb_basename(prog); |
| 9279 | # if ENABLE_FEATURE_SH_STANDALONE | 9285 | # if ENABLE_FEATURE_SH_STANDALONE |
| 9280 | if ((applet_no = find_applet_by_name_for_sh(name, path)) >= 0) { | 9286 | if ((applet_no = find_applet_by_name_for_sh(name, path)) >= 0) { |
| 9281 | tryexec(applet_no, nfpath, name, argv, envp); | 9287 | tryexec(applet_no, nfpath, nofork, name, argv, envp); |
| 9282 | e = errno; | 9288 | e = errno; |
| 9283 | } | 9289 | } |
| 9284 | # endif | 9290 | # endif |
| @@ -9295,7 +9301,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx, | |||
| 9295 | cmdname = stackblock(); | 9301 | cmdname = stackblock(); |
| 9296 | if (--idx < 0 && pathopt == NULL) { | 9302 | if (--idx < 0 && pathopt == NULL) { |
| 9297 | #if ENABLE_PLATFORM_MINGW32 | 9303 | #if ENABLE_PLATFORM_MINGW32 |
| 9298 | tryexec(IF_FEATURE_SH_STANDALONE(-1, nfpath,) | 9304 | tryexec(IF_FEATURE_SH_STANDALONE(-1, nfpath, nofork,) |
| 9299 | cmdname, argv, envp); | 9305 | cmdname, argv, envp); |
| 9300 | #else | 9306 | #else |
| 9301 | tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); | 9307 | tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); |
| @@ -11272,7 +11278,7 @@ execcmd(int argc UNUSED_PARAM, char **argv) | |||
| 11272 | prog = argv[0]; | 11278 | prog = argv[0]; |
| 11273 | if (optionarg) | 11279 | if (optionarg) |
| 11274 | argv[0] = optionarg; | 11280 | argv[0] = optionarg; |
| 11275 | shellexec(prog, argv, pathval(), 0, FALSE); | 11281 | shellexec(prog, argv, pathval(), 0, EXEC_FLAG); |
| 11276 | /* NOTREACHED */ | 11282 | /* NOTREACHED */ |
| 11277 | } | 11283 | } |
| 11278 | return 0; | 11284 | return 0; |
