Setuid Demystified Hao Chen David Wagner UC Berkeley Drew Dean SRI International Proceedings of the 11th USENIX Security Symposium San Francisco, California, USA August 5-9, 2002 1 Outline • Identified problems of SETUID – What is SETUID – SETUID mystery and problems • Provided solution – Use a formal model – Build the model automatically by state space exploration • Demonstrated Applications of FSA – – – – Understanding semantics of security operation API precisely Verifying Documentation Detecting Inconsistency in OS kernels Checking Proper use of API calls in programs • Proposed guidelines 2 What is setuid • Access control in Unix is based the User ID model • Each process has 3 user Ids: – Real uid (ruid) – Effective uid (euid) – Saved uid (suid) • Uid-setting system calls – setuid() seteuid() setreuid() setresuid() 3 Historical Artifacts • Early Unix • Two user IDs: ruid and euid. • Only one system call: setuid • Rules: • System V • Three user IDs: ruid, euid and suid • Two system call: setuid and seteuid • Rules: • BSD • Three user IDs: ruid, euid and suid • System call: setuid, seteuid, and setreuid • Rules: • Modern Unix • Three user IDs: ruid, euid and suid • System call: setuid, seteuid, setreuid and setresuid • Rules: 4 The Problems • Semantic mess – Design: confusing, surprising – Portability: semantic differences among OSs (e.g. Linux, Solaris, FreeBSD) – Documentation: incomplete, inaccurate, or incorrect 5 Objective • Understanding the semantics of security operation API in OS precisely • Verifying their documentations • Detecting inconsistency in OS kernels • Building security properties and checking them in programs automatically 6 Formal Model of the Setuid API • Finite State Automaton (FSA) model – States: describing the user IDs of a process – Transitions: describing the semantics of the setuid API calls Abstraction 0: root uid 1: a non-root uid seteuid(0) ruid=1 euid=0 suid=0 ruid=1 euid=1 suid=1 ruid=1 euid=1 suid=0 7 Construct the FSA • Challenge – Large number of transitions – Manual construction is laborious, error-prone • Solution – Automatic construction by a state space explorer: • Exhaustively makes all setuid API calls at each state of the FSA • Observes the resulting transitions 8 Determine Transitions Automatically by Simulation • Idea: Exhaustively make all system calls at each state For each state s=(ruid, euid, suid) where ruid, euid, suid {0, uid1 , uid2 , …} For each system call c {setuid(e), seteuid(e), setreuid(r,e), setresuid(r,e,s)} { Make the system call c in the state s Observe the ensuing state s’ c Add the transitions s' } 9 FSAs for setuid transitions Linux FreeBSD FSA for setresuid in Linux 11 Benefits of Using Formal Model • Correctness – Intuition: the transitions in the FSA are observed from running programs • Efficiency – The FSA is constructed automatically by the explorer • Portability: the explorer is portable to – Different Unix systems – Different versions of kernels • Lots of applications! 12 Applications: Find Documentation Errors • Incomplete man page – setuid(2) in Redhat Linux 7.2: fails to mention the Linux capabilities which affect how setuid() behaves • Wrong man pages suid – FreeBSD 4.4 Unprivileged users may change the ruid to the euid and vice versa – Redhat Linux 7.2 euid The setgid function checks the egid of the caller and if it is the superuser, … 13 Applications : Detect Inconsistencies in OS Kernel • File system uid (fsuid) in Linux – Is used for filesystem permission checking – Normally follows euid • An invariant in Linux 2.4.18 (kernel/sys.c) – fsuid is 0 only if at least one of ruid, euid, suid is 0 • Security motivation – Root privilege in fsuid is automatically dropped when it is dropped from ruid, euid, suid – Ensures that an fsuid-unware application can safely 14 drop root privilege in fsuid Applications : Detect Inconsistencies in OS Kernel (contd.) • A bug in Linux kernels <= 2.4.18 breaks the invariant – The invariant is satisfied in setuid(), seteuid(), setreuid() – But it is broken in setresuid() – fsuid = 0 and ruid != 0, euid != 0, suid != 0 is reachable (figure2) • The bug has been confirmed by Linux community 15 Check Proper Usage of the Setuid API in Programs • Questions – Can a setuid API call fail in this program? – Can this program fail to drop privilege? – Which part of this program run with privilege? • Approach – Model checking security properties in programs using the FSA of the setuid API • Results – Found known setuid bugs in sendmail 8.10.1 and 8.12.0 16 A Vulnerability in Sendmail Due to A Misuse of setuid. 17 General Guidelines (1) • Selecting an Appropriate System Call • setresuid has a clear semantics and is able to set each user ID individually, it should always be used if available. • Otherwise, to set only the effective uid, seteuid(new euid) should be used; to set all three user IDs, setreuid(new uid, new uid) should be used. • setuid should be avoided because its overloaded semantics and inconsistent implementation in different Unix systems may cause confusion and security vulnerabilities for the unwary programmer. 18 General Guidelines (2) • Obey the proper order of API calls – Drop group privileges before user privileges 19 General Guidelines (3) • Verifying Proper Execution of System Calls • Checking Return Codes • Verifying User IDs • Verifying Failures 20 An Improved API for Privilege Management – The API contains three functions: • Drop_priv_temp(new uid): Drop privilege temporarily. Move the privileged user ID from the effective uid to the saved uid. Assign new uid to the effective uid. • Drop_priv_perm(new uid): Drop privilege permanently. • Restore_priv: Restore privilege. – Beneficial properties • It does not affect the real uid. • It guarantees that all transitions in Figure 13 succeed. • It verifies that the user IDs are as expected after each uid-setting system call. 21 Conclusion • Identified the precise semantics – Use an FSA model – Built the model automatically by state space exploration • Formal models revealed pitfalls and bugs – – – – Discovered semantic pitfalls Found new documentation errors Detected the fsuid bug in the Linux kernel Verified the proper use of setuid API in some programs (sendmail 8.10.1 and 8.12.0) • Proposed guidelines for the setuid API 22