Passing FDs to activatable service

Simon McVittie smcv at collabora.com
Thu Mar 14 12:32:59 UTC 2019


On Thu, 14 Mar 2019 at 10:08:08 +0100, Ernestas Kulik wrote:
> All those things work as one would expect, except for one particular
> case - running reportd as root, letting it activate abrt-dbus and
> calling SaveElements with a bunch of FDs (it makes sure to not go over
> 16). abrt-dbus receives the message with the UNIX_FDS header set
> accordingly, but the actual FDs never seem to arrive.

D-Bus activation goes on a slightly weird code path: instead of being
able to deliver the message directly to abrt-dbus in its proper sequence,
the message bus has to start abrt-dbus, and put the message in a data
structure. When it sees abrt-dbus request its well-known bus name,
the message bus has to remember that it had a message put aside for
abrt-dbus, retrieve it and re-attempt delivery. It's possible that the
attached fds get lost somewhere along the way?

If they do, I would consider that to be bug in whatever message bus
implementation you're using (usually dbus-daemon, but maybe dbus-broker;
if in doubt ask your OS integrator).

If it's dbus-daemon, a regression test to dbus that demonstrates this bug
would be very helpful. test/sd-activation.c would probably be the best
starting point. Even if you don't have any particular interest in systemd,
I've found that a mock implementation of systemd activation is easier to
set up in a test than traditional activation, because the test can "talk
to itself" and pretend to be all of: the client, the activatable service,
and systemd.

If you're able to change your D-Bus API, you could maybe work around this
by sending a message without fds to activate abrt-dbus and establish an
object representing a session, then sending the fds by calling methods on
that session object in an abrt-dbus that is already running?

That would also have the advantage that the message bus doesn't have to
keep those fds held open for a long time (up to 25 seconds by default)
while it waits for abrt-dbus to start.

> it makes sure to not go over 16

Because fds have traditionally been a very limited resource (1K, 4K or
64K per process, and a few tens or hundreds of thousands for the entire
system) and it's difficult to avoid denial-of-service-prone situations
when doing fd-passing through an intermediary like the D-Bus message
bus, it's possible that we might have to reduce the default for the
arbitrary limit on fds per message in a future dbus release. If you have
an arbitrary number of fds to send and you are already splitting them
into arbitrary batches, it would be more conservative to use batches of
size 1, i.e. send each one in a separate message.

systemd >= 240 raises the hard fd limit by several orders of magnitude,
but not everyone uses systemd, and not everyone who uses systemd has
this version.

Regards,
    smcv


More information about the dbus mailing list