aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-10-07 12:50:51 +0100
committerRon Yorston <rmy@pobox.com>2024-10-07 12:50:51 +0100
commit5b30de8fba414f75cb25faebf5cd8f391e1deb75 (patch)
treedcb181f71a4ef80715976d5f5ef6554c019d53d7 /shell/ash.c
parent041f1d29671c58b839c8e63fced7aa901fbade45 (diff)
downloadbusybox-w32-5b30de8fba414f75cb25faebf5cd8f391e1deb75.tar.gz
busybox-w32-5b30de8fba414f75cb25faebf5cd8f391e1deb75.tar.bz2
busybox-w32-5b30de8fba414f75cb25faebf5cd8f391e1deb75.zip
ash: more changes to noexec applets
- Change the 'flags' argument to shellexec()/tryexec() so it only indicates that it's permissible to run ash_main() directly. The flag is only set TRUE in forkshell_shellexec(). - The check for a script with an interpreter which is an applet is now performed for all calls to tryexec(), not just those that originate from evalcommand(). Saves 64-80 bytes. GitHub issue #461.
Diffstat (limited to '')
-rw-r--r--shell/ash.c46
1 files changed, 16 insertions, 30 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 3865b72d4..679846574 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9090,28 +9090,24 @@ 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
9093#if ENABLE_PLATFORM_MINGW32
9094# define EXEC_FLAG 2
9095
9096static void 9093static void
9097tryexec(IF_FEATURE_SH_STANDALONE(int applet_no, const char *nfpath, int flags,) 9094#if ENABLE_PLATFORM_MINGW32
9095tryexec(IF_FEATURE_SH_STANDALONE(int applet_no, const char *path, int noexec,)
9098 const char *cmd, char **argv, char **envp) 9096 const char *cmd, char **argv, char **envp)
9099#else 9097#else
9100static void
9101tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp) 9098tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
9102#endif 9099#endif
9103{ 9100{
9104#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE 9101#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE
9105 struct forkshell *fs = (struct forkshell *)sticky_mem_start;
9106 interp_t interp; 9102 interp_t interp;
9107#endif 9103#endif
9108#if ENABLE_FEATURE_SH_STANDALONE 9104#if ENABLE_FEATURE_SH_STANDALONE
9109 if (applet_no >= 0) { 9105 if (applet_no >= 0) {
9110# if ENABLE_PLATFORM_MINGW32 9106# if ENABLE_PLATFORM_MINGW32
9111 /* Treat all applets as NOEXEC, including the shell itself 9107 /* Treat all applets as NOEXEC, including the shell itself
9112 * unless it was invoked by the exec builtin. */ 9108 * if we were called from forkshell_shellexec(). */
9113 if (applet_main[applet_no] != ash_main || !(flags & EXEC_FLAG)) {
9114 run_noexec: 9109 run_noexec:
9110 if (applet_main[applet_no] != ash_main || noexec) {
9115 /* mingw-w64's getopt() uses __argv[0] as the program name */ 9111 /* mingw-w64's getopt() uses __argv[0] as the program name */
9116 __argv[0] = (char *)cmd; 9112 __argv[0] = (char *)cmd;
9117 /* 'which' wants to know if it was invoked from a standalone 9113 /* 'which' wants to know if it was invoked from a standalone
@@ -9154,17 +9150,10 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9154 add_win32_extension((char *)cmd); 9150 add_win32_extension((char *)cmd);
9155 9151
9156# if ENABLE_FEATURE_SH_STANDALONE 9152# if ENABLE_FEATURE_SH_STANDALONE
9157 /* If nfpath is non-NULL evalcommand() has determined this 9153 /* If the command is a script with an interpreter which is an
9158 * command doesn't need a fork(). Even it's NULL we can 9154 * applet, we can run it as if it were a noexec applet. */
9159 * possibly avoid a fork if this is a FS_SHELLEXEC shell. */ 9155 if (parse_interpreter(cmd, &interp)) {
9160 if (nfpath == NULL && (fs && fs->fpid == FS_SHELLEXEC)) 9156 applet_no = find_applet_by_name_for_sh(interp.name, path);
9161 nfpath = pathval();
9162
9163 /* If nfpath is non-NULL and the command is a script with an
9164 * interpreter which is an applet, we can run it as if it
9165 * were a noexec applet. */
9166 if (nfpath && parse_interpreter(cmd, &interp)) {
9167 applet_no = find_applet_by_name_for_sh(interp.name, nfpath);
9168 if (applet_no >= 0) { 9157 if (applet_no >= 0) {
9169 argv[0] = (char *)cmd; 9158 argv[0] = (char *)cmd;
9170 /* evalcommand()/spawn_forkshell() add two elements before argv */ 9159 /* evalcommand()/spawn_forkshell() add two elements before argv */
@@ -9233,18 +9222,15 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
9233 */ 9222 */
9234static struct builtincmd *find_builtin(const char *name); 9223static struct builtincmd *find_builtin(const char *name);
9235static void shellexec(char *prog, char **argv, const char *path, int idx, 9224static void shellexec(char *prog, char **argv, const char *path, int idx,
9236 int nofork) NORETURN; 9225 int noexec) NORETURN;
9237static void shellexec(char *prog, char **argv, const char *path, int idx, 9226static void shellexec(char *prog, char **argv, const char *path, int idx,
9238 int nofork) 9227 int noexec)
9239{ 9228{
9240 char *cmdname; 9229 char *cmdname;
9241 int e; 9230 int e;
9242 char **envp; 9231 char **envp;
9243 int exerrno; 9232 int exerrno;
9244 int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ 9233 int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
9245#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE
9246 const char *nfpath = (nofork & ~EXEC_FLAG) ? path : NULL;
9247#endif
9248 9234
9249 envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL); 9235 envp = listvars(VEXPORT, VUNSET, /*strlist:*/ NULL, /*end:*/ NULL);
9250#if ENABLE_FEATURE_SH_STANDALONE && ENABLE_PLATFORM_MINGW32 && defined(_UCRT) 9236#if ENABLE_FEATURE_SH_STANDALONE && ENABLE_PLATFORM_MINGW32 && defined(_UCRT)
@@ -9266,7 +9252,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx,
9266 ) { 9252 ) {
9267#if ENABLE_PLATFORM_MINGW32 9253#if ENABLE_PLATFORM_MINGW32
9268 char *progext = stack_add_ext_space(prog); 9254 char *progext = stack_add_ext_space(prog);
9269 tryexec(IF_FEATURE_SH_STANDALONE(applet_no, nfpath, nofork,) 9255 tryexec(IF_FEATURE_SH_STANDALONE(applet_no, path, noexec,)
9270 progext, argv, envp); 9256 progext, argv, envp);
9271#else 9257#else
9272 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); 9258 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
@@ -9284,7 +9270,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx,
9284 const char *name = bb_basename(prog); 9270 const char *name = bb_basename(prog);
9285# if ENABLE_FEATURE_SH_STANDALONE 9271# if ENABLE_FEATURE_SH_STANDALONE
9286 if ((applet_no = find_applet_by_name_for_sh(name, path)) >= 0) { 9272 if ((applet_no = find_applet_by_name_for_sh(name, path)) >= 0) {
9287 tryexec(applet_no, nfpath, nofork, name, argv, envp); 9273 tryexec(applet_no, path, noexec, name, argv, envp);
9288 e = errno; 9274 e = errno;
9289 } 9275 }
9290# endif 9276# endif
@@ -9301,7 +9287,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx,
9301 cmdname = stackblock(); 9287 cmdname = stackblock();
9302 if (--idx < 0 && pathopt == NULL) { 9288 if (--idx < 0 && pathopt == NULL) {
9303#if ENABLE_PLATFORM_MINGW32 9289#if ENABLE_PLATFORM_MINGW32
9304 tryexec(IF_FEATURE_SH_STANDALONE(-1, nfpath, nofork,) 9290 tryexec(IF_FEATURE_SH_STANDALONE(-1, path, noexec,)
9305 cmdname, argv, envp); 9291 cmdname, argv, envp);
9306#else 9292#else
9307 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); 9293 tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
@@ -11278,7 +11264,7 @@ execcmd(int argc UNUSED_PARAM, char **argv)
11278 prog = argv[0]; 11264 prog = argv[0];
11279 if (optionarg) 11265 if (optionarg)
11280 argv[0] = optionarg; 11266 argv[0] = optionarg;
11281 shellexec(prog, argv, pathval(), 0, EXEC_FLAG); 11267 shellexec(prog, argv, pathval(), 0, FALSE);
11282 /* NOTREACHED */ 11268 /* NOTREACHED */
11283 } 11269 }
11284 return 0; 11270 return 0;
@@ -11834,7 +11820,7 @@ evalcommand(union node *cmd, int flags)
11834 /* fall through to exec'ing external program */ 11820 /* fall through to exec'ing external program */
11835 } 11821 }
11836#endif 11822#endif
11837 shellexec(argv[0], argv, path, cmdentry.u.index, TRUE); 11823 shellexec(argv[0], argv, path, cmdentry.u.index, FALSE);
11838 /* NOTREACHED */ 11824 /* NOTREACHED */
11839 } /* default */ 11825 } /* default */
11840 case CMDBUILTIN: 11826 case CMDBUILTIN:
@@ -16554,7 +16540,7 @@ forkshell_shellexec(struct forkshell *fs)
16554 char *path = fs->path; 16540 char *path = fs->path;
16555 16541
16556 FORCE_INT_ON; 16542 FORCE_INT_ON;
16557 shellexec(argv[0], argv, path, idx, FALSE); 16543 shellexec(argv[0], argv, path, idx, TRUE);
16558} 16544}
16559 16545
16560static void 16546static void