]> andersk Git - openssh.git/commitdiff
- (djm) Implement paranoid priv dropping checks, based on:
authordjm <djm>
Wed, 4 Jun 2003 23:53:31 +0000 (23:53 +0000)
committerdjm <djm>
Wed, 4 Jun 2003 23:53:31 +0000 (23:53 +0000)
   "SetUID demystified" - Hao Chen, David Wagner and Drew Dean
   Proceedings of USENIX Security Symposium 2002

ChangeLog
acconfig.h
configure.ac
includes.h
uidswap.c

index df52314062a45c08b13694c7771de896ba5528e9..d31e449c6c811a13a2b786758b1fde24afeeebdf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 20030605
  - (djm) Support AI_NUMERICHOST in fake-getaddrinfo.c. Needed for recent
    canohost.c changes.
+ - (djm) Implement paranoid priv dropping checks, based on:
+   "SetUID demystified" - Hao Chen, David Wagner and Drew Dean
+   Proceedings of USENIX Security Symposium 2002
 
 20030604
  - (djm) Bug #573 - Remove unneeded Krb headers and compat goop. Patch from
index 0cf4e0a755438521f47a8b5799f6f097547d40da..4f762978bda06290b6a74097b1c85d9b8b95ab6c 100644 (file)
@@ -8,6 +8,9 @@
 
 @TOP@
 
+/* Define if your platform breaks doing a seteuid before a setuid */
+#undef SETEUID_BREAKS_SETUID
+
 /* Define to a Set Process Title type if your system is */
 /* supported by bsd-setproctitle.c */
 #undef SPT_TYPE
index 11b7b4b200c5c309b1a63a70b2f214fe0a70b8a6..961559b97b097832c69fbb1322a866747a0b7924 100644 (file)
@@ -439,7 +439,7 @@ AC_ARG_WITH(libs,
 )
 
 # Checks for header files.
-AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \
+AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \
        getopt.h glob.h ia.h lastlog.h libgen.h limits.h login.h \
        login_cap.h maillock.h netdb.h netgroup.h \
        netinet/in_systm.h paths.h pty.h readpassphrase.h \
@@ -659,17 +659,18 @@ AC_ARG_WITH(tcp-wrappers,
 
 dnl    Checks for library functions. Please keep in alphabetical order
 AC_CHECK_FUNCS(\
-       arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename bcopy \
-       bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
+       arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename \
+       bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
        gai_strerror getaddrinfo getcwd getgrouplist getnameinfo getopt \
        getpeereid _getpty getrlimit getrusage getttyent glob inet_aton \
        inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \
        mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \
        pstat readpassphrase realpath recvmsg rresvport_af sendmsg \
        setdtablesize setegid setenv seteuid setgroups setlogin setpcred \
-       setproctitle setresgid setreuid setrlimit setsid setvbuf sigaction \
-       sigvec snprintf socketpair strerror strlcat strlcpy strmode strnvis \
-       sysconf tcgetpgrp truncate utimes vhangup vsnprintf waitpid \
+       setproctitle setregid setresgid setresuid setreuid setrlimit \
+       setsid setvbuf sigaction sigvec snprintf socketpair strerror \
+       strlcat strlcpy strmode strnvis sysconf tcgetpgrp truncate utimes \
+       vhangup vsnprintf waitpid \
 )
 
 AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP))
index b968be7f8f538549393e2a232527173f0852f666..c30c31577e783b50d8428a7b544c556f5d038dbc 100644 (file)
@@ -68,6 +68,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #ifdef HAVE_NEXT
 #  include <libc.h>
 #endif
+#define __USE_GNU /* before unistd.h, activate extra prototypes for glibc */
 #include <unistd.h> /* For STDIN_FILENO, etc */
 #include <termios.h> /* Struct winsize */
 
index db6253259ba58d1e65472eaa584e0ba5b28bf039..04c269b0a1769a39629c672f793061e9b383bb18 100644 (file)
--- 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);
+       }
 }
This page took 0.136719 seconds and 5 git commands to generate.