summaryrefslogtreecommitdiffstats
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 8314a7d2104d..e72548b5897e 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -89,7 +89,6 @@ struct key_type key_type_keyring = {
.preparse = keyring_preparse,
.free_preparse = keyring_free_preparse,
.instantiate = keyring_instantiate,
- .match = user_match,
.revoke = keyring_revoke,
.destroy = keyring_destroy,
.describe = keyring_describe,
@@ -512,6 +511,15 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
EXPORT_SYMBOL(keyring_alloc);
/*
+ * By default, we keys found by getting an exact match on their descriptions.
+ */
+bool key_default_cmp(const struct key *key,
+ const struct key_match_data *match_data)
+{
+ return strcmp(key->description, match_data->raw_data) == 0;
+}
+
+/*
* Iteration function to consider each key found.
*/
static int keyring_search_iterator(const void *object, void *iterator_data)
@@ -538,14 +546,15 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
}
if (key->expiry && ctx->now.tv_sec >= key->expiry) {
- ctx->result = ERR_PTR(-EKEYEXPIRED);
+ if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED))
+ ctx->result = ERR_PTR(-EKEYEXPIRED);
kleave(" = %d [expire]", ctx->skipped_ret);
goto skipped;
}
}
/* keys that don't match */
- if (!ctx->match(key, ctx->match_data)) {
+ if (!ctx->match_data.cmp(key, &ctx->match_data)) {
kleave(" = 0 [!match]");
return 0;
}
@@ -585,8 +594,7 @@ skipped:
*/
static int search_keyring(struct key *keyring, struct keyring_search_context *ctx)
{
- if ((ctx->flags & KEYRING_SEARCH_LOOKUP_TYPE) ==
- KEYRING_SEARCH_LOOKUP_DIRECT) {
+ if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_DIRECT) {
const void *object;
object = assoc_array_find(&keyring->keys,
@@ -621,16 +629,19 @@ static bool search_nested_keyrings(struct key *keyring,
ctx->index_key.type->name,
ctx->index_key.description);
+#define STATE_CHECKS (KEYRING_SEARCH_NO_STATE_CHECK | KEYRING_SEARCH_DO_STATE_CHECK)
+ BUG_ON((ctx->flags & STATE_CHECKS) == 0 ||
+ (ctx->flags & STATE_CHECKS) == STATE_CHECKS);
+
if (ctx->index_key.description)
ctx->index_key.desc_len = strlen(ctx->index_key.description);
/* Check to see if this top-level keyring is what we are looking for
* and whether it is valid or not.
*/
- if (ctx->flags & KEYRING_SEARCH_LOOKUP_ITERATE ||
+ if (ctx->match_data.lookup_type == KEYRING_SEARCH_LOOKUP_ITERATE ||
keyring_compare_object(keyring, &ctx->index_key)) {
ctx->skipped_ret = 2;
- ctx->flags |= KEYRING_SEARCH_DO_STATE_CHECK;
switch (ctx->iterator(keyring_key_to_ptr(keyring), ctx)) {
case 1:
goto found;
@@ -642,8 +653,6 @@ static bool search_nested_keyrings(struct key *keyring,
}
ctx->skipped_ret = 0;
- if (ctx->flags & KEYRING_SEARCH_NO_STATE_CHECK)
- ctx->flags &= ~KEYRING_SEARCH_DO_STATE_CHECK;
/* Start processing a new keyring */
descend_to_keyring:
@@ -885,16 +894,25 @@ key_ref_t keyring_search(key_ref_t keyring,
.index_key.type = type,
.index_key.description = description,
.cred = current_cred(),
- .match = type->match,
- .match_data = description,
- .flags = (type->def_lookup_type |
- KEYRING_SEARCH_DO_STATE_CHECK),
+ .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,
};
+ key_ref_t key;
+ int ret;
- if (!ctx.match)
- return ERR_PTR(-ENOKEY);
+ if (type->match_preparse) {
+ ret = type->match_preparse(&ctx.match_data);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ }
- return keyring_search_aux(keyring, &ctx);
+ key = keyring_search_aux(keyring, &ctx);
+
+ if (type->match_free)
+ type->match_free(&ctx.match_data);
+ return key;
}
EXPORT_SYMBOL(keyring_search);
@@ -1014,7 +1032,7 @@ static int keyring_detect_cycle_iterator(const void *object,
/* We might get a keyring with matching index-key that is nonetheless a
* different keyring. */
- if (key != ctx->match_data)
+ if (key != ctx->match_data.raw_data)
return 0;
ctx->result = ERR_PTR(-EDEADLK);
@@ -1031,14 +1049,14 @@ static int keyring_detect_cycle_iterator(const void *object,
static int keyring_detect_cycle(struct key *A, struct key *B)
{
struct keyring_search_context ctx = {
- .index_key = A->index_key,
- .match_data = A,
- .iterator = keyring_detect_cycle_iterator,
- .flags = (KEYRING_SEARCH_LOOKUP_DIRECT |
- KEYRING_SEARCH_NO_STATE_CHECK |
- KEYRING_SEARCH_NO_UPDATE_TIME |
- KEYRING_SEARCH_NO_CHECK_PERM |
- KEYRING_SEARCH_DETECT_TOO_DEEP),
+ .index_key = A->index_key,
+ .match_data.raw_data = A,
+ .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
+ .iterator = keyring_detect_cycle_iterator,
+ .flags = (KEYRING_SEARCH_NO_STATE_CHECK |
+ KEYRING_SEARCH_NO_UPDATE_TIME |
+ KEYRING_SEARCH_NO_CHECK_PERM |
+ KEYRING_SEARCH_DETECT_TOO_DEEP),
};
rcu_read_lock();
OpenPOWER on IntegriCloud