|
@@ -491,13 +491,18 @@ static long keyring_read(const struct key *keyring,
|
|
|
*/
|
|
|
struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
|
|
|
const struct cred *cred, key_perm_t perm,
|
|
|
- unsigned long flags, struct key *dest)
|
|
|
+ unsigned long flags,
|
|
|
+ int (*restrict_link)(struct key *,
|
|
|
+ const struct key_type *,
|
|
|
+ unsigned long,
|
|
|
+ const union key_payload *),
|
|
|
+ struct key *dest)
|
|
|
{
|
|
|
struct key *keyring;
|
|
|
int ret;
|
|
|
|
|
|
keyring = key_alloc(&key_type_keyring, description,
|
|
|
- uid, gid, cred, perm, flags);
|
|
|
+ uid, gid, cred, perm, flags, restrict_link);
|
|
|
if (!IS_ERR(keyring)) {
|
|
|
ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
|
|
|
if (ret < 0) {
|
|
@@ -510,6 +515,51 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
|
|
|
}
|
|
|
EXPORT_SYMBOL(keyring_alloc);
|
|
|
|
|
|
+/**
|
|
|
+ * keyring_restrict_trusted_only - Restrict additions to a keyring to trusted keys only
|
|
|
+ * @keyring: The keyring being added to.
|
|
|
+ * @type: The type of key being added.
|
|
|
+ * @flags: The key flags.
|
|
|
+ * @payload: The payload of the key intended to be added.
|
|
|
+ *
|
|
|
+ * Reject the addition of any links to a keyring that point to keys that aren't
|
|
|
+ * marked as being trusted. It can be overridden by passing
|
|
|
+ * KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when adding a key
|
|
|
+ * to a keyring.
|
|
|
+ *
|
|
|
+ * This is meant to be passed as the restrict_link parameter to
|
|
|
+ * keyring_alloc().
|
|
|
+ */
|
|
|
+int keyring_restrict_trusted_only(struct key *keyring,
|
|
|
+ const struct key_type *type,
|
|
|
+ unsigned long flags,
|
|
|
+ const union key_payload *payload)
|
|
|
+{
|
|
|
+ return flags & KEY_FLAG_TRUSTED ? 0 : -EPERM;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * restrict_link_reject - Give -EPERM to restrict link
|
|
|
+ * @keyring: The keyring being added to.
|
|
|
+ * @type: The type of key being added.
|
|
|
+ * @flags: The key flags.
|
|
|
+ * @payload: The payload of the key intended to be added.
|
|
|
+ *
|
|
|
+ * 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
|
|
|
+ * adding a key to a keyring.
|
|
|
+ *
|
|
|
+ * This is meant to be passed as the restrict_link parameter to
|
|
|
+ * keyring_alloc().
|
|
|
+ */
|
|
|
+int restrict_link_reject(struct key *keyring,
|
|
|
+ const struct key_type *type,
|
|
|
+ unsigned long flags,
|
|
|
+ const union key_payload *payload)
|
|
|
+{
|
|
|
+ return -EPERM;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* By default, we keys found by getting an exact match on their descriptions.
|
|
|
*/
|
|
@@ -1191,6 +1241,17 @@ void __key_link_end(struct key *keyring,
|
|
|
up_write(&keyring->sem);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Check addition of keys to restricted keyrings.
|
|
|
+ */
|
|
|
+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->flags, &key->payload);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* key_link - Link a key to a keyring
|
|
|
* @keyring: The keyring to make the link in.
|
|
@@ -1221,14 +1282,12 @@ int key_link(struct key *keyring, struct key *key)
|
|
|
key_check(keyring);
|
|
|
key_check(key);
|
|
|
|
|
|
- if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) &&
|
|
|
- !test_bit(KEY_FLAG_TRUSTED, &key->flags))
|
|
|
- return -EPERM;
|
|
|
-
|
|
|
ret = __key_link_begin(keyring, &key->index_key, &edit);
|
|
|
if (ret == 0) {
|
|
|
kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));
|
|
|
- ret = __key_link_check_live_key(keyring, key);
|
|
|
+ ret = __key_link_check_restriction(keyring, key);
|
|
|
+ if (ret == 0)
|
|
|
+ ret = __key_link_check_live_key(keyring, key);
|
|
|
if (ret == 0)
|
|
|
__key_link(key, &edit);
|
|
|
__key_link_end(keyring, &key->index_key, edit);
|