Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next-integrity

From Mimi:

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 pull request 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.)
This commit is contained in:
James Morris
2018-12-17 11:26:46 -08:00
20 changed files with 863 additions and 93 deletions

View File

@@ -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

View File

@@ -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;
}