aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/key.c')
-rw-r--r--security/keys/key.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index 01bbc6d9d19b..fdd5ca6d89fc 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
1/* key.c: basic authentication token and access key management 1/* Basic authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@ static void key_cleanup(struct work_struct *work);
34static DECLARE_WORK(key_cleanup_task, key_cleanup); 34static DECLARE_WORK(key_cleanup_task, key_cleanup);
35 35
36/* we serialise key instantiation and link */ 36/* we serialise key instantiation and link */
37DECLARE_RWSEM(key_construction_sem); 37DEFINE_MUTEX(key_construction_mutex);
38 38
39/* any key who's type gets unegistered will be re-typed to this */ 39/* any key who's type gets unegistered will be re-typed to this */
40static struct key_type key_type_dead = { 40static struct key_type key_type_dead = {
@@ -104,7 +104,7 @@ struct key_user *key_user_lookup(uid_t uid)
104 candidate->qnkeys = 0; 104 candidate->qnkeys = 0;
105 candidate->qnbytes = 0; 105 candidate->qnbytes = 0;
106 spin_lock_init(&candidate->lock); 106 spin_lock_init(&candidate->lock);
107 INIT_LIST_HEAD(&candidate->consq); 107 mutex_init(&candidate->cons_lock);
108 108
109 rb_link_node(&candidate->node, parent, p); 109 rb_link_node(&candidate->node, parent, p);
110 rb_insert_color(&candidate->node, &key_user_tree); 110 rb_insert_color(&candidate->node, &key_user_tree);
@@ -418,7 +418,7 @@ static int __key_instantiate_and_link(struct key *key,
418 awaken = 0; 418 awaken = 0;
419 ret = -EBUSY; 419 ret = -EBUSY;
420 420
421 down_write(&key_construction_sem); 421 mutex_lock(&key_construction_mutex);
422 422
423 /* can't instantiate twice */ 423 /* can't instantiate twice */
424 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 424 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
@@ -443,11 +443,11 @@ static int __key_instantiate_and_link(struct key *key,
443 } 443 }
444 } 444 }
445 445
446 up_write(&key_construction_sem); 446 mutex_unlock(&key_construction_mutex);
447 447
448 /* wake up anyone waiting for a key to be constructed */ 448 /* wake up anyone waiting for a key to be constructed */
449 if (awaken) 449 if (awaken)
450 wake_up_all(&request_key_conswq); 450 wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
451 451
452 return ret; 452 return ret;
453 453
@@ -500,7 +500,7 @@ int key_negate_and_link(struct key *key,
500 if (keyring) 500 if (keyring)
501 down_write(&keyring->sem); 501 down_write(&keyring->sem);
502 502
503 down_write(&key_construction_sem); 503 mutex_lock(&key_construction_mutex);
504 504
505 /* can't instantiate twice */ 505 /* can't instantiate twice */
506 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 506 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
@@ -525,14 +525,14 @@ int key_negate_and_link(struct key *key,
525 key_revoke(instkey); 525 key_revoke(instkey);
526 } 526 }
527 527
528 up_write(&key_construction_sem); 528 mutex_unlock(&key_construction_mutex);
529 529
530 if (keyring) 530 if (keyring)
531 up_write(&keyring->sem); 531 up_write(&keyring->sem);
532 532
533 /* wake up anyone waiting for a key to be constructed */ 533 /* wake up anyone waiting for a key to be constructed */
534 if (awaken) 534 if (awaken)
535 wake_up_all(&request_key_conswq); 535 wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
536 536
537 return ret; 537 return ret;
538 538
@@ -899,12 +899,14 @@ void key_revoke(struct key *key)
899{ 899{
900 key_check(key); 900 key_check(key);
901 901
902 /* make sure no one's trying to change or use the key when we mark 902 /* make sure no one's trying to change or use the key when we mark it
903 * it */ 903 * - we tell lockdep that we might nest because we might be revoking an
904 down_write(&key->sem); 904 * authorisation key whilst holding the sem on a key we've just
905 set_bit(KEY_FLAG_REVOKED, &key->flags); 905 * instantiated
906 906 */
907 if (key->type->revoke) 907 down_write_nested(&key->sem, 1);
908 if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags) &&
909 key->type->revoke)
908 key->type->revoke(key); 910 key->type->revoke(key);
909 911
910 up_write(&key->sem); 912 up_write(&key->sem);