aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-09-16 12:36:02 -0400
committerDavid Howells <dhowells@redhat.com>2014-09-16 12:36:02 -0400
commit462919591a1791e76042dc5c1e0148715df59beb (patch)
tree44a60ee5f08eab18b1a69f98d993f9a47a45fece /security/keys/keyring.c
parent53d91c5ce0cb8945b55e8bb54e551cabc51eb28d (diff)
KEYS: Preparse match data
Preparse the match data. This provides several advantages: (1) The preparser can reject invalid criteria up front. (2) The preparser can convert the criteria to binary data if necessary (the asymmetric key type really wants to do binary comparison of the key IDs). (3) The preparser can set the type of search to be performed. This means that it's not then a one-off setting in the key type. (4) The preparser can set an appropriate comparator function. Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Vivek Goyal <vgoyal@redhat.com>
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 8314a7d2104d..10f0a5f2d362 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -545,7 +545,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
545 } 545 }
546 546
547 /* keys that don't match */ 547 /* keys that don't match */
548 if (!ctx->match(key, ctx->match_data)) { 548 if (!ctx->match_data.cmp(key, &ctx->match_data)) {
549 kleave(" = 0 [!match]"); 549 kleave(" = 0 [!match]");
550 return 0; 550 return 0;
551 } 551 }
@@ -585,8 +585,7 @@ skipped:
585 */ 585 */
586static int search_keyring(struct key *keyring, struct keyring_search_context *ctx) 586static int search_keyring(struct key *keyring, struct keyring_search_context *ctx)
587{ 587{
588 if ((ctx->flags & KEYRING_SEARCH_LOOKUP_TYPE) == 588 if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_DIRECT) {
589 KEYRING_SEARCH_LOOKUP_DIRECT) {
590 const void *object; 589 const void *object;
591 590
592 object = assoc_array_find(&keyring->keys, 591 object = assoc_array_find(&keyring->keys,
@@ -627,7 +626,7 @@ static bool search_nested_keyrings(struct key *keyring,
627 /* Check to see if this top-level keyring is what we are looking for 626 /* Check to see if this top-level keyring is what we are looking for
628 * and whether it is valid or not. 627 * and whether it is valid or not.
629 */ 628 */
630 if (ctx->flags & KEYRING_SEARCH_LOOKUP_ITERATE || 629 if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_ITERATE ||
631 keyring_compare_object(keyring, &ctx->index_key)) { 630 keyring_compare_object(keyring, &ctx->index_key)) {
632 ctx->skipped_ret = 2; 631 ctx->skipped_ret = 2;
633 ctx->flags |= KEYRING_SEARCH_DO_STATE_CHECK; 632 ctx->flags |= KEYRING_SEARCH_DO_STATE_CHECK;
@@ -885,16 +884,28 @@ key_ref_t keyring_search(key_ref_t keyring,
885 .index_key.type = type, 884 .index_key.type = type,
886 .index_key.description = description, 885 .index_key.description = description,
887 .cred = current_cred(), 886 .cred = current_cred(),
888 .match = type->match, 887 .match_data.cmp = type->match,
889 .match_data = description, 888 .match_data.raw_data = description,
890 .flags = (type->def_lookup_type | 889 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
891 KEYRING_SEARCH_DO_STATE_CHECK), 890 .flags = KEYRING_SEARCH_DO_STATE_CHECK,
892 }; 891 };
892 key_ref_t key;
893 int ret;
893 894
894 if (!ctx.match) 895 if (!ctx.match_data.cmp)
895 return ERR_PTR(-ENOKEY); 896 return ERR_PTR(-ENOKEY);
896 897
897 return keyring_search_aux(keyring, &ctx); 898 if (type->match_preparse) {
899 ret = type->match_preparse(&ctx.match_data);
900 if (ret < 0)
901 return ERR_PTR(ret);
902 }
903
904 key = keyring_search_aux(keyring, &ctx);
905
906 if (type->match_free)
907 type->match_free(&ctx.match_data);
908 return key;
898} 909}
899EXPORT_SYMBOL(keyring_search); 910EXPORT_SYMBOL(keyring_search);
900 911
@@ -1014,7 +1025,7 @@ static int keyring_detect_cycle_iterator(const void *object,
1014 1025
1015 /* We might get a keyring with matching index-key that is nonetheless a 1026 /* We might get a keyring with matching index-key that is nonetheless a
1016 * different keyring. */ 1027 * different keyring. */
1017 if (key != ctx->match_data) 1028 if (key != ctx->match_data.raw_data)
1018 return 0; 1029 return 0;
1019 1030
1020 ctx->result = ERR_PTR(-EDEADLK); 1031 ctx->result = ERR_PTR(-EDEADLK);
@@ -1031,14 +1042,14 @@ static int keyring_detect_cycle_iterator(const void *object,
1031static int keyring_detect_cycle(struct key *A, struct key *B) 1042static int keyring_detect_cycle(struct key *A, struct key *B)
1032{ 1043{
1033 struct keyring_search_context ctx = { 1044 struct keyring_search_context ctx = {
1034 .index_key = A->index_key, 1045 .index_key = A->index_key,
1035 .match_data = A, 1046 .match_data.raw_data = A,
1036 .iterator = keyring_detect_cycle_iterator, 1047 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
1037 .flags = (KEYRING_SEARCH_LOOKUP_DIRECT | 1048 .iterator = keyring_detect_cycle_iterator,
1038 KEYRING_SEARCH_NO_STATE_CHECK | 1049 .flags = (KEYRING_SEARCH_NO_STATE_CHECK |
1039 KEYRING_SEARCH_NO_UPDATE_TIME | 1050 KEYRING_SEARCH_NO_UPDATE_TIME |
1040 KEYRING_SEARCH_NO_CHECK_PERM | 1051 KEYRING_SEARCH_NO_CHECK_PERM |
1041 KEYRING_SEARCH_DETECT_TOO_DEEP), 1052 KEYRING_SEARCH_DETECT_TOO_DEEP),
1042 }; 1053 };
1043 1054
1044 rcu_read_lock(); 1055 rcu_read_lock();