diff options
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r-- | security/keys/keyring.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 8314a7d2104d..10f0a5f2d362 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -545,7 +545,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) } /* 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 +585,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, @@ -627,7 +626,7 @@ static bool search_nested_keyrings(struct key *keyring, /* 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; @@ -885,16 +884,28 @@ 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 = type->match, + .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) + if (!ctx.match_data.cmp) return ERR_PTR(-ENOKEY); - return keyring_search_aux(keyring, &ctx); + if (type->match_preparse) { + ret = type->match_preparse(&ctx.match_data); + if (ret < 0) + return ERR_PTR(ret); + } + + key = keyring_search_aux(keyring, &ctx); + + if (type->match_free) + type->match_free(&ctx.match_data); + return key; } EXPORT_SYMBOL(keyring_search); @@ -1014,7 +1025,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 +1042,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(); |