Re: kdbus: credential faking

From: Casey Schaufler
Date: Fri Jul 10 2015 - 12:00:01 EST


On 7/10/2015 6:43 AM, David Herrmann wrote:
> Hi
>
> On Fri, Jul 10, 2015 at 3:25 PM, Stephen Smalley <sds@xxxxxxxxxxxxx> wrote:
>> On 07/09/2015 06:22 PM, David Herrmann wrote:
>>> To be clear, faking metadata has one use-case, and one use-case only:
>>> dbus1 compatibility
>>>
>>> In dbus1, clients connect to a unix-socket placed in the file-system
>>> hierarchy. To avoid breaking ABI for old clients, we support a
>>> unix-kdbus proxy. This proxy is called systemd-bus-proxyd. It is
>>> spawned once for each bus we proxy and simply remarshals messages from
>>> the client to kdbus and vice versa.
>> Is this truly necessary? Can't the distributions just update the client
>> side libraries to use kdbus if enabled and be done with it? Doesn't
>> this proxy undo many of the benefits of using kdbus in the first place?
> We need binary compatibility to dbus1. There're millions of
> applications and language bindings with dbus1 compiled in, which we
> cannot suddenly break.

Rubbish. That's like saying that systemd has to support starting
services from /etc/rc.d, or that the python runtime has to execute
perl scripts. If kdbus is better (or even just cooler or more popular)
the change over will be swift and painless. The *only* reason that
won't be true is if the benefits of kdbus are unclear, in which case
it shouldn't be adopted.

Also, I serious doubt your "millions" number. You might want to
try getting an credible estimate of the impact before using it as
an argument.

>
>>> With dbus1, clients can ask the dbus-daemon for the seclabel of a peer
>>> they talk to. They're free to use this information for any purpose. On
>>> kdbus, we want to be compatible to dbus-daemon. Therefore, if a native
>>> client queries kdbus for the seclabel of a peer behind a proxy, we
>>> want that query to return the actual seclabel of the peer, not the
>>> seclabel of the proxy. Same applies to PIDS and CREDS.
>>>
>>> This faked metadata is never used by the kernel for any security
>>> decisions. It's sole purpose is to return them if a native kdbus
>>> client queries another peer. Furthermore, this information is never
>>> transmitted as send-time metadata (as it is, in no way, send-time
>>> metadata), but only if you explicitly query the connection-time
>>> metadata of a peer (KDBUS_CMD_CONN_INFO).
>> I guess I don't understand the difference. Is there a separate facility
>> for obtaining the send-time metadata that is not subject to credential
>> faking?
> Each message carries metadata of the sender, that was collected at the
> time of _SEND_. This metadata cannot be faked.
> Additionally (for introspection and dbus1 compat), kdbus allows peers
> to query metadata of other peers, that were collected at the time of
> _CONNECT_. Privileged peers can provide faked _connection_ metadata,
> which has the side-effect of suppressing send-time metadata.
> It is up to the receiver to request connection-metadata if a message
> did not carry send-time metadata. We do this, currently, only to
> support legacy dbus1 clients which do not support send-time metadata.
>
>>> Regarding requiring CAP_SYS_ADMIN, I don't really see the point. In
>>> the kdbus security model, if you don't trust the bus-creator, you
>>> should not connect to the bus. A bus-creator can bypass kdbus
>>> policies, sniff on any transmission and modify bus behavior. It just
>>> seems logical to bind faked-metadata to the same privilege. However, I
>>> also have no strong feeling about that, if you place valid points. So
>>> please elaborate.
>>> But, please be aware that if we require privileges to fake metadata,
>>> then you need to have such privileges to provide a dbus1 proxy for
>>> your native bus on kdbus. In other words, users are able to create
>>> session/user buses, but they need CAP_SYS_ADMIN to spawn the dbus1
>>> proxy. This will have the net-effect of us requiring to run the proxy
>>> as root (which, I think, is worse than allowing bus-owners to fake
>>> _connection_ metadata).
>> Applications have a reasonable expectation that credentials supplied by
>> the kernel for a peer are trustworthy. Allowing unprivileged users to
>> forge arbitrary credentials and pids seems fraught with peril. You say
>> that one should never connect to a bus if you do not trust its creator.
>> What mechanisms are provided to allow me to determine whether I trust
>> the bus creator before connecting? Are those mechanisms automatically
>> employed by default?
> Regarding the default security model (uid based), each bus is prefixed
> by the uid of the bus-owner. This is enforced by the kernel. Hence, a
> process cannot 'accidentally' connect to a bus of a user they don't
> trust.

Wow. Are you really convinced by that argument? It's like saying that
you know what service is active on a port because you looked in
/etc/services. There are so many ways uids are being (miss/ab)used
on Linux systems these days that the idea of trusting a bus just
because its non-root uid is listed in a table somewhere (or worse,
coded in an API) is asking for exploits.

>
> Thanks
> David
>

--
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/