aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-07-02 08:39:09 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-07-02 08:39:09 -0400
commitd2f6409584e2c62ffad81690562330ff3bf4a458 (patch)
tree3bdfb97d0b51be2f7f414f2107e97603c1206abb /security/keys/key.c
parente1b09eba2686eca94a3a188042b518df6044a3c1 (diff)
parent4a89a04f1ee21a7c1f4413f1ad7dcfac50ff9b63 (diff)
Merge with master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'security/keys/key.c')
-rw-r--r--security/keys/key.c118
1 files changed, 60 insertions, 58 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index 59402c843203..fb89f9844465 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/* key.c: basic authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 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
@@ -294,7 +294,6 @@ struct key *key_alloc(struct key_type *type, const char *desc,
294 } 294 }
295 295
296 atomic_set(&key->usage, 1); 296 atomic_set(&key->usage, 1);
297 rwlock_init(&key->lock);
298 init_rwsem(&key->sem); 297 init_rwsem(&key->sem);
299 key->type = type; 298 key->type = type;
300 key->user = user; 299 key->user = user;
@@ -308,7 +307,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
308 key->payload.data = NULL; 307 key->payload.data = NULL;
309 308
310 if (!not_in_quota) 309 if (!not_in_quota)
311 key->flags |= KEY_FLAG_IN_QUOTA; 310 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
312 311
313 memset(&key->type_data, 0, sizeof(key->type_data)); 312 memset(&key->type_data, 0, sizeof(key->type_data));
314 313
@@ -359,7 +358,7 @@ int key_payload_reserve(struct key *key, size_t datalen)
359 key_check(key); 358 key_check(key);
360 359
361 /* contemplate the quota adjustment */ 360 /* contemplate the quota adjustment */
362 if (delta != 0 && key->flags & KEY_FLAG_IN_QUOTA) { 361 if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
363 spin_lock(&key->user->lock); 362 spin_lock(&key->user->lock);
364 363
365 if (delta > 0 && 364 if (delta > 0 &&
@@ -392,7 +391,8 @@ EXPORT_SYMBOL(key_payload_reserve);
392static int __key_instantiate_and_link(struct key *key, 391static int __key_instantiate_and_link(struct key *key,
393 const void *data, 392 const void *data,
394 size_t datalen, 393 size_t datalen,
395 struct key *keyring) 394 struct key *keyring,
395 struct key *instkey)
396{ 396{
397 int ret, awaken; 397 int ret, awaken;
398 398
@@ -405,27 +405,25 @@ static int __key_instantiate_and_link(struct key *key,
405 down_write(&key_construction_sem); 405 down_write(&key_construction_sem);
406 406
407 /* can't instantiate twice */ 407 /* can't instantiate twice */
408 if (!(key->flags & KEY_FLAG_INSTANTIATED)) { 408 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
409 /* instantiate the key */ 409 /* instantiate the key */
410 ret = key->type->instantiate(key, data, datalen); 410 ret = key->type->instantiate(key, data, datalen);
411 411
412 if (ret == 0) { 412 if (ret == 0) {
413 /* mark the key as being instantiated */ 413 /* mark the key as being instantiated */
414 write_lock(&key->lock);
415
416 atomic_inc(&key->user->nikeys); 414 atomic_inc(&key->user->nikeys);
417 key->flags |= KEY_FLAG_INSTANTIATED; 415 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
418 416
419 if (key->flags & KEY_FLAG_USER_CONSTRUCT) { 417 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
420 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
421 awaken = 1; 418 awaken = 1;
422 }
423
424 write_unlock(&key->lock);
425 419
426 /* and link it into the destination keyring */ 420 /* and link it into the destination keyring */
427 if (keyring) 421 if (keyring)
428 ret = __key_link(keyring, key); 422 ret = __key_link(keyring, key);
423
424 /* disable the authorisation key */
425 if (instkey)
426 key_revoke(instkey);
429 } 427 }
430 } 428 }
431 429
@@ -446,19 +444,21 @@ static int __key_instantiate_and_link(struct key *key,
446int key_instantiate_and_link(struct key *key, 444int key_instantiate_and_link(struct key *key,
447 const void *data, 445 const void *data,
448 size_t datalen, 446 size_t datalen,
449 struct key *keyring) 447 struct key *keyring,
448 struct key *instkey)
450{ 449{
451 int ret; 450 int ret;
452 451
453 if (keyring) 452 if (keyring)
454 down_write(&keyring->sem); 453 down_write(&keyring->sem);
455 454
456 ret = __key_instantiate_and_link(key, data, datalen, keyring); 455 ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey);
457 456
458 if (keyring) 457 if (keyring)
459 up_write(&keyring->sem); 458 up_write(&keyring->sem);
460 459
461 return ret; 460 return ret;
461
462} /* end key_instantiate_and_link() */ 462} /* end key_instantiate_and_link() */
463 463
464EXPORT_SYMBOL(key_instantiate_and_link); 464EXPORT_SYMBOL(key_instantiate_and_link);
@@ -469,7 +469,8 @@ EXPORT_SYMBOL(key_instantiate_and_link);
469 */ 469 */
470int key_negate_and_link(struct key *key, 470int key_negate_and_link(struct key *key,
471 unsigned timeout, 471 unsigned timeout,
472 struct key *keyring) 472 struct key *keyring,
473 struct key *instkey)
473{ 474{
474 struct timespec now; 475 struct timespec now;
475 int ret, awaken; 476 int ret, awaken;
@@ -486,26 +487,26 @@ int key_negate_and_link(struct key *key,
486 down_write(&key_construction_sem); 487 down_write(&key_construction_sem);
487 488
488 /* can't instantiate twice */ 489 /* can't instantiate twice */
489 if (!(key->flags & KEY_FLAG_INSTANTIATED)) { 490 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
490 /* mark the key as being negatively instantiated */ 491 /* mark the key as being negatively instantiated */
491 write_lock(&key->lock);
492
493 atomic_inc(&key->user->nikeys); 492 atomic_inc(&key->user->nikeys);
494 key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE; 493 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
494 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
495 now = current_kernel_time(); 495 now = current_kernel_time();
496 key->expiry = now.tv_sec + timeout; 496 key->expiry = now.tv_sec + timeout;
497 497
498 if (key->flags & KEY_FLAG_USER_CONSTRUCT) { 498 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
499 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
500 awaken = 1; 499 awaken = 1;
501 }
502 500
503 write_unlock(&key->lock);
504 ret = 0; 501 ret = 0;
505 502
506 /* and link it into the destination keyring */ 503 /* and link it into the destination keyring */
507 if (keyring) 504 if (keyring)
508 ret = __key_link(keyring, key); 505 ret = __key_link(keyring, key);
506
507 /* disable the authorisation key */
508 if (instkey)
509 key_revoke(instkey);
509 } 510 }
510 511
511 up_write(&key_construction_sem); 512 up_write(&key_construction_sem);
@@ -553,8 +554,10 @@ static void key_cleanup(void *data)
553 rb_erase(&key->serial_node, &key_serial_tree); 554 rb_erase(&key->serial_node, &key_serial_tree);
554 spin_unlock(&key_serial_lock); 555 spin_unlock(&key_serial_lock);
555 556
557 key_check(key);
558
556 /* deal with the user's key tracking and quota */ 559 /* deal with the user's key tracking and quota */
557 if (key->flags & KEY_FLAG_IN_QUOTA) { 560 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
558 spin_lock(&key->user->lock); 561 spin_lock(&key->user->lock);
559 key->user->qnkeys--; 562 key->user->qnkeys--;
560 key->user->qnbytes -= key->quotalen; 563 key->user->qnbytes -= key->quotalen;
@@ -562,7 +565,7 @@ static void key_cleanup(void *data)
562 } 565 }
563 566
564 atomic_dec(&key->user->nkeys); 567 atomic_dec(&key->user->nkeys);
565 if (key->flags & KEY_FLAG_INSTANTIATED) 568 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
566 atomic_dec(&key->user->nikeys); 569 atomic_dec(&key->user->nikeys);
567 570
568 key_user_put(key->user); 571 key_user_put(key->user);
@@ -631,9 +634,9 @@ struct key *key_lookup(key_serial_t id)
631 goto error; 634 goto error;
632 635
633 found: 636 found:
634 /* pretent doesn't exist if it's dead */ 637 /* pretend it doesn't exist if it's dead */
635 if (atomic_read(&key->usage) == 0 || 638 if (atomic_read(&key->usage) == 0 ||
636 (key->flags & KEY_FLAG_DEAD) || 639 test_bit(KEY_FLAG_DEAD, &key->flags) ||
637 key->type == &key_type_dead) 640 key->type == &key_type_dead)
638 goto not_found; 641 goto not_found;
639 642
@@ -708,12 +711,9 @@ static inline struct key *__key_update(struct key *key, const void *payload,
708 711
709 ret = key->type->update(key, payload, plen); 712 ret = key->type->update(key, payload, plen);
710 713
711 if (ret == 0) { 714 if (ret == 0)
712 /* updating a negative key instantiates it */ 715 /* updating a negative key instantiates it */
713 write_lock(&key->lock); 716 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
714 key->flags &= ~KEY_FLAG_NEGATIVE;
715 write_unlock(&key->lock);
716 }
717 717
718 up_write(&key->sem); 718 up_write(&key->sem);
719 719
@@ -793,7 +793,7 @@ struct key *key_create_or_update(struct key *keyring,
793 } 793 }
794 794
795 /* instantiate it and link it into the target keyring */ 795 /* instantiate it and link it into the target keyring */
796 ret = __key_instantiate_and_link(key, payload, plen, keyring); 796 ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
797 if (ret < 0) { 797 if (ret < 0) {
798 key_put(key); 798 key_put(key);
799 key = ERR_PTR(ret); 799 key = ERR_PTR(ret);
@@ -841,12 +841,9 @@ int key_update(struct key *key, const void *payload, size_t plen)
841 down_write(&key->sem); 841 down_write(&key->sem);
842 ret = key->type->update(key, payload, plen); 842 ret = key->type->update(key, payload, plen);
843 843
844 if (ret == 0) { 844 if (ret == 0)
845 /* updating a negative key instantiates it */ 845 /* updating a negative key instantiates it */
846 write_lock(&key->lock); 846 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
847 key->flags &= ~KEY_FLAG_NEGATIVE;
848 write_unlock(&key->lock);
849 }
850 847
851 up_write(&key->sem); 848 up_write(&key->sem);
852 } 849 }
@@ -892,10 +889,7 @@ struct key *key_duplicate(struct key *source, const char *desc)
892 goto error2; 889 goto error2;
893 890
894 atomic_inc(&key->user->nikeys); 891 atomic_inc(&key->user->nikeys);
895 892 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
896 write_lock(&key->lock);
897 key->flags |= KEY_FLAG_INSTANTIATED;
898 write_unlock(&key->lock);
899 893
900 error_k: 894 error_k:
901 up_read(&key_types_sem); 895 up_read(&key_types_sem);
@@ -922,9 +916,7 @@ void key_revoke(struct key *key)
922 /* make sure no one's trying to change or use the key when we mark 916 /* make sure no one's trying to change or use the key when we mark
923 * it */ 917 * it */
924 down_write(&key->sem); 918 down_write(&key->sem);
925 write_lock(&key->lock); 919 set_bit(KEY_FLAG_REVOKED, &key->flags);
926 key->flags |= KEY_FLAG_REVOKED;
927 write_unlock(&key->lock);
928 up_write(&key->sem); 920 up_write(&key->sem);
929 921
930} /* end key_revoke() */ 922} /* end key_revoke() */
@@ -975,24 +967,33 @@ void unregister_key_type(struct key_type *ktype)
975 /* withdraw the key type */ 967 /* withdraw the key type */
976 list_del_init(&ktype->link); 968 list_del_init(&ktype->link);
977 969
978 /* need to withdraw all keys of this type */ 970 /* mark all the keys of this type dead */
979 spin_lock(&key_serial_lock); 971 spin_lock(&key_serial_lock);
980 972
981 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { 973 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
982 key = rb_entry(_n, struct key, serial_node); 974 key = rb_entry(_n, struct key, serial_node);
983 975
984 if (key->type != ktype) 976 if (key->type == ktype)
985 continue; 977 key->type = &key_type_dead;
978 }
979
980 spin_unlock(&key_serial_lock);
981
982 /* make sure everyone revalidates their keys */
983 synchronize_rcu();
986 984
987 write_lock(&key->lock); 985 /* we should now be able to destroy the payloads of all the keys of
988 key->type = &key_type_dead; 986 * this type with impunity */
989 write_unlock(&key->lock); 987 spin_lock(&key_serial_lock);
988
989 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
990 key = rb_entry(_n, struct key, serial_node);
990 991
991 /* there shouldn't be anyone looking at the description or 992 if (key->type == ktype) {
992 * payload now */ 993 if (ktype->destroy)
993 if (ktype->destroy) 994 ktype->destroy(key);
994 ktype->destroy(key); 995 memset(&key->payload, 0xbd, sizeof(key->payload));
995 memset(&key->payload, 0xbd, sizeof(key->payload)); 996 }
996 } 997 }
997 998
998 spin_unlock(&key_serial_lock); 999 spin_unlock(&key_serial_lock);
@@ -1037,4 +1038,5 @@ void __init key_init(void)
1037 1038
1038 /* link the two root keyrings together */ 1039 /* link the two root keyrings together */
1039 key_link(&root_session_keyring, &root_user_keyring); 1040 key_link(&root_session_keyring, &root_user_keyring);
1041
1040} /* end key_init() */ 1042} /* end key_init() */