diff options
-rw-r--r-- | crypto/asymmetric_keys/asymmetric_type.c | 31 | ||||
-rw-r--r-- | include/keys/user-type.h | 4 | ||||
-rw-r--r-- | include/linux/key-type.h | 31 | ||||
-rw-r--r-- | net/dns_resolver/dns_key.c | 5 | ||||
-rw-r--r-- | security/keys/internal.h | 8 | ||||
-rw-r--r-- | security/keys/keyring.c | 49 | ||||
-rw-r--r-- | security/keys/proc.c | 8 | ||||
-rw-r--r-- | security/keys/process_keys.c | 13 | ||||
-rw-r--r-- | security/keys/request_key.c | 21 | ||||
-rw-r--r-- | security/keys/request_key_auth.c | 6 | ||||
-rw-r--r-- | security/keys/user_defined.c | 4 |
11 files changed, 129 insertions, 51 deletions
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index eb8cd46961a5..f666b4e8d256 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c | |||
@@ -59,9 +59,11 @@ EXPORT_SYMBOL_GPL(asymmetric_keyid_match); | |||
59 | * "id:<id>" - request a key matching the ID | 59 | * "id:<id>" - request a key matching the ID |
60 | * "<subtype>:<id>" - request a key of a subtype | 60 | * "<subtype>:<id>" - request a key of a subtype |
61 | */ | 61 | */ |
62 | static int asymmetric_key_match(const struct key *key, const void *description) | 62 | static int asymmetric_key_match(const struct key *key, |
63 | const struct key_match_data *match_data) | ||
63 | { | 64 | { |
64 | const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); | 65 | const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); |
66 | const char *description = match_data->raw_data; | ||
65 | const char *spec = description; | 67 | const char *spec = description; |
66 | const char *id; | 68 | const char *id; |
67 | ptrdiff_t speclen; | 69 | ptrdiff_t speclen; |
@@ -94,6 +96,31 @@ static int asymmetric_key_match(const struct key *key, const void *description) | |||
94 | } | 96 | } |
95 | 97 | ||
96 | /* | 98 | /* |
99 | * Preparse the match criterion. If we don't set lookup_type and cmp, | ||
100 | * the default will be an exact match on the key description. | ||
101 | * | ||
102 | * There are some specifiers for matching key IDs rather than by the key | ||
103 | * description: | ||
104 | * | ||
105 | * "id:<id>" - request a key by any available ID | ||
106 | * | ||
107 | * These have to be searched by iteration rather than by direct lookup because | ||
108 | * the key is hashed according to its description. | ||
109 | */ | ||
110 | static int asymmetric_key_match_preparse(struct key_match_data *match_data) | ||
111 | { | ||
112 | match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE; | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Free the preparsed the match criterion. | ||
118 | */ | ||
119 | static void asymmetric_key_match_free(struct key_match_data *match_data) | ||
120 | { | ||
121 | } | ||
122 | |||
123 | /* | ||
97 | * Describe the asymmetric key | 124 | * Describe the asymmetric key |
98 | */ | 125 | */ |
99 | static void asymmetric_key_describe(const struct key *key, struct seq_file *m) | 126 | static void asymmetric_key_describe(const struct key *key, struct seq_file *m) |
@@ -196,7 +223,9 @@ struct key_type key_type_asymmetric = { | |||
196 | .preparse = asymmetric_key_preparse, | 223 | .preparse = asymmetric_key_preparse, |
197 | .free_preparse = asymmetric_key_free_preparse, | 224 | .free_preparse = asymmetric_key_free_preparse, |
198 | .instantiate = generic_key_instantiate, | 225 | .instantiate = generic_key_instantiate, |
226 | .match_preparse = asymmetric_key_match_preparse, | ||
199 | .match = asymmetric_key_match, | 227 | .match = asymmetric_key_match, |
228 | .match_free = asymmetric_key_match_free, | ||
200 | .destroy = asymmetric_key_destroy, | 229 | .destroy = asymmetric_key_destroy, |
201 | .describe = asymmetric_key_describe, | 230 | .describe = asymmetric_key_describe, |
202 | .def_lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE, | 231 | .def_lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE, |
diff --git a/include/keys/user-type.h b/include/keys/user-type.h index 3ab1873a4bfa..66d92af30e7c 100644 --- a/include/keys/user-type.h +++ b/include/keys/user-type.h | |||
@@ -36,11 +36,13 @@ extern struct key_type key_type_user; | |||
36 | extern struct key_type key_type_logon; | 36 | extern struct key_type key_type_logon; |
37 | 37 | ||
38 | struct key_preparsed_payload; | 38 | struct key_preparsed_payload; |
39 | struct key_match_data; | ||
39 | 40 | ||
40 | extern int user_preparse(struct key_preparsed_payload *prep); | 41 | extern int user_preparse(struct key_preparsed_payload *prep); |
41 | extern void user_free_preparse(struct key_preparsed_payload *prep); | 42 | extern void user_free_preparse(struct key_preparsed_payload *prep); |
42 | extern int user_update(struct key *key, struct key_preparsed_payload *prep); | 43 | extern int user_update(struct key *key, struct key_preparsed_payload *prep); |
43 | extern int user_match(const struct key *key, const void *criterion); | 44 | extern int user_match(const struct key *key, |
45 | const struct key_match_data *match_data); | ||
44 | extern void user_revoke(struct key *key); | 46 | extern void user_revoke(struct key *key); |
45 | extern void user_destroy(struct key *key); | 47 | extern void user_destroy(struct key *key); |
46 | extern void user_describe(const struct key *user, struct seq_file *m); | 48 | extern void user_describe(const struct key *user, struct seq_file *m); |
diff --git a/include/linux/key-type.h b/include/linux/key-type.h index 44792ee649de..8aba688a451a 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h | |||
@@ -53,6 +53,22 @@ typedef int (*request_key_actor_t)(struct key_construction *key, | |||
53 | const char *op, void *aux); | 53 | const char *op, void *aux); |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Preparsed matching criterion. | ||
57 | */ | ||
58 | struct key_match_data { | ||
59 | /* Comparison function, defaults to type->match, but can be replaced by | ||
60 | * type->match_preparse(). */ | ||
61 | int (*cmp)(const struct key *key, | ||
62 | const struct key_match_data *match_data); | ||
63 | |||
64 | const void *raw_data; /* Raw match data */ | ||
65 | void *preparsed; /* For ->match_preparse() to stash stuff */ | ||
66 | unsigned lookup_type; /* Type of lookup for this search. */ | ||
67 | #define KEYRING_SEARCH_LOOKUP_DIRECT 0x0000 /* Direct lookup by description. */ | ||
68 | #define KEYRING_SEARCH_LOOKUP_ITERATE 0x0001 /* Iterative search. */ | ||
69 | }; | ||
70 | |||
71 | /* | ||
56 | * kernel managed key type definition | 72 | * kernel managed key type definition |
57 | */ | 73 | */ |
58 | struct key_type { | 74 | struct key_type { |
@@ -67,8 +83,6 @@ struct key_type { | |||
67 | 83 | ||
68 | /* Default key search algorithm. */ | 84 | /* Default key search algorithm. */ |
69 | unsigned def_lookup_type; | 85 | unsigned def_lookup_type; |
70 | #define KEYRING_SEARCH_LOOKUP_DIRECT 0x0000 /* Direct lookup by description. */ | ||
71 | #define KEYRING_SEARCH_LOOKUP_ITERATE 0x0001 /* Iterative search. */ | ||
72 | 86 | ||
73 | /* vet a description */ | 87 | /* vet a description */ |
74 | int (*vet_description)(const char *description); | 88 | int (*vet_description)(const char *description); |
@@ -96,8 +110,19 @@ struct key_type { | |||
96 | */ | 110 | */ |
97 | int (*update)(struct key *key, struct key_preparsed_payload *prep); | 111 | int (*update)(struct key *key, struct key_preparsed_payload *prep); |
98 | 112 | ||
113 | /* Preparse the data supplied to ->match() (optional). The | ||
114 | * data to be preparsed can be found in match_data->raw_data. | ||
115 | * The lookup type can also be set by this function. | ||
116 | */ | ||
117 | int (*match_preparse)(struct key_match_data *match_data); | ||
118 | |||
99 | /* match a key against a description */ | 119 | /* match a key against a description */ |
100 | int (*match)(const struct key *key, const void *desc); | 120 | int (*match)(const struct key *key, |
121 | const struct key_match_data *match_data); | ||
122 | |||
123 | /* Free preparsed match data (optional). This should be supplied it | ||
124 | * ->match_preparse() is supplied. */ | ||
125 | void (*match_free)(struct key_match_data *match_data); | ||
101 | 126 | ||
102 | /* clear some of the data from a key on revokation (optional) | 127 | /* clear some of the data from a key on revokation (optional) |
103 | * - the key's semaphore will be write-locked by the caller | 128 | * - the key's semaphore will be write-locked by the caller |
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index f380b2c58178..92df6e508ae7 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c | |||
@@ -177,10 +177,11 @@ static void dns_resolver_free_preparse(struct key_preparsed_payload *prep) | |||
177 | * should end with a period). The domain name is case-independent. | 177 | * should end with a period). The domain name is case-independent. |
178 | */ | 178 | */ |
179 | static int | 179 | static int |
180 | dns_resolver_match(const struct key *key, const void *description) | 180 | dns_resolver_match(const struct key *key, |
181 | const struct key_match_data *match_data) | ||
181 | { | 182 | { |
182 | int slen, dlen, ret = 0; | 183 | int slen, dlen, ret = 0; |
183 | const char *src = key->description, *dsp = description; | 184 | const char *src = key->description, *dsp = match_data->raw_data; |
184 | 185 | ||
185 | kenter("%s,%s", src, dsp); | 186 | kenter("%s,%s", src, dsp); |
186 | 187 | ||
diff --git a/security/keys/internal.h b/security/keys/internal.h index 5f20da01fd8d..805e60b0b87e 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -107,13 +107,10 @@ extern int iterate_over_keyring(const struct key *keyring, | |||
107 | int (*func)(const struct key *key, void *data), | 107 | int (*func)(const struct key *key, void *data), |
108 | void *data); | 108 | void *data); |
109 | 109 | ||
110 | typedef int (*key_match_func_t)(const struct key *, const void *); | ||
111 | |||
112 | struct keyring_search_context { | 110 | struct keyring_search_context { |
113 | struct keyring_index_key index_key; | 111 | struct keyring_index_key index_key; |
114 | const struct cred *cred; | 112 | const struct cred *cred; |
115 | key_match_func_t match; | 113 | struct key_match_data match_data; |
116 | const void *match_data; | ||
117 | unsigned flags; | 114 | unsigned flags; |
118 | #define KEYRING_SEARCH_LOOKUP_TYPE 0x0001 /* [as type->def_lookup_type] */ | 115 | #define KEYRING_SEARCH_LOOKUP_TYPE 0x0001 /* [as type->def_lookup_type] */ |
119 | #define KEYRING_SEARCH_NO_STATE_CHECK 0x0002 /* Skip state checks */ | 116 | #define KEYRING_SEARCH_NO_STATE_CHECK 0x0002 /* Skip state checks */ |
@@ -152,7 +149,8 @@ extern struct key *request_key_and_link(struct key_type *type, | |||
152 | struct key *dest_keyring, | 149 | struct key *dest_keyring, |
153 | unsigned long flags); | 150 | unsigned long flags); |
154 | 151 | ||
155 | extern int lookup_user_key_possessed(const struct key *key, const void *target); | 152 | extern int lookup_user_key_possessed(const struct key *key, |
153 | const struct key_match_data *match_data); | ||
156 | extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, | 154 | extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, |
157 | key_perm_t perm); | 155 | key_perm_t perm); |
158 | #define KEY_LOOKUP_CREATE 0x01 | 156 | #define KEY_LOOKUP_CREATE 0x01 |
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(); |
diff --git a/security/keys/proc.c b/security/keys/proc.c index d3f6f2fd21db..972eeb336b81 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c | |||
@@ -194,10 +194,10 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
194 | .index_key.type = key->type, | 194 | .index_key.type = key->type, |
195 | .index_key.description = key->description, | 195 | .index_key.description = key->description, |
196 | .cred = current_cred(), | 196 | .cred = current_cred(), |
197 | .match = lookup_user_key_possessed, | 197 | .match_data.cmp = lookup_user_key_possessed, |
198 | .match_data = key, | 198 | .match_data.raw_data = key, |
199 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | | 199 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
200 | KEYRING_SEARCH_LOOKUP_DIRECT), | 200 | .flags = KEYRING_SEARCH_NO_STATE_CHECK, |
201 | }; | 201 | }; |
202 | 202 | ||
203 | key_ref = make_key_ref(key, 0); | 203 | key_ref = make_key_ref(key, 0); |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 0cf8a130a267..08bd533d014f 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -489,9 +489,10 @@ found: | |||
489 | /* | 489 | /* |
490 | * See if the key we're looking at is the target key. | 490 | * See if the key we're looking at is the target key. |
491 | */ | 491 | */ |
492 | int lookup_user_key_possessed(const struct key *key, const void *target) | 492 | int lookup_user_key_possessed(const struct key *key, |
493 | const struct key_match_data *match_data) | ||
493 | { | 494 | { |
494 | return key == target; | 495 | return key == match_data->raw_data; |
495 | } | 496 | } |
496 | 497 | ||
497 | /* | 498 | /* |
@@ -516,9 +517,9 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, | |||
516 | key_perm_t perm) | 517 | key_perm_t perm) |
517 | { | 518 | { |
518 | struct keyring_search_context ctx = { | 519 | struct keyring_search_context ctx = { |
519 | .match = lookup_user_key_possessed, | 520 | .match_data.cmp = lookup_user_key_possessed, |
520 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | | 521 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
521 | KEYRING_SEARCH_LOOKUP_DIRECT), | 522 | .flags = KEYRING_SEARCH_NO_STATE_CHECK, |
522 | }; | 523 | }; |
523 | struct request_key_auth *rka; | 524 | struct request_key_auth *rka; |
524 | struct key *key; | 525 | struct key *key; |
@@ -673,7 +674,7 @@ try_again: | |||
673 | ctx.index_key.type = key->type; | 674 | ctx.index_key.type = key->type; |
674 | ctx.index_key.description = key->description; | 675 | ctx.index_key.description = key->description; |
675 | ctx.index_key.desc_len = strlen(key->description); | 676 | ctx.index_key.desc_len = strlen(key->description); |
676 | ctx.match_data = key; | 677 | ctx.match_data.raw_data = key; |
677 | kdebug("check possessed"); | 678 | kdebug("check possessed"); |
678 | skey_ref = search_process_keyrings(&ctx); | 679 | skey_ref = search_process_keyrings(&ctx); |
679 | kdebug("possessed=%p", skey_ref); | 680 | kdebug("possessed=%p", skey_ref); |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 381411941cc1..408523e5e2e2 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -531,9 +531,9 @@ struct key *request_key_and_link(struct key_type *type, | |||
531 | .index_key.type = type, | 531 | .index_key.type = type, |
532 | .index_key.description = description, | 532 | .index_key.description = description, |
533 | .cred = current_cred(), | 533 | .cred = current_cred(), |
534 | .match = type->match, | 534 | .match_data.cmp = type->match, |
535 | .match_data = description, | 535 | .match_data.raw_data = description, |
536 | .flags = KEYRING_SEARCH_LOOKUP_DIRECT, | 536 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
537 | }; | 537 | }; |
538 | struct key *key; | 538 | struct key *key; |
539 | key_ref_t key_ref; | 539 | key_ref_t key_ref; |
@@ -543,6 +543,14 @@ struct key *request_key_and_link(struct key_type *type, | |||
543 | ctx.index_key.type->name, ctx.index_key.description, | 543 | ctx.index_key.type->name, ctx.index_key.description, |
544 | callout_info, callout_len, aux, dest_keyring, flags); | 544 | callout_info, callout_len, aux, dest_keyring, flags); |
545 | 545 | ||
546 | if (type->match_preparse) { | ||
547 | ret = type->match_preparse(&ctx.match_data); | ||
548 | if (ret < 0) { | ||
549 | key = ERR_PTR(ret); | ||
550 | goto error; | ||
551 | } | ||
552 | } | ||
553 | |||
546 | /* search all the process keyrings for a key */ | 554 | /* search all the process keyrings for a key */ |
547 | key_ref = search_process_keyrings(&ctx); | 555 | key_ref = search_process_keyrings(&ctx); |
548 | 556 | ||
@@ -555,7 +563,7 @@ struct key *request_key_and_link(struct key_type *type, | |||
555 | if (ret < 0) { | 563 | if (ret < 0) { |
556 | key_put(key); | 564 | key_put(key); |
557 | key = ERR_PTR(ret); | 565 | key = ERR_PTR(ret); |
558 | goto error; | 566 | goto error_free; |
559 | } | 567 | } |
560 | } | 568 | } |
561 | } else if (PTR_ERR(key_ref) != -EAGAIN) { | 569 | } else if (PTR_ERR(key_ref) != -EAGAIN) { |
@@ -565,12 +573,15 @@ struct key *request_key_and_link(struct key_type *type, | |||
565 | * should consult userspace if we can */ | 573 | * should consult userspace if we can */ |
566 | key = ERR_PTR(-ENOKEY); | 574 | key = ERR_PTR(-ENOKEY); |
567 | if (!callout_info) | 575 | if (!callout_info) |
568 | goto error; | 576 | goto error_free; |
569 | 577 | ||
570 | key = construct_key_and_link(&ctx, callout_info, callout_len, | 578 | key = construct_key_and_link(&ctx, callout_info, callout_len, |
571 | aux, dest_keyring, flags); | 579 | aux, dest_keyring, flags); |
572 | } | 580 | } |
573 | 581 | ||
582 | error_free: | ||
583 | if (type->match_free) | ||
584 | type->match_free(&ctx.match_data); | ||
574 | error: | 585 | error: |
575 | kleave(" = %p", key); | 586 | kleave(" = %p", key); |
576 | return key; | 587 | return key; |
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 739e7455d388..9ae02819cc06 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
@@ -246,9 +246,9 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id) | |||
246 | .index_key.type = &key_type_request_key_auth, | 246 | .index_key.type = &key_type_request_key_auth, |
247 | .index_key.description = description, | 247 | .index_key.description = description, |
248 | .cred = current_cred(), | 248 | .cred = current_cred(), |
249 | .match = user_match, | 249 | .match_data.cmp = user_match, |
250 | .match_data = description, | 250 | .match_data.raw_data = description, |
251 | .flags = KEYRING_SEARCH_LOOKUP_DIRECT, | 251 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
252 | }; | 252 | }; |
253 | struct key *authkey; | 253 | struct key *authkey; |
254 | key_ref_t authkey_ref; | 254 | key_ref_t authkey_ref; |
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index eee340011f2b..ec8a56063b02 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c | |||
@@ -141,9 +141,9 @@ EXPORT_SYMBOL_GPL(user_update); | |||
141 | /* | 141 | /* |
142 | * match users on their name | 142 | * match users on their name |
143 | */ | 143 | */ |
144 | int user_match(const struct key *key, const void *description) | 144 | int user_match(const struct key *key, const struct key_match_data *match_data) |
145 | { | 145 | { |
146 | return strcmp(key->description, description) == 0; | 146 | return strcmp(key->description, match_data->raw_data) == 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | EXPORT_SYMBOL_GPL(user_match); | 149 | EXPORT_SYMBOL_GPL(user_match); |