diff options
Diffstat (limited to 'security/integrity/digsig.c')
| -rw-r--r-- | security/integrity/digsig.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 3b06a01bd0fd..45c3e5dda355 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -30,12 +30,13 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = { ".ima", #endif ".platform", + ".machine", }; #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY -#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted +#define restrict_link_to_ima restrict_link_by_digsig_builtin_and_secondary #else -#define restrict_link_to_ima restrict_link_by_builtin_trusted +#define restrict_link_to_ima restrict_link_by_digsig_builtin #endif static struct key *integrity_keyring_from_id(const unsigned int id) @@ -74,7 +75,8 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, /* v1 API expect signature without xattr type */ return digsig_verify(keyring, sig + 1, siglen - 1, digest, digestlen); - case 2: + case 2: /* regular file data hash based signature */ + case 3: /* struct ima_file_id data based signature */ return asymmetric_verify(keyring, sig, siglen, digest, digestlen); } @@ -111,6 +113,8 @@ static int __init __integrity_init_keyring(const unsigned int id, } else { if (id == INTEGRITY_KEYRING_PLATFORM) set_platform_trusted_keys(keyring[id]); + if (id == INTEGRITY_KEYRING_MACHINE && imputed_trust_enabled()) + set_machine_trusted_keys(keyring[id]); if (id == INTEGRITY_KEYRING_IMA) load_module_cert(keyring[id]); } @@ -122,11 +126,14 @@ int __init integrity_init_keyring(const unsigned int id) { struct key_restriction *restriction; key_perm_t perm; + int ret; perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH; - if (id == INTEGRITY_KEYRING_PLATFORM) { + if (id == INTEGRITY_KEYRING_PLATFORM || + (id == INTEGRITY_KEYRING_MACHINE && + !IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING))) { restriction = NULL; goto out; } @@ -138,11 +145,24 @@ int __init integrity_init_keyring(const unsigned int id) if (!restriction) return -ENOMEM; - restriction->check = restrict_link_to_ima; - perm |= KEY_USR_WRITE; + if (id == INTEGRITY_KEYRING_MACHINE) + restriction->check = restrict_link_by_ca; + else + restriction->check = restrict_link_to_ima; + + /* + * MOK keys can only be added through a read-only runtime services + * UEFI variable during boot. No additional keys shall be allowed to + * load into the machine keyring following init from userspace. + */ + if (id != INTEGRITY_KEYRING_MACHINE) + perm |= KEY_USR_WRITE; out: - return __integrity_init_keyring(id, perm, restriction); + ret = __integrity_init_keyring(id, perm, restriction); + if (ret) + kfree(restriction); + return ret; } static int __init integrity_add_key(const unsigned int id, const void *data, @@ -159,7 +179,8 @@ static int __init integrity_add_key(const unsigned int id, const void *data, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(key)) { rc = PTR_ERR(key); - pr_err("Problem loading X.509 certificate %d\n", rc); + if (id != INTEGRITY_KEYRING_MACHINE) + pr_err("Problem loading X.509 certificate %d\n", rc); } else { pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description); |
