Sharing credentials in general (Re: [GIT PULL] kdbus for 4.1-rc1)
From: Andy Lutomirski
Date: Thu Apr 23 2015 - 15:41:47 EST
On Thu, Apr 23, 2015 at 11:48 AM, Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
> On Thu, Apr 23, 2015 at 10:57 AM, Linus Torvalds
> <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>>
>> Same goes for uid etc - if you are implementing a service daemon, the
>> uid of the requester sure as hell makes a ton of difference in what
>> you might want to expose. Things like "does this user have access
>> rights to the printer?" are very natural questions to ask.
>
> Hmm. Looking at the code, it strikes me that not only does
> kdbus_meta_proc_collect() collect too much, but some of what it
> collects it just seems to do *wrong*.
>
> So I agree with collecting user and credential information (obviously
> unlike some people ;), but I think the code that does it is just
> wrong.
Can I try again, this time without reference to the rest of this
thread from hell?
Let's say I have a shiny kdbus system. I'm generally okay with my
printer daemon finding out that the Angry Penguins app I'm printing
from is uid 1000, that it has the admin's blessing to print, and even
that it's in such-and-such cgroup. That's not why I dislike this.
Objection 1: This thing is omnidirectional. I'm much less convinced
that it's okay for Angry Penguins or its associated ad network to find
out that the printer daemon is uid 38, that it's in cgroup
such-and-such, or that the printer daemon has the admin's permission
to feed the walruses.
Objection 2: There's a difference between the printer daemon knowing
that Angry Penguins has general permission to print and an explicit
assertion by Angry Penguins of its permission to print. Suppose that
printing is implemented by having Angry Penguins call the method Write
on some kdbus thing. Suppose further that changing root's password is
implemented by having the caller call the method Write on some other
kdbus thing. Before changing the password, the password daemon makes
sure that the caller (or the caller's kdbus conn or whatever) has
password-changing permissions. Before printing, the printer daemon
makes sure that the caller has printing permissions.
In kdbus, this is IMO a big problem. See, I can try to find some
setuid root program that takes a printer object as input (however
kdbus might do this -- presumably it would be an object name) and
calls Write to print some diagnostic thing. Now I just feed it the
password-changing thingy as input and I can get it to "print" to the
root password. Oops.
With sensible APIs, this problem goes away. If the actual API were:
call_a_method(object, method name, args, privileges to assert);
then it's a big red flag when a program calls:
call_a_method(untrusted_object, "Write", untrusted_data, all_my_privileges);
This is just like how open(untrusted_path) is bad news and everyone
knows it, whereas write(untrusted_fd, untrusted_data, len) is supposed
to be fine (see, for example, stdout in every setuid program ever).
In the model where system services get to know the identity of the
callers (ok so far) and where every single method call allows the
service to know every possible credential of the caller (kdbus with
sd-bus) and where those credentials are used for authentication
(probably every kdbus daemon ever), it follows that every method call
asserts every possible permission, and we're screwed.
As you pointed out with cmdline, it's not so easy to disentangle
knowledge of some attribute of a caller with use of that attribute as
authorization. So, if we give all the system daemons (and Angry
Pigeons!) the ability to know the credentials of their callers on all
method calls, then they'll use it for authorization, and now all
privileges are potentially dangerous merely to possess for all method
calls.
IMO we need an API where assertion of a privilege is Totally Obviously
Explicit And Clearly A Thing You Only Do With Careful Thought And Is
Expressed As Such In A Method Call (). SCM_CREDENTIALS gets this
wrong, and so does kdbus (and especially sd-bus).
(Alternatively, in a capability-based security model, access to the
password setting object *is* the permission to set passwords, and
there are no implicit/ambient privileges at all, so this is all moot.)
--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/