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

Thiago Macieira thiago at kde.org
Wed Nov 26 10:04:22 PST 2014


On Wednesday 26 November 2014 12:27:16 Lennart Poettering wrote:
> > Please also note that the autostart solution has a valid use-case which is
> > when a D-Bus application is launched in an environment where no bus had
> > been started before. I understand this is out-of-scope for kdbus, since
> > after all a regular user won't be able to create a kdbus bus if one
> > wasn't provided by a privileged process before. In an environment where a
> > kdbus bus wasn't provided, the only alternative is to fallback to dbus1.
> 
> Hmm? Creating busses requires no privileges. Users create their own
> busses without requiring any kind of privilege for that.

How is that secure? That would imply that any process, with any UID, can issue 
KDBUS_CMD_BUS_MAKE for a bus name that another UID would expect to use.

I must be misunderstanding something.

> My recommendation for StartServiceByName() is to convert it into a
> Ping() method call to the respective service and wait for it to
> return. This is at least what the compat proxy does.

Hmm... I had forgotten about Ping(). That sounds like a solution.

> > It would be nice if UpdateActivationEnvironment worked. This functionality
> > was added for people who need to update variables like XDG_DATA_DIRS
> > after starting the bus. If this one isn't present, we can report "not
> > implemented" and be fine with it. We'll just have to tell people to
> > configure their systemd user session environments properly.
> > 
> > The same goes for ReloadConfig, but I'd prefer to know whether that failed
> > (no config reloading is possible) or whether it happens automatically
> > whether the call was made or not. ReloadConfig is important when there
> > are new activatable services on a user's bus, such as newly-installed
> > applications.
> 
> If you really want to support this, then call into systemd for it, and
> make it graceful to support non-systemd systems. Return a notsupported
> error if the systemd service is not reachable.

Well, that's exactly what I want, but see below.

> > > Note that on dbus1 systemd systems we actually never provided
> > > UpdateActivationEnvironment correctly (since services got forked off
> > > PID 1, instead of dbus-daemon but the call would alter dbus-daemon's
> > > env block, not systemd's one), but nobody ever noticed. I really
> > > think you should just return some "not supported" error or make it a
> > > NOP if you don't want to pass this on to systemd.
> > 
> > I *want* to pass this to systemd, somehow. So the first question is
> > whether we can expect there to be a connection by systemd in the buses it
> > creates. On the system bus, there's org.freedesktop.systemd1 so I expect
> > that to continue. Can we expect a similar service on systemd-user buses?
> 
> Yes. systemd creates the bus and then acquires
> org.freedesktop.systemd1 on it, and does this for both the system and
> the user bus the same way.

My argument was for a more generic name, such as something in the 
org.freedesktop.DBus hierarchy. That way, if someone else wants to provide 
kdbus-powered buses, they'd implement that interface instead of trying to 
emulate systemd and playing catch-up and possibly bug compatibility.

Further, if it does acquire the org.freedesktop.DBus name itself, libraries 
won't have to emulate most of the compat behaviour by intercepting outgoing 
messages. Intercepting means EVERY message needs to be inspected at one point 
or another, instead of letting it fallback when the call actually happens. In 
other words, providing a fallback service optimises for the right use-case.

Since systemd will connect to the bus anyway and will acquire a name, it can 
acquire another.

> > > When creating the bus the creator can pass policy to the kernel so
> > > that there is no time window where the bus is accessible and open to
> > > manipulation from untrusted clients.
> > 
> > How can you update the policies then?
> 
> There's an ioctl for that too, that the creator can then call on the
> fd it has open.

I guess I got confused by the wording of what you can do with what file 
descriptors. I was under the impression that you'd need three file descriptors 
for a bus or an endpoint to make any useful use

 1) one fd that opened the "control" file (to create a bus) or to the bus (to 
create the endpoint)
 2) one fd that you'll want to open the bus/endpoint on so you can later send 
updates to the policies
 3) one fd to actually do talking on

My confusion was that the doc says that after CMD_xxx_MAKE the file descriptor 
can't be used again. 5.3 says "... is file descriptor will manage the newly 
created endpoint resource. It cannot be used to manage further resources." I 
guess I read "further resources" as including changing policies on this 
bus/endpoint.

Thanks for the clarification. I recommend adding a section on what steps to do 
to create a bus (including setting up policies, activators), one on creating 
an endpoint, and then one on how a controlling process should operate to 
manage the bus/endpoint properly.

> > > What's the usecase?
> > > 
> > > I mean you can fake p2p connections by allocating a bus and only
> > > connecting two peers to it (busses are relatively cheap now), but I am
> > > not sure why.
> > 
> > Because kdbus has a few extra advantages that sockets don't, like the
> > zero- or single-copy from process to process. And because we can: if the
> > necessary delta to support P2P is minimal, just a convention, then it's
> > more practical to keep everything centralised than to have an AF_UNIX
> > socket handler and a kdbus fd parser.
> 
> Well, but in those cases you can just use the user bus or system bus,
> there's no need to create a new bus just for the purpose of P2P...

That implies changes to the user application. I want to provide a replacement 
API for DBusServer.

> 
> > > Well, I doubt the usecase for direct links.
> > > 
> > > I mean, the reasons for peer-to-peer links I am aware of are:
> > > 
> > > a) performance
> > > b) network transparency
> > > c) IPC before dbus-daemon is around
> > > 
> > > a) and c) don't apply on kdbus anymore. And kdbus is inherently not a
> > > network transport, hence you have to use AF_INET there anyway.
> > 
> > Plus d) connection between processes of different privileges (e.g.,
> > different UIDs)
> 
> Why not use the regular system bus for that?

Because if both processes are unprivileged, neither can own a name in the 
system bus nor send messages to each other.

> > Correct me if I'm wrong, but doesn't the kernel impose a per-UID limit on
> > the number of FDs open?
> 
> To my knowledge only one per-process.

There's a system-wide limit, but it's much higher. Ok, so there doesn't seem 
to be a problem here.

> > For non-activatable services, any unhandled calls will get
> > KDBUS_ITEM_REPLY_DEAD sent back to the sender. The only difference from
> > what I was asking is timing: with a KDBUS_CMD_SHUTDOWN, the error
> > condition would come as soon as the message was sent, as opposed to when
> > the receiver closed the fd. I don't think that is a problem.
> 
> But does that timing fix anything? I don't see any race that was fixed
> by such differen behaviour.

I don't think that the timing change makes a difference to anyone.

> > 11.2 Wildcard names
> > 
> > "Policy holder connections may upload names that contain the wildcard
> > suffix (".*"). That way, a policy can be uploaded that is effective for
> > every well-kwown name that extends the provided name by exactly one more
> > level."
> > 
> > As I said, I kind of expect that the normal case is that the policy
> > applies to the entire tree, not just one more level.
> 
> Ah, OK, no I get the context!
> 
> So, dbus1 policy had this concept (see "own_prefix" in the man page)
> and we deemed it to actually be a useful one, given that this opens up
> using names as the synchronization primitive they are.
> 
> I think the reason to limit this to one label only is to keep a clear
> distinction between what is namespace and what is instance. And
> ensuring the instance is just the last label (for whatever you encode
> into it) and the other labels are namespace...
> 
> In general it is always easy to be strict initially and then open
> things up further when there's a strong usecase for it, rather than
> the other way round.

Fair enough. I guess that, if needed, you'll make the "full hierarchy" 
wildcard a double asterisk, e.g. "org.example.**".

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