diff options
Diffstat (limited to 'security/keys/key.c')
-rw-r--r-- | security/keys/key.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index 4a1297d1ada4..08531ad0f252 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -500,6 +500,7 @@ int key_negate_and_link(struct key *key, | |||
500 | set_bit(KEY_FLAG_INSTANTIATED, &key->flags); | 500 | set_bit(KEY_FLAG_INSTANTIATED, &key->flags); |
501 | now = current_kernel_time(); | 501 | now = current_kernel_time(); |
502 | key->expiry = now.tv_sec + timeout; | 502 | key->expiry = now.tv_sec + timeout; |
503 | key_schedule_gc(key->expiry); | ||
503 | 504 | ||
504 | if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) | 505 | if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) |
505 | awaken = 1; | 506 | awaken = 1; |
@@ -642,10 +643,8 @@ struct key *key_lookup(key_serial_t id) | |||
642 | goto error; | 643 | goto error; |
643 | 644 | ||
644 | found: | 645 | found: |
645 | /* pretend it doesn't exist if it's dead */ | 646 | /* pretend it doesn't exist if it is awaiting deletion */ |
646 | if (atomic_read(&key->usage) == 0 || | 647 | if (atomic_read(&key->usage) == 0) |
647 | test_bit(KEY_FLAG_DEAD, &key->flags) || | ||
648 | key->type == &key_type_dead) | ||
649 | goto not_found; | 648 | goto not_found; |
650 | 649 | ||
651 | /* this races with key_put(), but that doesn't matter since key_put() | 650 | /* this races with key_put(), but that doesn't matter since key_put() |
@@ -890,6 +889,9 @@ EXPORT_SYMBOL(key_update); | |||
890 | */ | 889 | */ |
891 | void key_revoke(struct key *key) | 890 | void key_revoke(struct key *key) |
892 | { | 891 | { |
892 | struct timespec now; | ||
893 | time_t time; | ||
894 | |||
893 | key_check(key); | 895 | key_check(key); |
894 | 896 | ||
895 | /* make sure no one's trying to change or use the key when we mark it | 897 | /* make sure no one's trying to change or use the key when we mark it |
@@ -902,6 +904,14 @@ void key_revoke(struct key *key) | |||
902 | key->type->revoke) | 904 | key->type->revoke) |
903 | key->type->revoke(key); | 905 | key->type->revoke(key); |
904 | 906 | ||
907 | /* set the death time to no more than the expiry time */ | ||
908 | now = current_kernel_time(); | ||
909 | time = now.tv_sec; | ||
910 | if (key->revoked_at == 0 || key->revoked_at > time) { | ||
911 | key->revoked_at = time; | ||
912 | key_schedule_gc(key->revoked_at); | ||
913 | } | ||
914 | |||
905 | up_write(&key->sem); | 915 | up_write(&key->sem); |
906 | 916 | ||
907 | } /* end key_revoke() */ | 917 | } /* end key_revoke() */ |
@@ -958,8 +968,10 @@ void unregister_key_type(struct key_type *ktype) | |||
958 | for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { | 968 | for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { |
959 | key = rb_entry(_n, struct key, serial_node); | 969 | key = rb_entry(_n, struct key, serial_node); |
960 | 970 | ||
961 | if (key->type == ktype) | 971 | if (key->type == ktype) { |
962 | key->type = &key_type_dead; | 972 | key->type = &key_type_dead; |
973 | set_bit(KEY_FLAG_DEAD, &key->flags); | ||
974 | } | ||
963 | } | 975 | } |
964 | 976 | ||
965 | spin_unlock(&key_serial_lock); | 977 | spin_unlock(&key_serial_lock); |
@@ -984,6 +996,8 @@ void unregister_key_type(struct key_type *ktype) | |||
984 | spin_unlock(&key_serial_lock); | 996 | spin_unlock(&key_serial_lock); |
985 | up_write(&key_types_sem); | 997 | up_write(&key_types_sem); |
986 | 998 | ||
999 | key_schedule_gc(0); | ||
1000 | |||
987 | } /* end unregister_key_type() */ | 1001 | } /* end unregister_key_type() */ |
988 | 1002 | ||
989 | EXPORT_SYMBOL(unregister_key_type); | 1003 | EXPORT_SYMBOL(unregister_key_type); |