Starting the kdbus discussions

Simon McVittie simon.mcvittie at collabora.co.uk
Mon Jan 6 03:18:10 PST 2014


On 03/01/14 22:58, Lennart Poettering wrote:
> On Fri, 03.01.14 19:55, Simon McVittie (simon.mcvittie at collabora.co.uk) wrote:
> 
>> This discusses "simple types" and "trivial types". D-Bus has no such
>> things: as far as I can tell, your "trivial types" are our "fixed types"
>> (all the numbers including 'y' and 'b', plus the fd type 'h'), and your
>> "simple types" are our "basic types" (fixed types, plus the string-like
>> types 'g', 'o' and 's').
>>
>> If your use of different terminology is accidental, please rename; if
>> it's deliberate, please define your terms (perhaps in terms of the ones
>> in D-Bus, or by copying text from the D-Bus Specification).
> 
> It's only half accidental. I tried to stay away from the term "fixed
> type", since in GVariant "fixed size" types cover more than "fixed"
> types in dbus1, and I didn't want to create more confusion between the
> two. (Less confusion by sloppy terminology, eh? ;-)). In gvariant
> structs of of numbers are fixed size too, and so are structs of strutcs
> of numbers and so on...)

Right, we may have been over-simplifying by calling them "fixed types":
more formally, they should be "fixed-size basic types". Structs
containing only fixed-size basic types are also fixed-size in
traditional D-Bus (if you ignore padding, which I consider to be more
like "wasted space before the next serialized value" than part of the
value itself), but they aren't basic (structs are containers, the
antonym of basic types).

The spec has only referred to fixed types since 2011, so I'd be happy to
review a patch renaming that concept to "trivial types". That would make
the type hierarchy into:

* basic
  * trivial
    * int16, uint32, handle, etc.
  * string-like
    * string
    * object path
    * signature
* container
  * array
  * struct
  * variant
  * maybe    (GVariant extension)

I'd rather keep the name "basic type" rather than renaming it to "simple
type", since that's been in the spec since at least 2005, and isn't
misleading like "fixed" is.

>> (These instructions for how to form the bloom filter are part of the
>> kernel: transport for D-Bus, not part of the underlying kernel
>> functionality, right? The kernel doesn't care?)
> 
> The kernel doesn't care about the bloom filter much. The identifier is
> called "bloom", but other than that the kernel doesn't know much about
> the contents of the match mask or the message filters

That makes sense. OK, so to the kdbus kernel module it's just opaque
data, and it's the D-Bus kernel: transport that defines semantics. (I
think it's worth distinguishing between the two.)

>>> To install matches for broadcast messages, use the KDBUS_CMD_ADD_MATCH
>>> ioctl
>> [...]
>>> To match against other user messages add a KDBUS_ITEM_BLOOM item in
>>> the match (see above).
>>
>> Does this mean that eavesdropping (receiving unicast messages intended
>> for a different recipient) is explicitly part of the kdbus API? This
>> is
> 
> Note that the bloom stuff applies exclusively to broadcast
> messages. Installing a bloom filter for unicast messages will yield no
> results. This is because clients sending messages will not calculate and
> attach the bloom filters for unicast messages, so there's nothing to
> match again.

Sorry, I'm confused. The text I quoted says you use KDBUS_CMD_ADD_MATCH
to match broadcasts, or KDBUS_ITEM_BLOOM to match "other user messages".
What other messages?

Re-reading it: OK, I think I see what's going on there, it just wasn't
immediately clear: you use KDBUS_CMD_ADD_MATCH to add a match rule for
broadcasts, and one of the many possible fields in the kdbus equivalent
of a dbus-1 "match rule" is KDBUS_ITEM_BLOOM, which is "match by any
criteria that are too complicated or general to have their own
KDBUS_ITEM_*".

> For eavesdropping we have a completely seperate connection
> type. Connections to the bus of type "monitor" won't get a unique id,
> and won't be able to send messages. However, they will get *all* unique
> messages, and optionally the broadcast messages too, if they also
> install a bloom filter.
> 
> Creating monitor connections requires privs in kdbus.

Great, that makes more sense.

>>> With $UID replaced by the callers numer user ID, and $XDG_RUNTIME_DIR
>>> following the XDG basedir spec.
>>
>> When substituting XDG_RUNTIME_DIR into a D-Bus address, it must be
>> escaped. (As an implementation detail, I think systemd only generates
>> values for XDG_RUNTIME_DIR where the escaped version equals the
>> unescaped version - but that isn't true in general, since it's a
>> user-controlled environment variable.)
> 
> Our own "libsystemd-bus" does that already.

Good; but when documenting this stuff, please mention that, so that
other implementations (GDBus, dbus, etc.) can interop.

>>> To additionally check against sender
>>> names, use the KDBUS_ITEM_ID (for unique id matches) and
>>> KDBUS_ITEM_NAME (for well-known name matches) item types.
>>
>> Does this actually match how dbus match rules for well-known names work?
> 
> What I wrote above was about NameOwnerChanged, which dbus-daemon only
> generates when the real owner changes ownership. You will not get it for
> queued names. The spec doesn't really clarify that, but I am pretty sure
> that would be quite useless, if it sent them out just for queuing too...

Ah, right. Yes, you only see NameOwnerChanged when the "primary owner"
changes.

My concern about the semantics of matching a queued sender/recipient in
an AddMatch might still apply to your ADD_MATCH, but not to your
NameOwnerChanged replacement.

> This is actually a good point you raise. For the bus proxy I have been
> forth and back over this, i.e. when we forward a message from the proxy
> whether we should override the sender for it, and make sure the unique
> name is replaced with the well-known name in it. I have changed this
> around and back a couple of times. Currently we leave the unique id in,
> and everything i tested works fine, including gdbus for its own internal
> messages to the driver.

In current D-Bus, messages that are forwarded through dbus-daemon are
unconditionally rewritten to contain the *unique* name of the sender
(e.g. :1.42), regardless of whether the original message had the unique
name, a correct well-known name, a spoofed well-known name, or no sender
field at all. For messages from the dbus-daemon itself - either signals
or replies - we put "org.freedesktop.DBus" in the sender (this is one of
the ways in which o.fd.DBus behaves like a unique name, even though it's
syntactically a well-known name).

I would much prefer it if your proxy/bridge guaranteed to do the same:
you're taking a performance hit to remarshal the message anyway, so you
might as well make sure to be 100% compatible, and not have to worry
about which implementations check this and under what circumstances.

I'm aware of several Telepathy applications that rely on method calls
having an application's unique name as sender, and a dbus-glib security
fix (CVE-2013-0292) that relies on NameOwnerChanged having o.fd.DBus as
sender. I'm not sure about method responses, but to be honest it's
better to do what dbus-daemon does and not have to worry about it.

The other context in which o.fd.DBus is special is when you ask the bus
driver about it via method calls: for instance,
GetNameOwner("org.freedesktop.DBus") == "org.freedesktop.DBus", just
like a unique name.

    S



More information about the dbus mailing list