Keyrings, user namespaces and the user_struct

David Howells dhowells at redhat.com
Wed Oct 26 14:34:50 UTC 2016


Andy Lutomirski <luto at amacapital.net> wrote:

> > | Not just questionable, completely wrong. The gist is that there is a
> > | *global* name -> key mapping for accessing keys by name, and user
> > | keyrings are stored in there under the name "_uid.%u", where %u
> > | refers to the *namespaced* UID. (See install_user_keyrings().)
> > | The result is that, if e.g. the user with UID 1000 has no running
> > | processes, a local attacker can enter a new user namespace, map UID
> > | 1000 in the namespace to some KUID he controls, do
> > | setresuid(1000, 1000, 1000), and now he owns user 1000's keyring.

Hmmm...  Having checked over the code, it might not be that simple.  Thanks to
something Eric Biederman added into find_keyring_by_name(), unless a keyring's
UID is a member of the current user namespace, you can't find that keyring by
name.

However, I'm not sure that that stops someone trying to find it by colliding
kuids since keys can't pin the user_struct without causing a loop.

Further, if the user_struct referring to a user (or user-session) keyring gets
deallocated, it drops its link to that keyring - though that's no guarantee
that the user keyrings will be deallocated themselves (there may be links from
elsewhere).

I'm wondering if I should move the user keyrings out of the user_struct so
that keys can pin the user_struct (and I could then merge the key_user struct
into it).

The user-keyring and user-session keyring could be kept in the user's
persistent keyring or in their own tree in the user namespace.  The former
would allow their easy reuse within a certain amount of time and the latter
would allow them to be easily revoked when the user_namespace struct is
destroyed.

I think Eric's patch to move the keyring list into the user_namespace struct
rather than having it be global is also a good step.

David


More information about the Containers mailing list