keys: the request_key() syscall should link an existing key to the dest keyring

The request_key() system call and request_key_and_link() should make a
link from an existing key to the destination keyring (if supplied), not
just from a new key to the destination keyring.

This can be tested by:

ring=`keyctl newring fred @s`
keyctl request2 user debug:a a
keyctl request user debug:a $ring
keyctl list $ring

If it says:

keyring is empty

then it didn't work. If it shows something like:

1 key in keyring:
1070462727: --alswrv 0 0 user: debug:a

then it did.

request_key() system call is meant to recursively search all your keyrings for
the key you desire, and, optionally, if it doesn't exist, call out to userspace
to create one for you.

If request_key() finds or creates a key, it should, optionally, create a link
to that key from the destination keyring specified.

Therefore, if, after a successful call to request_key() with a desination
keyring specified, you see the destination keyring empty, the code didn't work
correctly.

If you see the found key in the keyring, then it did - which is what the patch
is required for.

Signed-off-by: David Howells <dhowells@redhat.com>
Cc: James Morris <jmorris@namei.org>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by David Howells and committed by Linus Torvalds 03449cd9 a2cb9aeb

+8 -1
+8 -1
security/keys/request_key.c
··· 339 339 340 340 key_already_present: 341 341 mutex_unlock(&key_construction_mutex); 342 - if (dest_keyring) 342 + if (dest_keyring) { 343 + __key_link(dest_keyring, key_ref_to_ptr(key_ref)); 343 344 up_write(&dest_keyring->sem); 345 + } 344 346 mutex_unlock(&user->cons_lock); 345 347 key_put(key); 346 348 *_key = key = key_ref_to_ptr(key_ref); ··· 433 431 434 432 if (!IS_ERR(key_ref)) { 435 433 key = key_ref_to_ptr(key_ref); 434 + if (dest_keyring) { 435 + construct_get_dest_keyring(&dest_keyring); 436 + key_link(dest_keyring, key); 437 + key_put(dest_keyring); 438 + } 436 439 } else if (PTR_ERR(key_ref) != -EAGAIN) { 437 440 key = ERR_CAST(key_ref); 438 441 } else {