max connections per control group (cgroup)

Alban Crequy alban.crequy at collabora.co.uk
Thu Aug 14 07:41:17 PDT 2014


On Thu, 14 Aug 2014 14:55:15 +0100
Simon McVittie <simon.mcvittie at collabora.co.uk> wrote:

> On 14/08/14 14:09, Lennart Poettering wrote:
> > The race is basically: somebody connects to the bus and quickly
> > drops off again, and now you know the PID but cannot make sense of
> > it, because the client is already gone.
> > 
> > But thinking about this, this is probably not actually a problem
> > for the dbus case, since the authentication is synchronous, and
> > dbus hence always gets a chance to read the path and the race hence
> > goes away. Sorry for the confusion.
> 
> This sounds uncomfortably close to the race that existed in the
> unmerged patchset for Maemo's "libcreds" security framework:
> 
> * handshake and authenticate with dbus-daemon
> * send a message that a privileged user would be allowed to send but
>   you are not
> * quickly exec a privileged binary (I think the proof-of-concept
>   used ping, which is setuid root)
> * if you won the race, dbus-daemon looks in your /proc and sees "oh,
>   you're privileged, excellent" and forwards the message
> 
> Unpatched dbus is not vulnerable to this, because we receive the
> credentials via credentials-passing, once, on the first byte of the
> connection, and store them. All further interaction is done with the
> credentials that you had when you connected (and if you hand over your
> socket to a less-privileged process, it's your own fault you gave it
> your house keys and hoped it wouldn't steal anything).
> 
> I *think* security frameworks that rummage in /proc during the
> handshake are not vulnerable either, because if you exec the setuid
> binary before the handshake has completed, you will miss your
> opportunity to send the malicious message... but if you can queue up
> the rest of the client side of the handshake, plus the malicious
> message, in the outgoing socket buffer, and then exec the setuid
> binary, you might be able to get away with it, unless the end of the
> handshake happens to be something that depends on information that is
> only sent by dbus-daemon after it has already done its rummaging and
> is not feasible to guess?

In the case of max_connections_per_{user,process,cgroup}, the checks
are done in dbus-daemon during the Hello() command, so it is after the
initial handshake, and there are no information sent by dbus-daemon that
the client would need to know before queuing up malicious messages.

> Bottom line, looking for credentials in /proc is handy for debugging,
> but no substitute for actual kernel APIs; and I am uncomfortable with
> this style of API, and would not want to merge it without (a) comments
> documenting why it is safe and what assumptions it makes, and (b)
> having studied it in more detail than I can do right now.

There is no kernel APIs at the moment to get information about cgroups
in a synchronous and reliable way. There was some discussions on kernel
mailing lists last April about implementing SO_PEERCGROUP and
SO_PASSCGROUP but that work was not merged:
https://lkml.org/lkml/2014/4/15/644

Other kernel APIs which would bring the same features were discussed,
but nothing is ready yet:
- SCM_PROCINFO / SCM_IDENTITY http://lwn.net/Articles/600564/

I would like this API to exist too. It would solve the race mentioned
by Lennart, the /proc parsing issue I mentioned in
http://thread.gmane.org/gmane.linux.kernel.cgroups/11676
and it would make it easier to assess whether there is a similar
issue to Maemo's libcreds.

In this case however, I think it is safe because executing a setuid
program (or using pkexec) would not change the cgroup of the process,
so the limit should be correctly enforced.

Alban


More information about the dbus mailing list