aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2013-09-24 05:35:15 -0400
committerDavid Howells <dhowells@redhat.com>2013-09-24 05:35:15 -0400
commit16feef4340172b7dbb9cba60850e78fa6388adf1 (patch)
tree192d76bb3ba75b99c4a4746e2d47996b92b46e39 /security/keys
parent7e55ca6dcd07b45619035df343c9614a3ab35034 (diff)
KEYS: Consolidate the concept of an 'index key' for key access
Consolidate the concept of an 'index key' for accessing keys. The index key is the search term needed to find a key directly - basically the key type and the key description. We can add to that the description length. This will be useful when turning a keyring into an associative array rather than just a pointer block. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/internal.h8
-rw-r--r--security/keys/key.c72
-rw-r--r--security/keys/keyring.c37
-rw-r--r--security/keys/request_key.c12
4 files changed, 67 insertions, 62 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 490aef5ba34b..77441dd1f9d4 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -89,19 +89,17 @@ extern struct key_type *key_type_lookup(const char *type);
89extern void key_type_put(struct key_type *ktype); 89extern void key_type_put(struct key_type *ktype);
90 90
91extern int __key_link_begin(struct key *keyring, 91extern int __key_link_begin(struct key *keyring,
92 const struct key_type *type, 92 const struct keyring_index_key *index_key,
93 const char *description,
94 unsigned long *_prealloc); 93 unsigned long *_prealloc);
95extern int __key_link_check_live_key(struct key *keyring, struct key *key); 94extern int __key_link_check_live_key(struct key *keyring, struct key *key);
96extern void __key_link(struct key *keyring, struct key *key, 95extern void __key_link(struct key *keyring, struct key *key,
97 unsigned long *_prealloc); 96 unsigned long *_prealloc);
98extern void __key_link_end(struct key *keyring, 97extern void __key_link_end(struct key *keyring,
99 struct key_type *type, 98 const struct keyring_index_key *index_key,
100 unsigned long prealloc); 99 unsigned long prealloc);
101 100
102extern key_ref_t __keyring_search_one(key_ref_t keyring_ref, 101extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
103 const struct key_type *type, 102 const struct keyring_index_key *index_key,
104 const char *description,
105 key_perm_t perm); 103 key_perm_t perm);
106 104
107extern struct key *keyring_search_instkey(struct key *keyring, 105extern struct key *keyring_search_instkey(struct key *keyring,
diff --git a/security/keys/key.c b/security/keys/key.c
index 8fb7c7bd4657..7e6bc396bb23 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -242,8 +242,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
242 } 242 }
243 } 243 }
244 244
245 desclen = strlen(desc) + 1; 245 desclen = strlen(desc);
246 quotalen = desclen + type->def_datalen; 246 quotalen = desclen + 1 + type->def_datalen;
247 247
248 /* get hold of the key tracking for this user */ 248 /* get hold of the key tracking for this user */
249 user = key_user_lookup(uid); 249 user = key_user_lookup(uid);
@@ -277,7 +277,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
277 goto no_memory_2; 277 goto no_memory_2;
278 278
279 if (desc) { 279 if (desc) {
280 key->description = kmemdup(desc, desclen, GFP_KERNEL); 280 key->index_key.desc_len = desclen;
281 key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL);
281 if (!key->description) 282 if (!key->description)
282 goto no_memory_3; 283 goto no_memory_3;
283 } 284 }
@@ -285,7 +286,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
285 atomic_set(&key->usage, 1); 286 atomic_set(&key->usage, 1);
286 init_rwsem(&key->sem); 287 init_rwsem(&key->sem);
287 lockdep_set_class(&key->sem, &type->lock_class); 288 lockdep_set_class(&key->sem, &type->lock_class);
288 key->type = type; 289 key->index_key.type = type;
289 key->user = user; 290 key->user = user;
290 key->quotalen = quotalen; 291 key->quotalen = quotalen;
291 key->datalen = type->def_datalen; 292 key->datalen = type->def_datalen;
@@ -489,8 +490,7 @@ int key_instantiate_and_link(struct key *key,
489 } 490 }
490 491
491 if (keyring) { 492 if (keyring) {
492 ret = __key_link_begin(keyring, key->type, key->description, 493 ret = __key_link_begin(keyring, &key->index_key, &prealloc);
493 &prealloc);
494 if (ret < 0) 494 if (ret < 0)
495 goto error_free_preparse; 495 goto error_free_preparse;
496 } 496 }
@@ -499,7 +499,7 @@ int key_instantiate_and_link(struct key *key,
499 &prealloc); 499 &prealloc);
500 500
501 if (keyring) 501 if (keyring)
502 __key_link_end(keyring, key->type, prealloc); 502 __key_link_end(keyring, &key->index_key, prealloc);
503 503
504error_free_preparse: 504error_free_preparse:
505 if (key->type->preparse) 505 if (key->type->preparse)
@@ -548,8 +548,7 @@ int key_reject_and_link(struct key *key,
548 ret = -EBUSY; 548 ret = -EBUSY;
549 549
550 if (keyring) 550 if (keyring)
551 link_ret = __key_link_begin(keyring, key->type, 551 link_ret = __key_link_begin(keyring, &key->index_key, &prealloc);
552 key->description, &prealloc);
553 552
554 mutex_lock(&key_construction_mutex); 553 mutex_lock(&key_construction_mutex);
555 554
@@ -581,7 +580,7 @@ int key_reject_and_link(struct key *key,
581 mutex_unlock(&key_construction_mutex); 580 mutex_unlock(&key_construction_mutex);
582 581
583 if (keyring) 582 if (keyring)
584 __key_link_end(keyring, key->type, prealloc); 583 __key_link_end(keyring, &key->index_key, prealloc);
585 584
586 /* wake up anyone waiting for a key to be constructed */ 585 /* wake up anyone waiting for a key to be constructed */
587 if (awaken) 586 if (awaken)
@@ -780,25 +779,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
780 key_perm_t perm, 779 key_perm_t perm,
781 unsigned long flags) 780 unsigned long flags)
782{ 781{
783 unsigned long prealloc; 782 struct keyring_index_key index_key = {
783 .description = description,
784 };
784 struct key_preparsed_payload prep; 785 struct key_preparsed_payload prep;
785 const struct cred *cred = current_cred(); 786 const struct cred *cred = current_cred();
786 struct key_type *ktype; 787 unsigned long prealloc;
787 struct key *keyring, *key = NULL; 788 struct key *keyring, *key = NULL;
788 key_ref_t key_ref; 789 key_ref_t key_ref;
789 int ret; 790 int ret;
790 791
791 /* look up the key type to see if it's one of the registered kernel 792 /* look up the key type to see if it's one of the registered kernel
792 * types */ 793 * types */
793 ktype = key_type_lookup(type); 794 index_key.type = key_type_lookup(type);
794 if (IS_ERR(ktype)) { 795 if (IS_ERR(index_key.type)) {
795 key_ref = ERR_PTR(-ENODEV); 796 key_ref = ERR_PTR(-ENODEV);
796 goto error; 797 goto error;
797 } 798 }
798 799
799 key_ref = ERR_PTR(-EINVAL); 800 key_ref = ERR_PTR(-EINVAL);
800 if (!ktype->match || !ktype->instantiate || 801 if (!index_key.type->match || !index_key.type->instantiate ||
801 (!description && !ktype->preparse)) 802 (!index_key.description && !index_key.type->preparse))
802 goto error_put_type; 803 goto error_put_type;
803 804
804 keyring = key_ref_to_ptr(keyring_ref); 805 keyring = key_ref_to_ptr(keyring_ref);
@@ -812,21 +813,22 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
812 memset(&prep, 0, sizeof(prep)); 813 memset(&prep, 0, sizeof(prep));
813 prep.data = payload; 814 prep.data = payload;
814 prep.datalen = plen; 815 prep.datalen = plen;
815 prep.quotalen = ktype->def_datalen; 816 prep.quotalen = index_key.type->def_datalen;
816 if (ktype->preparse) { 817 if (index_key.type->preparse) {
817 ret = ktype->preparse(&prep); 818 ret = index_key.type->preparse(&prep);
818 if (ret < 0) { 819 if (ret < 0) {
819 key_ref = ERR_PTR(ret); 820 key_ref = ERR_PTR(ret);
820 goto error_put_type; 821 goto error_put_type;
821 } 822 }
822 if (!description) 823 if (!index_key.description)
823 description = prep.description; 824 index_key.description = prep.description;
824 key_ref = ERR_PTR(-EINVAL); 825 key_ref = ERR_PTR(-EINVAL);
825 if (!description) 826 if (!index_key.description)
826 goto error_free_prep; 827 goto error_free_prep;
827 } 828 }
829 index_key.desc_len = strlen(index_key.description);
828 830
829 ret = __key_link_begin(keyring, ktype, description, &prealloc); 831 ret = __key_link_begin(keyring, &index_key, &prealloc);
830 if (ret < 0) { 832 if (ret < 0) {
831 key_ref = ERR_PTR(ret); 833 key_ref = ERR_PTR(ret);
832 goto error_free_prep; 834 goto error_free_prep;
@@ -844,9 +846,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
844 * key of the same type and description in the destination keyring and 846 * key of the same type and description in the destination keyring and
845 * update that instead if possible 847 * update that instead if possible
846 */ 848 */
847 if (ktype->update) { 849 if (index_key.type->update) {
848 key_ref = __keyring_search_one(keyring_ref, ktype, description, 850 key_ref = __keyring_search_one(keyring_ref, &index_key, 0);
849 0);
850 if (!IS_ERR(key_ref)) 851 if (!IS_ERR(key_ref))
851 goto found_matching_key; 852 goto found_matching_key;
852 } 853 }
@@ -856,16 +857,17 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
856 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; 857 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
857 perm |= KEY_USR_VIEW; 858 perm |= KEY_USR_VIEW;
858 859
859 if (ktype->read) 860 if (index_key.type->read)
860 perm |= KEY_POS_READ; 861 perm |= KEY_POS_READ;
861 862
862 if (ktype == &key_type_keyring || ktype->update) 863 if (index_key.type == &key_type_keyring ||
864 index_key.type->update)
863 perm |= KEY_POS_WRITE; 865 perm |= KEY_POS_WRITE;
864 } 866 }
865 867
866 /* allocate a new key */ 868 /* allocate a new key */
867 key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred, 869 key = key_alloc(index_key.type, index_key.description,
868 perm, flags); 870 cred->fsuid, cred->fsgid, cred, perm, flags);
869 if (IS_ERR(key)) { 871 if (IS_ERR(key)) {
870 key_ref = ERR_CAST(key); 872 key_ref = ERR_CAST(key);
871 goto error_link_end; 873 goto error_link_end;
@@ -882,12 +884,12 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
882 key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); 884 key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
883 885
884error_link_end: 886error_link_end:
885 __key_link_end(keyring, ktype, prealloc); 887 __key_link_end(keyring, &index_key, prealloc);
886error_free_prep: 888error_free_prep:
887 if (ktype->preparse) 889 if (index_key.type->preparse)
888 ktype->free_preparse(&prep); 890 index_key.type->free_preparse(&prep);
889error_put_type: 891error_put_type:
890 key_type_put(ktype); 892 key_type_put(index_key.type);
891error: 893error:
892 return key_ref; 894 return key_ref;
893 895
@@ -895,7 +897,7 @@ error:
895 /* we found a matching key, so we're going to try to update it 897 /* we found a matching key, so we're going to try to update it
896 * - we can drop the locks first as we have the key pinned 898 * - we can drop the locks first as we have the key pinned
897 */ 899 */
898 __key_link_end(keyring, ktype, prealloc); 900 __key_link_end(keyring, &index_key, prealloc);
899 901
900 key_ref = __key_update(key_ref, &prep); 902 key_ref = __key_update(key_ref, &prep);
901 goto error_free_prep; 903 goto error_free_prep;
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index f78406372ebe..c7f59f9dd7b6 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -538,8 +538,7 @@ EXPORT_SYMBOL(keyring_search);
538 * to the returned key reference. 538 * to the returned key reference.
539 */ 539 */
540key_ref_t __keyring_search_one(key_ref_t keyring_ref, 540key_ref_t __keyring_search_one(key_ref_t keyring_ref,
541 const struct key_type *ktype, 541 const struct keyring_index_key *index_key,
542 const char *description,
543 key_perm_t perm) 542 key_perm_t perm)
544{ 543{
545 struct keyring_list *klist; 544 struct keyring_list *klist;
@@ -558,9 +557,9 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
558 smp_rmb(); 557 smp_rmb();
559 for (loop = 0; loop < nkeys ; loop++) { 558 for (loop = 0; loop < nkeys ; loop++) {
560 key = rcu_dereference(klist->keys[loop]); 559 key = rcu_dereference(klist->keys[loop]);
561 if (key->type == ktype && 560 if (key->type == index_key->type &&
562 (!key->type->match || 561 (!key->type->match ||
563 key->type->match(key, description)) && 562 key->type->match(key, index_key->description)) &&
564 key_permission(make_key_ref(key, possessed), 563 key_permission(make_key_ref(key, possessed),
565 perm) == 0 && 564 perm) == 0 &&
566 !(key->flags & ((1 << KEY_FLAG_INVALIDATED) | 565 !(key->flags & ((1 << KEY_FLAG_INVALIDATED) |
@@ -747,8 +746,8 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
747/* 746/*
748 * Preallocate memory so that a key can be linked into to a keyring. 747 * Preallocate memory so that a key can be linked into to a keyring.
749 */ 748 */
750int __key_link_begin(struct key *keyring, const struct key_type *type, 749int __key_link_begin(struct key *keyring, const struct keyring_index_key *index_key,
751 const char *description, unsigned long *_prealloc) 750 unsigned long *_prealloc)
752 __acquires(&keyring->sem) 751 __acquires(&keyring->sem)
753 __acquires(&keyring_serialise_link_sem) 752 __acquires(&keyring_serialise_link_sem)
754{ 753{
@@ -759,7 +758,8 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
759 size_t size; 758 size_t size;
760 int loop, lru, ret; 759 int loop, lru, ret;
761 760
762 kenter("%d,%s,%s,", key_serial(keyring), type->name, description); 761 kenter("%d,%s,%s,",
762 key_serial(keyring), index_key->type->name, index_key->description);
763 763
764 if (keyring->type != &key_type_keyring) 764 if (keyring->type != &key_type_keyring)
765 return -ENOTDIR; 765 return -ENOTDIR;
@@ -772,7 +772,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
772 772
773 /* serialise link/link calls to prevent parallel calls causing a cycle 773 /* serialise link/link calls to prevent parallel calls causing a cycle
774 * when linking two keyring in opposite orders */ 774 * when linking two keyring in opposite orders */
775 if (type == &key_type_keyring) 775 if (index_key->type == &key_type_keyring)
776 down_write(&keyring_serialise_link_sem); 776 down_write(&keyring_serialise_link_sem);
777 777
778 klist = rcu_dereference_locked_keyring(keyring); 778 klist = rcu_dereference_locked_keyring(keyring);
@@ -784,8 +784,8 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
784 for (loop = klist->nkeys - 1; loop >= 0; loop--) { 784 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
785 struct key *key = rcu_deref_link_locked(klist, loop, 785 struct key *key = rcu_deref_link_locked(klist, loop,
786 keyring); 786 keyring);
787 if (key->type == type && 787 if (key->type == index_key->type &&
788 strcmp(key->description, description) == 0) { 788 strcmp(key->description, index_key->description) == 0) {
789 /* Found a match - we'll replace the link with 789 /* Found a match - we'll replace the link with
790 * one to the new key. We record the slot 790 * one to the new key. We record the slot
791 * position. 791 * position.
@@ -865,7 +865,7 @@ error_quota:
865 key_payload_reserve(keyring, 865 key_payload_reserve(keyring,
866 keyring->datalen - KEYQUOTA_LINK_BYTES); 866 keyring->datalen - KEYQUOTA_LINK_BYTES);
867error_sem: 867error_sem:
868 if (type == &key_type_keyring) 868 if (index_key->type == &key_type_keyring)
869 up_write(&keyring_serialise_link_sem); 869 up_write(&keyring_serialise_link_sem);
870error_krsem: 870error_krsem:
871 up_write(&keyring->sem); 871 up_write(&keyring->sem);
@@ -957,16 +957,17 @@ void __key_link(struct key *keyring, struct key *key,
957 * 957 *
958 * Must be called with __key_link_begin() having being called. 958 * Must be called with __key_link_begin() having being called.
959 */ 959 */
960void __key_link_end(struct key *keyring, struct key_type *type, 960void __key_link_end(struct key *keyring,
961 const struct keyring_index_key *index_key,
961 unsigned long prealloc) 962 unsigned long prealloc)
962 __releases(&keyring->sem) 963 __releases(&keyring->sem)
963 __releases(&keyring_serialise_link_sem) 964 __releases(&keyring_serialise_link_sem)
964{ 965{
965 BUG_ON(type == NULL); 966 BUG_ON(index_key->type == NULL);
966 BUG_ON(type->name == NULL); 967 BUG_ON(index_key->type->name == NULL);
967 kenter("%d,%s,%lx", keyring->serial, type->name, prealloc); 968 kenter("%d,%s,%lx", keyring->serial, index_key->type->name, prealloc);
968 969
969 if (type == &key_type_keyring) 970 if (index_key->type == &key_type_keyring)
970 up_write(&keyring_serialise_link_sem); 971 up_write(&keyring_serialise_link_sem);
971 972
972 if (prealloc) { 973 if (prealloc) {
@@ -1007,12 +1008,12 @@ int key_link(struct key *keyring, struct key *key)
1007 key_check(keyring); 1008 key_check(keyring);
1008 key_check(key); 1009 key_check(key);
1009 1010
1010 ret = __key_link_begin(keyring, key->type, key->description, &prealloc); 1011 ret = __key_link_begin(keyring, &key->index_key, &prealloc);
1011 if (ret == 0) { 1012 if (ret == 0) {
1012 ret = __key_link_check_live_key(keyring, key); 1013 ret = __key_link_check_live_key(keyring, key);
1013 if (ret == 0) 1014 if (ret == 0)
1014 __key_link(keyring, key, &prealloc); 1015 __key_link(keyring, key, &prealloc);
1015 __key_link_end(keyring, key->type, prealloc); 1016 __key_link_end(keyring, &key->index_key, prealloc);
1016 } 1017 }
1017 1018
1018 return ret; 1019 return ret;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 172115b38054..586cb79ee82d 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -352,6 +352,11 @@ static int construct_alloc_key(struct key_type *type,
352 struct key_user *user, 352 struct key_user *user,
353 struct key **_key) 353 struct key **_key)
354{ 354{
355 const struct keyring_index_key index_key = {
356 .type = type,
357 .description = description,
358 .desc_len = strlen(description),
359 };
355 const struct cred *cred = current_cred(); 360 const struct cred *cred = current_cred();
356 unsigned long prealloc; 361 unsigned long prealloc;
357 struct key *key; 362 struct key *key;
@@ -379,8 +384,7 @@ static int construct_alloc_key(struct key_type *type,
379 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags); 384 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
380 385
381 if (dest_keyring) { 386 if (dest_keyring) {
382 ret = __key_link_begin(dest_keyring, type, description, 387 ret = __key_link_begin(dest_keyring, &index_key, &prealloc);
383 &prealloc);
384 if (ret < 0) 388 if (ret < 0)
385 goto link_prealloc_failed; 389 goto link_prealloc_failed;
386 } 390 }
@@ -400,7 +404,7 @@ static int construct_alloc_key(struct key_type *type,
400 404
401 mutex_unlock(&key_construction_mutex); 405 mutex_unlock(&key_construction_mutex);
402 if (dest_keyring) 406 if (dest_keyring)
403 __key_link_end(dest_keyring, type, prealloc); 407 __key_link_end(dest_keyring, &index_key, prealloc);
404 mutex_unlock(&user->cons_lock); 408 mutex_unlock(&user->cons_lock);
405 *_key = key; 409 *_key = key;
406 kleave(" = 0 [%d]", key_serial(key)); 410 kleave(" = 0 [%d]", key_serial(key));
@@ -416,7 +420,7 @@ key_already_present:
416 ret = __key_link_check_live_key(dest_keyring, key); 420 ret = __key_link_check_live_key(dest_keyring, key);
417 if (ret == 0) 421 if (ret == 0)
418 __key_link(dest_keyring, key, &prealloc); 422 __key_link(dest_keyring, key, &prealloc);
419 __key_link_end(dest_keyring, type, prealloc); 423 __key_link_end(dest_keyring, &index_key, prealloc);
420 if (ret < 0) 424 if (ret < 0)
421 goto link_check_failed; 425 goto link_check_failed;
422 } 426 }