From 5fe46a45c834bf2e336d979e2ae755b94e01d707 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 5 Jun 2003 09:53:31 +1000 Subject: - (djm) Implement paranoid priv dropping checks, based on: "SetUID demystified" - Hao Chen, David Wagner and Drew Dean Proceedings of USENIX Security Symposium 2002 --- uidswap.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'uidswap.c') diff --git a/uidswap.c b/uidswap.c index db625325..04c269b0 100644 --- a/uidswap.c +++ b/uidswap.c @@ -143,16 +143,63 @@ restore_uid(void) void permanently_set_uid(struct passwd *pw) { + uid_t old_uid = getuid(); + gid_t old_gid = getgid(); + if (temporarily_use_uid_effective) fatal("permanently_set_uid: temporarily_use_uid effective"); debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid, (u_int)pw->pw_gid); + +#if defined(HAVE_SETRESGID) + if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) + fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#elif defined(HAVE_SETREGID) + if (setregid(pw->pw_gid, pw->pw_gid) < 0) + fatal("setregid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#else if (setegid(pw->pw_gid) < 0) fatal("setegid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); if (setgid(pw->pw_gid) < 0) fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#endif + +#if defined(HAVE_SETRESUID) + if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) + fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#elif defined(HAVE_SETRESUID) + if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) + fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#else +# ifndef SETEUID_BREAKS_SETUID if (seteuid(pw->pw_uid) < 0) fatal("seteuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +# endif if (setuid(pw->pw_uid) < 0) fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#endif + + /* Try restoration of GID if changed (test clearing of saved gid) */ + if (old_gid != pw->pw_gid && + (setgid(old_gid) != -1 || setegid(old_gid) != -1)) + fatal("%s: was able to restore old [e]gid"); + + /* Verify GID drop was successful */ + if (getgid() != pw->pw_gid || getegid() != pw->pw_gid) { + fatal("%s: egid incorrect gid:%u egid:%u (should be %u)", + __func__, (u_int)getgid(), (u_int)getegid(), + (u_int)pw->pw_gid); + } + + /* Try restoration of UID if changed (test clearing of saved uid) */ + if (old_uid != pw->pw_uid && + (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) + fatal("%s: was able to restore old [e]uid"); + + /* Verify UID drop was successful */ + if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) { + fatal("%s: euid incorrect uid:%u euid:%u (should be %u)", + __func__, (u_int)getuid(), (u_int)geteuid(), + (u_int)pw->pw_uid); + } } -- cgit v1.2.1