]> mj.ucw.cz Git - suidgw.git/commitdiff
Dropped emulation of real/effective/saved ID semantics
authorMartin Mares <mj@ucw.cz>
Tue, 12 Feb 2013 12:55:48 +0000 (13:55 +0100)
committerMartin Mares <mj@ucw.cz>
Tue, 12 Feb 2013 12:55:48 +0000 (13:55 +0100)
It breaks Perl.

README
suidgw.c

diff --git a/README b/README
index a6e2031c8ce7f3ecd0a7017beb05742060b5ed63..64cccff19a30e75689f51b13814034bf276ed543 100644 (file)
--- 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.
index 63ac0d34123db5337cde2e8838b333974f7e33ad..4e49abc0fbc2173ab3fea83d81b36008773bd395 100644 (file)
--- 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");