Skip to content
David Rheinsberg edited this page Jan 10, 2024 · 16 revisions

While dbus-broker aims to keep perfect compatibility to existing D-Bus implementations, the D-Bus specification, as well as the reference implementation, there are several occasions where it deviates. Usually, the reason behind those deviations is to mitigate possible attacks, or to improve performance. The complete list of known deviations is as follows:

  • Reply Policies: While the reference-implementation supports applying D-Bus policies to method-returns, as well as filtering on whether a reply is expected or not, dbus-broker does not support this. Specifically, dbus-broker only allows expected replies, and those are allowed unconditionally. Unexpected-replies and Reply-filtering have no known users (nor use-cases), hence support has been dropped. Note that in the case of SELinux, this means that it is sufficient to grant access in one direction (to send a method call), and the reverse (to send the reply) is implicit. This avoids overly broad permissions.

  • at_console Policies: D-Bus policies in the at_console=true context behave differently. The reference implementation selects the context based on sd_uid_get_seats(3) returning greater than zero. This has the effect that a connection is considered at-console for its lifetime if, and only if, at its time of connect there was a session on this machine, which had a seat assigned and was owned by the same UID. In many cases it has the wanted effect, but is not equivalent to the desired effect of checking whether the connection is currently part of the active session of the targeted seat. Hence, dbus-broker reduces the complexity of this implementation by considered a user at-console if, and only if, they has a UID higher than SYSTEMUIDMAX as provided by systemd. Additionally, we allow specific system users to be specified at compile time, which should also be considered at-console.

  • Eavesdropping: The concept of eavesdropping has been deprecated in favor of monitoring upstream, though the reference implementation still implements both. For the time being eavesdropping is not implemented in dbus-broker.

  • Destination matches: A monitor may install matches filtering on a given destination. However, monitoring is performed at the time of send, whereas the matching on a destination can only be performed at the time of receive. The reason for this is that in order to be consistent, matching must use all the names owned by the receiving peer at the time of receive, not only the destination specified in the message. Usually send and receive are conceptually simultaneous, but in the case of service activation they are not. The reference implementation solve this by silently dropping messages, instead, we treat any match specifying a destination filter as if the destination filter had not been there, i.e., as if it were a wildcard. This means we err on the side of delivering unexpected messages, rather than dropping expected ones.

  • Recursive FD Passing: The linux kernel allows queuing a socket on itself. If a client passes a message with its own end of the Unix-Domain-Socket as payload, the message will keep the client alive, even if the original client exits and closes its FDs. As such, if the message is directed at itself, there will be no way of disconnecting that client. While dbus-daemon applies timeouts to pending messages (and thus disconnects some of those clients after 120s), dbus-broker does not cleanup such clients. Instead, dbus-broker allows such clients to "pin themselves" if they wish to, relying on its resource accounting to make sure this cannot be exploited.

  • Direct Activation: Historically, all activated services were forked and exec'ed by the respective bus implementation. With the introduction of systemd, activated service could opt-in to be run executed by systemd as a systemd service instead. With dbus-broker, direct activation is no longer supported, rather all activation requests are forwarded to systemd. In case no systemd service has been configured for a given dbus service, a TransientUnit is generated and used instead.

  • Capture Sender State for Activation: When an activated name is acquired, forwarding pending messages to it depends on the state of the original sender, both the policy applied to the sender, and the names it owns. This determines both whether or not the message should be transmitted at all, but also which eavesdroppers should receive a copy of the message. The dbus-broker captures the state (policy and names) of the sending peer at send time, and uses this state at the time of activation. The alternative would be to use the state of the sender at activation, but that would mean that changes a peer makes to its own state (such as dropping or acquiring names), after sending a message, may affect the delivery of the message, and in the worst case, if the sender has disconnected by the time the receiver is activated the message would have to be unconditionally dropped. Intuitively, what this all means is that policy decisions and eavesdropping is performed based on the state of the sender at send, and the receiver at receive. Except for the case of activation, send and receive occurs simultaneously.

  • Usernames in SASL: We require UIDs as identification in SASL, in case clients opt-in (clients can always provide an empty identification on AF_UNIX). We reject user-names, unlike dbus-daemon, which accepts them. We are unaware of any application using this feature. To avoid runtime NSS requests, we do not implement this feature.

  • Self-activating Services: The provided compatibility launcher supports service files that have no activation-method specified. In those cases, activation requests on these services will rely on the service activating itself via other means (in most cases you would use this for services that show up unconditionally, like systemd1). This deviates from dbus-daemon, which would refuse such service files.