mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
KEYS: Preparse match data
Preparse the match data. This provides several advantages:
(1) The preparser can reject invalid criteria up front.
(2) The preparser can convert the criteria to binary data if necessary (the
asymmetric key type really wants to do binary comparison of the key IDs).
(3) The preparser can set the type of search to be performed. This means
that it's not then a one-off setting in the key type.
(4) The preparser can set an appropriate comparator function.
Signed-off-by: David Howells <[email protected]>
Acked-by: Vivek Goyal <[email protected]>
This commit is contained in:
parent
53d91c5ce0
commit
462919591a
11 changed files with 129 additions and 51 deletions
|
|
@ -107,13 +107,10 @@ extern int iterate_over_keyring(const struct key *keyring,
|
|||
int (*func)(const struct key *key, void *data),
|
||||
void *data);
|
||||
|
||||
typedef int (*key_match_func_t)(const struct key *, const void *);
|
||||
|
||||
struct keyring_search_context {
|
||||
struct keyring_index_key index_key;
|
||||
const struct cred *cred;
|
||||
key_match_func_t match;
|
||||
const void *match_data;
|
||||
struct key_match_data match_data;
|
||||
unsigned flags;
|
||||
#define KEYRING_SEARCH_LOOKUP_TYPE 0x0001 /* [as type->def_lookup_type] */
|
||||
#define KEYRING_SEARCH_NO_STATE_CHECK 0x0002 /* Skip state checks */
|
||||
|
|
@ -152,7 +149,8 @@ extern struct key *request_key_and_link(struct key_type *type,
|
|||
struct key *dest_keyring,
|
||||
unsigned long flags);
|
||||
|
||||
extern int lookup_user_key_possessed(const struct key *key, const void *target);
|
||||
extern int lookup_user_key_possessed(const struct key *key,
|
||||
const struct key_match_data *match_data);
|
||||
extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
|
||||
key_perm_t perm);
|
||||
#define KEY_LOOKUP_CREATE 0x01
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -194,10 +194,10 @@ static int proc_keys_show(struct seq_file *m, void *v)
|
|||
.index_key.type = key->type,
|
||||
.index_key.description = key->description,
|
||||
.cred = current_cred(),
|
||||
.match = lookup_user_key_possessed,
|
||||
.match_data = key,
|
||||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_LOOKUP_DIRECT),
|
||||
.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,
|
||||
};
|
||||
|
||||
key_ref = make_key_ref(key, 0);
|
||||
|
|
|
|||
|
|
@ -489,9 +489,10 @@ found:
|
|||
/*
|
||||
* See if the key we're looking at is the target key.
|
||||
*/
|
||||
int lookup_user_key_possessed(const struct key *key, const void *target)
|
||||
int lookup_user_key_possessed(const struct key *key,
|
||||
const struct key_match_data *match_data)
|
||||
{
|
||||
return key == target;
|
||||
return key == match_data->raw_data;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -516,9 +517,9 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
|
|||
key_perm_t perm)
|
||||
{
|
||||
struct keyring_search_context ctx = {
|
||||
.match = lookup_user_key_possessed,
|
||||
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
|
||||
KEYRING_SEARCH_LOOKUP_DIRECT),
|
||||
.match_data.cmp = lookup_user_key_possessed,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.flags = KEYRING_SEARCH_NO_STATE_CHECK,
|
||||
};
|
||||
struct request_key_auth *rka;
|
||||
struct key *key;
|
||||
|
|
@ -673,7 +674,7 @@ try_again:
|
|||
ctx.index_key.type = key->type;
|
||||
ctx.index_key.description = key->description;
|
||||
ctx.index_key.desc_len = strlen(key->description);
|
||||
ctx.match_data = key;
|
||||
ctx.match_data.raw_data = key;
|
||||
kdebug("check possessed");
|
||||
skey_ref = search_process_keyrings(&ctx);
|
||||
kdebug("possessed=%p", skey_ref);
|
||||
|
|
|
|||
|
|
@ -531,9 +531,9 @@ struct key *request_key_and_link(struct key_type *type,
|
|||
.index_key.type = type,
|
||||
.index_key.description = description,
|
||||
.cred = current_cred(),
|
||||
.match = type->match,
|
||||
.match_data = description,
|
||||
.flags = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.match_data.cmp = type->match,
|
||||
.match_data.raw_data = description,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
};
|
||||
struct key *key;
|
||||
key_ref_t key_ref;
|
||||
|
|
@ -543,6 +543,14 @@ struct key *request_key_and_link(struct key_type *type,
|
|||
ctx.index_key.type->name, ctx.index_key.description,
|
||||
callout_info, callout_len, aux, dest_keyring, flags);
|
||||
|
||||
if (type->match_preparse) {
|
||||
ret = type->match_preparse(&ctx.match_data);
|
||||
if (ret < 0) {
|
||||
key = ERR_PTR(ret);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* search all the process keyrings for a key */
|
||||
key_ref = search_process_keyrings(&ctx);
|
||||
|
||||
|
|
@ -555,7 +563,7 @@ struct key *request_key_and_link(struct key_type *type,
|
|||
if (ret < 0) {
|
||||
key_put(key);
|
||||
key = ERR_PTR(ret);
|
||||
goto error;
|
||||
goto error_free;
|
||||
}
|
||||
}
|
||||
} else if (PTR_ERR(key_ref) != -EAGAIN) {
|
||||
|
|
@ -565,12 +573,15 @@ struct key *request_key_and_link(struct key_type *type,
|
|||
* should consult userspace if we can */
|
||||
key = ERR_PTR(-ENOKEY);
|
||||
if (!callout_info)
|
||||
goto error;
|
||||
goto error_free;
|
||||
|
||||
key = construct_key_and_link(&ctx, callout_info, callout_len,
|
||||
aux, dest_keyring, flags);
|
||||
}
|
||||
|
||||
error_free:
|
||||
if (type->match_free)
|
||||
type->match_free(&ctx.match_data);
|
||||
error:
|
||||
kleave(" = %p", key);
|
||||
return key;
|
||||
|
|
|
|||
|
|
@ -246,9 +246,9 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
|
|||
.index_key.type = &key_type_request_key_auth,
|
||||
.index_key.description = description,
|
||||
.cred = current_cred(),
|
||||
.match = user_match,
|
||||
.match_data = description,
|
||||
.flags = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
.match_data.cmp = user_match,
|
||||
.match_data.raw_data = description,
|
||||
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
|
||||
};
|
||||
struct key *authkey;
|
||||
key_ref_t authkey_ref;
|
||||
|
|
|
|||
|
|
@ -141,9 +141,9 @@ EXPORT_SYMBOL_GPL(user_update);
|
|||
/*
|
||||
* match users on their name
|
||||
*/
|
||||
int user_match(const struct key *key, const void *description)
|
||||
int user_match(const struct key *key, const struct key_match_data *match_data)
|
||||
{
|
||||
return strcmp(key->description, description) == 0;
|
||||
return strcmp(key->description, match_data->raw_data) == 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(user_match);
|
||||
|
|
|
|||
Loading…
Reference in a new issue