Mercurial > hg > toybox
changeset 1467:d1411369baa7 draft
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.
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 09 Sep 2014 23:42:25 -0500 |
parents | aa0ae038e275 |
children | 6fd5e556f89d |
files | main.c toys.h |
diffstat | 2 files changed, 8 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/main.c Tue Sep 09 20:13:03 2014 -0500 +++ b/main.c Tue Sep 09 23:42:25 2014 -0500 @@ -119,12 +119,18 @@ } // 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");
--- a/toys.h Tue Sep 09 20:13:03 2014 -0500 +++ b/toys.h Tue Sep 09 23:42:25 2014 -0500 @@ -132,6 +132,7 @@ int toycount; // Total number of commands in this build int signal; // generic_signal() records what signal it saw here int signalfd; // and writes signal to this fd, if set + int recursion; // How many nested calls to toy_exec() // This is at the end so toy_init() doesn't zero it. jmp_buf *rebound; // longjmp here instead of exit when do_rebound set