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 | 1163 | key_ref_t keyring_search(key_ref_t keyring_ref, |
| 1164 | 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 | − is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful, | |
| 1169 | − the returned key will need to be released. | |
| 1168 | + This searches the specified keyring only (recurse == false) or keyring tree | |
| 1169 | + (recurse == true) specified for a matching key. Error ENOKEY is returned | |
| 1170 | + upon failure (use IS_ERR/PTR_ERR to determine). If successful, the returned | |
| 1171 | + key will need to be released. | |
| 1170 | 1172 | |
| 1171 | 1173 | The possession attribute from the keyring reference is used to control |
| 1172 | 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 | 128 | *p = 0; |
| 129 | 129 | |
| 130 | 130 | kref = keyring_search(make_key_ref(blacklist_keyring, true), |
| 131 | − &key_type_blacklist, buffer); | |
| 131 | + &key_type_blacklist, buffer, false); | |
| 132 | 132 | if (!IS_ERR(kref)) { |
| 133 | 133 | key_ref_put(kref); |
| 134 | 134 | ret = -EKEYREJECTED; |
| @@ -87,7 +87,7 @@ struct key *find_asymmetric_key(struct key *keyring, · 86 unmodified lines | ||
| 87 | 87 | pr_debug("Look up: \"%s\"\n", req); |
| 88 | 88 | |
| 89 | 89 | ref = keyring_search(make_key_ref(keyring, 1), |
| 90 | − &key_type_asymmetric, req); | |
| 90 | + &key_type_asymmetric, req, true); | |
| 91 | 91 | if (IS_ERR(ref)) |
| 92 | 92 | pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref)); |
| 93 | 93 | kfree(req); |
| @@ -341,7 +341,8 @@ extern int keyring_clear(struct key *keyring); · 340 unmodified lines | ||
| 341 | 341 | |
| 342 | 342 | extern key_ref_t keyring_search(key_ref_t keyring, |
| 343 | 343 | struct key_type *type, |
| 344 | − const char *description); | |
| 344 | + const char *description, | |
| 345 | + bool recurse); | |
| 345 | 346 | |
| 346 | 347 | extern int keyring_add_key(struct key *keyring, |
| 347 | 348 | struct key *key); |
| @@ -221,7 +221,7 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen, · 220 unmodified lines | ||
| 221 | 221 | /* search in specific keyring */ |
| 222 | 222 | key_ref_t kref; |
| 223 | 223 | kref = keyring_search(make_key_ref(keyring, 1UL), |
| 224 | − &key_type_user, name); | |
| 224 | + &key_type_user, name, true); | |
| 225 | 225 | if (IS_ERR(kref)) |
| 226 | 226 | key = ERR_CAST(kref); |
| 227 | 227 | else |
| @@ -148,7 +148,7 @@ found_service: · 147 unmodified lines | ||
| 148 | 148 | |
| 149 | 149 | /* look through the service's keyring */ |
| 150 | 150 | kref = keyring_search(make_key_ref(rx->securities, 1UL), |
| 151 | − &key_type_rxrpc_s, kdesc); | |
| 151 | + &key_type_rxrpc_s, kdesc, true); | |
| 152 | 152 | if (IS_ERR(kref)) { |
| 153 | 153 | read_unlock(&local->services_lock); |
| 154 | 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 | 39 | key_ref_t kref; |
| 40 | 40 | |
| 41 | 41 | kref = keyring_search(make_key_ref(key, 1), |
| 42 | − &key_type_asymmetric, name); | |
| 42 | + &key_type_asymmetric, name, true); | |
| 43 | 43 | if (!IS_ERR(kref)) { |
| 44 | 44 | pr_err("Key '%s' is in ima_blacklist_keyring\n", name); |
| 45 | 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 | 51 | key_ref_t kref; |
| 52 | 52 | |
| 53 | 53 | kref = keyring_search(make_key_ref(keyring, 1), |
| 54 | − &key_type_asymmetric, name); | |
| 54 | + &key_type_asymmetric, name, true); | |
| 55 | 55 | if (IS_ERR(kref)) |
| 56 | 56 | key = ERR_CAST(kref); |
| 57 | 57 | else |
| @@ -127,6 +127,7 @@ struct keyring_search_context { · 126 unmodified lines | ||
| 127 | 127 | #define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */ |
| 128 | 128 | #define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */ |
| 129 | 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 | 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 | 764 | /* do the search */ |
| 765 | − key_ref = keyring_search(keyring_ref, ktype, description); | |
| 765 | + key_ref = keyring_search(keyring_ref, ktype, description, true); | |
| 766 | 766 | if (IS_ERR(key_ref)) { |
| 767 | 767 | ret = PTR_ERR(key_ref); |
| 768 | 768 | |
| @@ -685,6 +685,9 @@ descend_to_keyring: · 684 unmodified lines | ||
| 685 | 685 | * Non-keyrings avoid the leftmost branch of the root entirely (root |
| 686 | 686 | * slots 1-15). |
| 687 | 687 | */ |
| 688 | + if (!(ctx->flags & KEYRING_SEARCH_RECURSE)) | |
| 689 | + goto not_this_keyring; | |
| 690 | + | |
| 688 | 691 | ptr = READ_ONCE(keyring->keys.root); |
| 689 | 692 | if (!ptr) |
| 690 | 693 | goto not_this_keyring; |
| @@ -885,13 +888,15 @@ key_ref_t keyring_search_rcu(key_ref_t keyring_ref, · 194 unmodified lines | ||
| 885 | 888 | * @keyring: The root of the keyring tree to be searched. |
| 886 | 889 | * @type: The type of keyring we want to find. |
| 887 | 890 | * @description: The name of the keyring we want to find. |
| 891 | + * @recurse: True to search the children of @keyring also | |
| 888 | 892 | * |
| 889 | 893 | * As keyring_search_rcu() above, but using the current task's credentials and |
| 890 | 894 | * type's default matching function and preferred search method. |
| 891 | 895 | */ |
| 892 | 896 | key_ref_t keyring_search(key_ref_t keyring, |
| 893 | 897 | struct key_type *type, |
| 894 | − const char *description) | |
| 898 | + const char *description, | |
| 899 | + bool recurse) | |
| 895 | 900 | { |
| 896 | 901 | struct keyring_search_context ctx = { |
| 897 | 902 | .index_key.type = type, |
| @@ -906,6 +911,8 @@ key_ref_t keyring_search(key_ref_t keyring, · 8 unmodified lines | ||
| 906 | 911 | key_ref_t key; |
| 907 | 912 | int ret; |
| 908 | 913 | |
| 914 | + if (recurse) | |
| 915 | + ctx.flags |= KEYRING_SEARCH_RECURSE; | |
| 909 | 916 | if (type->match_preparse) { |
| 910 | 917 | ret = type->match_preparse(&ctx.match_data); |
| 911 | 918 | if (ret < 0) |
| @@ -1176,7 +1183,8 @@ static int keyring_detect_cycle(struct key *A, struct key *B) · 264 unmodified lines | ||
| 1176 | 1183 | .flags = (KEYRING_SEARCH_NO_STATE_CHECK | |
| 1177 | 1184 | KEYRING_SEARCH_NO_UPDATE_TIME | |
| 1178 | 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 | 1190 | rcu_read_lock(); |
| @@ -170,7 +170,8 @@ static int proc_keys_show(struct seq_file *m, void *v) · 169 unmodified lines | ||
| 170 | 170 | .match_data.cmp = lookup_user_key_possessed, |
| 171 | 171 | .match_data.raw_data = key, |
| 172 | 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 | 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 | 531 | struct keyring_search_context ctx = { |
| 532 | 532 | .match_data.cmp = lookup_user_key_possessed, |
| 533 | 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 | 537 | struct request_key_auth *rka; |
| 537 | 538 | struct key *key; |
| @@ -569,7 +569,8 @@ struct key *request_key_and_link(struct key_type *type, · 568 unmodified lines | ||
| 569 | 569 | .match_data.raw_data = description, |
| 570 | 570 | .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
| 571 | 571 | .flags = (KEYRING_SEARCH_DO_STATE_CHECK | |
| 572 | − KEYRING_SEARCH_SKIP_EXPIRED), | |
| 572 | + KEYRING_SEARCH_SKIP_EXPIRED | | |
| 573 | + KEYRING_SEARCH_RECURSE), | |
| 573 | 574 | }; |
| 574 | 575 | struct key *key; |
| 575 | 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 | 252 | .match_data.cmp = key_default_cmp, |
| 253 | 253 | .match_data.raw_data = description, |
| 254 | 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 | 258 | struct key *authkey; |
| 258 | 259 | key_ref_t authkey_ref; |