Summary - Setuid Demystified - access control mainly based on uid's - poorly designed - widely misunderstood - documented incorrectly - differ among systems - three user id's: ruid, euid, suid, (fsuid in linux) - access control is based on the euid - forked process inherits these from parent - exec'd file keeps caller's three ids, unless set-user-id flag set in which case it uses euid and suid of file owner - temp. drop privileges by putting priv. euid in suid, and non priv. in euid - perm. drop privilges by replacing all three with non priv. - modify user id's with syscalls: setuid, seteuid, setreuid, setresuid... - different sematics for different os's - solaris doesn't have suid, though can use /proc for this functionality - setresuid(r,e,s): e==0 -> all change, e!=0 -> each must be one of current - setuid(newid) on os - linux, solaris: if e=0, then all three get changed to newid else if newid==r or newid==s, then only euid is updated, - freebsd: if the call is successful, then all three are updated - formal model - build an FSA to model how the system handles uid's and their manipulation - the states are cross-products of the kernel variables used that affect it - state model generally consists of ruidxeuidxsuid, and each can be one of root and three distinct non-root values - they ran the simulations on all possible transistions from a user process to help with confidence that the system actually behaves code makes it look - for each call, check the return value, AND explicitly check the uid's turned out as expected - applications of the formal model - verify man pages - linux doesn't mention SETUID capability bit says setgid checks egid of user, though it checks euid - freebsd says non-priv. user can swap ruid and euid, though not quite true - identify implementation differences - detecting inconsistency within an OS kernel - linux tries to keep invarient that fsuid=0 only if one of uid's is 0 though there is a sequence of calls that can violated this - check proper usage of uid-setting system calls - check when programs could/should (temp) drop privileges based what they execute and when (they're currently working on this) - formal model conclusions - makes it easier to describe semantics a systems uid-settings syscalls - reliable, created/runs in same env. as user programs - useful in identifying semantic differences in os's - verfiy that system is behaving as we think it is - checking proper usage in uid-setting syscalls in programs automatically - guidelines on usage - use setresuid() if possible, setreuid() otherwise - always drop gid privileges before uid privileges - check return codes - check that the values think are now there are actually correct - use their improved API, more intuitive, can work across platforms - drop priv temp - restore priv - drop priv perm