Passing FDs to activatable service

Ernestas Kulik ernestas.kulik at gmail.com
Fri Mar 15 14:01:08 UTC 2019


On Thu, 2019-03-14 at 12:32 +0000, Simon McVittie wrote:
> 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?

Looks like I didn’t mention a couple other things: I don’t see this
issue when doing session (reportd) <-> system (abrt-dbus), and system
<-> system results in dropped FDs even after activation (but, again,
not if I pop a root shell and run abrt-dbus there), so surely it can’t
be hitting the same code path all the time?

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

AFAIK, it’s dbus-broker in Fedora, but it happens with both? I tried
disabling one and enabling the other in systemd, so not sure if that
counts as switching between them.

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

Thanks for the advice. I tried implementing a dummy service and client,
but I can’t reproduce the issue with those, so I’m going crazy thinking
that something is wrong with either reportd or abrt-dbus, but I can’t
imagine what.

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

That’s what it did originally, but I thought it smart to reduce the
number of round-trips. No problem, though.

> 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