keys: Add a 'recurse' flag for keyring searches
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. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
Родитель
355ef8e158
Коммит
dcf49dbc80
|
@ -1162,11 +1162,13 @@ payload contents" for more information.
|
|||
|
||||
key_ref_t keyring_search(key_ref_t keyring_ref,
|
||||
const struct key_type *type,
|
||||
const char *description)
|
||||
const char *description,
|
||||
bool recurse)
|
||||
|
||||
This searches the keyring tree specified for a matching key. Error ENOKEY
|
||||
is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
|
||||
the returned key will need to be released.
|
||||
This searches the specified keyring only (recurse == false) or keyring tree
|
||||
(recurse == true) specified for a matching key. Error ENOKEY is returned
|
||||
upon failure (use IS_ERR/PTR_ERR to determine). If successful, the returned
|
||||
key will need to be released.
|
||||
|
||||
The possession attribute from the keyring reference is used to control
|
||||
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)
|
|||
*p = 0;
|
||||
|
||||
kref = keyring_search(make_key_ref(blacklist_keyring, true),
|
||||
&key_type_blacklist, buffer);
|
||||
&key_type_blacklist, buffer, false);
|
||||
if (!IS_ERR(kref)) {
|
||||
key_ref_put(kref);
|
||||
ret = -EKEYREJECTED;
|
||||
|
|
|
@ -87,7 +87,7 @@ struct key *find_asymmetric_key(struct key *keyring,
|
|||
pr_debug("Look up: \"%s\"\n", req);
|
||||
|
||||
ref = keyring_search(make_key_ref(keyring, 1),
|
||||
&key_type_asymmetric, req);
|
||||
&key_type_asymmetric, req, true);
|
||||
if (IS_ERR(ref))
|
||||
pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
|
||||
kfree(req);
|
||||
|
|
|
@ -341,7 +341,8 @@ extern int keyring_clear(struct key *keyring);
|
|||
|
||||
extern key_ref_t keyring_search(key_ref_t keyring,
|
||||
struct key_type *type,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool recurse);
|
||||
|
||||
extern int keyring_add_key(struct key *keyring,
|
||||
struct key *key);
|
||||
|
|
|
@ -221,7 +221,7 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen,
|
|||
/* search in specific keyring */
|
||||
key_ref_t kref;
|
||||
kref = keyring_search(make_key_ref(keyring, 1UL),
|
||||
&key_type_user, name);
|
||||
&key_type_user, name, true);
|
||||
if (IS_ERR(kref))
|
||||
key = ERR_CAST(kref);
|
||||
else
|
||||
|
|
|
@ -148,7 +148,7 @@ found_service:
|
|||
|
||||
/* look through the service's keyring */
|
||||
kref = keyring_search(make_key_ref(rx->securities, 1UL),
|
||||
&key_type_rxrpc_s, kdesc);
|
||||
&key_type_rxrpc_s, kdesc, true);
|
||||
if (IS_ERR(kref)) {
|
||||
read_unlock(&local->services_lock);
|
||||
_leave(" = %ld [search]", PTR_ERR(kref));
|
||||
|
|
|
@ -39,7 +39,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
|
|||
key_ref_t kref;
|
||||
|
||||
kref = keyring_search(make_key_ref(key, 1),
|
||||
&key_type_asymmetric, name);
|
||||
&key_type_asymmetric, name, true);
|
||||
if (!IS_ERR(kref)) {
|
||||
pr_err("Key '%s' is in ima_blacklist_keyring\n", name);
|
||||
return ERR_PTR(-EKEYREJECTED);
|
||||
|
@ -51,7 +51,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
|
|||
key_ref_t kref;
|
||||
|
||||
kref = keyring_search(make_key_ref(keyring, 1),
|
||||
&key_type_asymmetric, name);
|
||||
&key_type_asymmetric, name, true);
|
||||
if (IS_ERR(kref))
|
||||
key = ERR_CAST(kref);
|
||||
else
|
||||
|
|
|
@ -127,6 +127,7 @@ struct keyring_search_context {
|
|||
#define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */
|
||||
#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */
|
||||
#define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */
|
||||
#define KEYRING_SEARCH_RECURSE 0x0040 /* Search child keyrings also */
|
||||
|
||||
int (*iterator)(const void *object, void *iterator_data);
|
||||
|
||||
|
|
|
@ -762,7 +762,7 @@ long keyctl_keyring_search(key_serial_t ringid,
|
|||
}
|
||||
|
||||
/* do the search */
|
||||
key_ref = keyring_search(keyring_ref, ktype, description);
|
||||
key_ref = keyring_search(keyring_ref, ktype, description, true);
|
||||
if (IS_ERR(key_ref)) {
|
||||
ret = PTR_ERR(key_ref);
|
||||
|
||||
|
|
|
@ -685,6 +685,9 @@ descend_to_keyring:
|
|||
* Non-keyrings avoid the leftmost branch of the root entirely (root
|
||||
* slots 1-15).
|
||||
*/
|
||||
if (!(ctx->flags & KEYRING_SEARCH_RECURSE))
|
||||
goto not_this_keyring;
|
||||
|
||||
ptr = READ_ONCE(keyring->keys.root);
|
||||
if (!ptr)
|
||||
goto not_this_keyring;
|
||||
|
@ -885,13 +888,15 @@ key_ref_t keyring_search_rcu(key_ref_t keyring_ref,
|
|||
* @keyring: The root of the keyring tree to be searched.
|
||||
* @type: The type of keyring we want to find.
|
||||
* @description: The name of the keyring we want to find.
|
||||
* @recurse: True to search the children of @keyring also
|
||||
*
|
||||
* As keyring_search_rcu() above, but using the current task's credentials and
|
||||
* type's default matching function and preferred search method.
|
||||
*/
|
||||
key_ref_t keyring_search(key_ref_t keyring,
|
||||
struct key_type *type,
|
||||
const char *description)
|
||||
const char *description,
|
||||
bool recurse)
|
||||
{
|
||||
struct keyring_search_context ctx = {
|
||||
.index_key.type = type,
|
||||
|
@ -906,6 +911,8 @@ key_ref_t keyring_search(key_ref_t keyring,
|
|||
key_ref_t key;
|
||||
int ret;
|
||||
|
||||
if (recurse)
|
||||
ctx.flags |= KEYRING_SEARCH_RECURSE;
|
||||
if (type->match_preparse) {
|
||||
ret = type->match_preparse(&ctx.match_data);
|
||||
if (ret < 0)
|
||||
|
@ -1176,7 +1183,8 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
|
|||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_NO_UPDATE_TIME |
|
||||
KEYRING_SEARCH_NO_CHECK_PERM |
|
||||
KEYRING_SEARCH_DETECT_TOO_DEEP),
|
||||
KEYRING_SEARCH_DETECT_TOO_DEEP |
|
||||
KEYRING_SEARCH_RECURSE),
|
||||
};
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -170,7 +170,8 @@ static int proc_keys_show(struct seq_file *m, void *v)
|
|||
.match_data.cmp = lookup_user_key_possessed,
|
||||
.match_data.raw_data = key,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = KEYRING_SEARCH_NO_STATE_CHECK,
|
||||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_RECURSE),
|
||||
};
|
||||
|
||||
key_ref = make_key_ref(key, 0);
|
||||
|
|
|
@ -531,7 +531,8 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
|
|||
struct keyring_search_context ctx = {
|
||||
.match_data.cmp = lookup_user_key_possessed,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = KEYRING_SEARCH_NO_STATE_CHECK,
|
||||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_RECURSE),
|
||||
};
|
||||
struct request_key_auth *rka;
|
||||
struct key *key;
|
||||
|
|
|
@ -569,7 +569,8 @@ struct key *request_key_and_link(struct key_type *type,
|
|||
.match_data.raw_data = description,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = (KEYRING_SEARCH_DO_STATE_CHECK |
|
||||
KEYRING_SEARCH_SKIP_EXPIRED),
|
||||
KEYRING_SEARCH_SKIP_EXPIRED |
|
||||
KEYRING_SEARCH_RECURSE),
|
||||
};
|
||||
struct key *key;
|
||||
key_ref_t key_ref;
|
||||
|
|
|
@ -252,7 +252,8 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
|
|||
.match_data.cmp = key_default_cmp,
|
||||
.match_data.raw_data = description,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = KEYRING_SEARCH_DO_STATE_CHECK,
|
||||
.flags = (KEYRING_SEARCH_DO_STATE_CHECK |
|
||||
KEYRING_SEARCH_RECURSE),
|
||||
};
|
||||
struct key *authkey;
|
||||
key_ref_t authkey_ref;
|
||||
|
|
Загрузка…
Ссылка в новой задаче