Wireshark-dev: Re: [Wireshark-dev] [Wireshark-bugs] [Bug 1741] Privilege separation patch
Guy Harris wrote:
> setuid() *should*, at least according to the Single UNIX Specification,
> set the real, effective, and set-user ID if the process is running with
> appropriate privileges. The same applies, *mutatis mutandis*, to setgid().
According to "Setuid Demystified", this may not work in some cases. The
paper is 5 years old now, so I'm not sure how much of it still applies.
However, uidswap.c:permanently_drop_suid() in the OpenSSH distribution
seems to prefer setresuid() over setuid():
void
permanently_drop_suid(uid_t uid)
{
uid_t old_uid = getuid();
debug("permanently_drop_suid: %u", (u_int)uid);
#if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID)
if (setresuid(uid, uid, uid) < 0)
fatal("setresuid %u: %.100s", (u_int)uid, strerror(errno));
#elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID)
if (setreuid(uid, uid) < 0)
fatal("setreuid %u: %.100s", (u_int)uid, strerror(errno));
#else
# ifndef SETEUID_BREAKS_SETUID
if (seteuid(uid) < 0)
fatal("seteuid %u: %.100s", (u_int)uid, strerror(errno));
# endif
if (setuid(uid) < 0)
fatal("setuid %u: %.100s", (u_int)uid, strerror(errno));
#endif
#ifndef HAVE_CYGWIN
/* Try restoration of UID if changed (test clearing of saved uid) */
if (old_uid != uid &&
(setuid(old_uid) != -1 || seteuid(old_uid) != -1))
fatal("%s: was able to restore old [e]uid", __func__);
#endif
/* Verify UID drop was successful */
if (getuid() != uid || geteuid() != uid) {
fatal("%s: euid incorrect uid:%u euid:%u (should be %u)",
__func__, (u_int)getuid(), (u_int)geteuid(), (u_int)uid);
}
}
BROKEN_SETRESUID, BROKEN_SETREUID, and SETEUID_BREAKS_SETUID are defined
at configure time using OS pattern matching.
> In Mac OS X 10.4 and later, a process can, in effect, belong to a bigger
> group set than just the group set that fits in the credentials (checks
> whether a process's group set includes a given group are done by sending
> a message to memberd). As I remember, the right way to change the group
> set of a process is to call initgroups(), passing it the user name of
> the user whose group set you want the process to pick up and that user's
> primary group ID. initgroups() is a BSDism, and has been picked up by
> other OSes, so it's not OS X-only; we should probably use it if available.
>
> Should the group set be changed *before* setting the effective user ID?
> _______________________________________________
> Wireshark-dev mailing list
> Wireshark-dev@xxxxxxxxxxxxx
> http://www.wireshark.org/mailman/listinfo/wireshark-dev