diff options
author | Ron Yorston <rmy@pobox.com> | 2024-10-07 12:50:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-10-07 12:50:51 +0100 |
commit | 5b30de8fba414f75cb25faebf5cd8f391e1deb75 (patch) | |
tree | dcb181f71a4ef80715976d5f5ef6554c019d53d7 /shell/ash.c | |
parent | 041f1d29671c58b839c8e63fced7aa901fbade45 (diff) | |
download | busybox-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.c | 46 |
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; | |||
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 | #if ENABLE_PLATFORM_MINGW32 | ||
9094 | # define EXEC_FLAG 2 | ||
9095 | |||
9096 | static void | 9093 | static void |
9097 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no, const char *nfpath, int flags,) | 9094 | #if ENABLE_PLATFORM_MINGW32 |
9095 | tryexec(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 |
9100 | static void | ||
9101 | tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp) | 9098 | tryexec(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 | */ |
9234 | static struct builtincmd *find_builtin(const char *name); | 9223 | static struct builtincmd *find_builtin(const char *name); |
9235 | static void shellexec(char *prog, char **argv, const char *path, int idx, | 9224 | static void shellexec(char *prog, char **argv, const char *path, int idx, |
9236 | int nofork) NORETURN; | 9225 | int noexec) NORETURN; |
9237 | static void shellexec(char *prog, char **argv, const char *path, int idx, | 9226 | static 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 | ||
16560 | static void | 16546 | static void |