diff options
| author | Rob Landley <rob@landley.net> | 2014-09-09 23:42:25 -0500 | 
|---|---|---|
| committer | Rob Landley <rob@landley.net> | 2014-09-09 23:42:25 -0500 | 
| commit | c6705af4231b8071830721f98021d0e79223da12 (patch) | |
| tree | 5edbeb82e1a0840044ccb697c3c31829fe34016e | |
| parent | 7a07c6bc431d441a2363b58a1d82fe7a2a6d75f2 (diff) | |
| download | toybox-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.
| -rw-r--r-- | main.c | 8 | ||||
| -rw-r--r-- | toys.h | 1 | 
2 files changed, 8 insertions, 1 deletions
| @@ -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"); @@ -132,6 +132,7 @@ extern struct toy_context {    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 | 
