From: Martin Mares Date: Tue, 12 Feb 2013 12:55:48 +0000 (+0100) Subject: Dropped emulation of real/effective/saved ID semantics X-Git-Tag: v1.3~6 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=341c2f7c636f16c00af6d9f73bb16b6f749901cf;p=suidgw.git Dropped emulation of real/effective/saved ID semantics It breaks Perl. --- diff --git a/README b/README index a6e2031..64cccff 100644 --- a/README +++ b/README @@ -39,9 +39,17 @@ Theory of operation o The suidgw finds /usr/lib/suidgw/$SCRIPT and checks that the current (real) user is allowed to run it. - o Then it switches the effective and saved UID and runs the script. + o Then it switches real, effective, and saved UID and runs the script. Environment variables are sanitized (currently, the whole environment is reset; in the future, we may propagate some variables if needed) and so are file descriptors (we make sure that fd's 0 to 2 exist). o The action is logged to the syslog (facility auth, level info). + + +CAVEAT: We do not emulate proper POSIX real/effective/saved UID semantics, +because when a recent Perl interpreter detects that real != effective, it +refuses to run. Therefore we set all three UIDs and GIDs to the new effective +user/group and record the ID's of the caller in environment variables ORIG_UID +and ORIG_GID. Still, Linux kernel notices the UID changes and marks the task +as undumpable, so this should be secure. diff --git a/suidgw.c b/suidgw.c index 63ac0d3..4e49abc 100644 --- a/suidgw.c +++ b/suidgw.c @@ -39,13 +39,17 @@ static const char * const script_dirs[] = { "/usr/local/lib/suidgw", "/usr/lib/suidgw", #ifdef DEBUG - "./scripts", + "./tests/scripts", #endif NULL }; +static char env_orig_uid[32], env_orig_gid[32]; + static char *sanitized_env[] = { "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + env_orig_uid, + env_orig_gid, NULL }; @@ -73,6 +77,12 @@ static void sanitize_fds(void) close(fd); } +static void sanitize_env(void) +{ + snprintf(env_orig_uid, sizeof(env_orig_uid), "ORIG_UID=%d", (int) getuid()); + snprintf(env_orig_gid, sizeof(env_orig_gid), "ORIG_GID=%d", (int) getgid()); +} + static bool get_program_name(const char *arg0) { // If arg0 is a path, extract the last component @@ -141,16 +151,17 @@ static void check_stat(void) static void switch_ugid(void) { - if (setresgid(getgid(), use_gid, use_gid) < 0) + if (setresgid(use_gid, use_gid, use_gid) < 0) die("Failed to set group id: %m"); - if (setresuid(getuid(), use_uid, use_uid) < 0) + if (setresuid(use_uid, use_uid, use_uid) < 0) die("Failed to set user id: %m"); } int main(int argc UNUSED, char **argv) { sanitize_fds(); + sanitize_env(); if (geteuid()) die("Must be run setuid");