tech-kern archive


Re: Capsicum: practical capabilities for UNIX

On Mon, 27 Sep 2010, der Mouse wrote:

POSIX.1e "capabilities" are actually coarse-grained OS privileges,

Not all that coarse-grained as compared to traditional Unix privileges!

Certainly true :-).

However, they are coarse to the point of being relativley unusable for most purposes. It's nice to be able to assign the right to bind low port numbers, but it's preferable to be able to assign a specific low port number. In practice, that need is better met by an ACL model (bind can bind port X, apache can bind port Y); since UNIX supports file descriptor passing already, we can implement that ACL in userspace and use a capability-like approach to pass it to the daemon rather than adding a new ACL model in kernel. Only, wouldn't it be nice if we could do that with other things too, within an application...

Capabilities in a classic security sense are unforgeable tokens of authority that can be delegated.

Sounds a lot like POSIX "capabilities" to me - it's just that the authority comes in, as compared to non-POSIX "capabilities", relatively coarse chunks and is passed around in a rather different way.

I can see the argument here, but am not sure I really agree. The reason that I feel that POSIX capabilities don't align well with history notions of capability is that they can't be delegated between processes non-hierarchically, or even after a child has forked(), without resorting to tagging them on to executables (similar to setuid binaries) in the global file system namespace. In classic capability system designs, the idea of non-hierarchical delegation is central as it allows applications to define their own security models (see also CAP, Hydra, Eros, etc). Often it's done via the abstraction of a namespace, but the implementation of the namespace can be entirely controlled by the service or application.

About ten years ago, I experimented with delegating UNIX privileges using file descriptors ("tokens"), but wasn't satisfied with the composition properties, so didn't reuse the idea in Capsicum. In particular, the existing file descriptor behaviour of UNIX seems to align well with capability concepts in a way likely to work well with current applications (not a coincidence, of course, but hence using that as the starting point in Capsicum), whereas many existing UNIX programs have strong notions of manipulating privilege using UIDs rather than as file rights. While it seemed that correct usage was likely possible, the potential for something catastrophic was worrying.

An example of the kinds of things that easily go wrong when modifying the UNIX privilege model include the Linux privileges + sendmail bug: in the particular composition they selected, setuid root programs that weren't written to the new privilege model might end up with their privilege masks set in unexpected ways, and would therefore fail unexpectedly. While it was undoubtably poor programming practice that sendmail didn't check whether setuid() failed when getuid() had returned 0, it wasn't incorrect until the privilege model was modified without revisiting the assumptions of all applications that depended on it. You might argue that this problem occurred because the model selected in Linux allowed negative delegation of rights, violating the privilege escalation assumption of setuid binaries.


Home | Main Index | Thread Index | Old Index