keys: Implement a 'container' keyring

Implement a per-container keyring, dangling it off of a user_namespace.
The properties of this keyring are such that it's searched by request_key()
selectively before or after the other keyrings have been searched, but the
keys in it don't grant possession to the denizens of the container, and so
the denizens can't see such keys unless those keys grant direct access
through the ACL.  The kernel recurses up the user_namespace stack looking
for keyrings.

The container manager, however, can access the keyring, and can add, update
and remove keys therein.

This allows the container manager to push filesystem authentication keys,
for example, into the container and to keep them refreshed without the
denizens of the container needing to know anything about it.

To this end, the following pieces are also added:

 (1) A new keyctl function, KEYCTL_GET_CONTAINER_KEYRING, to get the
     container keyring from a user namespace:

	keyring = keyctl_get_userns_keyring(int userns_fd,
					    key_serial_t dest_keyring);

     Get the container keyring attached to a user namespace, creating it if
     it doesn't exist.  A file descriptor pointing to the user namespace
     must be supplied.  The keyring will be linked into the destination
     keyring if one is supplied (ie. not 0).  The keyring will be owned by
     the user_namespace's owner and will grant various permissions to the
     possessor.

 (2) An ACL ACE type that allows access to a key by a container:

	keyctl_grant_acl(key_serial_t key,
			 KEY_ACE_SUBJ_CONTAINER,
			 int userns_fd,
			 KEY_ACE_SEARCH);

     This grants the kernel the ability to use a key on behalf of the
     denizens of a container, but doesn't grant any other rights, including
     the ability of the denizens see the key even exists.

This can then be tested with something like the following from the command
line:

 (1) Get the container keyring for a user namespace and link it to the
     session keyring.  The container is referenced as file descriptor 5.

	# keyctl get_container 5 @s 5</proc/self/ns/user
	197321290

 (2) Get a key that should be placed into the container, e.g.:

	# kinit foo@EXAMPLE.COM
	# aklog-kafs example.com

     This, say, adds key 748104263 to the session keyring.

 (3) Grant permission to the container to use the key:

	# keyctl grant 748104263 cont:5 s 5</proc/self/ns/user

 (4) Move (or link) the key into the container keyring:

	# keyctl move 748104263 @s 197321290

 (5) View the resultant keyrings:

	# keyctl show
	Session Keyring
	 711486290 --alswrv      0     0  keyring: _ses
	 468790230 ---lswrv      0 65534   \_ keyring: _uid.0
	 197321290 ----swrv      0 65534   \_ keyring: .container
	 748104263 --alswrv      0     0       \_ rxrpc: afs@example.com

Signed-off-by: David Howells <dhowells@redhat.com>
12 files changed