aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c31
-rw-r--r--include/keys/user-type.h4
-rw-r--r--include/linux/key-type.h31
-rw-r--r--net/dns_resolver/dns_key.c5
-rw-r--r--security/keys/internal.h8
-rw-r--r--security/keys/keyring.c49
-rw-r--r--security/keys/proc.c8
-rw-r--r--security/keys/process_keys.c13
-rw-r--r--security/keys/request_key.c21
-rw-r--r--security/keys/request_key_auth.c6
-rw-r--r--security/keys/user_defined.c4
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 */
62static int asymmetric_key_match(const struct key *key, const void *description) 62static 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 */
110static 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 */
119static 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 */
99static void asymmetric_key_describe(const struct key *key, struct seq_file *m) 126static 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;
36extern struct key_type key_type_logon; 36extern struct key_type key_type_logon;
37 37
38struct key_preparsed_payload; 38struct key_preparsed_payload;
39struct key_match_data;
39 40
40extern int user_preparse(struct key_preparsed_payload *prep); 41extern int user_preparse(struct key_preparsed_payload *prep);
41extern void user_free_preparse(struct key_preparsed_payload *prep); 42extern void user_free_preparse(struct key_preparsed_payload *prep);
42extern int user_update(struct key *key, struct key_preparsed_payload *prep); 43extern int user_update(struct key *key, struct key_preparsed_payload *prep);
43extern int user_match(const struct key *key, const void *criterion); 44extern int user_match(const struct key *key,
45 const struct key_match_data *match_data);
44extern void user_revoke(struct key *key); 46extern void user_revoke(struct key *key);
45extern void user_destroy(struct key *key); 47extern void user_destroy(struct key *key);
46extern void user_describe(const struct key *user, struct seq_file *m); 48extern 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 */
58struct 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 */
58struct key_type { 74struct 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 */
179static int 179static int
180dns_resolver_match(const struct key *key, const void *description) 180dns_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
110typedef int (*key_match_func_t)(const struct key *, const void *);
111
112struct keyring_search_context { 110struct 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
155extern int lookup_user_key_possessed(const struct key *key, const void *target); 152extern int lookup_user_key_possessed(const struct key *key,
153 const struct key_match_data *match_data);
156extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, 154extern 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 */
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();
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 */
492int lookup_user_key_possessed(const struct key *key, const void *target) 492int 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
582error_free:
583 if (type->match_free)
584 type->match_free(&ctx.match_data);
574error: 585error:
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 */
144int user_match(const struct key *key, const void *description) 144int 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
149EXPORT_SYMBOL_GPL(user_match); 149EXPORT_SYMBOL_GPL(user_match);