diff options
author | Nayna Jain <nayna@linux.ibm.com> | 2018-12-08 23:26:59 +0300 |
---|---|---|
committer | Mimi Zohar <zohar@linux.ibm.com> | 2018-12-13 06:02:28 +0300 |
commit | 9dc92c45177ab70e20ae94baa2f2e558da63a9c7 (patch) | |
tree | 6620a5636e038d1cfb08d985e6effe541307d82e /security/integrity/digsig.c | |
parent | a802ed0dd9c2607cc219574e881062d43ea3b7e0 (diff) | |
download | linux-9dc92c45177ab70e20ae94baa2f2e558da63a9c7.tar.xz |
integrity: Define a trusted platform keyring
On secure boot enabled systems, a verified kernel may need to kexec
additional kernels. For example, it may be used as a bootloader needing
to kexec a target kernel or it may need to kexec a crashdump kernel. In
such cases, it may want to verify the signature of the next kernel
image.
It is further possible that the kernel image is signed with third party
keys which are stored as platform or firmware keys in the 'db' variable.
The kernel, however, can not directly verify these platform keys, and an
administrator may therefore not want to trust them for arbitrary usage.
In order to differentiate platform keys from other keys and provide the
necessary separation of trust, the kernel needs an additional keyring to
store platform keys.
This patch creates the new keyring called ".platform" to isolate keys
provided by platform from keys by kernel. These keys are used to
facilitate signature verification during kexec. Since the scope of this
keyring is only the platform/firmware keys, it cannot be updated from
userspace.
This keyring can be enabled by setting CONFIG_INTEGRITY_PLATFORM_KEYRING.
Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Acked-by: Serge Hallyn <serge@hallyn.com>
Reviewed-by: James Morris <james.morris@microsoft.com>
Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Diffstat (limited to 'security/integrity/digsig.c')
-rw-r--r-- | security/integrity/digsig.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 5eacba858e4b..4a22730e0cc6 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -35,6 +35,7 @@ static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = { ".ima", #endif "_module", + ".platform", }; #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY @@ -73,26 +74,14 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen, return -EOPNOTSUPP; } -int __init integrity_init_keyring(const unsigned int id) +static int __integrity_init_keyring(const unsigned int id, key_perm_t perm, + struct key_restriction *restriction) { const struct cred *cred = current_cred(); - struct key_restriction *restriction; int err = 0; - if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) - return 0; - - restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); - if (!restriction) - return -ENOMEM; - - restriction->check = restrict_link_to_ima; - keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), - KGIDT_INIT(0), cred, - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ | - KEY_USR_WRITE | KEY_USR_SEARCH), + KGIDT_INIT(0), cred, perm, KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL); if (IS_ERR(keyring[id])) { @@ -101,9 +90,37 @@ int __init integrity_init_keyring(const unsigned int id) keyring_name[id], err); keyring[id] = NULL; } + return err; } +int __init integrity_init_keyring(const unsigned int id) +{ + struct key_restriction *restriction; + key_perm_t perm; + + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW + | KEY_USR_READ | KEY_USR_SEARCH; + + if (id == INTEGRITY_KEYRING_PLATFORM) { + restriction = NULL; + goto out; + } + + if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) + return 0; + + restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); + if (!restriction) + return -ENOMEM; + + restriction->check = restrict_link_to_ima; + perm |= KEY_USR_WRITE; + +out: + return __integrity_init_keyring(id, perm, restriction); +} + int __init integrity_load_x509(const unsigned int id, const char *path) { key_ref_t key; |