aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2010-04-27 16:13:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-04-27 19:26:03 -0400
commit03449cd9eaa4fa3a7faa4a59474bafe2e90bd143 (patch)
treef0f8b573553e0ac436b06b3f7853033a46b90a8e
parenta2cb9aeb3c9b2475955cec328487484034f414e4 (diff)
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>
-rw-r--r--security/keys/request_key.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index ea97c3120d66..d737cea5347c 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -339,8 +339,10 @@ static int construct_alloc_key(struct key_type *type,
339 339
340key_already_present: 340key_already_present:
341 mutex_unlock(&key_construction_mutex); 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 up_write(&dest_keyring->sem); 344 up_write(&dest_keyring->sem);
345 }
344 mutex_unlock(&user->cons_lock); 346 mutex_unlock(&user->cons_lock);
345 key_put(key); 347 key_put(key);
346 *_key = key = key_ref_to_ptr(key_ref); 348 *_key = key = key_ref_to_ptr(key_ref);
@@ -431,6 +433,11 @@ struct key *request_key_and_link(struct key_type *type,
431 433
432 if (!IS_ERR(key_ref)) { 434 if (!IS_ERR(key_ref)) {
433 key = key_ref_to_ptr(key_ref); 435 key = key_ref_to_ptr(key_ref);
436 if (dest_keyring) {
437 construct_get_dest_keyring(&dest_keyring);
438 key_link(dest_keyring, key);
439 key_put(dest_keyring);
440 }
434 } else if (PTR_ERR(key_ref) != -EAGAIN) { 441 } else if (PTR_ERR(key_ref) != -EAGAIN) {
435 key = ERR_CAST(key_ref); 442 key = ERR_CAST(key_ref);
436 } else { 443 } else {