From 5ac7eace2d00eab5ae0e9fdee63e38aee6001f7c Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 6 Apr 2016 16:14:24 +0100 Subject: 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 Reviewed-by: Mimi Zohar --- security/integrity/digsig.c | 7 ++-- security/integrity/ima/ima_mok.c | 8 ++--- security/keys/key.c | 43 +++++++++++++++++++---- security/keys/keyring.c | 73 ++++++++++++++++++++++++++++++++++++---- security/keys/persistent.c | 4 +-- security/keys/process_keys.c | 16 +++++---- security/keys/request_key.c | 4 +-- security/keys/request_key_auth.c | 2 +- 8 files changed, 124 insertions(+), 33 deletions(-) (limited to 'security') diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 8ef15118cc78..659566c2200b 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -83,10 +83,9 @@ int __init integrity_init_keyring(const unsigned int id) ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH), - KEY_ALLOC_NOT_IN_QUOTA, NULL); - if (!IS_ERR(keyring[id])) - set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); - else { + KEY_ALLOC_NOT_IN_QUOTA, + NULL, NULL); + if (IS_ERR(keyring[id])) { err = PTR_ERR(keyring[id]); pr_info("Can't allocate %s keyring (%d)\n", keyring_name[id], err); diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c index 676885e4320e..ef91248cb934 100644 --- a/security/integrity/ima/ima_mok.c +++ b/security/integrity/ima/ima_mok.c @@ -35,20 +35,20 @@ __init int ima_mok_init(void) (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH, - KEY_ALLOC_NOT_IN_QUOTA, NULL); + KEY_ALLOC_NOT_IN_QUOTA, + keyring_restrict_trusted_only, NULL); ima_blacklist_keyring = keyring_alloc(".ima_blacklist", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH, - KEY_ALLOC_NOT_IN_QUOTA, NULL); + KEY_ALLOC_NOT_IN_QUOTA, + keyring_restrict_trusted_only, NULL); if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) panic("Can't allocate IMA MOK or blacklist keyrings."); - set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags); - set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags); set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags); return 0; } 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: * @cred: The credentials specifying UID namespace. * @perm: The permissions mask of the new key. * @flags: Flags specifying quota properties. + * @restrict_link: Optional link restriction method for new keyrings. * * Allocate a key of the specified type with the attributes given. The key is * returned in an uninstantiated state and the caller needs to instantiate the @@ -223,7 +224,11 @@ serial_exists: */ struct key *key_alloc(struct key_type *type, const char *desc, kuid_t uid, kgid_t gid, const struct cred *cred, - key_perm_t perm, unsigned long flags) + key_perm_t perm, unsigned long flags, + int (*restrict_link)(struct key *, + const struct key_type *, + unsigned long, + const union key_payload *)) { struct key_user *user = NULL; struct key *key; @@ -291,6 +296,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, key->uid = uid; key->gid = gid; key->perm = perm; + key->restrict_link = restrict_link; if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) key->flags |= 1 << KEY_FLAG_IN_QUOTA; @@ -496,6 +502,12 @@ int key_instantiate_and_link(struct key *key, } if (keyring) { + if (keyring->restrict_link) { + ret = keyring->restrict_link(keyring, key->type, + key->flags, &prep.payload); + if (ret < 0) + goto error; + } ret = __key_link_begin(keyring, &key->index_key, &edit); if (ret < 0) goto error; @@ -551,8 +563,12 @@ int key_reject_and_link(struct key *key, awaken = 0; ret = -EBUSY; - if (keyring) + if (keyring) { + if (keyring->restrict_link) + return -EPERM; + link_ret = __key_link_begin(keyring, &key->index_key, &edit); + } mutex_lock(&key_construction_mutex); @@ -793,6 +809,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, struct key *keyring, *key = NULL; key_ref_t key_ref; int ret; + int (*restrict_link)(struct key *, + const struct key_type *, + unsigned long, + const union key_payload *) = NULL; /* look up the key type to see if it's one of the registered kernel * types */ @@ -811,6 +831,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, key_check(keyring); + key_ref = ERR_PTR(-EPERM); + if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION)) + restrict_link = keyring->restrict_link; + key_ref = ERR_PTR(-ENOTDIR); if (keyring->type != &key_type_keyring) goto error_put_type; @@ -835,10 +859,15 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, } index_key.desc_len = strlen(index_key.description); - key_ref = ERR_PTR(-EPERM); - if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags)) - goto error_free_prep; - flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0; + if (restrict_link) { + unsigned long kflags = prep.trusted ? KEY_FLAG_TRUSTED : 0; + ret = restrict_link(keyring, + index_key.type, kflags, &prep.payload); + if (ret < 0) { + key_ref = ERR_PTR(ret); + goto error_free_prep; + } + } ret = __key_link_begin(keyring, &index_key, &edit); if (ret < 0) { @@ -879,7 +908,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, /* allocate a new key */ key = key_alloc(index_key.type, index_key.description, - cred->fsuid, cred->fsgid, cred, perm, flags); + cred->fsuid, cred->fsgid, cred, perm, flags, NULL); if (IS_ERR(key)) { key_ref = ERR_CAST(key); goto error_link_end; diff --git a/security/keys/keyring.c b/security/keys/keyring.c index f931ccfeefb0..d2d1f3378008 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -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); diff --git a/security/keys/persistent.c b/security/keys/persistent.c index c9fae5ea89fe..2ef45b319dd9 100644 --- a/security/keys/persistent.c +++ b/security/keys/persistent.c @@ -26,7 +26,7 @@ static int key_create_persistent_register(struct user_namespace *ns) current_cred(), ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ), - KEY_ALLOC_NOT_IN_QUOTA, NULL); + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -60,7 +60,7 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid, uid, INVALID_GID, current_cred(), ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ), - KEY_ALLOC_NOT_IN_QUOTA, + KEY_ALLOC_NOT_IN_QUOTA, NULL, ns->persistent_keyring_register); if (IS_ERR(persistent)) return ERR_CAST(persistent); diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index e6d50172872f..40a885239782 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -76,7 +76,8 @@ int install_user_keyrings(void) if (IS_ERR(uid_keyring)) { uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, cred, user_keyring_perm, - KEY_ALLOC_IN_QUOTA, NULL); + KEY_ALLOC_IN_QUOTA, + NULL, NULL); if (IS_ERR(uid_keyring)) { ret = PTR_ERR(uid_keyring); goto error; @@ -92,7 +93,8 @@ int install_user_keyrings(void) session_keyring = keyring_alloc(buf, user->uid, INVALID_GID, cred, user_keyring_perm, - KEY_ALLOC_IN_QUOTA, NULL); + KEY_ALLOC_IN_QUOTA, + NULL, NULL); if (IS_ERR(session_keyring)) { ret = PTR_ERR(session_keyring); goto error_release; @@ -134,7 +136,8 @@ int install_thread_keyring_to_cred(struct cred *new) keyring = keyring_alloc("_tid", new->uid, new->gid, new, KEY_POS_ALL | KEY_USR_VIEW, - KEY_ALLOC_QUOTA_OVERRUN, NULL); + KEY_ALLOC_QUOTA_OVERRUN, + NULL, NULL); if (IS_ERR(keyring)) return PTR_ERR(keyring); @@ -180,7 +183,8 @@ int install_process_keyring_to_cred(struct cred *new) keyring = keyring_alloc("_pid", new->uid, new->gid, new, KEY_POS_ALL | KEY_USR_VIEW, - KEY_ALLOC_QUOTA_OVERRUN, NULL); + KEY_ALLOC_QUOTA_OVERRUN, + NULL, NULL); if (IS_ERR(keyring)) return PTR_ERR(keyring); @@ -231,7 +235,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred, KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, - flags, NULL); + flags, NULL, NULL); if (IS_ERR(keyring)) return PTR_ERR(keyring); } else { @@ -785,7 +789,7 @@ long join_session_keyring(const char *name) keyring = keyring_alloc( name, old->uid, old->gid, old, KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK, - KEY_ALLOC_IN_QUOTA, NULL); + KEY_ALLOC_IN_QUOTA, NULL, NULL); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); goto error2; diff --git a/security/keys/request_key.c b/security/keys/request_key.c index c7a117c9a8f3..a29e3554751e 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -116,7 +116,7 @@ static int call_sbin_request_key(struct key_construction *cons, cred = get_current_cred(); keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred, KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, - KEY_ALLOC_QUOTA_OVERRUN, NULL); + KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL); put_cred(cred); if (IS_ERR(keyring)) { ret = PTR_ERR(keyring); @@ -355,7 +355,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx, key = key_alloc(ctx->index_key.type, ctx->index_key.description, ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred, - perm, flags); + perm, flags, NULL); if (IS_ERR(key)) goto alloc_failed; diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 4f0f112fe276..9db8b4a82787 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -202,7 +202,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, authkey = key_alloc(&key_type_request_key_auth, desc, cred->fsuid, cred->fsgid, cred, KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | - KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); + KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL); if (IS_ERR(authkey)) { ret = PTR_ERR(authkey); goto error_alloc; -- cgit v1.2.3 From a511e1af8b12f44c6e55786c463c9f093c214fb6 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 6 Apr 2016 16:14:26 +0100 Subject: KEYS: Move the point of trust determination to __key_link() Move the point at which a key is determined to be trustworthy to __key_link() so that we use the contents of the keyring being linked in to to determine whether the key being linked in is trusted or not. What is 'trusted' then becomes a matter of what's in the keyring. Currently, the test is done when the key is parsed, but given that at that point we can only sensibly refer to the contents of the system trusted keyring, we can only use that as the basis for working out the trustworthiness of a new key. With this change, a trusted keyring is a set of keys that once the trusted-only flag is set cannot be added to except by verification through one of the contained keys. Further, adding a key into a trusted keyring, whilst it might grant trustworthiness in the context of that keyring, does not automatically grant trustworthiness in the context of a second keyring to which it could be secondarily linked. To accomplish this, the authentication data associated with the key source must now be retained. For an X.509 cert, this means the contents of the AuthorityKeyIdentifier and the signature data. If system keyrings are disabled then restrict_link_by_builtin_trusted() resolves to restrict_link_reject(). The integrity digital signature code still works correctly with this as it was previously using KEY_FLAG_TRUSTED_ONLY, which doesn't permit anything to be added if there is no system keyring against which trust can be determined. Signed-off-by: David Howells --- certs/system_keyring.c | 20 +++++++++-- crypto/asymmetric_keys/restrict.c | 62 ++++++++++++++++---------------- crypto/asymmetric_keys/x509_parser.h | 6 ---- crypto/asymmetric_keys/x509_public_key.c | 21 +---------- include/crypto/public_key.h | 7 ++++ include/keys/system_keyring.h | 19 ++++------ kernel/module_signing.c | 2 +- security/integrity/digsig.c | 33 ++++++++++++++++- security/integrity/ima/ima_mok.c | 6 ++-- 9 files changed, 100 insertions(+), 76 deletions(-) (limited to 'security') diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 417d65882870..4e2fa8ab01d6 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -18,12 +18,26 @@ #include #include -struct key *system_trusted_keyring; -EXPORT_SYMBOL_GPL(system_trusted_keyring); +static struct key *system_trusted_keyring; extern __initconst const u8 system_certificate_list[]; extern __initconst const unsigned long system_certificate_list_size; +/** + * restrict_link_by_builtin_trusted - Restrict keyring addition by system CA + * + * Restrict the addition of keys into a keyring based on the key-to-be-added + * being vouched for by a key in the system keyring. + */ +int restrict_link_by_builtin_trusted(struct key *keyring, + const struct key_type *type, + unsigned long flags, + const union key_payload *payload) +{ + return restrict_link_by_signature(system_trusted_keyring, + type, payload); +} + /* * Load the compiled-in keys */ @@ -37,7 +51,7 @@ static __init int system_trusted_keyring_init(void) ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), KEY_ALLOC_NOT_IN_QUOTA, - keyring_restrict_trusted_only, NULL); + restrict_link_by_builtin_trusted, NULL); if (IS_ERR(system_trusted_keyring)) panic("Can't allocate system trusted keyring\n"); return 0; diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c index b4c10f2f5034..ac4bddf669de 100644 --- a/crypto/asymmetric_keys/restrict.c +++ b/crypto/asymmetric_keys/restrict.c @@ -1,6 +1,6 @@ /* Instantiate a public key crypto key from an X.509 Certificate * - * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or @@ -9,20 +9,12 @@ * 2 of the Licence, or (at your option) any later version. */ -#define pr_fmt(fmt) "X.509: "fmt +#define pr_fmt(fmt) "ASYM: "fmt #include #include -#include #include -#include -#include -#include -#include -#include -#include #include #include "asymmetric_keys.h" -#include "x509_parser.h" static bool use_builtin_keys; static struct asymmetric_key_id *ca_keyid; @@ -62,45 +54,55 @@ static int __init ca_keys_setup(char *str) __setup("ca_keys=", ca_keys_setup); #endif -/* +/** + * 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. + * @type: The type of key being added. + * @payload: The payload of the new key. + * * 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 * new certificate as being trusted. * - * Return 0 if the new certificate was successfully validated, 1 if we couldn't - * find a matching parent certificate in the trusted list and an error if there - * is a matching certificate but the signature check fails. + * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a + * matching parent certificate in the trusted list, -EKEYREJECTED if the + * 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 x509_validate_trust(struct x509_certificate *cert, - struct key *trust_keyring) +int restrict_link_by_signature(struct key *trust_keyring, + const struct key_type *type, + const union key_payload *payload) { - struct public_key_signature *sig = cert->sig; + const struct public_key_signature *sig; struct key *key; - int ret = 1; + int ret; - if (!sig->auth_ids[0] && !sig->auth_ids[1]) - return 1; + pr_devel("==>%s()\n", __func__); if (!trust_keyring) + return -ENOKEY; + + if (type != &key_type_asymmetric) return -EOPNOTSUPP; + + sig = payload->data[asym_auth]; + if (!sig->auth_ids[0] && !sig->auth_ids[1]) + return 0; + if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid)) return -EPERM; - if (cert->unsupported_sig) - return -ENOPKG; + /* See if we have a key that signed this one. */ key = find_asymmetric_key(trust_keyring, sig->auth_ids[0], sig->auth_ids[1], false); if (IS_ERR(key)) - return PTR_ERR(key); + return -ENOKEY; - if (!use_builtin_keys || - test_bit(KEY_FLAG_BUILTIN, &key->flags)) { - ret = verify_signature(key, cert->sig); - if (ret == -ENOPKG) - cert->unsupported_sig = true; - } + if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags)) + ret = -ENOKEY; + else + ret = verify_signature(key, sig); key_put(key); return ret; } -EXPORT_SYMBOL_GPL(x509_validate_trust); diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h index 7a802b09a509..05eef1c68881 100644 --- a/crypto/asymmetric_keys/x509_parser.h +++ b/crypto/asymmetric_keys/x509_parser.h @@ -58,9 +58,3 @@ extern int x509_decode_time(time64_t *_t, size_t hdrlen, */ extern int x509_get_sig_params(struct x509_certificate *cert); extern int x509_check_for_self_signed(struct x509_certificate *cert); - -/* - * public_key_trust.c - */ -extern int x509_validate_trust(struct x509_certificate *cert, - struct key *trust_keyring); diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 6d7f42f0de9a..fb732296cd36 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -178,31 +178,12 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) cert->pub->id_type = "X509"; - /* See if we can derive the trustability of this certificate. - * - * When it comes to self-signed certificates, we cannot evaluate - * trustedness except by the fact that we obtained it from a trusted - * location. So we just rely on x509_validate_trust() failing in this - * case. - * - * Note that there's a possibility of a self-signed cert matching a - * cert that we have (most likely a duplicate that we already trust) - - * in which case it will be marked trusted. - */ - if (cert->unsupported_sig || cert->self_signed) { + if (cert->unsupported_sig) { public_key_signature_free(cert->sig); cert->sig = NULL; } else { pr_devel("Cert Signature: %s + %s\n", cert->sig->pkey_algo, cert->sig->hash_algo); - - ret = x509_validate_trust(cert, get_system_trusted_keyring()); - if (ret) - ret = x509_validate_trust(cert, get_ima_mok_keyring()); - if (ret == -EKEYREJECTED) - goto error_free_cert; - if (!ret) - prep->trusted = true; } /* Propose a description */ diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index 96ef27b8dd41..882ca0e1e7a5 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -47,6 +47,13 @@ extern void public_key_signature_free(struct public_key_signature *sig); extern struct asymmetric_key_subtype public_key_subtype; struct key; +struct key_type; +union key_payload; + +extern int restrict_link_by_signature(struct key *trust_keyring, + const struct key_type *type, + const union key_payload *payload); + extern int verify_signature(const struct key *key, const struct public_key_signature *sig); diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index b2d645ac35a0..93715913a0b1 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -12,22 +12,17 @@ #ifndef _KEYS_SYSTEM_KEYRING_H #define _KEYS_SYSTEM_KEYRING_H +#include + #ifdef CONFIG_SYSTEM_TRUSTED_KEYRING -#include -#include -#include +extern int restrict_link_by_builtin_trusted(struct key *keyring, + const struct key_type *type, + unsigned long flags, + const union key_payload *payload); -extern struct key *system_trusted_keyring; -static inline struct key *get_system_trusted_keyring(void) -{ - return system_trusted_keyring; -} #else -static inline struct key *get_system_trusted_keyring(void) -{ - return NULL; -} +#define restrict_link_by_builtin_trusted restrict_link_reject #endif #ifdef CONFIG_IMA_MOK_KEYRING diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 6a64e03b9f44..937c844bee4a 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include "module-internal.h" diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 659566c2200b..d647178c6bbd 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include "integrity.h" @@ -40,6 +42,35 @@ static bool init_keyring __initdata = true; static bool init_keyring __initdata; #endif +#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING +/* + * Restrict the addition of keys into the IMA keyring. + * + * Any key that needs to go in .ima keyring must be signed by CA in + * either .system or .ima_mok keyrings. + */ +static int restrict_link_by_ima_mok(struct key *keyring, + const struct key_type *type, + unsigned long flags, + const union key_payload *payload) +{ + int ret; + + ret = restrict_link_by_builtin_trusted(keyring, type, flags, payload); + if (ret != -ENOKEY) + return ret; + + return restrict_link_by_signature(get_ima_mok_keyring(), + type, payload); +} +#else +/* + * If there's no system trusted keyring, then keys cannot be loaded into + * .ima_mok and added keys cannot be marked trusted. + */ +#define restrict_link_by_ima_mok restrict_link_reject +#endif + int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, const char *digest, int digestlen) { @@ -84,7 +115,7 @@ int __init integrity_init_keyring(const unsigned int id) KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH), KEY_ALLOC_NOT_IN_QUOTA, - NULL, NULL); + restrict_link_by_ima_mok, NULL); if (IS_ERR(keyring[id])) { err = PTR_ERR(keyring[id]); pr_info("Can't allocate %s keyring (%d)\n", diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c index ef91248cb934..2988726d30d6 100644 --- a/security/integrity/ima/ima_mok.c +++ b/security/integrity/ima/ima_mok.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include struct key *ima_mok_keyring; @@ -36,7 +36,7 @@ __init int ima_mok_init(void) KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, - keyring_restrict_trusted_only, NULL); + restrict_link_by_builtin_trusted, NULL); ima_blacklist_keyring = keyring_alloc(".ima_blacklist", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), @@ -44,7 +44,7 @@ __init int ima_mok_init(void) KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, - keyring_restrict_trusted_only, NULL); + restrict_link_by_builtin_trusted, NULL); if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) panic("Can't allocate IMA MOK or blacklist keyrings."); -- cgit v1.2.3 From 77f68bac9481ad440f4f34dda3d28c2dce6eb87b Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 6 Apr 2016 16:14:26 +0100 Subject: KEYS: Remove KEY_FLAG_TRUSTED and KEY_ALLOC_TRUSTED Remove KEY_FLAG_TRUSTED and KEY_ALLOC_TRUSTED as they're no longer meaningful. Also we can drop the trusted flag from the preparse structure. Given this, we no longer need to pass the key flags through to restrict_link(). Further, we can now get rid of keyring_restrict_trusted_only() also. Signed-off-by: David Howells --- certs/system_keyring.c | 2 -- include/keys/system_keyring.h | 1 - include/linux/key-type.h | 1 - include/linux/key.h | 21 +++++---------------- security/integrity/digsig.c | 3 +-- security/keys/key.c | 11 ++--------- security/keys/keyring.c | 29 +---------------------------- 7 files changed, 9 insertions(+), 59 deletions(-) (limited to 'security') diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 4e2fa8ab01d6..e460d00a7781 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -31,7 +31,6 @@ extern __initconst const unsigned long system_certificate_list_size; */ int restrict_link_by_builtin_trusted(struct key *keyring, const struct key_type *type, - unsigned long flags, const union key_payload *payload) { return restrict_link_by_signature(system_trusted_keyring, @@ -97,7 +96,6 @@ static __init int load_system_certificate_list(void) ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ), KEY_ALLOC_NOT_IN_QUOTA | - KEY_ALLOC_TRUSTED | KEY_ALLOC_BUILT_IN | KEY_ALLOC_BYPASS_RESTRICTION); if (IS_ERR(key)) { diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index 93715913a0b1..c72330ae76df 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -18,7 +18,6 @@ extern int restrict_link_by_builtin_trusted(struct key *keyring, const struct key_type *type, - unsigned long flags, const union key_payload *payload); #else diff --git a/include/linux/key-type.h b/include/linux/key-type.h index 7463355a198b..eaee981c5558 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h @@ -45,7 +45,6 @@ struct key_preparsed_payload { size_t datalen; /* Raw datalen */ size_t quotalen; /* Quota length for proposed payload */ time_t expiry; /* Expiry time of key */ - bool trusted; /* True if key is trusted */ }; typedef int (*request_key_actor_t)(struct key_construction *key, diff --git a/include/linux/key.h b/include/linux/key.h index 83b603639d2e..722914798f37 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -173,10 +173,9 @@ struct key { #define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ #define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ -#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ -#define KEY_FLAG_BUILTIN 9 /* set if key is built in to the kernel */ -#define KEY_FLAG_ROOT_CAN_INVAL 10 /* set if key can be invalidated by root without permission */ -#define KEY_FLAG_KEEP 11 /* set if key should not be removed */ +#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */ +#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */ +#define KEY_FLAG_KEEP 10 /* set if key should not be removed */ /* the key type and key description string * - the desc is used to match a key against search criteria @@ -217,7 +216,6 @@ struct key { */ int (*restrict_link)(struct key *keyring, const struct key_type *type, - unsigned long flags, const union key_payload *payload); }; @@ -229,16 +227,14 @@ extern struct key *key_alloc(struct key_type *type, unsigned long flags, int (*restrict_link)(struct key *, const struct key_type *, - unsigned long, const union key_payload *)); #define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */ #define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ -#define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */ -#define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */ -#define KEY_ALLOC_BYPASS_RESTRICTION 0x0010 /* Override the check on restricted keyrings */ +#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */ +#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */ extern void key_revoke(struct key *key); extern void key_invalidate(struct key *key); @@ -309,18 +305,11 @@ extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid unsigned long flags, int (*restrict_link)(struct key *, const struct key_type *, - unsigned long, const union key_payload *), struct key *dest); -extern int keyring_restrict_trusted_only(struct key *keyring, - const struct key_type *type, - unsigned long, - const union key_payload *payload); - extern int restrict_link_reject(struct key *keyring, const struct key_type *type, - unsigned long flags, const union key_payload *payload); extern int keyring_clear(struct key *keyring); diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index d647178c6bbd..98ee4c752cf5 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -51,12 +51,11 @@ static bool init_keyring __initdata; */ static int restrict_link_by_ima_mok(struct key *keyring, const struct key_type *type, - unsigned long flags, const union key_payload *payload) { int ret; - ret = restrict_link_by_builtin_trusted(keyring, type, flags, payload); + ret = restrict_link_by_builtin_trusted(keyring, type, payload); if (ret != -ENOKEY) return ret; diff --git a/security/keys/key.c b/security/keys/key.c index deb881754e03..bd5a272f28a6 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -227,7 +227,6 @@ struct key *key_alloc(struct key_type *type, const char *desc, key_perm_t perm, unsigned long flags, int (*restrict_link)(struct key *, const struct key_type *, - unsigned long, const union key_payload *)) { struct key_user *user = NULL; @@ -300,8 +299,6 @@ struct key *key_alloc(struct key_type *type, const char *desc, if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) key->flags |= 1 << KEY_FLAG_IN_QUOTA; - if (flags & KEY_ALLOC_TRUSTED) - key->flags |= 1 << KEY_FLAG_TRUSTED; if (flags & KEY_ALLOC_BUILT_IN) key->flags |= 1 << KEY_FLAG_BUILTIN; @@ -504,7 +501,7 @@ int key_instantiate_and_link(struct key *key, if (keyring) { if (keyring->restrict_link) { ret = keyring->restrict_link(keyring, key->type, - key->flags, &prep.payload); + &prep.payload); if (ret < 0) goto error; } @@ -811,7 +808,6 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, int ret; int (*restrict_link)(struct key *, const struct key_type *, - unsigned long, const union key_payload *) = NULL; /* look up the key type to see if it's one of the registered kernel @@ -843,7 +839,6 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, prep.data = payload; prep.datalen = plen; prep.quotalen = index_key.type->def_datalen; - prep.trusted = flags & KEY_ALLOC_TRUSTED; prep.expiry = TIME_T_MAX; if (index_key.type->preparse) { ret = index_key.type->preparse(&prep); @@ -860,9 +855,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, index_key.desc_len = strlen(index_key.description); if (restrict_link) { - unsigned long kflags = prep.trusted ? KEY_FLAG_TRUSTED : 0; - ret = restrict_link(keyring, - index_key.type, kflags, &prep.payload); + ret = restrict_link(keyring, index_key.type, &prep.payload); if (ret < 0) { key_ref = ERR_PTR(ret); goto error_free_prep; diff --git a/security/keys/keyring.c b/security/keys/keyring.c index d2d1f3378008..c91e4e0cea08 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -494,7 +494,6 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, unsigned long flags, int (*restrict_link)(struct key *, const struct key_type *, - unsigned long, const union key_payload *), struct key *dest) { @@ -515,34 +514,10 @@ 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 @@ -554,7 +529,6 @@ int keyring_restrict_trusted_only(struct key *keyring, */ int restrict_link_reject(struct key *keyring, const struct key_type *type, - unsigned long flags, const union key_payload *payload) { return -EPERM; @@ -1248,8 +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->flags, &key->payload); + return keyring->restrict_link(keyring, key->type, &key->payload); } /** -- cgit v1.2.3 From 56104cf2b8d20eed32c14eac8ac574c35377ab38 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 7 Apr 2016 09:45:23 +0100 Subject: IMA: Use the the system trusted keyrings instead of .ima_mok Add a config option (IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY) that, when enabled, allows keys to be added to the IMA keyrings by userspace - with the restriction that each must be signed by a key in the system trusted keyrings. EPERM will be returned if this option is disabled, ENOKEY will be returned if no authoritative key can be found and EKEYREJECTED will be returned if the signature doesn't match. Other errors such as ENOPKG may also be returned. If this new option is enabled, the builtin system keyring is searched, as is the secondary system keyring if that is also enabled. Intermediate keys between the builtin system keyring and the key being added can be added to the secondary keyring (which replaces .ima_mok) to form a trust chain - provided they are also validly signed by a key in one of the trusted keyrings. The .ima_mok keyring is then removed and the IMA blacklist keyring gets its own config option (IMA_BLACKLIST_KEYRING). Signed-off-by: David Howells Signed-off-by: Mimi Zohar --- include/keys/system_keyring.h | 13 ++----------- security/integrity/digsig.c | 30 ++++-------------------------- security/integrity/ima/Kconfig | 36 +++++++++++++++++++++++------------- security/integrity/ima/Makefile | 2 +- security/integrity/ima/ima_mok.c | 17 ++++------------- 5 files changed, 34 insertions(+), 64 deletions(-) (limited to 'security') diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index 614424029de7..fbd4647767e9 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -33,28 +33,19 @@ extern int restrict_link_by_builtin_and_secondary_trusted( #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted #endif -#ifdef CONFIG_IMA_MOK_KEYRING -extern struct key *ima_mok_keyring; +#ifdef CONFIG_IMA_BLACKLIST_KEYRING extern struct key *ima_blacklist_keyring; -static inline struct key *get_ima_mok_keyring(void) -{ - return ima_mok_keyring; -} static inline struct key *get_ima_blacklist_keyring(void) { return ima_blacklist_keyring; } #else -static inline struct key *get_ima_mok_keyring(void) -{ - return NULL; -} static inline struct key *get_ima_blacklist_keyring(void) { return NULL; } -#endif /* CONFIG_IMA_MOK_KEYRING */ +#endif /* CONFIG_IMA_BLACKLIST_KEYRING */ #endif /* _KEYS_SYSTEM_KEYRING_H */ diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 98ee4c752cf5..4304372b323f 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -42,32 +42,10 @@ static bool init_keyring __initdata = true; static bool init_keyring __initdata; #endif -#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING -/* - * Restrict the addition of keys into the IMA keyring. - * - * Any key that needs to go in .ima keyring must be signed by CA in - * either .system or .ima_mok keyrings. - */ -static int restrict_link_by_ima_mok(struct key *keyring, - const struct key_type *type, - const union key_payload *payload) -{ - int ret; - - ret = restrict_link_by_builtin_trusted(keyring, type, payload); - if (ret != -ENOKEY) - return ret; - - return restrict_link_by_signature(get_ima_mok_keyring(), - type, payload); -} +#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY +#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted #else -/* - * If there's no system trusted keyring, then keys cannot be loaded into - * .ima_mok and added keys cannot be marked trusted. - */ -#define restrict_link_by_ima_mok restrict_link_reject +#define restrict_link_to_ima restrict_link_by_builtin_trusted #endif int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, @@ -114,7 +92,7 @@ int __init integrity_init_keyring(const unsigned int id) KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE | KEY_USR_SEARCH), KEY_ALLOC_NOT_IN_QUOTA, - restrict_link_by_ima_mok, NULL); + restrict_link_to_ima, NULL); if (IS_ERR(keyring[id])) { err = PTR_ERR(keyring[id]); pr_info("Can't allocate %s keyring (%d)\n", diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index e54a8a8dae94..5487827fa86c 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -155,23 +155,33 @@ config IMA_TRUSTED_KEYRING This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING -config IMA_MOK_KEYRING - bool "Create IMA machine owner keys (MOK) and blacklist keyrings" +config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY + bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)" + depends on SYSTEM_TRUSTED_KEYRING + depends on SECONDARY_TRUSTED_KEYRING + depends on INTEGRITY_ASYMMETRIC_KEYS + select INTEGRITY_TRUSTED_KEYRING + default n + help + Keys may be added to the IMA or IMA blacklist keyrings, if the + key is validly signed by a CA cert in the system built-in or + secondary trusted keyrings. + + Intermediate keys between those the kernel has compiled in and the + IMA keys to be added may be added to the system secondary keyring, + provided they are validly signed by a key already resident in the + built-in or secondary trusted keyrings. + +config IMA_BLACKLIST_KEYRING + bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)" depends on SYSTEM_TRUSTED_KEYRING depends on IMA_TRUSTED_KEYRING default n help - This option creates IMA MOK and blacklist keyrings. IMA MOK is an - intermediate keyring that sits between .system and .ima keyrings, - effectively forming a simple CA hierarchy. To successfully import a - key into .ima_mok it must be signed by a key which CA is in .system - keyring. On turn any key that needs to go in .ima keyring must be - signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty - at kernel boot. - - IMA blacklist keyring contains all revoked IMA keys. It is consulted - before any other keyring. If the search is successful the requested - operation is rejected and error is returned to the caller. + This option creates an IMA blacklist keyring, which contains all + revoked IMA keys. It is consulted before any other keyring. If + the search is successful the requested operation is rejected and + an error is returned to the caller. config IMA_LOAD_X509 bool "Load X509 certificate onto the '.ima' trusted keyring" diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index a8539f9e060f..9aeaedad1e2b 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -8,4 +8,4 @@ obj-$(CONFIG_IMA) += ima.o ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ ima_policy.o ima_template.o ima_template_lib.o ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o -obj-$(CONFIG_IMA_MOK_KEYRING) += ima_mok.o +obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c index 2988726d30d6..74a279957464 100644 --- a/security/integrity/ima/ima_mok.c +++ b/security/integrity/ima/ima_mok.c @@ -20,23 +20,14 @@ #include -struct key *ima_mok_keyring; struct key *ima_blacklist_keyring; /* - * Allocate the IMA MOK and blacklist keyrings + * Allocate the IMA blacklist keyring */ __init int ima_mok_init(void) { - pr_notice("Allocating IMA MOK and blacklist keyrings.\n"); - - ima_mok_keyring = keyring_alloc(".ima_mok", - KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), - (KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ | - KEY_USR_WRITE | KEY_USR_SEARCH, - KEY_ALLOC_NOT_IN_QUOTA, - restrict_link_by_builtin_trusted, NULL); + pr_notice("Allocating IMA blacklist keyring.\n"); ima_blacklist_keyring = keyring_alloc(".ima_blacklist", KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), @@ -46,8 +37,8 @@ __init int ima_mok_init(void) KEY_ALLOC_NOT_IN_QUOTA, restrict_link_by_builtin_trusted, NULL); - if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) - panic("Can't allocate IMA MOK or blacklist keyrings."); + if (IS_ERR(ima_blacklist_keyring)) + panic("Can't allocate IMA blacklist keyring."); set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags); return 0; -- cgit v1.2.3