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 | |
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.
-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; |