aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2014-09-09 23:42:25 -0500
committerRob Landley <rob@landley.net>2014-09-09 23:42:25 -0500
commitc6705af4231b8071830721f98021d0e79223da12 (patch)
tree5edbeb82e1a0840044ccb697c3c31829fe34016e /main.c
parent7a07c6bc431d441a2363b58a1d82fe7a2a6d75f2 (diff)
downloadtoybox-c6705af4231b8071830721f98021d0e79223da12.tar.gz
Two problems: 1) Sometimes toy_exec() needs to re-exec to gain dropped root permissions, 2) shouldn't recurse forever without exec, stack depth increases and we may leak other resources. Limit it to ~5 levels.
Diffstat (limited to 'main.c')
-rw-r--r--main.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/main.c b/main.c
index 5bd44602..cfa2cc99 100644
--- a/main.c
+++ b/main.c
@@ -119,12 +119,18 @@ void toy_init(struct toy_list *which, char *argv[])
}
// Like exec() but runs an internal toybox command instead of another file.
-// Only returns if it can't find the command, otherwise exit() when done.
+// Only returns if it can't run command internally, otherwise exit() when done.
void toy_exec(char *argv[])
{
struct toy_list *which;
+ // Return if we can't find it, or need to re-exec to acquire root,
+ // or if stack depth is getting silly.
if (!(which = toy_find(argv[0]))) return;
+ if (toys.recursion && (which->flags & TOYFLAG_ROOTONLY) && getuid()) return;
+ if (toys.recursion++ > 5) return;
+
+ // Run command
toy_init(which, argv);
if (toys.which) toys.which->toy_main();
if (fflush(NULL) || ferror(stdout)) perror_exit("write");