diff options
Diffstat (limited to 'Add-option-to-automatically-enforce-module-signature.patch')
-rw-r--r-- | Add-option-to-automatically-enforce-module-signature.patch | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/Add-option-to-automatically-enforce-module-signature.patch b/Add-option-to-automatically-enforce-module-signature.patch new file mode 100644 index 000000000..ebabac62e --- /dev/null +++ b/Add-option-to-automatically-enforce-module-signature.patch @@ -0,0 +1,217 @@ +From 6b6203b92cfb457a0669a9c87a29b360405bffc6 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Fri, 9 Aug 2013 18:36:30 -0400 +Subject: [PATCH 10/20] Add option to automatically enforce module signatures + when in Secure Boot mode + +UEFI Secure Boot provides a mechanism for ensuring that the firmware will +only load signed bootloaders and kernels. Certain use cases may also +require that all kernel modules also be signed. Add a configuration option +that enforces this automatically when enabled. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +--- + Documentation/x86/zero-page.txt | 2 ++ + arch/x86/Kconfig | 11 ++++++ + arch/x86/boot/compressed/eboot.c | 66 +++++++++++++++++++++++++++++++++++ + arch/x86/include/uapi/asm/bootparam.h | 3 +- + arch/x86/kernel/setup.c | 6 ++++ + include/linux/module.h | 6 ++++ + kernel/module.c | 7 ++++ + 7 files changed, 100 insertions(+), 1 deletion(-) + +diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt +index 95a4d34af3fd..b8527c6b7646 100644 +--- a/Documentation/x86/zero-page.txt ++++ b/Documentation/x86/zero-page.txt +@@ -31,6 +31,8 @@ Offset Proto Name Meaning + 1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) + 1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer + (below) ++1EB/001 ALL kbd_status Numlock is enabled ++1EC/001 ALL secure_boot Secure boot is enabled in the firmware + 1EF/001 ALL sentinel Used to detect broken bootloaders + 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures + 2D0/A00 ALL e820_map E820 memory map table +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index bada636d1065..d666ef8b616c 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -1786,6 +1786,17 @@ config EFI_MIXED + + If unsure, say N. + ++config EFI_SECURE_BOOT_SIG_ENFORCE ++ def_bool n ++ depends on EFI ++ prompt "Force module signing when UEFI Secure Boot is enabled" ++ ---help--- ++ UEFI Secure Boot provides a mechanism for ensuring that the ++ firmware will only load signed bootloaders and kernels. Certain ++ use cases may also require that all kernel modules also be signed. ++ Say Y here to automatically enable module signature enforcement ++ when a system boots with UEFI Secure Boot enabled. ++ + config SECCOMP + def_bool y + prompt "Enable seccomp to safely compute untrusted bytecode" +diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c +index cc69e37548db..ebc85c1eefd6 100644 +--- a/arch/x86/boot/compressed/eboot.c ++++ b/arch/x86/boot/compressed/eboot.c +@@ -12,6 +12,7 @@ + #include <asm/efi.h> + #include <asm/setup.h> + #include <asm/desc.h> ++#include <asm/bootparam_utils.h> + + #include "../string.h" + #include "eboot.h" +@@ -537,6 +538,67 @@ static void setup_efi_pci(struct boot_params *params) + efi_call_early(free_pool, pci_handle); + } + ++static int get_secure_boot(void) ++{ ++ u8 sb, setup; ++ unsigned long datasize = sizeof(sb); ++ efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID; ++ efi_status_t status; ++ ++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable, ++ L"SecureBoot", &var_guid, NULL, &datasize, &sb); ++ ++ if (status != EFI_SUCCESS) ++ return 0; ++ ++ if (sb == 0) ++ return 0; ++ ++ ++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable, ++ L"SetupMode", &var_guid, NULL, &datasize, ++ &setup); ++ ++ if (status != EFI_SUCCESS) ++ return 0; ++ ++ if (setup == 1) ++ return 0; ++ ++ return 1; ++} ++ ++ ++/* ++ * See if we have Graphics Output Protocol ++ */ ++static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, ++ unsigned long size) ++{ ++ efi_status_t status; ++ void **gop_handle = NULL; ++ ++ status = efi_call_early(allocate_pool, EFI_LOADER_DATA, ++ size, (void **)&gop_handle); ++ if (status != EFI_SUCCESS) ++ return status; ++ ++ status = efi_call_early(locate_handle, ++ EFI_LOCATE_BY_PROTOCOL, ++ proto, NULL, &size, gop_handle); ++ if (status != EFI_SUCCESS) ++ goto free_handle; ++ ++ if (efi_early->is64) ++ status = setup_gop64(si, proto, size, gop_handle); ++ else ++ status = setup_gop32(si, proto, size, gop_handle); ++ ++free_handle: ++ efi_call_early(free_pool, gop_handle); ++ return status; ++} ++ + static efi_status_t + setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height) + { +@@ -1094,6 +1156,10 @@ struct boot_params *efi_main(struct efi_config *c, + else + setup_boot_services32(efi_early); + ++ sanitize_boot_params(boot_params); ++ ++ boot_params->secure_boot = get_secure_boot(); ++ + setup_graphics(boot_params); + + setup_efi_pci(boot_params); +diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h +index c18ce67495fa..2b3e5427097b 100644 +--- a/arch/x86/include/uapi/asm/bootparam.h ++++ b/arch/x86/include/uapi/asm/bootparam.h +@@ -134,7 +134,8 @@ struct boot_params { + __u8 eddbuf_entries; /* 0x1e9 */ + __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ + __u8 kbd_status; /* 0x1eb */ +- __u8 _pad5[3]; /* 0x1ec */ ++ __u8 secure_boot; /* 0x1ec */ ++ __u8 _pad5[2]; /* 0x1ed */ + /* + * The sentinel is set to a nonzero value (0xff) in header.S. + * +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index bbfbca5fea0c..d40e961753c9 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1160,6 +1160,12 @@ void __init setup_arch(char **cmdline_p) + + io_delay_init(); + ++#ifdef CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE ++ if (boot_params.secure_boot) { ++ enforce_signed_modules(); ++ } ++#endif ++ + /* + * Parse the ACPI tables for possible boot-time SMP configuration. + */ +diff --git a/include/linux/module.h b/include/linux/module.h +index 05bd6c989a0c..32327704e18d 100644 +--- a/include/linux/module.h ++++ b/include/linux/module.h +@@ -260,6 +260,12 @@ extern const typeof(name) __mod_##type##__##name##_device_table \ + + struct notifier_block; + ++#ifdef CONFIG_MODULE_SIG ++extern void enforce_signed_modules(void); ++#else ++static inline void enforce_signed_modules(void) {}; ++#endif ++ + #ifdef CONFIG_MODULES + + extern int modules_disabled; /* for sysctl */ +diff --git a/kernel/module.c b/kernel/module.c +index cb864505d020..cb1f1da69bf4 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -4285,6 +4285,13 @@ void module_layout(struct module *mod, + EXPORT_SYMBOL(module_layout); + #endif + ++#ifdef CONFIG_MODULE_SIG ++void enforce_signed_modules(void) ++{ ++ sig_enforce = true; ++} ++#endif ++ + bool secure_modules(void) + { + #ifdef CONFIG_MODULE_SIG +-- +2.9.3 + |