From aa6821ce14464a9cd67c10033c85052c10c06c84 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 6 Aug 2023 18:40:54 -0500 Subject: [PATCH] Enable shell command recursion. --- main.c | 4 ++-- toys.h | 1 + toys/pending/sh.c | 19 ++++++++++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/main.c b/main.c index b4971bcd..6fc27099 100644 --- a/main.c +++ b/main.c @@ -207,7 +207,7 @@ void toy_init(struct toy_list *which, char *argv[]) // Run an internal toybox command. // Only returns if it can't run command internally, otherwise xexit() when done. -static void toy_exec_which(struct toy_list *which, char *argv[]) +void toy_exec_which(struct toy_list *which, char *argv[]) { // Return if we can't find it (which includes no multiplexer case), if (!which || (which->flags&TOYFLAG_NOFORK)) return; @@ -219,7 +219,7 @@ static void toy_exec_which(struct toy_list *which, char *argv[]) // Signed typecast so stack growth direction is irrelevant: we're measuring // the distance between two pointers on the same stack, hence the labs(). if (!CFG_TOYBOX_NORECURSE && toys.stacktop) - if (labs((long)toys.stacktop-(long)&which)>6000) return; + if (labs((long)toys.stacktop-(long)&which)>24000) return; // Return if we need to re-exec to acquire root via suid bit. if (toys.which && (which->flags&TOYFLAG_ROOTONLY) && toys.wasroot) return; diff --git a/toys.h b/toys.h index ebe0a321..49b02ffb 100644 --- a/toys.h +++ b/toys.h @@ -92,6 +92,7 @@ void show_help(FILE *out, int full); void check_help(char **arg); void toy_singleinit(struct toy_list *which, char *argv[]); void toy_init(struct toy_list *which, char *argv[]); +void toy_exec_which(struct toy_list *which, char *argv[]); void toy_exec(char *argv[]); // Array of available commands diff --git a/toys/pending/sh.c b/toys/pending/sh.c index 139c394d..fc9edcff 100644 --- a/toys/pending/sh.c +++ b/toys/pending/sh.c @@ -2704,16 +2704,18 @@ notfd: // Call binary, or run script via xexec("sh --") static void sh_exec(char **argv) { - char *pp = getvar("PATH" ? : _PATH_DEFPATH), *cc = TT.isexec ? : *argv, *ss, + char *pp = getvar("PATH" ? : _PATH_DEFPATH), *ss = TT.isexec ? : *argv, **sss = 0, **oldenv = environ, **argv2; - struct string_list *sl; + struct string_list *sl = 0; + struct toy_list *tl = 0; if (getpid() != TT.pid) signal(SIGINT, SIG_DFL); // TODO: restore all? errno = ENOENT; - if (strchr(ss = cc, '/')) { + if (strchr(ss, '/')) { if (access(ss, X_OK)) ss = 0; - } else for (sl = find_in_path(pp, cc); sl || (ss = 0); free(llist_pop(&sl))) - if (!access(ss = sl->str, X_OK)) break; + } else if (CFG_TOYBOX_NORECURSE || !toys.stacktop || !(tl = toy_find(ss))) + for (sl = find_in_path(pp, ss); sl || (ss = 0); free(llist_pop(&sl))) + if (!access(ss = sl->str, X_OK)) break; if (ss) { struct sh_vars **vv = visible_vars(); @@ -2730,13 +2732,16 @@ static void sh_exec(char **argv) } aa.v[aa.c] = 0; if (!sss) { - arg_add(&aa, 0); + if (aa.c