]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86/efi: Set securelevel when loaded without efi stub
authorDan Duval <dan.duval@oracle.com>
Fri, 11 Dec 2015 20:20:20 +0000 (15:20 -0500)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 16 Mar 2016 15:18:26 +0000 (08:18 -0700)
Orabug: 22364965

With UEFI Secure Boot enabled and securelevel set, after a kernel is loaded
using kexec and booted, securelevel is disabled. With the securelevel patch
set, the state of UEFI Secure Boot is queried when booted via the efi stub, but
kexec does not use the efi stub.

To allow kernels which are not loaded through the efi stub to properly set
securelevel as well, add a new init routine to start_kernel() to query the
state of UEFI Secure Boot and enable securelevel if needed.

Taken from https://bugzilla.redhat.com/attachment.cgi?id=1052836 .

Signed-off-by: Linn Crosetto <linn@hp.com>
Signed-off-by: Dan Duval <dan.duval@oracle.com>
(cherry picked from commit a954f7350658a8fde4b893c7b74de8137864ad12)
Signed-off-by: Dan Duval <dan.duval@oracle.com>
arch/x86/kernel/setup.c
arch/x86/platform/efi/efi.c
include/linux/efi.h
init/main.c

index 97838c712a96a319e73c29b46e3929afd07873e0..7cea402a45d332fa50fc5b7544c3e4ae4d395e97 100644 (file)
@@ -1157,14 +1157,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.
         */
index 02744df576d52588a35308998ecc1a138435012e..fc8c2054f3ab36b91cc5040236e637dfdcbf3ed1 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/io.h>
 #include <linux/reboot.h>
 #include <linux/bcd.h>
+#include <linux/security.h>
 
 #include <asm/setup.h>
 #include <asm/efi.h>
@@ -78,6 +79,41 @@ static int __init setup_add_efi_memmap(char *arg)
 }
 early_param("add_efi_memmap", setup_add_efi_memmap);
 
+static int __init efi_secure_boot_enabled(void)
+{
+       efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
+       static efi_char16_t sb_var[] = {
+               'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+       static efi_char16_t sm_var[] = {
+               'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
+       u8 sb, setup;
+       unsigned long datasize = sizeof(sb);
+       efi_status_t status;
+
+       if (boot_params.secure_boot)
+               return 1;
+
+       status = efi.get_variable((efi_char16_t*)sb_var,
+                               &var_guid, NULL, &datasize, &sb);
+
+       if (status != EFI_SUCCESS)
+               return 0;
+
+       if (sb == 0)
+               return 0;
+
+       status = efi.get_variable((efi_char16_t*)sm_var,
+                               &var_guid, NULL, &datasize, &setup);
+
+       if (status != EFI_SUCCESS)
+               return 0;
+
+       if (setup == 1)
+               return 0;
+
+       return 1;
+}
+
 static efi_status_t __init phys_efi_set_virtual_address_map(
        unsigned long memory_map_size,
        unsigned long descriptor_size,
@@ -436,6 +472,17 @@ static int __init efi_memmap_init(void)
        return 0;
 }
 
+void __init efi_secure_boot_init(void)
+{
+       if (!efi_secure_boot_enabled())
+               return;
+
+       boot_params.secure_boot = 1;
+#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL
+       set_securelevel(1);
+#endif
+}
+
 void __init efi_init(void)
 {
        efi_char16_t *c16;
index 03eed462480c127402f08b31d130c1bf85cae6e7..10df94c7b35c4feb84d9e0f5a5990c1f2a678917 100644 (file)
@@ -890,6 +890,7 @@ extern void efi_enter_virtual_mode (void);  /* switch EFI to virtual mode, if pos
 extern void efi_late_init(void);
 extern void efi_free_boot_services(void);
 extern efi_status_t efi_query_variable_store(u32 attributes, unsigned long size);
+extern void efi_secure_boot_init(void);
 #else
 static inline void efi_late_init(void) {}
 static inline void efi_free_boot_services(void) {}
index 2115055faeac948bd164c9e8d574795f557f02a5..eee9db77db76bfbd487d5d5f0dc38acfc8274a00 100644 (file)
@@ -639,6 +639,8 @@ asmlinkage __visible void __init start_kernel(void)
        if (efi_enabled(EFI_RUNTIME_SERVICES))
                efi_enter_virtual_mode();
 #endif
+       if (efi_enabled(EFI_RUNTIME_SERVICES))
+               efi_secure_boot_init();
 #ifdef CONFIG_X86_ESPFIX64
        /* Should be run before the first non-init thread is created */
        init_espfix_bsp();