| From 03449cd9eaa4fa3a7faa4a59474bafe2e90bd143 Mon Sep 17 00:00:00 2001 |
| From: David Howells <dhowells@redhat.com> |
| Date: Tue, 27 Apr 2010 13:13:08 -0700 |
| Subject: keys: the request_key() syscall should link an existing key to the dest keyring |
| |
| From: David Howells <dhowells@redhat.com> |
| |
| commit 03449cd9eaa4fa3a7faa4a59474bafe2e90bd143 upstream. |
| |
| 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> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| security/keys/request_key.c | 9 ++++++++- |
| 1 file changed, 8 insertions(+), 1 deletion(-) |
| |
| --- a/security/keys/request_key.c |
| +++ b/security/keys/request_key.c |
| @@ -336,8 +336,10 @@ static int construct_alloc_key(struct ke |
| |
| key_already_present: |
| mutex_unlock(&key_construction_mutex); |
| - if (dest_keyring) |
| + if (dest_keyring) { |
| + __key_link(dest_keyring, key_ref_to_ptr(key_ref)); |
| up_write(&dest_keyring->sem); |
| + } |
| mutex_unlock(&user->cons_lock); |
| key_put(key); |
| *_key = key = key_ref_to_ptr(key_ref); |
| @@ -428,6 +430,11 @@ struct key *request_key_and_link(struct |
| |
| if (!IS_ERR(key_ref)) { |
| key = key_ref_to_ptr(key_ref); |
| + if (dest_keyring) { |
| + construct_get_dest_keyring(&dest_keyring); |
| + key_link(dest_keyring, key); |
| + key_put(dest_keyring); |
| + } |
| } else if (PTR_ERR(key_ref) != -EAGAIN) { |
| key = ERR_CAST(key_ref); |
| } else { |