From b22c43e5b3c6ee6b703a06373da46bc24b97f323 Mon Sep 17 00:00:00 2001 From: Linn Crosetto Date: Wed, 16 Nov 2016 12:33:52 -0800 Subject: [PATCH] acpi: Disable ACPI table override if securelevel is set From the kernel documentation (initrd_table_override.txt): If the ACPI_INITRD_TABLE_OVERRIDE compile option is true, it is possible to override nearly any ACPI table provided by the BIOS with an instrumented, modified one. When securelevel is set, the kernel should disallow any unauthenticated changes to kernel space. ACPI tables contain code invoked by the kernel, so do not allow ACPI tables to be overridden if securelevel is set. Signed-off-by: Linn Crosetto Orabug: 25058372 CVE: CVE-2016-3699 Signed-off-by: Chuck Anderson Reviewed-by: Guru Anbalagane --- arch/x86/kernel/setup.c | 16 ++++++++-------- drivers/acpi/osl.c | 6 ++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 97838c712a96..5813e2d48eb7 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1147,6 +1147,14 @@ void __init setup_arch(char **cmdline_p) /* Allocate bigger log buffer */ setup_log_buf(1); +#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL + if (boot_params.secure_boot) { + set_bit(EFI_SECURE_BOOT, &efi.flags); + set_securelevel(1); + pr_info("Secure boot enabled\n"); + } +#endif + reserve_initrd(); #if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD) @@ -1157,14 +1165,6 @@ void __init setup_arch(char **cmdline_p) io_delay_init(); -#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL - if (boot_params.secure_boot) { - set_bit(EFI_SECURE_BOOT, &efi.flags); - set_securelevel(1); - pr_info("Secure boot enabled\n"); - } -#endif - /* * Parse the ACPI tables for possible boot-time SMP configuration. */ diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 5a2e173cf315..82a5b1f6d464 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -651,6 +651,12 @@ void __init acpi_initrd_override(void *data, size_t size) if (table_nr == 0) return; + if (get_securelevel() > 0) { + pr_notice(PREFIX + "securelevel enabled, ignoring table override\n"); + return; +} + acpi_tables_addr = memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT, all_tables_size, PAGE_SIZE); -- 2.50.1