Mercurial > hg > toybox
changeset 370:c7a26e26ad08
Add TOYBOX_SUID.
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 05 Jan 2010 12:17:05 -0600 |
parents | 5715eed39575 |
children | 2cec41ee6eea |
files | Config.in lib/lib.c lib/lib.h main.c toys.h |
diffstat | 5 files changed, 39 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Config.in Tue Jan 05 10:48:32 2010 -0600 +++ b/Config.in Tue Jan 05 12:17:05 2010 -0600 @@ -11,6 +11,14 @@ With no arguments, shows available commands. First argument is name of a command to run, followed by any arguments to that command. +config TOYBOX_SUID + bool "SUID support" + default y + help + Support for suid commands, which run as root. This means toybox must + be installed suid root, and drops permissions before running commands + which do not require root access. + config TOYBOX_FREE bool "Free memory unnecessarily" default n
--- a/lib/lib.c Tue Jan 05 10:48:32 2010 -0600 +++ b/lib/lib.c Tue Jan 05 12:17:05 2010 -0600 @@ -369,6 +369,16 @@ if (!*p) break; } } + +// setuid() can fail (for example, too many processes belonging to that user), +// which opens a security hole if the process continues as the original user. + +void xsetuid(uid_t uid) +{ + if (setuid(uid)) perror_exit("xsetuid"); +} + + // Find all file in a colon-separated path with access type "type" (generally // X_OK or R_OK). Returns a list of absolute paths to each file found, in // order.
--- a/lib/lib.h Tue Jan 05 10:48:32 2010 -0600 +++ b/lib/lib.h Tue Jan 05 12:17:05 2010 -0600 @@ -81,6 +81,7 @@ char *xabspath(char *path); void xchdir(char *path); void xmkpath(char *path, int mode); +void xsetuid(uid_t uid); struct string_list *find_in_path(char *path, char *filename); void utoa_to_buf(unsigned n, char *buf, unsigned buflen); void itoa_to_buf(int n, char *buf, unsigned buflen);
--- a/main.c Tue Jan 05 10:48:32 2010 -0600 +++ b/main.c Tue Jan 05 12:17:05 2010 -0600 @@ -64,6 +64,21 @@ void toy_init(struct toy_list *which, char *argv[]) { + // Drop permissions for non-suid commands. + + if (CFG_TOYBOX_SUID) { + uid_t uid = getuid(), euid = geteuid(); + + if (!(which->flags & TOYFLAG_STAYROOT)) { + if (uid != euid) xsetuid(euid=uid); + } else if (CFG_TOYBOX_DEBUG && uid) + error_exit("Not installed suid root"); + + if ((which->flags & TOYFLAG_NEEDROOT) && euid) + error_exit("Not root"); + + } + // Free old toys contents here? toys.which = which;
--- a/toys.h Tue Jan 05 10:48:32 2010 -0600 +++ b/toys.h Tue Jan 05 12:17:05 2010 -0600 @@ -68,6 +68,11 @@ // Start applet with a umask of 0 (saves old umask in this.old_umask) #define TOYFLAG_UMASK (1<<5) +// This applet runs as root. +#define TOYFLAG_STAYROOT (1<<6) +#define TOYFLAG_NEEDROOT (1<<7) +#define TOYFLAG_ROOTONLY (TOYFLAG_STAYROOT|TOYFLAG_NEEDROOT) + // Array of available applets extern struct toy_list {