The kdbuswreck
The kdbuswreck
Posted Apr 23, 2015 8:55 UTC (Thu) by kentonv (subscriber, #92073)In reply to: The kdbuswreck by fandingo
Parent article: The kdbuswreck
Crapabilities are broken because, among other things:
* Crapabilities are hopelessly inexpressive, largely because they designate verbs rather than nouns. Choosing a random example, CAP_KILL lets me send signals to any process. Probably in any case where this might be useful, what would be *more* useful would be the ability to designate *specific* processes which I'm allowed to signal, or the specific signals I'm allowed to send.
* Due in no small part to the previous point, most individual crapabilities seem to end up opening a trivial privilege escalation to full root, and thus don't offer much actual protection compared to full root. Those that don't at least tend to allow trivial DoS attacks.
* The design goes out of its way to make it difficult to delegate crapabilities between processes or programs. E.g. if you aren't UID zero, you basically can't delegate a crapability through exec() (unless the system admin blesses all binaries involved, which in practice is often impractical, especially when, say, you want to invoke the shell to execute a command or script, so now you need to bless /bin/sh). This severely limits how systems can be designed -- you can't have a bunch of loosely-coupled programs that exec() each other in the unix tradition; you instead must have one monolithic binary. These harsh restrictions do not provide any actual security benefit -- a program which wishes to maliciously leak its crapabilities can always arrange to listen on a socket and execute operations requested by anyone.
* Crapabilities are "ambient authority". It is difficult for a program to specify exactly when it intends to exercise a crapability and when it doesn't, and as a result it tends to be easy to trick programs into exercising them at the wrong time, commonly known as a "confused deputy attack". It sounds like kdbus is likely to exacerbate this, by allowing a process's capabilities to unexpectedly affect the way other processes react to its dbus requests.
The alternative proposal is simple: represent capabilities (the real kind) as file descriptors. A privileged process could open file descriptors representing specific capabilities, like, say, the ability to send signals to some process. It could then delegate power by transmitting said file descriptors via the usual means -- parent->child inheritance, SCM_RIGHTS, etc. To exercise such a capability, the user must explicitly pass the capability file descriptor to whatever system call exercises it. (Think of the *at() (openat(), etc.) system calls, which (sort of) do this for the file system.)
The Capsicum project is aiming to implement this vision, and is doing it right. Capsicum is already in FreeBSD and should be accepted into Linux as well. (I'm not affiliated with Capsicum, but I am the lead dev of Sandstorm which is built on the same principles.)
