diff options
Diffstat (limited to 'security')
-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 |
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 | ||
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); |