aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-02 09:43:14 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-02 09:43:14 -0800
commitf218a29c25ad8abdb961435d6b8139f462061364 (patch)
treec5ef7e5b8730be6f5a5c1c16517c3b2dc2fa6b70 /arch
parent8e143b90e4d45cca3dc53760d3cfab988bc74571 (diff)
parentc7f7e58fcbf33589f11bfde0506e076a00627e59 (diff)
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull integrity updates from James Morris: "In Linux 4.19, a new LSM hook named security_kernel_load_data was upstreamed, allowing LSMs and IMA to prevent the kexec_load syscall. Different signature verification methods exist for verifying the kexec'ed kernel image. This adds additional support in IMA to prevent loading unsigned kernel images via the kexec_load syscall, independently of the IMA policy rules, based on the runtime "secure boot" flag. An initial IMA kselftest is included. In addition, this pull request defines a new, separate keyring named ".platform" for storing the preboot/firmware keys needed for verifying the kexec'ed kernel image's signature and includes the associated IMA kexec usage of the ".platform" keyring. (David Howell's and Josh Boyer's patches for reading the preboot/firmware keys, which were previously posted for a different use case scenario, are included here)" * 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: integrity: Remove references to module keyring ima: Use inode_is_open_for_write ima: Support platform keyring for kernel appraisal efi: Allow the "db" UEFI variable to be suppressed efi: Import certificates from UEFI Secure Boot efi: Add an EFI signature blob parser efi: Add EFI signature data types integrity: Load certs to the platform keyring integrity: Define a trusted platform keyring selftests/ima: kexec_load syscall test ima: don't measure/appraise files on efivarfs x86/ima: retry detecting secure boot mode docs: Extend trusted keys documentation for TPM 2.0 x86/ima: define arch_get_ima_policy() for x86 ima: add support for arch specific policies ima: refactor ima_init_policy() ima: prevent kexec_load syscall based on runtime secureboot flag x86/ima: define arch_ima_get_secureboot integrity: support new struct public_key_signature encoding field
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/Makefile4
-rw-r--r--arch/x86/kernel/ima_arch.c75
2 files changed, 79 insertions, 0 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 8824d01c0c35..eb51b0e1189c 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -150,3 +150,7 @@ ifeq ($(CONFIG_X86_64),y)
obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o
obj-y += vsmp_64.o
endif
+
+ifdef CONFIG_EFI
+obj-$(CONFIG_IMA) += ima_arch.o
+endif
diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c
new file mode 100644
index 000000000000..e47cd9390ab4
--- /dev/null
+++ b/arch/x86/kernel/ima_arch.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 IBM Corporation
+ */
+#include <linux/efi.h>
+#include <linux/ima.h>
+
+extern struct boot_params boot_params;
+
+static enum efi_secureboot_mode get_sb_mode(void)
+{
+ efi_char16_t efi_SecureBoot_name[] = L"SecureBoot";
+ efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
+ efi_status_t status;
+ unsigned long size;
+ u8 secboot;
+
+ size = sizeof(secboot);
+
+ /* Get variable contents into buffer */
+ status = efi.get_variable(efi_SecureBoot_name, &efi_variable_guid,
+ NULL, &size, &secboot);
+ if (status == EFI_NOT_FOUND) {
+ pr_info("ima: secureboot mode disabled\n");
+ return efi_secureboot_mode_disabled;
+ }
+
+ if (status != EFI_SUCCESS) {
+ pr_info("ima: secureboot mode unknown\n");
+ return efi_secureboot_mode_unknown;
+ }
+
+ if (secboot == 0) {
+ pr_info("ima: secureboot mode disabled\n");
+ return efi_secureboot_mode_disabled;
+ }
+
+ pr_info("ima: secureboot mode enabled\n");
+ return efi_secureboot_mode_enabled;
+}
+
+bool arch_ima_get_secureboot(void)
+{
+ static enum efi_secureboot_mode sb_mode;
+ static bool initialized;
+
+ if (!initialized && efi_enabled(EFI_BOOT)) {
+ sb_mode = boot_params.secure_boot;
+
+ if (sb_mode == efi_secureboot_mode_unset)
+ sb_mode = get_sb_mode();
+ initialized = true;
+ }
+
+ if (sb_mode == efi_secureboot_mode_enabled)
+ return true;
+ else
+ return false;
+}
+
+/* secureboot arch rules */
+static const char * const sb_arch_rules[] = {
+#if !IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG)
+ "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig",
+#endif /* CONFIG_KEXEC_VERIFY_SIG */
+ "measure func=KEXEC_KERNEL_CHECK",
+ NULL
+};
+
+const char * const *arch_get_ima_policy(void)
+{
+ if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot())
+ return sb_arch_rules;
+ return NULL;
+}