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: Mat Martineau <mathew.j.martineau@linux.intel.com>
This commit is contained in:
Mat Martineau 2016-08-30 11:33:13 -07:00
parent 469ff8f7d4
commit aaf66c8838
8 changed files with 39 additions and 25 deletions

View File

@ -1054,10 +1054,10 @@ payload contents" for more information.
can be verified by a key the kernel already has.
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. Note that when a new key is being created, this is called between
payload preparsing and actual key creation. The function should return 0
to allow the link or an error to reject it.
added to, the key type, the payload of the key being added, and data to be
used in the restriction check. Note that when a new key is being created,
this is called between payload preparsing and actual key creation. The
function should return 0 to allow the link or an error to reject it.
A convenience function, restrict_link_reject, exists to always return
-EPERM to in this case.

View File

@ -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
* 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 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
@ -49,20 +51,22 @@ int restrict_link_by_builtin_trusted(struct key *keyring,
* keyrings.
*/
int restrict_link_by_builtin_and_secondary_trusted(
struct key *keyring,
struct key *dest_keyring,
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
* through to the builtin keyring and the search will follow that link.
*/
if (type == &key_type_keyring &&
keyring == secondary_trusted_keys &&
dest_keyring == secondary_trusted_keys &&
payload == &builtin_trusted_keys->payload)
/* Allow the builtin keyring to be added to the secondary */
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

View File

@ -56,9 +56,10 @@ __setup("ca_keys=", ca_keys_setup);
/**
* 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.
* @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
* those is the signing key and validates the new certificate, then mark the
@ -69,9 +70,10 @@ __setup("ca_keys=", ca_keys_setup);
* 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.
*/
int restrict_link_by_signature(struct key *trust_keyring,
int restrict_link_by_signature(struct key *dest_keyring,
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;
struct key *key;

View File

@ -50,9 +50,10 @@ struct key;
struct key_type;
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 union key_payload *payload);
const union key_payload *payload,
struct key *trust_keyring);
extern int verify_signature(const struct key *key,
const struct public_key_signature *sig);

View File

@ -18,7 +18,8 @@
extern int restrict_link_by_builtin_trusted(struct key *keyring,
const struct key_type *type,
const union key_payload *payload);
const union key_payload *payload,
struct key *restriction_key);
#else
#define restrict_link_by_builtin_trusted restrict_link_reject
@ -28,7 +29,8 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring,
extern int restrict_link_by_builtin_and_secondary_trusted(
struct key *keyring,
const struct key_type *type,
const union key_payload *payload);
const union key_payload *payload,
struct key *restriction_key);
#else
#define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
#endif

View File

@ -127,9 +127,10 @@ static inline bool is_key_possessed(const key_ref_t key_ref)
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 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
extern int restrict_link_reject(struct key *keyring,
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);

View File

@ -499,7 +499,7 @@ int key_instantiate_and_link(struct key *key,
if (keyring) {
if (keyring->restrict_link) {
ret = keyring->restrict_link(keyring, key->type,
&prep.payload);
&prep.payload, NULL);
if (ret < 0)
goto error;
}
@ -851,7 +851,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
index_key.desc_len = strlen(index_key.description);
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) {
key_ref = ERR_PTR(ret);
goto error_free_prep;

View File

@ -517,6 +517,7 @@ EXPORT_SYMBOL(keyring_alloc);
* @keyring: The keyring being added to.
* @type: The type of key being 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
* passing KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when
@ -527,7 +528,8 @@ EXPORT_SYMBOL(keyring_alloc);
*/
int restrict_link_reject(struct key *keyring,
const struct key_type *type,
const union key_payload *payload)
const union key_payload *payload,
struct key *restriction_key)
{
return -EPERM;
}
@ -1220,7 +1222,7 @@ static int __key_link_check_restriction(struct key *keyring, struct key *key)
{
if (!keyring->restrict_link)
return 0;
return keyring->restrict_link(keyring, key->type, &key->payload);
return keyring->restrict_link(keyring, key->type, &key->payload, NULL);
}
/**