Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e59428f7 authored by David Howells's avatar David Howells
Browse files

keys: Move the RCU locks outwards from the keyring search functions



Move the RCU locks outwards from the keyring search functions so that it
will become possible to provide an RCU-capable partial request_key()
function in a later commit.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent a09003b5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ The Search Algorithm

A search of any particular keyring proceeds in the following fashion:

  1) When the key management code searches for a key (keyring_search_aux) it
  1) When the key management code searches for a key (keyring_search_rcu) it
     firstly calls key_permission(SEARCH) on the keyring it's starting with,
     if this denies permission, it doesn't search further.

+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
 * Authorisation record for request_key().
 */
struct request_key_auth {
	struct rcu_head		rcu;
	struct key		*target_key;
	struct key		*dest_keyring;
	const struct cred	*cred;
+3 −3
Original line number Diff line number Diff line
@@ -139,11 +139,11 @@ struct keyring_search_context {

extern bool key_default_cmp(const struct key *key,
			    const struct key_match_data *match_data);
extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
extern key_ref_t keyring_search_rcu(key_ref_t keyring_ref,
				    struct keyring_search_context *ctx);

extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx);
extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx);
extern key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx);
extern key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx);

extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);

+9 −7
Original line number Diff line number Diff line
@@ -835,7 +835,7 @@ static bool search_nested_keyrings(struct key *keyring,
}

/**
 * keyring_search_aux - Search a keyring tree for a key matching some criteria
 * keyring_search_rcu - Search a keyring tree for a matching key under RCU
 * @keyring_ref: A pointer to the keyring with possession indicator.
 * @ctx: The keyring search context.
 *
@@ -847,7 +847,9 @@ static bool search_nested_keyrings(struct key *keyring,
 * addition, the LSM gets to forbid keyring searches and key matches.
 *
 * The search is performed as a breadth-then-depth search up to the prescribed
 * limit (KEYRING_SEARCH_MAX_DEPTH).
 * limit (KEYRING_SEARCH_MAX_DEPTH).  The caller must hold the RCU read lock to
 * prevent keyrings from being destroyed or rearranged whilst they are being
 * searched.
 *
 * Keys are matched to the type provided and are then filtered by the match
 * function, which is given the description to use in any way it sees fit.  The
@@ -866,7 +868,7 @@ static bool search_nested_keyrings(struct key *keyring,
 * In the case of a successful return, the possession attribute from
 * @keyring_ref is propagated to the returned key reference.
 */
key_ref_t keyring_search_aux(key_ref_t keyring_ref,
key_ref_t keyring_search_rcu(key_ref_t keyring_ref,
			     struct keyring_search_context *ctx)
{
	struct key *keyring;
@@ -888,11 +890,9 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
			return ERR_PTR(err);
	}

	rcu_read_lock();
	ctx->now = ktime_get_real_seconds();
	if (search_nested_keyrings(keyring, ctx))
		__key_get(key_ref_to_ptr(ctx->result));
	rcu_read_unlock();
	return ctx->result;
}

@@ -902,7 +902,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
 * @type: The type of keyring we want to find.
 * @description: The name of the keyring we want to find.
 *
 * As keyring_search_aux() above, but using the current task's credentials and
 * 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,
@@ -928,7 +928,9 @@ key_ref_t keyring_search(key_ref_t keyring,
			return ERR_PTR(ret);
	}

	key = keyring_search_aux(keyring, &ctx);
	rcu_read_lock();
	key = keyring_search_rcu(keyring, &ctx);
	rcu_read_unlock();

	if (type->match_free)
		type->match_free(&ctx.match_data);
+3 −1
Original line number Diff line number Diff line
@@ -179,7 +179,9 @@ static int proc_keys_show(struct seq_file *m, void *v)
	 * skip if the key does not indicate the possessor can view it
	 */
	if (key->perm & KEY_POS_VIEW) {
		skey_ref = search_my_process_keyrings(&ctx);
		rcu_read_lock();
		skey_ref = search_cred_keyrings_rcu(&ctx);
		rcu_read_unlock();
		if (!IS_ERR(skey_ref)) {
			key_ref_put(skey_ref);
			key_ref = make_key_ref(key, 1);
Loading