diff options
Diffstat (limited to 'security/keys/key.c')
-rw-r--r-- | security/keys/key.c | 320 |
1 files changed, 193 insertions, 127 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index c1eac8084ade..84d4eb568b08 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -39,10 +39,10 @@ static DECLARE_RWSEM(key_types_sem); | |||
39 | static void key_cleanup(struct work_struct *work); | 39 | static void key_cleanup(struct work_struct *work); |
40 | static DECLARE_WORK(key_cleanup_task, key_cleanup); | 40 | static DECLARE_WORK(key_cleanup_task, key_cleanup); |
41 | 41 | ||
42 | /* we serialise key instantiation and link */ | 42 | /* We serialise key instantiation and link */ |
43 | DEFINE_MUTEX(key_construction_mutex); | 43 | DEFINE_MUTEX(key_construction_mutex); |
44 | 44 | ||
45 | /* any key who's type gets unegistered will be re-typed to this */ | 45 | /* Any key who's type gets unegistered will be re-typed to this */ |
46 | static struct key_type key_type_dead = { | 46 | static struct key_type key_type_dead = { |
47 | .name = "dead", | 47 | .name = "dead", |
48 | }; | 48 | }; |
@@ -56,10 +56,9 @@ void __key_check(const struct key *key) | |||
56 | } | 56 | } |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | /*****************************************************************************/ | ||
60 | /* | 59 | /* |
61 | * get the key quota record for a user, allocating a new record if one doesn't | 60 | * Get the key quota record for a user, allocating a new record if one doesn't |
62 | * already exist | 61 | * already exist. |
63 | */ | 62 | */ |
64 | struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns) | 63 | struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns) |
65 | { | 64 | { |
@@ -67,7 +66,7 @@ struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns) | |||
67 | struct rb_node *parent = NULL; | 66 | struct rb_node *parent = NULL; |
68 | struct rb_node **p; | 67 | struct rb_node **p; |
69 | 68 | ||
70 | try_again: | 69 | try_again: |
71 | p = &key_user_tree.rb_node; | 70 | p = &key_user_tree.rb_node; |
72 | spin_lock(&key_user_lock); | 71 | spin_lock(&key_user_lock); |
73 | 72 | ||
@@ -124,18 +123,16 @@ struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns) | |||
124 | goto out; | 123 | goto out; |
125 | 124 | ||
126 | /* okay - we found a user record for this UID */ | 125 | /* okay - we found a user record for this UID */ |
127 | found: | 126 | found: |
128 | atomic_inc(&user->usage); | 127 | atomic_inc(&user->usage); |
129 | spin_unlock(&key_user_lock); | 128 | spin_unlock(&key_user_lock); |
130 | kfree(candidate); | 129 | kfree(candidate); |
131 | out: | 130 | out: |
132 | return user; | 131 | return user; |
132 | } | ||
133 | 133 | ||
134 | } /* end key_user_lookup() */ | ||
135 | |||
136 | /*****************************************************************************/ | ||
137 | /* | 134 | /* |
138 | * dispose of a user structure | 135 | * Dispose of a user structure |
139 | */ | 136 | */ |
140 | void key_user_put(struct key_user *user) | 137 | void key_user_put(struct key_user *user) |
141 | { | 138 | { |
@@ -146,14 +143,11 @@ void key_user_put(struct key_user *user) | |||
146 | 143 | ||
147 | kfree(user); | 144 | kfree(user); |
148 | } | 145 | } |
146 | } | ||
149 | 147 | ||
150 | } /* end key_user_put() */ | ||
151 | |||
152 | /*****************************************************************************/ | ||
153 | /* | 148 | /* |
154 | * assign a key the next unique serial number | 149 | * Allocate a serial number for a key. These are assigned randomly to avoid |
155 | * - these are assigned randomly to avoid security issues through covert | 150 | * security issues through covert channel problems. |
156 | * channel problems | ||
157 | */ | 151 | */ |
158 | static inline void key_alloc_serial(struct key *key) | 152 | static inline void key_alloc_serial(struct key *key) |
159 | { | 153 | { |
@@ -211,18 +205,36 @@ serial_exists: | |||
211 | if (key->serial < xkey->serial) | 205 | if (key->serial < xkey->serial) |
212 | goto attempt_insertion; | 206 | goto attempt_insertion; |
213 | } | 207 | } |
208 | } | ||
214 | 209 | ||
215 | } /* end key_alloc_serial() */ | 210 | /** |
216 | 211 | * key_alloc - Allocate a key of the specified type. | |
217 | /*****************************************************************************/ | 212 | * @type: The type of key to allocate. |
218 | /* | 213 | * @desc: The key description to allow the key to be searched out. |
219 | * allocate a key of the specified type | 214 | * @uid: The owner of the new key. |
220 | * - update the user's quota to reflect the existence of the key | 215 | * @gid: The group ID for the new key's group permissions. |
221 | * - called from a key-type operation with key_types_sem read-locked by | 216 | * @cred: The credentials specifying UID namespace. |
222 | * key_create_or_update() | 217 | * @perm: The permissions mask of the new key. |
223 | * - this prevents unregistration of the key type | 218 | * @flags: Flags specifying quota properties. |
224 | * - upon return the key is as yet uninstantiated; the caller needs to either | 219 | * |
225 | * instantiate the key or discard it before returning | 220 | * Allocate a key of the specified type with the attributes given. The key is |
221 | * returned in an uninstantiated state and the caller needs to instantiate the | ||
222 | * key before returning. | ||
223 | * | ||
224 | * The user's key count quota is updated to reflect the creation of the key and | ||
225 | * the user's key data quota has the default for the key type reserved. The | ||
226 | * instantiation function should amend this as necessary. If insufficient | ||
227 | * quota is available, -EDQUOT will be returned. | ||
228 | * | ||
229 | * The LSM security modules can prevent a key being created, in which case | ||
230 | * -EACCES will be returned. | ||
231 | * | ||
232 | * Returns a pointer to the new key if successful and an error code otherwise. | ||
233 | * | ||
234 | * Note that the caller needs to ensure the key type isn't uninstantiated. | ||
235 | * Internally this can be done by locking key_types_sem. Externally, this can | ||
236 | * be done by either never unregistering the key type, or making sure | ||
237 | * key_alloc() calls don't race with module unloading. | ||
226 | */ | 238 | */ |
227 | struct key *key_alloc(struct key_type *type, const char *desc, | 239 | struct key *key_alloc(struct key_type *type, const char *desc, |
228 | uid_t uid, gid_t gid, const struct cred *cred, | 240 | uid_t uid, gid_t gid, const struct cred *cred, |
@@ -344,14 +356,19 @@ no_quota: | |||
344 | key_user_put(user); | 356 | key_user_put(user); |
345 | key = ERR_PTR(-EDQUOT); | 357 | key = ERR_PTR(-EDQUOT); |
346 | goto error; | 358 | goto error; |
347 | 359 | } | |
348 | } /* end key_alloc() */ | ||
349 | |||
350 | EXPORT_SYMBOL(key_alloc); | 360 | EXPORT_SYMBOL(key_alloc); |
351 | 361 | ||
352 | /*****************************************************************************/ | 362 | /** |
353 | /* | 363 | * key_payload_reserve - Adjust data quota reservation for the key's payload |
354 | * reserve an amount of quota for the key's payload | 364 | * @key: The key to make the reservation for. |
365 | * @datalen: The amount of data payload the caller now wants. | ||
366 | * | ||
367 | * Adjust the amount of the owning user's key data quota that a key reserves. | ||
368 | * If the amount is increased, then -EDQUOT may be returned if there isn't | ||
369 | * enough free quota available. | ||
370 | * | ||
371 | * If successful, 0 is returned. | ||
355 | */ | 372 | */ |
356 | int key_payload_reserve(struct key *key, size_t datalen) | 373 | int key_payload_reserve(struct key *key, size_t datalen) |
357 | { | 374 | { |
@@ -384,15 +401,14 @@ int key_payload_reserve(struct key *key, size_t datalen) | |||
384 | key->datalen = datalen; | 401 | key->datalen = datalen; |
385 | 402 | ||
386 | return ret; | 403 | return ret; |
387 | 404 | } | |
388 | } /* end key_payload_reserve() */ | ||
389 | |||
390 | EXPORT_SYMBOL(key_payload_reserve); | 405 | EXPORT_SYMBOL(key_payload_reserve); |
391 | 406 | ||
392 | /*****************************************************************************/ | ||
393 | /* | 407 | /* |
394 | * instantiate a key and link it into the target keyring atomically | 408 | * Instantiate a key and link it into the target keyring atomically. Must be |
395 | * - called with the target keyring's semaphore writelocked | 409 | * called with the target keyring's semaphore writelocked. The target key's |
410 | * semaphore need not be locked as instantiation is serialised by | ||
411 | * key_construction_mutex. | ||
396 | */ | 412 | */ |
397 | static int __key_instantiate_and_link(struct key *key, | 413 | static int __key_instantiate_and_link(struct key *key, |
398 | const void *data, | 414 | const void *data, |
@@ -441,12 +457,23 @@ static int __key_instantiate_and_link(struct key *key, | |||
441 | wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT); | 457 | wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT); |
442 | 458 | ||
443 | return ret; | 459 | return ret; |
460 | } | ||
444 | 461 | ||
445 | } /* end __key_instantiate_and_link() */ | 462 | /** |
446 | 463 | * key_instantiate_and_link - Instantiate a key and link it into the keyring. | |
447 | /*****************************************************************************/ | 464 | * @key: The key to instantiate. |
448 | /* | 465 | * @data: The data to use to instantiate the keyring. |
449 | * instantiate a key and link it into the target keyring atomically | 466 | * @datalen: The length of @data. |
467 | * @keyring: Keyring to create a link in on success (or NULL). | ||
468 | * @authkey: The authorisation token permitting instantiation. | ||
469 | * | ||
470 | * Instantiate a key that's in the uninstantiated state using the provided data | ||
471 | * and, if successful, link it in to the destination keyring if one is | ||
472 | * supplied. | ||
473 | * | ||
474 | * If successful, 0 is returned, the authorisation token is revoked and anyone | ||
475 | * waiting for the key is woken up. If the key was already instantiated, | ||
476 | * -EBUSY will be returned. | ||
450 | */ | 477 | */ |
451 | int key_instantiate_and_link(struct key *key, | 478 | int key_instantiate_and_link(struct key *key, |
452 | const void *data, | 479 | const void *data, |
@@ -471,14 +498,28 @@ int key_instantiate_and_link(struct key *key, | |||
471 | __key_link_end(keyring, key->type, prealloc); | 498 | __key_link_end(keyring, key->type, prealloc); |
472 | 499 | ||
473 | return ret; | 500 | return ret; |
474 | 501 | } | |
475 | } /* end key_instantiate_and_link() */ | ||
476 | 502 | ||
477 | EXPORT_SYMBOL(key_instantiate_and_link); | 503 | EXPORT_SYMBOL(key_instantiate_and_link); |
478 | 504 | ||
479 | /*****************************************************************************/ | 505 | /** |
480 | /* | 506 | * key_negate_and_link - Negatively instantiate a key and link it into the keyring. |
481 | * negatively instantiate a key and link it into the target keyring atomically | 507 | * @key: The key to instantiate. |
508 | * @timeout: The timeout on the negative key. | ||
509 | * @keyring: Keyring to create a link in on success (or NULL). | ||
510 | * @authkey: The authorisation token permitting instantiation. | ||
511 | * | ||
512 | * Negatively instantiate a key that's in the uninstantiated state and, if | ||
513 | * successful, set its timeout and link it in to the destination keyring if one | ||
514 | * is supplied. The key and any links to the key will be automatically garbage | ||
515 | * collected after the timeout expires. | ||
516 | * | ||
517 | * Negative keys are used to rate limit repeated request_key() calls by causing | ||
518 | * them to return -ENOKEY until the negative key expires. | ||
519 | * | ||
520 | * If successful, 0 is returned, the authorisation token is revoked and anyone | ||
521 | * waiting for the key is woken up. If the key was already instantiated, | ||
522 | * -EBUSY will be returned. | ||
482 | */ | 523 | */ |
483 | int key_negate_and_link(struct key *key, | 524 | int key_negate_and_link(struct key *key, |
484 | unsigned timeout, | 525 | unsigned timeout, |
@@ -535,22 +576,23 @@ int key_negate_and_link(struct key *key, | |||
535 | wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT); | 576 | wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT); |
536 | 577 | ||
537 | return ret == 0 ? link_ret : ret; | 578 | return ret == 0 ? link_ret : ret; |
538 | 579 | } | |
539 | } /* end key_negate_and_link() */ | ||
540 | 580 | ||
541 | EXPORT_SYMBOL(key_negate_and_link); | 581 | EXPORT_SYMBOL(key_negate_and_link); |
542 | 582 | ||
543 | /*****************************************************************************/ | ||
544 | /* | 583 | /* |
545 | * do cleaning up in process context so that we don't have to disable | 584 | * Garbage collect keys in process context so that we don't have to disable |
546 | * interrupts all over the place | 585 | * interrupts all over the place. |
586 | * | ||
587 | * key_put() schedules this rather than trying to do the cleanup itself, which | ||
588 | * means key_put() doesn't have to sleep. | ||
547 | */ | 589 | */ |
548 | static void key_cleanup(struct work_struct *work) | 590 | static void key_cleanup(struct work_struct *work) |
549 | { | 591 | { |
550 | struct rb_node *_n; | 592 | struct rb_node *_n; |
551 | struct key *key; | 593 | struct key *key; |
552 | 594 | ||
553 | go_again: | 595 | go_again: |
554 | /* look for a dead key in the tree */ | 596 | /* look for a dead key in the tree */ |
555 | spin_lock(&key_serial_lock); | 597 | spin_lock(&key_serial_lock); |
556 | 598 | ||
@@ -564,7 +606,7 @@ static void key_cleanup(struct work_struct *work) | |||
564 | spin_unlock(&key_serial_lock); | 606 | spin_unlock(&key_serial_lock); |
565 | return; | 607 | return; |
566 | 608 | ||
567 | found_dead_key: | 609 | found_dead_key: |
568 | /* we found a dead key - once we've removed it from the tree, we can | 610 | /* we found a dead key - once we've removed it from the tree, we can |
569 | * drop the lock */ | 611 | * drop the lock */ |
570 | rb_erase(&key->serial_node, &key_serial_tree); | 612 | rb_erase(&key->serial_node, &key_serial_tree); |
@@ -601,14 +643,15 @@ static void key_cleanup(struct work_struct *work) | |||
601 | 643 | ||
602 | /* there may, of course, be more than one key to destroy */ | 644 | /* there may, of course, be more than one key to destroy */ |
603 | goto go_again; | 645 | goto go_again; |
646 | } | ||
604 | 647 | ||
605 | } /* end key_cleanup() */ | 648 | /** |
606 | 649 | * key_put - Discard a reference to a key. | |
607 | /*****************************************************************************/ | 650 | * @key: The key to discard a reference from. |
608 | /* | 651 | * |
609 | * dispose of a reference to a key | 652 | * Discard a reference to a key, and when all the references are gone, we |
610 | * - when all the references are gone, we schedule the cleanup task to come and | 653 | * schedule the cleanup task to come and pull it out of the tree in process |
611 | * pull it out of the tree in definite process context | 654 | * context at some later time. |
612 | */ | 655 | */ |
613 | void key_put(struct key *key) | 656 | void key_put(struct key *key) |
614 | { | 657 | { |
@@ -618,14 +661,11 @@ void key_put(struct key *key) | |||
618 | if (atomic_dec_and_test(&key->usage)) | 661 | if (atomic_dec_and_test(&key->usage)) |
619 | schedule_work(&key_cleanup_task); | 662 | schedule_work(&key_cleanup_task); |
620 | } | 663 | } |
621 | 664 | } | |
622 | } /* end key_put() */ | ||
623 | |||
624 | EXPORT_SYMBOL(key_put); | 665 | EXPORT_SYMBOL(key_put); |
625 | 666 | ||
626 | /*****************************************************************************/ | ||
627 | /* | 667 | /* |
628 | * find a key by its serial number | 668 | * Find a key by its serial number. |
629 | */ | 669 | */ |
630 | struct key *key_lookup(key_serial_t id) | 670 | struct key *key_lookup(key_serial_t id) |
631 | { | 671 | { |
@@ -647,11 +687,11 @@ struct key *key_lookup(key_serial_t id) | |||
647 | goto found; | 687 | goto found; |
648 | } | 688 | } |
649 | 689 | ||
650 | not_found: | 690 | not_found: |
651 | key = ERR_PTR(-ENOKEY); | 691 | key = ERR_PTR(-ENOKEY); |
652 | goto error; | 692 | goto error; |
653 | 693 | ||
654 | found: | 694 | found: |
655 | /* pretend it doesn't exist if it is awaiting deletion */ | 695 | /* pretend it doesn't exist if it is awaiting deletion */ |
656 | if (atomic_read(&key->usage) == 0) | 696 | if (atomic_read(&key->usage) == 0) |
657 | goto not_found; | 697 | goto not_found; |
@@ -661,16 +701,16 @@ struct key *key_lookup(key_serial_t id) | |||
661 | */ | 701 | */ |
662 | atomic_inc(&key->usage); | 702 | atomic_inc(&key->usage); |
663 | 703 | ||
664 | error: | 704 | error: |
665 | spin_unlock(&key_serial_lock); | 705 | spin_unlock(&key_serial_lock); |
666 | return key; | 706 | return key; |
707 | } | ||
667 | 708 | ||
668 | } /* end key_lookup() */ | ||
669 | |||
670 | /*****************************************************************************/ | ||
671 | /* | 709 | /* |
672 | * find and lock the specified key type against removal | 710 | * Find and lock the specified key type against removal. |
673 | * - we return with the sem readlocked | 711 | * |
712 | * We return with the sem read-locked if successful. If the type wasn't | ||
713 | * available -ENOKEY is returned instead. | ||
674 | */ | 714 | */ |
675 | struct key_type *key_type_lookup(const char *type) | 715 | struct key_type *key_type_lookup(const char *type) |
676 | { | 716 | { |
@@ -688,26 +728,23 @@ struct key_type *key_type_lookup(const char *type) | |||
688 | up_read(&key_types_sem); | 728 | up_read(&key_types_sem); |
689 | ktype = ERR_PTR(-ENOKEY); | 729 | ktype = ERR_PTR(-ENOKEY); |
690 | 730 | ||
691 | found_kernel_type: | 731 | found_kernel_type: |
692 | return ktype; | 732 | return ktype; |
733 | } | ||
693 | 734 | ||
694 | } /* end key_type_lookup() */ | ||
695 | |||
696 | /*****************************************************************************/ | ||
697 | /* | 735 | /* |
698 | * unlock a key type | 736 | * Unlock a key type locked by key_type_lookup(). |
699 | */ | 737 | */ |
700 | void key_type_put(struct key_type *ktype) | 738 | void key_type_put(struct key_type *ktype) |
701 | { | 739 | { |
702 | up_read(&key_types_sem); | 740 | up_read(&key_types_sem); |
741 | } | ||
703 | 742 | ||
704 | } /* end key_type_put() */ | ||
705 | |||
706 | /*****************************************************************************/ | ||
707 | /* | 743 | /* |
708 | * attempt to update an existing key | 744 | * Attempt to update an existing key. |
709 | * - the key has an incremented refcount | 745 | * |
710 | * - we need to put the key if we get an error | 746 | * The key is given to us with an incremented refcount that we need to discard |
747 | * if we get an error. | ||
711 | */ | 748 | */ |
712 | static inline key_ref_t __key_update(key_ref_t key_ref, | 749 | static inline key_ref_t __key_update(key_ref_t key_ref, |
713 | const void *payload, size_t plen) | 750 | const void *payload, size_t plen) |
@@ -742,13 +779,32 @@ error: | |||
742 | key_put(key); | 779 | key_put(key); |
743 | key_ref = ERR_PTR(ret); | 780 | key_ref = ERR_PTR(ret); |
744 | goto out; | 781 | goto out; |
782 | } | ||
745 | 783 | ||
746 | } /* end __key_update() */ | 784 | /** |
747 | 785 | * key_create_or_update - Update or create and instantiate a key. | |
748 | /*****************************************************************************/ | 786 | * @keyring_ref: A pointer to the destination keyring with possession flag. |
749 | /* | 787 | * @type: The type of key. |
750 | * search the specified keyring for a key of the same description; if one is | 788 | * @description: The searchable description for the key. |
751 | * found, update it, otherwise add a new one | 789 | * @payload: The data to use to instantiate or update the key. |
790 | * @plen: The length of @payload. | ||
791 | * @perm: The permissions mask for a new key. | ||
792 | * @flags: The quota flags for a new key. | ||
793 | * | ||
794 | * Search the destination keyring for a key of the same description and if one | ||
795 | * is found, update it, otherwise create and instantiate a new one and create a | ||
796 | * link to it from that keyring. | ||
797 | * | ||
798 | * If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be | ||
799 | * concocted. | ||
800 | * | ||
801 | * Returns a pointer to the new key if successful, -ENODEV if the key type | ||
802 | * wasn't available, -ENOTDIR if the keyring wasn't a keyring, -EACCES if the | ||
803 | * caller isn't permitted to modify the keyring or the LSM did not permit | ||
804 | * creation of the key. | ||
805 | * | ||
806 | * On success, the possession flag from the keyring ref will be tacked on to | ||
807 | * the key ref before it is returned. | ||
752 | */ | 808 | */ |
753 | key_ref_t key_create_or_update(key_ref_t keyring_ref, | 809 | key_ref_t key_create_or_update(key_ref_t keyring_ref, |
754 | const char *type, | 810 | const char *type, |
@@ -855,14 +911,21 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
855 | 911 | ||
856 | key_ref = __key_update(key_ref, payload, plen); | 912 | key_ref = __key_update(key_ref, payload, plen); |
857 | goto error; | 913 | goto error; |
858 | 914 | } | |
859 | } /* end key_create_or_update() */ | ||
860 | |||
861 | EXPORT_SYMBOL(key_create_or_update); | 915 | EXPORT_SYMBOL(key_create_or_update); |
862 | 916 | ||
863 | /*****************************************************************************/ | 917 | /** |
864 | /* | 918 | * key_update - Update a key's contents. |
865 | * update a key | 919 | * @key_ref: The pointer (plus possession flag) to the key. |
920 | * @payload: The data to be used to update the key. | ||
921 | * @plen: The length of @payload. | ||
922 | * | ||
923 | * Attempt to update the contents of a key with the given payload data. The | ||
924 | * caller must be granted Write permission on the key. Negative keys can be | ||
925 | * instantiated by this method. | ||
926 | * | ||
927 | * Returns 0 on success, -EACCES if not permitted and -EOPNOTSUPP if the key | ||
928 | * type does not support updating. The key type may return other errors. | ||
866 | */ | 929 | */ |
867 | int key_update(key_ref_t key_ref, const void *payload, size_t plen) | 930 | int key_update(key_ref_t key_ref, const void *payload, size_t plen) |
868 | { | 931 | { |
@@ -891,14 +954,17 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) | |||
891 | 954 | ||
892 | error: | 955 | error: |
893 | return ret; | 956 | return ret; |
894 | 957 | } | |
895 | } /* end key_update() */ | ||
896 | |||
897 | EXPORT_SYMBOL(key_update); | 958 | EXPORT_SYMBOL(key_update); |
898 | 959 | ||
899 | /*****************************************************************************/ | 960 | /** |
900 | /* | 961 | * key_revoke - Revoke a key. |
901 | * revoke a key | 962 | * @key: The key to be revoked. |
963 | * | ||
964 | * Mark a key as being revoked and ask the type to free up its resources. The | ||
965 | * revocation timeout is set and the key and all its links will be | ||
966 | * automatically garbage collected after key_gc_delay amount of time if they | ||
967 | * are not manually dealt with first. | ||
902 | */ | 968 | */ |
903 | void key_revoke(struct key *key) | 969 | void key_revoke(struct key *key) |
904 | { | 970 | { |
@@ -926,14 +992,16 @@ void key_revoke(struct key *key) | |||
926 | } | 992 | } |
927 | 993 | ||
928 | up_write(&key->sem); | 994 | up_write(&key->sem); |
929 | 995 | } | |
930 | } /* end key_revoke() */ | ||
931 | |||
932 | EXPORT_SYMBOL(key_revoke); | 996 | EXPORT_SYMBOL(key_revoke); |
933 | 997 | ||
934 | /*****************************************************************************/ | 998 | /** |
935 | /* | 999 | * register_key_type - Register a type of key. |
936 | * register a type of key | 1000 | * @ktype: The new key type. |
1001 | * | ||
1002 | * Register a new key type. | ||
1003 | * | ||
1004 | * Returns 0 on success or -EEXIST if a type of this name already exists. | ||
937 | */ | 1005 | */ |
938 | int register_key_type(struct key_type *ktype) | 1006 | int register_key_type(struct key_type *ktype) |
939 | { | 1007 | { |
@@ -953,17 +1021,19 @@ int register_key_type(struct key_type *ktype) | |||
953 | list_add(&ktype->link, &key_types_list); | 1021 | list_add(&ktype->link, &key_types_list); |
954 | ret = 0; | 1022 | ret = 0; |
955 | 1023 | ||
956 | out: | 1024 | out: |
957 | up_write(&key_types_sem); | 1025 | up_write(&key_types_sem); |
958 | return ret; | 1026 | return ret; |
959 | 1027 | } | |
960 | } /* end register_key_type() */ | ||
961 | |||
962 | EXPORT_SYMBOL(register_key_type); | 1028 | EXPORT_SYMBOL(register_key_type); |
963 | 1029 | ||
964 | /*****************************************************************************/ | 1030 | /** |
965 | /* | 1031 | * unregister_key_type - Unregister a type of key. |
966 | * unregister a type of key | 1032 | * @ktype: The key type. |
1033 | * | ||
1034 | * Unregister a key type and mark all the extant keys of this type as dead. | ||
1035 | * Those keys of this type are then destroyed to get rid of their payloads and | ||
1036 | * they and their links will be garbage collected as soon as possible. | ||
967 | */ | 1037 | */ |
968 | void unregister_key_type(struct key_type *ktype) | 1038 | void unregister_key_type(struct key_type *ktype) |
969 | { | 1039 | { |
@@ -1010,14 +1080,11 @@ void unregister_key_type(struct key_type *ktype) | |||
1010 | up_write(&key_types_sem); | 1080 | up_write(&key_types_sem); |
1011 | 1081 | ||
1012 | key_schedule_gc(0); | 1082 | key_schedule_gc(0); |
1013 | 1083 | } | |
1014 | } /* end unregister_key_type() */ | ||
1015 | |||
1016 | EXPORT_SYMBOL(unregister_key_type); | 1084 | EXPORT_SYMBOL(unregister_key_type); |
1017 | 1085 | ||
1018 | /*****************************************************************************/ | ||
1019 | /* | 1086 | /* |
1020 | * initialise the key management stuff | 1087 | * Initialise the key management state. |
1021 | */ | 1088 | */ |
1022 | void __init key_init(void) | 1089 | void __init key_init(void) |
1023 | { | 1090 | { |
@@ -1037,5 +1104,4 @@ void __init key_init(void) | |||
1037 | 1104 | ||
1038 | rb_insert_color(&root_key_user.node, | 1105 | rb_insert_color(&root_key_user.node, |
1039 | &key_user_tree); | 1106 | &key_user_tree); |
1040 | 1107 | } | |
1041 | } /* end key_init() */ | ||