Add a 'recurse' flag for keyring searches so that the flag can be omitted and recursion disabled, thereby allowing just the nominated keyring to be searched and none of the children.
Unified · Split
| @@ -1162,11 +1162,13 @@ payload contents" for more information. · 1161 unmodified lines | |||
| 1162 | 1162 | ||
| 1163 | key_ref_t keyring_search(key_ref_t keyring_ref, | 1163 | key_ref_t keyring_search(key_ref_t keyring_ref, |
| 1164 | const struct key_type *type, | 1164 | const struct key_type *type, |
| 1165 | const char *description) | 1165 | const char *description, |
| 1166 | bool recurse) | ||
| 1166 | 1167 | ||
| 1167 | This searches the keyring tree specified for a matching key. Error ENOKEY | 1168 | This searches the specified keyring only (recurse == false) or keyring tree |
| 1168 | is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful, | 1169 | (recurse == true) specified for a matching key. Error ENOKEY is returned |
| 1169 | the returned key will need to be released. | 1170 | upon failure (use IS_ERR/PTR_ERR to determine). If successful, the returned |
| 1171 | key will need to be released. | ||
| 1170 | 1172 | ||
| 1171 | The possession attribute from the keyring reference is used to control | 1173 | The possession attribute from the keyring reference is used to control |
| 1172 | access through the permissions mask and is propagated to the returned key | 1174 | access through the permissions mask and is propagated to the returned key |
| @@ -128,7 +128,7 @@ int is_hash_blacklisted(const u8 *hash, size_t hash_len, const char *type) · 127 unmodified lines | |||
| 128 | *p = 0; | 128 | *p = 0; |
| 129 | 129 | ||
| 130 | kref = keyring_search(make_key_ref(blacklist_keyring, true), | 130 | kref = keyring_search(make_key_ref(blacklist_keyring, true), |
| 131 | &key_type_blacklist, buffer); | 131 | &key_type_blacklist, buffer, false); |
| 132 | if (!IS_ERR(kref)) { | 132 | if (!IS_ERR(kref)) { |
| 133 | key_ref_put(kref); | 133 | key_ref_put(kref); |
| 134 | ret = -EKEYREJECTED; | 134 | ret = -EKEYREJECTED; |
| @@ -87,7 +87,7 @@ struct key *find_asymmetric_key(struct key *keyring, · 86 unmodified lines | |||
| 87 | pr_debug("Look up: \"%s\"\n", req); | 87 | pr_debug("Look up: \"%s\"\n", req); |
| 88 | 88 | ||
| 89 | ref = keyring_search(make_key_ref(keyring, 1), | 89 | ref = keyring_search(make_key_ref(keyring, 1), |
| 90 | &key_type_asymmetric, req); | 90 | &key_type_asymmetric, req, true); |
| 91 | if (IS_ERR(ref)) | 91 | if (IS_ERR(ref)) |
| 92 | pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref)); | 92 | pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref)); |
| 93 | kfree(req); | 93 | kfree(req); |
| @@ -341,7 +341,8 @@ extern int keyring_clear(struct key *keyring); · 340 unmodified lines | |||
| 341 | 341 | ||
| 342 | extern key_ref_t keyring_search(key_ref_t keyring, | 342 | extern key_ref_t keyring_search(key_ref_t keyring, |
| 343 | struct key_type *type, | 343 | struct key_type *type, |
| 344 | const char *description); | 344 | const char *description, |
| 345 | bool recurse); | ||
| 345 | 346 | ||
| 346 | extern int keyring_add_key(struct key *keyring, | 347 | extern int keyring_add_key(struct key *keyring, |
| 347 | struct key *key); | 348 | struct key *key); |
| @@ -221,7 +221,7 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen, · 220 unmodified lines | |||
| 221 | /* search in specific keyring */ | 221 | /* search in specific keyring */ |
| 222 | key_ref_t kref; | 222 | key_ref_t kref; |
| 223 | kref = keyring_search(make_key_ref(keyring, 1UL), | 223 | kref = keyring_search(make_key_ref(keyring, 1UL), |
| 224 | &key_type_user, name); | 224 | &key_type_user, name, true); |
| 225 | if (IS_ERR(kref)) | 225 | if (IS_ERR(kref)) |
| 226 | key = ERR_CAST(kref); | 226 | key = ERR_CAST(kref); |
| 227 | else | 227 | else |
| @@ -148,7 +148,7 @@ found_service: · 147 unmodified lines | |||
| 148 | 148 | ||
| 149 | /* look through the service's keyring */ | 149 | /* look through the service's keyring */ |
| 150 | kref = keyring_search(make_key_ref(rx->securities, 1UL), | 150 | kref = keyring_search(make_key_ref(rx->securities, 1UL), |
| 151 | &key_type_rxrpc_s, kdesc); | 151 | &key_type_rxrpc_s, kdesc, true); |
| 152 | if (IS_ERR(kref)) { | 152 | if (IS_ERR(kref)) { |
| 153 | read_unlock(&local->services_lock); | 153 | read_unlock(&local->services_lock); |
| 154 | _leave(" = %ld [search]", PTR_ERR(kref)); | 154 | _leave(" = %ld [search]", PTR_ERR(kref)); |
| @@ -39,7 +39,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) · 38 unmodified lines | |||
| 39 | key_ref_t kref; | 39 | key_ref_t kref; |
| 40 | 40 | ||
| 41 | kref = keyring_search(make_key_ref(key, 1), | 41 | kref = keyring_search(make_key_ref(key, 1), |
| 42 | &key_type_asymmetric, name); | 42 | &key_type_asymmetric, name, true); |
| 43 | if (!IS_ERR(kref)) { | 43 | if (!IS_ERR(kref)) { |
| 44 | pr_err("Key '%s' is in ima_blacklist_keyring\n", name); | 44 | pr_err("Key '%s' is in ima_blacklist_keyring\n", name); |
| 45 | return ERR_PTR(-EKEYREJECTED); | 45 | return ERR_PTR(-EKEYREJECTED); |
| @@ -51,7 +51,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) · 5 unmodified lines | |||
| 51 | key_ref_t kref; | 51 | key_ref_t kref; |
| 52 | 52 | ||
| 53 | kref = keyring_search(make_key_ref(keyring, 1), | 53 | kref = keyring_search(make_key_ref(keyring, 1), |
| 54 | &key_type_asymmetric, name); | 54 | &key_type_asymmetric, name, true); |
| 55 | if (IS_ERR(kref)) | 55 | if (IS_ERR(kref)) |
| 56 | key = ERR_CAST(kref); | 56 | key = ERR_CAST(kref); |
| 57 | else | 57 | else |
| @@ -127,6 +127,7 @@ struct keyring_search_context { · 126 unmodified lines | |||
| 127 | #define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */ | 127 | #define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */ |
| 128 | #define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */ | 128 | #define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */ |
| 129 | #define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */ | 129 | #define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */ |
| 130 | #define KEYRING_SEARCH_RECURSE 0x0040 /* Search child keyrings also */ | ||
| 130 | 131 | ||
| 131 | int (*iterator)(const void *object, void *iterator_data); | 132 | int (*iterator)(const void *object, void *iterator_data); |
| 132 | 133 | ||
| @@ -762,7 +762,7 @@ long keyctl_keyring_search(key_serial_t ringid, · 761 unmodified lines | |||
| 762 | } | 762 | } |
| 763 | 763 | ||
| 764 | /* do the search */ | 764 | /* do the search */ |
| 765 | key_ref = keyring_search(keyring_ref, ktype, description); | 765 | key_ref = keyring_search(keyring_ref, ktype, description, true); |
| 766 | if (IS_ERR(key_ref)) { | 766 | if (IS_ERR(key_ref)) { |
| 767 | ret = PTR_ERR(key_ref); | 767 | ret = PTR_ERR(key_ref); |
| 768 | 768 | ||
| @@ -685,6 +685,9 @@ descend_to_keyring: · 684 unmodified lines | |||
| 685 | * Non-keyrings avoid the leftmost branch of the root entirely (root | 685 | * Non-keyrings avoid the leftmost branch of the root entirely (root |
| 686 | * slots 1-15). | 686 | * slots 1-15). |
| 687 | */ | 687 | */ |
| 688 | if (!(ctx->flags & KEYRING_SEARCH_RECURSE)) | ||
| 689 | goto not_this_keyring; | ||
| 690 | |||
| 688 | ptr = READ_ONCE(keyring->keys.root); | 691 | ptr = READ_ONCE(keyring->keys.root); |
| 689 | if (!ptr) | 692 | if (!ptr) |
| 690 | goto not_this_keyring; | 693 | goto not_this_keyring; |
| @@ -885,13 +888,15 @@ key_ref_t keyring_search_rcu(key_ref_t keyring_ref, · 194 unmodified lines | |||
| 885 | * @keyring: The root of the keyring tree to be searched. | 888 | * @keyring: The root of the keyring tree to be searched. |
| 886 | * @type: The type of keyring we want to find. | 889 | * @type: The type of keyring we want to find. |
| 887 | * @description: The name of the keyring we want to find. | 890 | * @description: The name of the keyring we want to find. |
| 891 | * @recurse: True to search the children of @keyring also | ||
| 888 | * | 892 | * |
| 889 | * As keyring_search_rcu() above, but using the current task's credentials and | 893 | * As keyring_search_rcu() above, but using the current task's credentials and |
| 890 | * type's default matching function and preferred search method. | 894 | * type's default matching function and preferred search method. |
| 891 | */ | 895 | */ |
| 892 | key_ref_t keyring_search(key_ref_t keyring, | 896 | key_ref_t keyring_search(key_ref_t keyring, |
| 893 | struct key_type *type, | 897 | struct key_type *type, |
| 894 | const char *description) | 898 | const char *description, |
| 899 | bool recurse) | ||
| 895 | { | 900 | { |
| 896 | struct keyring_search_context ctx = { | 901 | struct keyring_search_context ctx = { |
| 897 | .index_key.type = type, | 902 | .index_key.type = type, |
| @@ -906,6 +911,8 @@ key_ref_t keyring_search(key_ref_t keyring, · 8 unmodified lines | |||
| 906 | key_ref_t key; | 911 | key_ref_t key; |
| 907 | int ret; | 912 | int ret; |
| 908 | 913 | ||
| 914 | if (recurse) | ||
| 915 | ctx.flags |= KEYRING_SEARCH_RECURSE; | ||
| 909 | if (type->match_preparse) { | 916 | if (type->match_preparse) { |
| 910 | ret = type->match_preparse(&ctx.match_data); | 917 | ret = type->match_preparse(&ctx.match_data); |
| 911 | if (ret < 0) | 918 | if (ret < 0) |
| @@ -1176,7 +1183,8 @@ static int keyring_detect_cycle(struct key *A, struct key *B) · 264 unmodified lines | |||
| 1176 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | | 1183 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | |
| 1177 | KEYRING_SEARCH_NO_UPDATE_TIME | | 1184 | KEYRING_SEARCH_NO_UPDATE_TIME | |
| 1178 | KEYRING_SEARCH_NO_CHECK_PERM | | 1185 | KEYRING_SEARCH_NO_CHECK_PERM | |
| 1179 | KEYRING_SEARCH_DETECT_TOO_DEEP), | 1186 | KEYRING_SEARCH_DETECT_TOO_DEEP | |
| 1187 | KEYRING_SEARCH_RECURSE), | ||
| 1180 | }; | 1188 | }; |
| 1181 | 1189 | ||
| 1182 | rcu_read_lock(); | 1190 | rcu_read_lock(); |
| @@ -170,7 +170,8 @@ static int proc_keys_show(struct seq_file *m, void *v) · 169 unmodified lines | |||
| 170 | .match_data.cmp = lookup_user_key_possessed, | 170 | .match_data.cmp = lookup_user_key_possessed, |
| 171 | .match_data.raw_data = key, | 171 | .match_data.raw_data = key, |
| 172 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, | 172 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
| 173 | .flags = KEYRING_SEARCH_NO_STATE_CHECK, | 173 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | |
| 174 | KEYRING_SEARCH_RECURSE), | ||
| 174 | }; | 175 | }; |
| 175 | 176 | ||
| 176 | key_ref = make_key_ref(key, 0); | 177 | key_ref = make_key_ref(key, 0); |
| @@ -531,7 +531,8 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, · 530 unmodified lines | |||
| 531 | struct keyring_search_context ctx = { | 531 | struct keyring_search_context ctx = { |
| 532 | .match_data.cmp = lookup_user_key_possessed, | 532 | .match_data.cmp = lookup_user_key_possessed, |
| 533 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, | 533 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
| 534 | .flags = KEYRING_SEARCH_NO_STATE_CHECK, | 534 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | |
| 535 | KEYRING_SEARCH_RECURSE), | ||
| 535 | }; | 536 | }; |
| 536 | struct request_key_auth *rka; | 537 | struct request_key_auth *rka; |
| 537 | struct key *key; | 538 | struct key *key; |
| @@ -569,7 +569,8 @@ struct key *request_key_and_link(struct key_type *type, · 568 unmodified lines | |||
| 569 | .match_data.raw_data = description, | 569 | .match_data.raw_data = description, |
| 570 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, | 570 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
| 571 | .flags = (KEYRING_SEARCH_DO_STATE_CHECK | | 571 | .flags = (KEYRING_SEARCH_DO_STATE_CHECK | |
| 572 | KEYRING_SEARCH_SKIP_EXPIRED), | 572 | KEYRING_SEARCH_SKIP_EXPIRED | |
| 573 | KEYRING_SEARCH_RECURSE), | ||
| 573 | }; | 574 | }; |
| 574 | struct key *key; | 575 | struct key *key; |
| 575 | key_ref_t key_ref; | 576 | key_ref_t key_ref; |
| @@ -252,7 +252,8 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id) · 251 unmodified lines | |||
| 252 | .match_data.cmp = key_default_cmp, | 252 | .match_data.cmp = key_default_cmp, |
| 253 | .match_data.raw_data = description, | 253 | .match_data.raw_data = description, |
| 254 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, | 254 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
| 255 | .flags = KEYRING_SEARCH_DO_STATE_CHECK, | 255 | .flags = (KEYRING_SEARCH_DO_STATE_CHECK | |
| 256 | KEYRING_SEARCH_RECURSE), | ||
| 256 | }; | 257 | }; |
| 257 | struct key *authkey; | 258 | struct key *authkey; |
| 258 | key_ref_t authkey_ref; | 259 | key_ref_t authkey_ref; |