Enable shell command recursion.

This commit is contained in:
Rob Landley 2023-08-06 18:40:54 -05:00
parent dbd8ccc856
commit aa6821ce14
3 changed files with 15 additions and 9 deletions

4
main.c
View File

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

1
toys.h
View File

@ -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

View File

@ -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<uu) aa.v[++aa.c] = 0;
else arg_add(&aa, 0);
sss = aa.v+aa.c-1;
}
*sss = xmprintf("_=%s", ss);
// exec or source
// Run builtin, exec command, or call shell script without #!
toy_exec_which(tl, argv);
execve(ss, argv, environ);
// shell script without #!
if (errno == ENOEXEC) {
for (argc = 0; argv[argc]; argc++);
argv2 = xmalloc((argc+3)*sizeof(char *));