KEYS: Split role of the keyring pointer for keyring restrict functions
authorMat Martineau <mathew.j.martineau@linux.intel.com>
Tue, 30 Aug 2016 18:33:13 +0000 (11:33 -0700)
committerMat Martineau <mathew.j.martineau@linux.intel.com>
Mon, 3 Apr 2017 17:24:56 +0000 (10:24 -0700)
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>
Documentation/security/keys.txt
certs/system_keyring.c
crypto/asymmetric_keys/restrict.c
include/crypto/public_key.h
include/keys/system_keyring.h
include/linux/key.h
security/keys/key.c
security/keys/keyring.c

index 4502237b12a76b4883fcd6d2ef22860bfd7ea5bb..bb575ab80207977e520e713a012e96f9e8816ec6 100644 (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.
index 50979d6dcecd80140840d7cdb4e0816adcb30c20..e39cce68dcfac9dc92144c2a3fd27b355476b14a 100644 (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
 
index 19d1afb9890f660e43ee95261cf0a703e44f92c6..a3afbf78325590872e2a2f3ebc1a0c5cb3dd95a3 100644 (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;
index 882ca0e1e7a5967e1dde952c8e5ecdf616b0f2fd..ec0262fa08f828213ac1afc0b223a9b32696a647 100644 (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);
index 0d8762622ab99dbe83dbeb87943712586ee52942..359c2f936004b42d4e892170f6e686213d7e3d63 100644 (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
index 3bb3270438696a792617f716b9616195d25d7d3c..c59d1008c4fc6cc8d24d80d16745d231294a77f9 100644 (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);
 
index 08dfa13f6a85059cfc38e205dbedc9521cc34ada..27fc1bb4003419407e793db4162c6a9ec194d800 100644 (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;
index 1b29ac759bf79ead7e7401bad1cabf05412cbb46..2ccc66ec35d723ebb198f355a358a45bcf0d65f6 100644 (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);
 }
 
 /**