diff options
author | David Howells <dhowells@redhat.com> | 2014-09-16 12:36:02 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-09-16 12:36:02 -0400 |
commit | 462919591a1791e76042dc5c1e0148715df59beb (patch) | |
tree | 44a60ee5f08eab18b1a69f98d993f9a47a45fece /security/keys/keyring.c | |
parent | 53d91c5ce0cb8945b55e8bb54e551cabc51eb28d (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.c | 49 |
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 | */ |
586 | static int search_keyring(struct key *keyring, struct keyring_search_context *ctx) | 586 | static 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 | } |
899 | EXPORT_SYMBOL(keyring_search); | 910 | EXPORT_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, | |||
1031 | static int keyring_detect_cycle(struct key *A, struct key *B) | 1042 | static 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(); |