Re: Sending caps to userspace (Re: [GIT PULL] kdbus for 4.1-rc1)

From: Daniel Mack
Date: Thu Apr 16 2015 - 06:14:19 EST


On 04/15/2015 05:42 PM, Andy Lutomirski wrote:
> On Apr 15, 2015 5:00 AM, "Greg Kroah-Hartman"

> I looked. AFAICT polkit doesn't use caps. Systemd does (look for
> VTABLE_CAP and the associated code) for reasons that escape me. I
> have yet to find a single cap-guarded method in the systemd code base
> that isn't also guarded by dbus policy and/or polkit.
>
> That latter part is important for two reasons. Reason 1: the cap code
> doesn't seem to do anything, which makes it hard for me to break.
> (It's also spaghetti strung across lots of files, so I could be
> wrong.).

The sd-bus code in systemd uses the caps logic on the kdbus layer only.
On dbus1, caps aren't considered due to the obvious race gaps, hence the
code paths you looked are are ineffective in your setup.

> Reason 2: if the cap code isn't actually serving a security
> purpose, correctly or otherwise, why is it there? Can't it just be
> deleted?

It is currently used for kdbus, and we've still not been given a
concrete reason why that's a bad idea.

The set of capabilities a task has set when it calls into the kernel is
authoritative, otherwise the kernel couldn't take it into account. If a
task or binary file is able to gain bits in the caps mask, that's a
problem of its own already, independent from kdbus.

The code in kdbus never adds any capabilities to anything, it doesn't
bump the receiver's caps or suchlike. All it does is taking the current
caps at the time of sending a message, and putting them into a metadata
item as passive information, so privileged userspace can take that as a
measure to make similar assumptions than a syscall handler would do.
Unlike cap_get_pid(), however, this transport doesn't suffer from the
described races.

We are aware of the issue user namespaces give a task more caps than its
parent has, but as explained, kdbus addresses that by dropping the
capability information from the metadata if the sender and the receiver
are in different user namespaces.

> Those other things are probably okay. I actually tried setcap
> cap_sys_boot=eip dbus-send, and I still couldn't make systemctl reboot
> work in an ssh session. In my book, that's a good thing.

Note that with kdbus, this will actually succeed, just as reboot(2)
called from a binary that has cap_sys_boot=eip succeeds.

We really don't insist in anything here, but we'd like to get a precise
technical reason of why you think this is an issue, with an example of
how current kdbus could be exploited.


Thanks,
Daniel

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/