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=truecontext 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-consolefor 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-consoleif, and only if, they has a UID higher than
SYSTEMUIDMAXas provided by systemd. Additionally, we allow specific system users to be specified at compile time, which should also be considered
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
receievare 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.
Directory watching: We never use
inotifyand friends to watch file activity, unlike dbus-daemon. We require an explicit reload request to re-fetch the service configurations.
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.