[systemd-devel] Unprivileged poweroff

Djalal Harouni tixxdz at opendz.org
Wed Oct 22 17:05:32 PDT 2014


On Wed, Oct 22, 2014 at 12:59:45PM +0100, Simon McVittie wrote:
> On 22/10/14 12:37, Lennart Poettering wrote:
> > When used with kdbus we actually do check for that client-side
> > capability. THis is not available on dbus1 however, since we cannot
> > determine the capability racefreely and thus safely
> 
> ... because the kernel doesn't give us that ability on Unix sockets. See
> <https://bugs.freedesktop.org/show_bug.cgi?id=83499> for more on what
> Unix socket semantics *do* allow socket-based D-Bus to rely on.
Yes. From that link the privileged process should not trust the passed
fds (including:stdin...) so we can blame it... but in the other hand,
even if it closes the fds, there will always be a window for races...
but hey it should also be careful what to do with these fds. Anyway
running a suid in an untrusted environment is just asking for trouble.

> A solution requires new kernel features: either something like kdbus, or
> a way for a Unix socket client to prove to the server that it had a
> particular capability either at the time the socket opened (a new
> SCM_CAPABILITIES analogous to SCM_CREDS?) or at the time that a
> particular message was queued (subtle, probably best avoided).
Hmm, when the message is queued you should just trust those
capabilities (metadata), there is no another way! so if it is really
unprivileged you are safe. For two reasons:

1) Even if privileged leaks the connection fd to unprivileged, you will
   get the capabilities of the unprivileged one. The real one that is
   sending messages.

2) Privileged should not trust the passed fd nor queue a message using
   this passed fd. No sane program should do this, otherwise it will
   just break every thing.

   And if we assume from that fdo bug id=83499:
   "* connect to the D-Bus socket
   * race with dbus-daemon, and win:
     - queue up the entire handshake, plus a malicious message, in the
       outgoing socket buffer
     - make the D-Bus connection not close-on-exec
     - exec() a setuid process, or fd-pass the D-Bus connection to a more
       privileged process
   * dbus-daemon checks the sender's credentials (let's say "uid 1000"),
     and thinks it has the credentials of the setuid process
     (e.g. "uid 0")
   * now dbus-daemon reads the malicious message, determines that uid 0
     may send it, and forwards it to the recipient, with no indication
     that uid 1000 was actually responsible"

   So:
   If the unprivileged queues up a message then exec() a suid and passes
   the fd to the privileged one, we sill get the capabilities of the
   process that did send the message, the unprivileged one. This way if
   we ever someday get SCM_CAPABILITIES, it should reflect the caps at
   the time the message was queued, *not* when the connection was opened.


Here, the capabilities are metadata attached to the message, that can't
be faked...


However, when trying to talk to a service/well-known name from a pure
D-Bus perspective, you talk to the interface that is offering the
poweroff methode, then in this case the TALK check is performed against
creds (uid/gid) at the *time* the connection was *created*. So if uid/gid
do not match, good, unprivileged do not allow contacting the service at
all.

However if uid/gid matches or if the connection was created by a
privileged, we allow the TALK to that service since it was privileged or
the uid/gid did match when the connection was created. The privileged is
*responsible* of the connection fd.

Doing this allows privileged to create connections (store the cred),
drop privs, then pass the connection fd to a normal process. This way
some unprivileged code is able to talk to some restricted names... and
the receiving service is able to inspect the *correct* capabilities of
this unprivileged (capabilities gathered when the message was queued).


Hope I'm not missing something, otherwise let me know, thank you Simon!


>     S
> 
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel

-- 
Djalal Harouni
http://opendz.org


More information about the systemd-devel mailing list