aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-10-06 13:39:09 +0100
committerRon Yorston <rmy@pobox.com>2024-10-06 13:39:09 +0100
commit041f1d29671c58b839c8e63fced7aa901fbade45 (patch)
tree148d9f0a4829981c491743c158450db9290adb05
parent4c095ae6efd1fa8773a58fb4a1dc79f5810b2369 (diff)
downloadbusybox-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.c24
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;
9090static int builtinloc = -1; /* index in path of %builtin, or -1 */ 9090static int builtinloc = -1; /* index in path of %builtin, or -1 */
9091 9091
9092 9092
9093static void
9094#if ENABLE_PLATFORM_MINGW32 9093#if ENABLE_PLATFORM_MINGW32
9095tryexec(IF_FEATURE_SH_STANDALONE(int applet_no, const char *nfpath,) 9094# define EXEC_FLAG 2
9095
9096static void
9097tryexec(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
9100static void
9098tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp) 9101tryexec(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;