Singularity: Rethinking the Software Stack ========================================== What is the motivation for this work? OS architectures of 60s-70s leading to: Security vulnerabilities Unexpected interactions among applications Errant extensions/plug-ins/drivers "Perceived lack of robustness" What's a software isolated process (SIP)? Used like a process in today's OSes Isolated by software, not MMU, using type-safe language (Sing#, based on C#) No shared memory with other SIPs Has its own garbage collector (but can be wholly reclaimed w/o GC on exit) "Sealed" code--i.e., no mutable or dynamically generated code--Why? (p. 2) Facilitate static analysis Allow you to identify a process by its code segment Eliminate need to duplicate OS-style access control in runtime--why? Same SIP mechanism provides both processes and dynamically-loaded code Kernel-provided access control already works at SIP granularity Hence use kernel to control extensions just like processes (end p. 2) Why are SIPs faster in Table 1? Don't require VM or switching between hardware protection domains What is a channel, and how do channels work? Bi-directional (but asymmetric), typed, inter-SIP communication mechanism Specifies types of message Includes a *contract* mechanism restricting what messages can be sent when See example in Listings 1-2 How does a channel send objects between SIPs, given no shared memory? Special memory region known as "exchange stack" shared between SIPs But any given object in an exchange stack owned by only one SIP Only one owner ensured by "linear types"--what's this? Basically a single-use reference, invalid after sending to channel Idea similar to C++'s auto_ptr (where assignment destroys the original) What is a manifest-based program (MBP)? All software must be described by a manifest, which specifies: - The executable code it will use - System resources (e.g., IO ports for a device driver) - Desired capabilities - Dependencies on other programs Specifies code in MSIL format to facilitate verification of properties Somewhat extreme at the time (work started ~2003, published April 2007) Does idea seem more common now? Smart phones What does the kernel look like in Singularity (p. 4)? 90% written in Sing#, or unsafe dialect of Sing# (especially GC) Assembly language for small things (thread switch, interrupt vector) 6% C++ (debugger and system initialization) What facilities are implemented in kernel? Scheduling, protected access to hardware resources, system memory management, thread and thread stack management, creating/destroying SIPs Not implemented in kernel: file systems, device drivers, ... Makes Singularity a microkernel What is the system call interface like? 192 System calls (p. 5)--big for a microkernel; even linux only has 312! But numbers aren't everything--avoiding ioctl important too--why? ioctl basically allows arbitrary new syscalls to be added State isolation invariant (p. 5): cannot directly alter the state of another process through ABI functions What's an example of ABI calls that violate this on Linux Modifying shared memory, using futexes to synchronize across processes Using ptrace, or opening and writing to /proc//mem So how would you implement cross-SIP synchronization? Have to use a mutex server SIP What's a handle? Indexes a per SIP table, somewhat like the file descriptor table in Unix Unlike fds, handles are not ints, but rather protected by wrapper type E.g., slot 5 might be a mutex, so mutex object wraps private index 5 Note slot numbers are never recycled, as can't guarantee old objects gone Instead, sounds like SIP library code is responsible for recycling them On traditional OS, can implement threads in kernel or as library Which is better? Depends uthreads have very low context switch & synchronization overhead kthreads deal with blocking (syscalls, page faults) much better Does singularity use uthreads or kthreads? Definitely kthreads, because implemented in the kernel But language-based protection makes kernel crossings much cheaper Kind of have the best of both worlds What does the word principal mean in OS security? A principal is a source of requests On linux, principals are user IDs; a process acts on behalf of UID principal In Jif, principals are users who can add and remove restrictions on data What's a principal in HiStar? Privileges represented by ownership of categories So principals correspond to sets of categories threads can own What's a principal in Capsicum? Privileges are capabilities, but capabilities are very dynamic Might have some higher-level notion of principal outside kernel What are principals in Singularity (Sec 3.6, p. 7)? Principals are applications Users are roles (further subdividing application privileges) If Channels are like capabilities, why do you also need principals? Kernel tells you principal sending you a message over channel Helps services decide when to return capabilities E.g., only return capability for particular file to its owner Can also delegate authority over a channel In Capsicum, how would you verify a process doesn't access network? Check all initial capabilities to ensure no network Plus check transitive closure of capabilities you can get from initial ones How would you do this in Singularity? Can statically check if app ever uses the network contract Types and contracts are big difference between capabilities and channels (Of course, also need to check SIP can't relay data through third-party) Can you implement information flow control on Singularity? Can do the same thing as KeyKOS, but requires app refactoring What is compile-time reflection (CTR)? How would this work (from p. 9)? A protection domain could, in principle, host a single process containing unverifiable code written in an unsafe language such as C++. What evaluation questions should we ask? Performance? (p. 10 & Figure 5) Practicality? Security/reliability - how to evaluate?