dbus2 / zbus

Rust D-Bus crate.
Other
316 stars 70 forks source link

🐛 zbus: Fix deadlock during name registration #867

Closed dvrabel-ntnx closed 6 days ago

dvrabel-ntnx commented 1 week ago

When registering a name, zbus will deadlock if it receives many messages before the RequestName reply. This occurs because:

  1. The RequestName() call means the dbus server can send messages for that name before it sends the RequestName() reply.

  2. While name registration is in progress the registered names lock is held.

  3. These messages are queued on a sender channel.

  4. The queued messages are not dispatched because the object server task blocks waiting for the registered names lock (see 2 above).

  5. This sender channel can become full, blocking the receiver task when it attempts to enqueue on a full channel.

  6. If the receiver task blocks it does not receive the RequestName() reply and name registration.

  7. Since name registration never completes the registered names lock is never released, none of the pending messages are dispatched, the sender remains full and the receiver never receives any more messages.

This deadlock is most likely to occur if the dbus service is a dbus-activated systemd service. The dbus server will hold calls while the service is starting, releasing them when RequestName() is called but before the RequestName() reply is sent.

Avoid this deadlock by not attempting to take the registered names lock in the object server task. The check that the destination is a registered name is unnecessary as the dbus server will not send messages for unregistered names.

This allows the object server to dispatch messages while name registration is in progress so the sender does not become full and thus the receiver does not block.