Re: Issues with capability bits and meta-data in kdbus

Linus Torvalds
2015-04-22T01:30:10Z

On Tue, Apr 21, 2015 at 2:06 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
>
> - The userspace interface for capability bits has a version number that
> determines the quantity and the meaning of the bits, kdbus does not
> pass that number to userspace.

Well, realistically, we'll just have to freeze the version anyway.
There's no sane way not to - if anybody believes that you can change
the version without breaking all kdbus users, they are living in some
drug-induced happy-land.

So we could make the version number available to match other
interfaces, but in practice that will just make people think that the
capabilities are versioned, which in reality they are not.

> - There is a well defined translation of capability bits between user
> namespaces kdbus does not perform that translation.

Now this looks like a big oversight, and serious.

If you have a capability inside a lower namespace, and can fool the
other end of a kdbus connection into thinking that you have that
capability globally, then that sounds like a very obvious and bad
security issue. This needs fixing. That said, it's likely a fairly
simple fix.

> - Access to the capability bits is guarded with PTRACE_MAY_READ
> kdbus does not honor that and thus leaks information.

Now, this is likely not a real problem.

Yes, when you try to read other processes capabilities, you need
PTRACE_MAY_READ to see them. HOWEVER, that's not really what a kdbus
message would do - it doesn't "read somebody elses capabilities". When
you do a kdbus write, you export your *own* capabilities. If you don't
want others to know what privileges you have, then you shouldn't be
using kdbus.

It's like saying "you need PTRACE_MAY_READ" to be able to read the
process image of another process. True. But if that other process does
a "write()" system call, then the written data will contain the data
from that process. That's how write works.

> - Usage of the capability bits by userspace is a layering violation.
>
> - The layering violation results in a privilege escalation (by
> definiton) whenever userspace uses the presence of the capability bits
> to allow anything.

Well, but that's a user space decision thing. If some system daemon
uses the capabilities of the other end to decide to accept some
message or not, that's a policy decision by that (privileged) system
daemon. The daemon itself obviously still needs to have the proper
capabilities in order to do any action that needs such capabilities.

So it's not a privilege escalation. It's intentional.

> - Another kind of privilege escalation happens when userspace makes a
> decision based on the absense of in kernel capability bits.

I don't see that this is any different from the above.

So I agree that kdbus clearly *must* translate the capabilities when
passing messages from one namespace to another. The fact that you may
have setuid rights in one container, does *not* necessarily mean that
the recipient in another namespace should think you have that
capability - because in the receiving namespace the originator may not
have that capability at all.

So I think that one is a real and serious bug. But the other
complaints seem to be off the mark. It seems quite reasonable to me to
say that a recipient should be able to distinguish between *root*
sending it a dbus message to take down the system, and some random
luser doing the same.

Linus