From 462919591a1791e76042dc5c1e0148715df59beb Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 16 Sep 2014 17:36:02 +0100 Subject: 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 Acked-by: Vivek Goyal --- security/keys/request_key.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'security/keys/request_key.c') diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 381411941cc1..408523e5e2e2 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -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; -- cgit v1.2.3 From c06cfb08b88dfbe13be44a69ae2fdc3a7c902d81 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 16 Sep 2014 17:36:06 +0100 Subject: KEYS: Remove key_type::match in favour of overriding default by match_preparse A previous patch added a ->match_preparse() method to the key type. This is allowed to override the function called by the iteration algorithm. Therefore, we can just set a default that simply checks for an exact match of the key description with the original criterion data and allow match_preparse to override it as needed. The key_type::match op is then redundant and can be removed, as can the user_match() function. Signed-off-by: David Howells Acked-by: Vivek Goyal --- crypto/asymmetric_keys/asymmetric_type.c | 6 +++--- crypto/asymmetric_keys/pkcs7_key_type.c | 1 - fs/cifs/cifs_spnego.c | 1 - fs/cifs/cifsacl.c | 1 - fs/nfs/idmap.c | 2 -- include/keys/user-type.h | 3 --- include/linux/key-type.h | 4 ---- net/ceph/crypto.c | 1 - net/dns_resolver/dns_key.c | 17 +++++++++++++---- net/rxrpc/ar-key.c | 2 -- security/keys/big_key.c | 1 - security/keys/encrypted-keys/encrypted.c | 1 - security/keys/internal.h | 2 ++ security/keys/key.c | 2 +- security/keys/keyring.c | 15 ++++++++++----- security/keys/request_key.c | 2 +- security/keys/request_key_auth.c | 2 +- security/keys/trusted.c | 1 - security/keys/user_defined.c | 12 ------------ 19 files changed, 31 insertions(+), 45 deletions(-) (limited to 'security/keys/request_key.c') diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index 9d78ad7754d9..7c0498968975 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -59,8 +59,8 @@ EXPORT_SYMBOL_GPL(asymmetric_keyid_match); * "id:" - request a key matching the ID * ":" - request a key of a subtype */ -static int asymmetric_key_match(const struct key *key, - const struct key_match_data *match_data) +static int asymmetric_key_cmp(const struct key *key, + const struct key_match_data *match_data) { const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); const char *description = match_data->raw_data; @@ -110,6 +110,7 @@ static int asymmetric_key_match(const struct key *key, static int asymmetric_key_match_preparse(struct key_match_data *match_data) { match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE; + match_data->cmp = asymmetric_key_cmp; return 0; } @@ -224,7 +225,6 @@ struct key_type key_type_asymmetric = { .free_preparse = asymmetric_key_free_preparse, .instantiate = generic_key_instantiate, .match_preparse = asymmetric_key_match_preparse, - .match = asymmetric_key_match, .match_free = asymmetric_key_match_free, .destroy = asymmetric_key_destroy, .describe = asymmetric_key_describe, diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c index d1faa1df1dec..751f8fd7335d 100644 --- a/crypto/asymmetric_keys/pkcs7_key_type.c +++ b/crypto/asymmetric_keys/pkcs7_key_type.c @@ -75,7 +75,6 @@ static struct key_type key_type_pkcs7 = { .preparse = pkcs7_preparse, .free_preparse = user_free_preparse, .instantiate = generic_key_instantiate, - .match = user_match, .revoke = user_revoke, .destroy = user_destroy, .describe = user_describe, diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index a3e932547617..f4cf200b3c76 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c @@ -62,7 +62,6 @@ cifs_spnego_key_destroy(struct key *key) struct key_type cifs_spnego_key_type = { .name = "cifs.spnego", .instantiate = cifs_spnego_key_instantiate, - .match = user_match, .destroy = cifs_spnego_key_destroy, .describe = user_describe, }; diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 7ff866dbb89e..6d00c419cbae 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -84,7 +84,6 @@ static struct key_type cifs_idmap_key_type = { .instantiate = cifs_idmap_key_instantiate, .destroy = cifs_idmap_key_destroy, .describe = user_describe, - .match = user_match, }; static char * diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 7dd55b745c4d..2f5db844c172 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -177,7 +177,6 @@ static struct key_type key_type_id_resolver = { .preparse = user_preparse, .free_preparse = user_free_preparse, .instantiate = generic_key_instantiate, - .match = user_match, .revoke = user_revoke, .destroy = user_destroy, .describe = user_describe, @@ -401,7 +400,6 @@ static struct key_type key_type_id_resolver_legacy = { .preparse = user_preparse, .free_preparse = user_free_preparse, .instantiate = generic_key_instantiate, - .match = user_match, .revoke = user_revoke, .destroy = user_destroy, .describe = user_describe, diff --git a/include/keys/user-type.h b/include/keys/user-type.h index 66d92af30e7c..cebefb069c44 100644 --- a/include/keys/user-type.h +++ b/include/keys/user-type.h @@ -36,13 +36,10 @@ extern struct key_type key_type_user; extern struct key_type key_type_logon; struct key_preparsed_payload; -struct key_match_data; extern int user_preparse(struct key_preparsed_payload *prep); extern void user_free_preparse(struct key_preparsed_payload *prep); extern int user_update(struct key *key, struct key_preparsed_payload *prep); -extern int user_match(const struct key *key, - const struct key_match_data *match_data); extern void user_revoke(struct key *key); extern void user_destroy(struct key *key); extern void user_describe(const struct key *user, struct seq_file *m); diff --git a/include/linux/key-type.h b/include/linux/key-type.h index bf93ea609273..c14816bd3b44 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h @@ -113,10 +113,6 @@ struct key_type { */ int (*match_preparse)(struct key_match_data *match_data); - /* match a key against a description */ - int (*match)(const struct key *key, - const struct key_match_data *match_data); - /* Free preparsed match data (optional). This should be supplied it * ->match_preparse() is supplied. */ void (*match_free)(struct key_match_data *match_data); diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index ffeba8f9dda9..62fc5e7a9acf 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -476,7 +476,6 @@ struct key_type key_type_ceph = { .preparse = ceph_key_preparse, .free_preparse = ceph_key_free_preparse, .instantiate = generic_key_instantiate, - .match = user_match, .destroy = ceph_key_destroy, }; diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index 92df6e508ae7..a07b9ba7e0b7 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c @@ -176,9 +176,8 @@ static void dns_resolver_free_preparse(struct key_preparsed_payload *prep) * The domain name may be a simple name or an absolute domain name (which * should end with a period). The domain name is case-independent. */ -static int -dns_resolver_match(const struct key *key, - const struct key_match_data *match_data) +static int dns_resolver_cmp(const struct key *key, + const struct key_match_data *match_data) { int slen, dlen, ret = 0; const char *src = key->description, *dsp = match_data->raw_data; @@ -209,6 +208,16 @@ no_match: return ret; } +/* + * Preparse the match criterion. + */ +static int dns_resolver_match_preparse(struct key_match_data *match_data) +{ + match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE; + match_data->cmp = dns_resolver_cmp; + return 0; +} + /* * Describe a DNS key */ @@ -243,7 +252,7 @@ struct key_type key_type_dns_resolver = { .preparse = dns_resolver_preparse, .free_preparse = dns_resolver_free_preparse, .instantiate = generic_key_instantiate, - .match = dns_resolver_match, + .match_preparse = dns_resolver_match_preparse, .revoke = user_revoke, .destroy = user_destroy, .describe = dns_resolver_describe, diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index 3907add75932..10c6cb694b43 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c @@ -44,7 +44,6 @@ struct key_type key_type_rxrpc = { .preparse = rxrpc_preparse, .free_preparse = rxrpc_free_preparse, .instantiate = generic_key_instantiate, - .match = user_match, .destroy = rxrpc_destroy, .describe = rxrpc_describe, .read = rxrpc_read, @@ -61,7 +60,6 @@ struct key_type key_type_rxrpc_s = { .preparse = rxrpc_preparse_s, .free_preparse = rxrpc_free_preparse_s, .instantiate = generic_key_instantiate, - .match = user_match, .destroy = rxrpc_destroy_s, .describe = rxrpc_describe, }; diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 4045c13a761a..b6adb94f6d52 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -36,7 +36,6 @@ struct key_type key_type_big_key = { .preparse = big_key_preparse, .free_preparse = big_key_free_preparse, .instantiate = generic_key_instantiate, - .match = user_match, .revoke = big_key_revoke, .destroy = big_key_destroy, .describe = big_key_describe, diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 5fe443d120af..db9675db1026 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c @@ -970,7 +970,6 @@ struct key_type key_type_encrypted = { .name = "encrypted", .instantiate = encrypted_instantiate, .update = encrypted_update, - .match = user_match, .destroy = encrypted_destroy, .describe = user_describe, .read = encrypted_read, diff --git a/security/keys/internal.h b/security/keys/internal.h index b47cc532be1e..e66a16cb63e1 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -127,6 +127,8 @@ struct keyring_search_context { struct timespec now; }; +extern int 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, struct keyring_search_context *ctx); diff --git a/security/keys/key.c b/security/keys/key.c index b90a68c4e2c4..8c0092ca0443 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -799,7 +799,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, } key_ref = ERR_PTR(-EINVAL); - if (!index_key.type->match || !index_key.type->instantiate || + if (!index_key.type->instantiate || (!index_key.description && !index_key.type->preparse)) goto error_put_type; diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 10f0a5f2d362..253c9a0eb092 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, @@ -511,6 +510,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. + */ +int 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. */ @@ -884,7 +892,7 @@ key_ref_t keyring_search(key_ref_t keyring, .index_key.type = type, .index_key.description = description, .cred = current_cred(), - .match_data.cmp = type->match, + .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, @@ -892,9 +900,6 @@ key_ref_t keyring_search(key_ref_t keyring, key_ref_t key; int ret; - if (!ctx.match_data.cmp) - return ERR_PTR(-ENOKEY); - if (type->match_preparse) { ret = type->match_preparse(&ctx.match_data); if (ret < 0) diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 408523e5e2e2..dc6ed32b7844 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -531,7 +531,7 @@ struct key *request_key_and_link(struct key_type *type, .index_key.type = type, .index_key.description = description, .cred = current_cred(), - .match_data.cmp = type->match, + .match_data.cmp = key_default_cmp, .match_data.raw_data = description, .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, }; diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 9ae02819cc06..6639e2cb8853 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -246,7 +246,7 @@ 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_data.cmp = user_match, + .match_data.cmp = key_default_cmp, .match_data.raw_data = description, .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, }; diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 6b804aa4529a..c0594cb07ada 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -1096,7 +1096,6 @@ struct key_type key_type_trusted = { .name = "trusted", .instantiate = trusted_instantiate, .update = trusted_update, - .match = user_match, .destroy = trusted_destroy, .describe = user_describe, .read = trusted_read, diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index cd7e726e8646..36b47bbd3d8c 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@ -30,7 +30,6 @@ struct key_type key_type_user = { .free_preparse = user_free_preparse, .instantiate = generic_key_instantiate, .update = user_update, - .match = user_match, .revoke = user_revoke, .destroy = user_destroy, .describe = user_describe, @@ -51,7 +50,6 @@ struct key_type key_type_logon = { .free_preparse = user_free_preparse, .instantiate = generic_key_instantiate, .update = user_update, - .match = user_match, .revoke = user_revoke, .destroy = user_destroy, .describe = user_describe, @@ -136,16 +134,6 @@ error: EXPORT_SYMBOL_GPL(user_update); -/* - * match users on their name - */ -int user_match(const struct key *key, const struct key_match_data *match_data) -{ - return strcmp(key->description, match_data->raw_data) == 0; -} - -EXPORT_SYMBOL_GPL(user_match); - /* * dispose of the links from a revoked keyring * - called with the key sem write-locked -- cgit v1.2.3