aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-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
7 files changed, 65 insertions, 44 deletions
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);