Skip to content

Commit

Permalink
KEYS: Split role of the keyring pointer for keyring restrict functions
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mjmartineau committed Apr 3, 2017
1 parent 469ff8f commit aaf66c8
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 25 deletions.
8 changes: 4 additions & 4 deletions Documentation/security/keys.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
18 changes: 11 additions & 7 deletions certs/system_keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
8 changes: 5 additions & 3 deletions crypto/asymmetric_keys/restrict.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions include/crypto/public_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions include/keys/system_keyring.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
8 changes: 5 additions & 3 deletions include/linux/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/*****************************************************************************/
/*
Expand Down Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions security/keys/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions security/keys/keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}

/**
Expand Down

0 comments on commit aaf66c8

Please sign in to comment.