Commit aaf66c88 authored by Mat Martineau's avatar Mat Martineau

KEYS: Split role of the keyring pointer for keyring restrict functions

The first argument to the restrict_link_func_t functions was a keyring
pointer. These functions are called by the key subsystem with this
argument set to the destination keyring, but restrict_link_by_signature
expects a pointer to the relevant trusted keyring.

Restrict functions may need something other than a single struct key
pointer to allow or reject key linkage, so the data used to make that
decision (such as the trust keyring) is moved to a new, fourth
argument. The first argument is now always the destination keyring.
Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
parent 469ff8f7
...@@ -1054,10 +1054,10 @@ payload contents" for more information. ...@@ -1054,10 +1054,10 @@ payload contents" for more information.
can be verified by a key the kernel already has. can be verified by a key the kernel already has.
When called, the restriction function will be passed the keyring being When called, the restriction function will be passed the keyring being
added to, the key flags value and the type and payload of the key being added to, the key type, the payload of the key being added, and data to be
added. Note that when a new key is being created, this is called between used in the restriction check. Note that when a new key is being created,
payload preparsing and actual key creation. The function should return 0 this is called between payload preparsing and actual key creation. The
to allow the link or an error to reject it. function should return 0 to allow the link or an error to reject it.
A convenience function, restrict_link_reject, exists to always return A convenience function, restrict_link_reject, exists to always return
-EPERM to in this case. -EPERM to in this case.
......
...@@ -32,11 +32,13 @@ extern __initconst const unsigned long system_certificate_list_size; ...@@ -32,11 +32,13 @@ extern __initconst const unsigned long system_certificate_list_size;
* Restrict the addition of keys into a keyring based on the key-to-be-added * Restrict the addition of keys into a keyring based on the key-to-be-added
* being vouched for by a key in the built in system keyring. * being vouched for by a key in the built in system keyring.
*/ */
int restrict_link_by_builtin_trusted(struct key *keyring, int restrict_link_by_builtin_trusted(struct key *dest_keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload) const union key_payload *payload,
struct key *restriction_key)
{ {
return restrict_link_by_signature(builtin_trusted_keys, type, payload); return restrict_link_by_signature(dest_keyring, type, payload,
builtin_trusted_keys);
} }
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
...@@ -49,20 +51,22 @@ int restrict_link_by_builtin_trusted(struct key *keyring, ...@@ -49,20 +51,22 @@ int restrict_link_by_builtin_trusted(struct key *keyring,
* keyrings. * keyrings.
*/ */
int restrict_link_by_builtin_and_secondary_trusted( int restrict_link_by_builtin_and_secondary_trusted(
struct key *keyring, struct key *dest_keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload) const union key_payload *payload,
struct key *restrict_key)
{ {
/* If we have a secondary trusted keyring, then that contains a link /* If we have a secondary trusted keyring, then that contains a link
* through to the builtin keyring and the search will follow that link. * through to the builtin keyring and the search will follow that link.
*/ */
if (type == &key_type_keyring && if (type == &key_type_keyring &&
keyring == secondary_trusted_keys && dest_keyring == secondary_trusted_keys &&
payload == &builtin_trusted_keys->payload) payload == &builtin_trusted_keys->payload)
/* Allow the builtin keyring to be added to the secondary */ /* Allow the builtin keyring to be added to the secondary */
return 0; return 0;
return restrict_link_by_signature(secondary_trusted_keys, type, payload); return restrict_link_by_signature(dest_keyring, type, payload,
secondary_trusted_keys);
} }
#endif #endif
......
...@@ -56,9 +56,10 @@ __setup("ca_keys=", ca_keys_setup); ...@@ -56,9 +56,10 @@ __setup("ca_keys=", ca_keys_setup);
/** /**
* restrict_link_by_signature - Restrict additions to a ring of public keys * restrict_link_by_signature - Restrict additions to a ring of public keys
* @trust_keyring: A ring of keys that can be used to vouch for the new cert. * @dest_keyring: Keyring being linked to.
* @type: The type of key being added. * @type: The type of key being added.
* @payload: The payload of the new key. * @payload: The payload of the new key.
* @trust_keyring: A ring of keys that can be used to vouch for the new cert.
* *
* Check the new certificate against the ones in the trust keyring. If one of * Check the new certificate against the ones in the trust keyring. If one of
* those is the signing key and validates the new certificate, then mark the * those is the signing key and validates the new certificate, then mark the
...@@ -69,9 +70,10 @@ __setup("ca_keys=", ca_keys_setup); ...@@ -69,9 +70,10 @@ __setup("ca_keys=", ca_keys_setup);
* signature check fails or the key is blacklisted and some other error if * signature check fails or the key is blacklisted and some other error if
* there is a matching certificate but the signature check cannot be performed. * there is a matching certificate but the signature check cannot be performed.
*/ */
int restrict_link_by_signature(struct key *trust_keyring, int restrict_link_by_signature(struct key *dest_keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload) const union key_payload *payload,
struct key *trust_keyring)
{ {
const struct public_key_signature *sig; const struct public_key_signature *sig;
struct key *key; struct key *key;
......
...@@ -50,9 +50,10 @@ struct key; ...@@ -50,9 +50,10 @@ struct key;
struct key_type; struct key_type;
union key_payload; union key_payload;
extern int restrict_link_by_signature(struct key *trust_keyring, extern int restrict_link_by_signature(struct key *dest_keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload); const union key_payload *payload,
struct key *trust_keyring);
extern int verify_signature(const struct key *key, extern int verify_signature(const struct key *key,
const struct public_key_signature *sig); const struct public_key_signature *sig);
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
extern int restrict_link_by_builtin_trusted(struct key *keyring, extern int restrict_link_by_builtin_trusted(struct key *keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload); const union key_payload *payload,
struct key *restriction_key);
#else #else
#define restrict_link_by_builtin_trusted restrict_link_reject #define restrict_link_by_builtin_trusted restrict_link_reject
...@@ -28,7 +29,8 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring, ...@@ -28,7 +29,8 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring,
extern int restrict_link_by_builtin_and_secondary_trusted( extern int restrict_link_by_builtin_and_secondary_trusted(
struct key *keyring, struct key *keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload); const union key_payload *payload,
struct key *restriction_key);
#else #else
#define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
#endif #endif
......
...@@ -127,9 +127,10 @@ static inline bool is_key_possessed(const key_ref_t key_ref) ...@@ -127,9 +127,10 @@ static inline bool is_key_possessed(const key_ref_t key_ref)
return (unsigned long) key_ref & 1UL; return (unsigned long) key_ref & 1UL;
} }
typedef int (*key_restrict_link_func_t)(struct key *keyring, typedef int (*key_restrict_link_func_t)(struct key *dest_keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload); const union key_payload *payload,
struct key *restriction_key);
/*****************************************************************************/ /*****************************************************************************/
/* /*
...@@ -309,7 +310,8 @@ extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid ...@@ -309,7 +310,8 @@ extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid
extern int restrict_link_reject(struct key *keyring, extern int restrict_link_reject(struct key *keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload); const union key_payload *payload,
struct key *restriction_key);
extern int keyring_clear(struct key *keyring); extern int keyring_clear(struct key *keyring);
......
...@@ -499,7 +499,7 @@ int key_instantiate_and_link(struct key *key, ...@@ -499,7 +499,7 @@ int key_instantiate_and_link(struct key *key,
if (keyring) { if (keyring) {
if (keyring->restrict_link) { if (keyring->restrict_link) {
ret = keyring->restrict_link(keyring, key->type, ret = keyring->restrict_link(keyring, key->type,
&prep.payload); &prep.payload, NULL);
if (ret < 0) if (ret < 0)
goto error; goto error;
} }
...@@ -851,7 +851,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, ...@@ -851,7 +851,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
index_key.desc_len = strlen(index_key.description); index_key.desc_len = strlen(index_key.description);
if (restrict_link) { if (restrict_link) {
ret = restrict_link(keyring, index_key.type, &prep.payload); ret = restrict_link(keyring, index_key.type, &prep.payload,
NULL);
if (ret < 0) { if (ret < 0) {
key_ref = ERR_PTR(ret); key_ref = ERR_PTR(ret);
goto error_free_prep; goto error_free_prep;
......
...@@ -517,6 +517,7 @@ EXPORT_SYMBOL(keyring_alloc); ...@@ -517,6 +517,7 @@ EXPORT_SYMBOL(keyring_alloc);
* @keyring: The keyring being added to. * @keyring: The keyring being added to.
* @type: The type of key being added. * @type: The type of key being added.
* @payload: The payload of the key intended to be added. * @payload: The payload of the key intended to be added.
* @data: Additional data for evaluating restriction.
* *
* Reject the addition of any links to a keyring. It can be overridden by * Reject the addition of any links to a keyring. It can be overridden by
* passing KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when * passing KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when
...@@ -527,7 +528,8 @@ EXPORT_SYMBOL(keyring_alloc); ...@@ -527,7 +528,8 @@ EXPORT_SYMBOL(keyring_alloc);
*/ */
int restrict_link_reject(struct key *keyring, int restrict_link_reject(struct key *keyring,
const struct key_type *type, const struct key_type *type,
const union key_payload *payload) const union key_payload *payload,
struct key *restriction_key)
{ {
return -EPERM; return -EPERM;
} }
...@@ -1220,7 +1222,7 @@ static int __key_link_check_restriction(struct key *keyring, struct key *key) ...@@ -1220,7 +1222,7 @@ static int __key_link_check_restriction(struct key *keyring, struct key *key)
{ {
if (!keyring->restrict_link) if (!keyring->restrict_link)
return 0; return 0;
return keyring->restrict_link(keyring, key->type, &key->payload); return keyring->restrict_link(keyring, key->type, &key->payload, NULL);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment