[systemd-devel] SD_BUS_VTABLE_CAPABILITY

Tom Gundersen teg at jklm.no
Thu Apr 16 03:23:00 PDT 2015


Hi Andy,

On Thu, Apr 16, 2015 at 2:55 AM, Andy Lutomirski <luto at amacapital.net> wrote:
> Yesterday, I discovered SD_BUS_VTABLE_CAPABILITY.  Are there any
> examples in which it does anything?

Please note that you need to be using kdbus to get any capabilities
transported, so in dbus1 this does nothing (as on dbus1 using
capabilities would be racy). Are you testing this on kdbus?

> If so, I don't suppose any of you
> could give me an example of:
>
> $ cp `which dbus-send` .
> $ sudo setcap all=eip dbus-send
> $ dbus-send [not sure what goes here]
>
> that passes an authentication test that would have failed without the setcap?

Note that dbus-send is the old dbus1 command, and will always go via
the bus proxy that connects dbus1 clients to kdbus. As such, it will
only carry the credentials that are available safely on dbus1, and
hence not capabilities. So even if you do use kdbus on your machine,
this example would not work.

To be clear, the reason we do not use the capability logic on dbus1,
but only on kdbus is as follows: On kdbus, the capabilities are
attached to the method call itself, hence we safely know that at the
time the method call was issued by the client side, that client
actually really had those capabilities. On dbus1 however, which uses
AF_UNIX/SOCK_STREAM, this is not possible: we only get the
UID/GID/PID, hence we could only derive the caps from
/proc/$PID/status. But this opens this up for a vulnerability: if a
client quickly issues a method call, and then exec()s a suid binary,
it could happen that the service side would read the capabilities from
that SUID process, and not the original process, and the exploit was
successful. We cannot allow that, hence no capabilities on dbus1,
instead we open up things to a much, much broader uid == 0. kdbus
allows us to be much stricter there, by allowing us to check only one
specific capability.

An equivalent example to the one you gave using native kdbus would be:

$ cp `which busctl` .
$ sudo setcap all=eip busctl
$ ./busctl call org.freedesktop.timedate1 /org/freedesktop/timedate1
org.freedesktop.timedate1 SetTimezone "sb" Europe/London 0

> In the interest of full disclosure, I'm asking because I think that
> one of two things is true:
>
> 1. The SD_BUS_VTABLE_CAPABILITY code is useless and should therefore be deleted.

This is not the case.

> 2. The SD_BUS_VTABLE_CAPABILITY code is exploitably buggy and should
> therefore be deleted.

I have heard this claim from you many times, but so far I haven't been
able to figure out what you have in mind. Could you either give an
example of an exploit or at least the general scheme you have in mind?

Cheers,

Tom


More information about the systemd-devel mailing list