Re: kdbus: credential faking

From: David Herrmann
Date: Fri Jul 10 2015 - 12:48:14 EST


Hi

On Fri, Jul 10, 2015 at 4:47 PM, Stephen Smalley <sds@xxxxxxxxxxxxx> wrote:
> On 07/10/2015 09:43 AM, David Herrmann wrote:
>> On Fri, Jul 10, 2015 at 3:25 PM, Stephen Smalley <sds@xxxxxxxxxxxxx> wrote:
>>> On 07/09/2015 06:22 PM, David Herrmann wrote:
>>>> 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.
>
> So the "privileged" peer (which just means the bus owner, which can be
> completely unprivileged from a typical DAC perspective) can both prevent
> the receiver from getting the (real, unfakeable) send-time metadata and
> supply arbitrary fake credentials for the connection metadata? And the

(Limited to PIDS/CREDS/SECLABEL metadata, but) yes.

Note that this is all under the assumption that you never connect to a
bus owned by someone else but you or root. Hence, a peer can only fake
metadata, if it can also ptrace you.

> legacy dbus1 clients (i.e. all current DBUS applications?) will always
> use this potentially faked metadata. Meanwhile, what about new dbus
> clients? What is the standard behavior for them when the send-time
> metadata is suppressed? Do they always fall back to the connection
> metadata?

This is a decision user-space has to make. In sd-bus, if we trust the
bus (root owned, or our own), we always fall back to connection
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.
>
> And how do they go about looking up / obtaining the destination bus name
> in the first place? At what point would they in fact do any validation
> that the uid prefix of the bus is what they expect?

To connect to your user-bus, you open:
/sys/fs/kdbus/1000-user/bus
(replacing '1000' by getuid(2))

To connect to the system-bus, you open:
/sys/fs/kdbus/0-system/bus

In both cases, you trust the uid, as it's either root or yourself.
Exact same logic applies if you open the dbus1 unix-sockets. You
simply open /run/user/1000/bus (or /run/dbus/system_bus_socket).

I don't see a reason why you'd ever connect to a bus of another user.
If you want to talk to another user, you should use a channel both of
you trust, that is, a system bus.

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/