aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-04-06 11:14:24 -0400
committerDavid Howells <dhowells@redhat.com>2016-04-11 17:37:37 -0400
commit5ac7eace2d00eab5ae0e9fdee63e38aee6001f7c (patch)
tree59e124fb6daa1dd81aef5f7d660a31cc55dab539 /security/keys/key.c
parentbda850cd214e90b1be0cc25bc48c4f6ac53eb543 (diff)
KEYS: Add a facility to restrict new links into a keyring
Add a facility whereby proposed new links to be added to a keyring can be vetted, permitting them to be rejected if necessary. This can be used to block public keys from which the signature cannot be verified or for which the signature verification fails. It could also be used to provide blacklisting. This affects operations like add_key(), KEYCTL_LINK and KEYCTL_INSTANTIATE. To this end: (1) A function pointer is added to the key struct that, if set, points to the vetting function. This is called as: int (*restrict_link)(struct key *keyring, const struct key_type *key_type, unsigned long key_flags, const union key_payload *key_payload), where 'keyring' will be the keyring being added to, key_type and key_payload will describe the key being added and key_flags[*] can be AND'ed with KEY_FLAG_TRUSTED. [*] This parameter will be removed in a later patch when KEY_FLAG_TRUSTED is removed. The function should return 0 to allow the link to take place or an error (typically -ENOKEY, -ENOPKG or -EKEYREJECTED) to reject the link. The pointer should not be set directly, but rather should be set through keyring_alloc(). Note that if called during add_key(), preparse is called before this method, but a key isn't actually allocated until after this function is called. (2) KEY_ALLOC_BYPASS_RESTRICTION is added. This can be passed to key_create_or_update() or key_instantiate_and_link() to bypass the restriction check. (3) KEY_FLAG_TRUSTED_ONLY is removed. The entire contents of a keyring with this restriction emplaced can be considered 'trustworthy' by virtue of being in the keyring when that keyring is consulted. (4) key_alloc() and keyring_alloc() take an extra argument that will be used to set restrict_link in the new key. This ensures that the pointer is set before the key is published, thus preventing a window of unrestrictedness. Normally this argument will be NULL. (5) As a temporary affair, keyring_restrict_trusted_only() is added. It should be passed to keyring_alloc() as the extra argument instead of setting KEY_FLAG_TRUSTED_ONLY on a keyring. This will be replaced in a later patch with functions that look in the appropriate places for authoritative keys. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/keys/key.c')
-rw-r--r--security/keys/key.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index b28755131687..deb881754e03 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -201,6 +201,7 @@ serial_exists:
201 * @cred: The credentials specifying UID namespace. 201 * @cred: The credentials specifying UID namespace.
202 * @perm: The permissions mask of the new key. 202 * @perm: The permissions mask of the new key.
203 * @flags: Flags specifying quota properties. 203 * @flags: Flags specifying quota properties.
204 * @restrict_link: Optional link restriction method for new keyrings.
204 * 205 *
205 * Allocate a key of the specified type with the attributes given. The key is 206 * Allocate a key of the specified type with the attributes given. The key is
206 * returned in an uninstantiated state and the caller needs to instantiate the 207 * returned in an uninstantiated state and the caller needs to instantiate the
@@ -223,7 +224,11 @@ serial_exists:
223 */ 224 */
224struct key *key_alloc(struct key_type *type, const char *desc, 225struct key *key_alloc(struct key_type *type, const char *desc,
225 kuid_t uid, kgid_t gid, const struct cred *cred, 226 kuid_t uid, kgid_t gid, const struct cred *cred,
226 key_perm_t perm, unsigned long flags) 227 key_perm_t perm, unsigned long flags,
228 int (*restrict_link)(struct key *,
229 const struct key_type *,
230 unsigned long,
231 const union key_payload *))
227{ 232{
228 struct key_user *user = NULL; 233 struct key_user *user = NULL;
229 struct key *key; 234 struct key *key;
@@ -291,6 +296,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
291 key->uid = uid; 296 key->uid = uid;
292 key->gid = gid; 297 key->gid = gid;
293 key->perm = perm; 298 key->perm = perm;
299 key->restrict_link = restrict_link;
294 300
295 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 301 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
296 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 302 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
@@ -496,6 +502,12 @@ int key_instantiate_and_link(struct key *key,
496 } 502 }
497 503
498 if (keyring) { 504 if (keyring) {
505 if (keyring->restrict_link) {
506 ret = keyring->restrict_link(keyring, key->type,
507 key->flags, &prep.payload);
508 if (ret < 0)
509 goto error;
510 }
499 ret = __key_link_begin(keyring, &key->index_key, &edit); 511 ret = __key_link_begin(keyring, &key->index_key, &edit);
500 if (ret < 0) 512 if (ret < 0)
501 goto error; 513 goto error;
@@ -551,8 +563,12 @@ int key_reject_and_link(struct key *key,
551 awaken = 0; 563 awaken = 0;
552 ret = -EBUSY; 564 ret = -EBUSY;
553 565
554 if (keyring) 566 if (keyring) {
567 if (keyring->restrict_link)
568 return -EPERM;
569
555 link_ret = __key_link_begin(keyring, &key->index_key, &edit); 570 link_ret = __key_link_begin(keyring, &key->index_key, &edit);
571 }
556 572
557 mutex_lock(&key_construction_mutex); 573 mutex_lock(&key_construction_mutex);
558 574
@@ -793,6 +809,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
793 struct key *keyring, *key = NULL; 809 struct key *keyring, *key = NULL;
794 key_ref_t key_ref; 810 key_ref_t key_ref;
795 int ret; 811 int ret;
812 int (*restrict_link)(struct key *,
813 const struct key_type *,
814 unsigned long,
815 const union key_payload *) = NULL;
796 816
797 /* look up the key type to see if it's one of the registered kernel 817 /* look up the key type to see if it's one of the registered kernel
798 * types */ 818 * types */
@@ -811,6 +831,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
811 831
812 key_check(keyring); 832 key_check(keyring);
813 833
834 key_ref = ERR_PTR(-EPERM);
835 if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
836 restrict_link = keyring->restrict_link;
837
814 key_ref = ERR_PTR(-ENOTDIR); 838 key_ref = ERR_PTR(-ENOTDIR);
815 if (keyring->type != &key_type_keyring) 839 if (keyring->type != &key_type_keyring)
816 goto error_put_type; 840 goto error_put_type;
@@ -835,10 +859,15 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
835 } 859 }
836 index_key.desc_len = strlen(index_key.description); 860 index_key.desc_len = strlen(index_key.description);
837 861
838 key_ref = ERR_PTR(-EPERM); 862 if (restrict_link) {
839 if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags)) 863 unsigned long kflags = prep.trusted ? KEY_FLAG_TRUSTED : 0;
840 goto error_free_prep; 864 ret = restrict_link(keyring,
841 flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0; 865 index_key.type, kflags, &prep.payload);
866 if (ret < 0) {
867 key_ref = ERR_PTR(ret);
868 goto error_free_prep;
869 }
870 }
842 871
843 ret = __key_link_begin(keyring, &index_key, &edit); 872 ret = __key_link_begin(keyring, &index_key, &edit);
844 if (ret < 0) { 873 if (ret < 0) {
@@ -879,7 +908,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
879 908
880 /* allocate a new key */ 909 /* allocate a new key */
881 key = key_alloc(index_key.type, index_key.description, 910 key = key_alloc(index_key.type, index_key.description,
882 cred->fsuid, cred->fsgid, cred, perm, flags); 911 cred->fsuid, cred->fsgid, cred, perm, flags, NULL);
883 if (IS_ERR(key)) { 912 if (IS_ERR(key)) {
884 key_ref = ERR_CAST(key); 913 key_ref = ERR_CAST(key);
885 goto error_link_end; 914 goto error_link_end;