Comment 13 for bug 75602

Revision history for this message
In , Simon McVittie (smcv) wrote :

From that mail:
> The solution is a bit hairy, because it does require a changed kernel
> (at least I haven't found any other way to test the group of another
> process efficiently).

There's also an interesting attack based on a race condition, if dbus-daemon performs access control by asking the kernel for a process's credentials by pid:

* attacker has (say) uid 1001, gid 11111 and pid 12345

* attacker sends a D-Bus message which is only allowed for group 22222
  (or for uid 0, for that matter)

* [race] attacker immediately uses exec() to replace itself with any
  setuid-0 or setgid-22222 binary

* [race] dbus-daemon asks the kernel "what is the gid of pid 12345?"
  (or for the uid 0 case, "what is the uid of pid 12345?"

* if the dbus-daemon wins the race, the kernel replies "11111"
  (or 1001) and permission is denied

* if the attacker wins the race, the kernel replies "22222" (or 0)
  and permission is granted!

... so, don't do that.

For local Unix sockets on Linux, the credentials exchange step at the beginning of the connection means that dbus-daemon can validate the connection's uid, pid and one of its groups - but there's no way to get the other groups, unless the connecting process sends one message per group. This would require modifications to dbus-daemon and all client libraries wishing to use this mechanism (libdbus, QtDBus, GDBus, etc.), and wouldn't work for non-local connections, or on platforms where this credentials-passing doesn't work.

A new syscall of the form "what are the uid, gid and all supplementary groups at the other end of this socket?" or "does the other end of this socket have these credentials?" would also solve this, albeit in a completely non-portable way.