[systemd-devel] Compatibility between D-Bus and kdbus

Thiago Macieira thiago at kde.org
Tue Nov 25 18:46:26 PST 2014


On Wednesday 26 November 2014 00:46:50 David Herrmann wrote:
> We had "systemd-bus-driverd", which implemented org.freedesktop.DBus
> as normal service. However, this didn't work out as many dbus clients
> rely on this services to not be re-ordered in regard to external
> requests.
> 
> In particular, if gdbus runs AddMatch(), it assumes the match takes
> effect immediately. If it sends a method call to another service after
> installing the match, and this triggers a signal, gdbus assumes the
> AddMatch() call to have succeeded (without waiting for the reply).
> However, if org.freedesktop.DBus is not implemented by the bus, but by
> an external service, you cannot guarantee that messages targetted at
> different receivers don't get re-ordered, and there're no guarantees
> which process gets scheduled first.
> 
> This is a real bug and we couldn't figure out a way to fix it. Current
> DBus applications depend on org.freedesktop.DBus to be handled by the
> bus entity _in-order_. Therefore, we dropped systemd-bus-driverd and
> all the kdbus ioctls that we added to support this.

Aside from the connection-control mechanisms (AddMatch, RemoveMatch), did you 
see any problems?

User code usually shouldn't be doing AddMatch and RemoveMatch (the only case I 
can think of is dconf, which does its own parsing of the message payload). 
That's the domain of the binding, which will know that it connected to kdbus 
and won't be making those calls.

As I said in the reply to Lennart, I'm specifically looking for 
StartServiceByName. Everything else is emulatable anyway or nonsense in kdbus.

> > By the way, is there a way to ensure that a given connection is the first
> > connection? As soon as the bus creator is able to connect to the
> > /sys/fs/kdbus path, so is another process and therefore this other
> > process could maliciously acquire names it shouldn't.
> 
> Acquiring names requires matching policies. If you setup your policies
> in a way that two applications can acquire the same name, you're doing
> something wrong. Or maybe I don't understand your use-case?

No, it was my misunderstanding. The endpoint creator should set up a policy so 
that it itself can acquire the name(s) it needs, then deny any other 
connections owning names or TALKing to each other. This effectively creates a 
many-to-one bus system. E.g., a fake P2P.

> > Ok, so any application that connected to the "bus" bus can then create
> > custom endpoints. Correct?
> 
> No, custom endpoints can only be created by privileged users. On the
> system-bus, this means root, on the user-bus this means processes of
> the user itself.

Sorry, I meant application connected to the a user's "bus" bus. Like you said, 
that means any application with the same UID, which means all applications 
that were allowed to connect to "bus" in the first place.

> kdbus implements bus-based IPC. If you want P2P IPC, use one of the
> established transports.
> 
> Yes, kdbus has some handy features people like to see on unix-sockets
> (like flexible metadata transports), but our current policy is "fix
> unix sockets!", and "this can optionally be implemented later on".
> There is no plan to support P2P connections in the initial kdbus
> draft.

I'm not asking for much more for P2P connections in kdbus. I think that it's 
already doable by restricting an endpoint to a many-to-one system.

> Custom endpoints do _not_ create new buses. Really. You could create a
> custom bus and use it for just 2 connections, but then you could also
> just use socketpair(2). Note that there was some discussion on
> "anonymous buses", which would allow to create such buses on the fly.
> But again, this will not be part of the initial kdbus draft. If anyone
> cares, submit it as patches once kdbus is upstream.

As far as I can tell, an "anonymous bus" in the sense of a bus with a 
randomised name is doable by having the proper interface in the systemd1 
system bus service. An application would request the bus and receive as a 
reply the address of the bus, the file descriptor for the control, and a file 
descriptor to a privileged connection so it can control the policies.

This does not require kernel-side modifications, only in systemd.

> > Understood, but coming from userspace's perspective this seems ill-advised
> > and optimising for the wrong use-case. The common case is that syscalls
> > are not interrupted: with a timeout, there's one clock_gettime() call
> > *after* the interruption if any; with the timestamp, there's always one
> > before the syscall.
> 
> Use clock_gettime(CLOCK_MONOTONIC_COARSE). This reads the time from
> the VDSO, which is a simple memory read. No trap/syscall is involved.
> Downside is that you loose precision, but that should really be fine
> for this use-case.

I need to read a little more on the coarse monotonic clock to see what cases 
it's applicable for and when you should avoid it.

In this specific case, precision is not required, as a 25-second timeout is 
really long. Currently, QtDBus on dbus1 may get that wrong for as much as one 
full second (less than 5% error).
-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358



More information about the systemd-devel mailing list