Capsicum: Lightweight Isolation for FreeBSD Processes
Before I start, I should admit to a little bit of potential bias in this article. As a FreeBSD developer and a member of the Cambridge University Computer Lab's Security Group, I'm naturally inclined to like a feature developed by that research group for FreeBSD. That said, I wasn't working here when it was developed, so I am not praising my own child, so to speak.
So, with that disclaimer out of the way, what is Capsicum? Before I get into any details, it's worth spending some time understanding the two approaches to security.
One is to try to verify that the code does what it is supposed to do. This is a laudable goal, but ultimately likely to be futile. The Java VM, for example, has a complex bytecode verifier that checks for invalid things. If you search the CVE database, you can find numerous cases where bugs in the verifier, or in the JIT, have allowed attackers to escape the sandbox.
The other approach is to assume that security holes are caused by bugs, that all code contains bugs, and that good code should attempt to limit the damage that bugs can do. This is the point of Capsicum: It is a very lightweight set of tools to allow applications to isolate parts of themselves.
Files and Processes
To understand how Capsicum works, it's important to understand how process isolation in UNIX works. Each process gets exclusive use of one or more processors for a small period at a time, and exclusive use of a block of memory. The memory access is enforced by the CPU and, in the absence of bugs in the hardware, the process can't escape from this by itself. If it tries to access any memory that it doesn't own, then you will get a segmentation fault and, usually, your program will be killed.
To access anything outside of this little encapsulated world, the process must make system calls and ask the kernel to do something on its behalf. This is quite important because any I/O (even just reading from the terminal) requires access outside of the process's private world.
In UNIX, everything is a file. The standard input is a file descriptor that may refer to a file, a pipe, or a terminal device. The same applies to the standard output and to every other resource that the program interacts with.
From a security perspective, I/O is really the only important thing to worry about. A compromised program can do nothing too serious (maybe flatten your battery and make the room slightly warmer) without I/O. With I/O, it can read (and modify) your documents, connect to remote servers, and so on. If you want programs to be secure, then you want to limit the amount of I/O that they can perform.