summaryrefslogtreecommitdiffstats
path: root/security/keys/request_key.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-05-30 12:37:39 +0200
committerDavid Howells <dhowells@redhat.com>2019-05-30 23:30:55 +0200
commitdf593ee23e05cdda16c8c995e5818779431bb29f (patch)
tree1abe20cf6ac343d4b0f92756c19ad1b6b7a70a65 /security/keys/request_key.c
parentkeys: Break bits out of key_unlink() (diff)
downloadlinux-df593ee23e05cdda16c8c995e5818779431bb29f.tar.xz
linux-df593ee23e05cdda16c8c995e5818779431bb29f.zip
keys: Hoist locking out of __key_link_begin()
Hoist the locking of out of __key_link_begin() and into its callers. This is necessary to allow the upcoming key_move() operation to correctly order taking of the source keyring semaphore, the destination keyring semaphore and the keyring serialisation lock. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'security/keys/request_key.c')
-rw-r--r--security/keys/request_key.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 1f234b019437..857da65e1940 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -343,7 +343,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
struct key_user *user,
struct key **_key)
{
- struct assoc_array_edit *edit;
+ struct assoc_array_edit *edit = NULL;
struct key *key;
key_perm_t perm;
key_ref_t key_ref;
@@ -372,6 +372,9 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
if (dest_keyring) {
+ ret = __key_link_lock(dest_keyring, &ctx->index_key);
+ if (ret < 0)
+ goto link_lock_failed;
ret = __key_link_begin(dest_keyring, &ctx->index_key, &edit);
if (ret < 0)
goto link_prealloc_failed;
@@ -423,6 +426,8 @@ link_check_failed:
return ret;
link_prealloc_failed:
+ __key_link_end(dest_keyring, &ctx->index_key, edit);
+link_lock_failed:
mutex_unlock(&user->cons_lock);
key_put(key);
kleave(" = %d [prelink]", ret);