Commit 4a1106af authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'efi_updates_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI updates from Borislav Petkov:
 "These got delayed due to a last minute ia64 build issue which got
  fixed in the meantime.

  EFI updates collected by Ard Biesheuvel:

   - Don't move BSS section around pointlessly in the x86 decompressor

   - Refactor helper for discovering the EFI secure boot mode

   - Wire up EFI secure boot to IMA for arm64

   - Some fixes for the capsule loader

   - Expose the RT_PROP table via the EFI test module

   - Relax DT and kernel placement restrictions on ARM

  with a few followup fixes:

   - fix the build breakage on IA64 caused by recent capsule loader
     changes

   - suppress a type mismatch build warning in the expansion of
     EFI_PHYS_ALIGN on ARM"

* tag 'efi_updates_for_v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi: arm: force use of unsigned type for EFI_PHYS_ALIGN
  efi: ia64: disable the capsule loader
  efi: stub: get rid of efi_get_max_fdt_addr()
  efi/efi_test: read RuntimeServicesSupported
  efi: arm: reduce minimum alignment of uncompressed kernel
  efi: capsule: clean scatter-gather entries from the D-cache
  efi: capsule: use atomic kmap for transient sglist mappings
  efi: x86/xen: switch to efi_get_secureboot_mode helper
  arm64/ima: add ima_arch support
  ima: generalize x86/EFI arch glue for other EFI architectures
  efi: generalize efi_get_secureboot
  efi/libstub: EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER should not default to yes
  efi/x86: Only copy the compressed kernel image in efi_relocate_kernel()
  efi/libstub/x86: simplify efi_is_native()
parents 60e8edd2 3dcb8b53
...@@ -66,24 +66,17 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) ...@@ -66,24 +66,17 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt)
#define MAX_UNCOMP_KERNEL_SIZE SZ_32M #define MAX_UNCOMP_KERNEL_SIZE SZ_32M
/* /*
* phys-to-virt patching requires that the physical to virtual offset fits * phys-to-virt patching requires that the physical to virtual offset is a
* into the immediate field of an add/sub instruction, which comes down to the * multiple of 2 MiB. However, using an alignment smaller than TEXT_OFFSET
* 24 least significant bits being zero, and so the offset should be a multiple * here throws off the memory allocation logic, so let's use the lowest power
* of 16 MB. Since PAGE_OFFSET itself is a multiple of 16 MB, the physical * of two greater than 2 MiB and greater than TEXT_OFFSET.
* base should be aligned to 16 MB as well.
*/ */
#define EFI_PHYS_ALIGN SZ_16M #define EFI_PHYS_ALIGN max(UL(SZ_2M), roundup_pow_of_two(TEXT_OFFSET))
/* on ARM, the FDT should be located in a lowmem region */
static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
{
return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M;
}
/* on ARM, the initrd should be loaded in a lowmem region */ /* on ARM, the initrd should be loaded in a lowmem region */
static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
{ {
return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M; return round_down(image_addr, SZ_4M) + SZ_512M;
} }
struct efi_arm_entry_state { struct efi_arm_entry_state {
...@@ -93,4 +86,9 @@ struct efi_arm_entry_state { ...@@ -93,4 +86,9 @@ struct efi_arm_entry_state {
u32 sctlr_after_ebs; u32 sctlr_after_ebs;
}; };
static inline void efi_capsule_flush_cache_range(void *addr, int size)
{
__cpuc_flush_dcache_area(addr, size);
}
#endif /* _ASM_ARM_EFI_H */ #endif /* _ASM_ARM_EFI_H */
...@@ -1877,6 +1877,7 @@ config EFI ...@@ -1877,6 +1877,7 @@ config EFI
select EFI_RUNTIME_WRAPPERS select EFI_RUNTIME_WRAPPERS
select EFI_STUB select EFI_STUB
select EFI_GENERIC_STUB select EFI_GENERIC_STUB
imply IMA_SECURE_AND_OR_TRUSTED_BOOT
default y default y
help help
This option provides support for runtime services provided This option provides support for runtime services provided
......
...@@ -64,12 +64,6 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); ...@@ -64,12 +64,6 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
#define EFI_KIMG_ALIGN \ #define EFI_KIMG_ALIGN \
(SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN) (SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN)
/* on arm64, the FDT may be located anywhere in system RAM */
static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
{
return ULONG_MAX;
}
/* /*
* On arm64, we have to ensure that the initrd ends up in the linear region, * On arm64, we have to ensure that the initrd ends up in the linear region,
* which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is * which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is
...@@ -141,4 +135,9 @@ static inline void efi_set_pgd(struct mm_struct *mm) ...@@ -141,4 +135,9 @@ static inline void efi_set_pgd(struct mm_struct *mm)
void efi_virtmap_load(void); void efi_virtmap_load(void);
void efi_virtmap_unload(void); void efi_virtmap_unload(void);
static inline void efi_capsule_flush_cache_range(void *addr, int size)
{
__flush_dcache_area(addr, size);
}
#endif /* _ASM_EFI_H */ #endif /* _ASM_EFI_H */
...@@ -27,12 +27,6 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); ...@@ -27,12 +27,6 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
#define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE)
/* on RISC-V, the FDT may be located anywhere in system RAM */
static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr)
{
return ULONG_MAX;
}
/* Load initrd at enough distance from DRAM start */ /* Load initrd at enough distance from DRAM start */
static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
{ {
......
...@@ -35,7 +35,7 @@ cflags-$(CONFIG_X86_32) := -march=i386 ...@@ -35,7 +35,7 @@ cflags-$(CONFIG_X86_32) := -march=i386
cflags-$(CONFIG_X86_64) := -mcmodel=small -mno-red-zone cflags-$(CONFIG_X86_64) := -mcmodel=small -mno-red-zone
KBUILD_CFLAGS += $(cflags-y) KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += -mno-mmx -mno-sse KBUILD_CFLAGS += -mno-mmx -mno-sse
KBUILD_CFLAGS += -ffreestanding KBUILD_CFLAGS += -ffreestanding -fshort-wchar
KBUILD_CFLAGS += -fno-stack-protector KBUILD_CFLAGS += -fno-stack-protector
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
KBUILD_CFLAGS += $(call cc-disable-warning, gnu) KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
......
...@@ -213,8 +213,6 @@ static inline bool efi_is_64bit(void) ...@@ -213,8 +213,6 @@ static inline bool efi_is_64bit(void)
static inline bool efi_is_native(void) static inline bool efi_is_native(void)
{ {
if (!IS_ENABLED(CONFIG_X86_64))
return true;
return efi_is_64bit(); return efi_is_64bit();
} }
...@@ -382,4 +380,7 @@ static inline void efi_fake_memmap_early(void) ...@@ -382,4 +380,7 @@ static inline void efi_fake_memmap_early(void)
} }
#endif #endif
#define arch_ima_efi_boot_mode \
({ extern struct boot_params boot_params; boot_params.secure_boot; })
#endif /* _ASM_X86_EFI_H */ #endif /* _ASM_X86_EFI_H */
...@@ -161,5 +161,3 @@ ifeq ($(CONFIG_X86_64),y) ...@@ -161,5 +161,3 @@ ifeq ($(CONFIG_X86_64),y)
obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o
obj-y += vsmp_64.o obj-y += vsmp_64.o
endif endif
obj-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_arch.o
...@@ -93,37 +93,22 @@ static efi_system_table_t __init *xen_efi_probe(void) ...@@ -93,37 +93,22 @@ static efi_system_table_t __init *xen_efi_probe(void)
/* /*
* Determine whether we're in secure boot mode. * Determine whether we're in secure boot mode.
*
* Please keep the logic in sync with
* drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
*/ */
static enum efi_secureboot_mode xen_efi_get_secureboot(void) static enum efi_secureboot_mode xen_efi_get_secureboot(void)
{ {
static efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID; static efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
enum efi_secureboot_mode mode;
efi_status_t status; efi_status_t status;
u8 moksbstate, secboot, setupmode; u8 moksbstate;
unsigned long size; unsigned long size;
size = sizeof(secboot); mode = efi_get_secureboot_mode(efi.get_variable);
status = efi.get_variable(L"SecureBoot", &efi_variable_guid, if (mode == efi_secureboot_mode_unknown) {
NULL, &size, &secboot); pr_err("Could not determine UEFI Secure Boot status.\n");
return efi_secureboot_mode_unknown;
if (status == EFI_NOT_FOUND) }
return efi_secureboot_mode_disabled; if (mode != efi_secureboot_mode_enabled)
return mode;
if (status != EFI_SUCCESS)
goto out_efi_err;
size = sizeof(setupmode);
status = efi.get_variable(L"SetupMode", &efi_variable_guid,
NULL, &size, &setupmode);
if (status != EFI_SUCCESS)
goto out_efi_err;
if (secboot == 0 || setupmode == 1)
return efi_secureboot_mode_disabled;
/* See if a user has put the shim into insecure mode. */ /* See if a user has put the shim into insecure mode. */
size = sizeof(moksbstate); size = sizeof(moksbstate);
...@@ -140,10 +125,6 @@ static enum efi_secureboot_mode xen_efi_get_secureboot(void) ...@@ -140,10 +125,6 @@ static enum efi_secureboot_mode xen_efi_get_secureboot(void)
secure_boot_enabled: secure_boot_enabled:
pr_info("UEFI Secure Boot is enabled.\n"); pr_info("UEFI Secure Boot is enabled.\n");
return efi_secureboot_mode_enabled; return efi_secureboot_mode_enabled;
out_efi_err:
pr_err("Could not determine UEFI Secure Boot status.\n");
return efi_secureboot_mode_unknown;
} }
void __init xen_efi_init(struct boot_params *boot_params) void __init xen_efi_init(struct boot_params *boot_params)
......
...@@ -122,7 +122,7 @@ config EFI_ARMSTUB_DTB_LOADER ...@@ -122,7 +122,7 @@ config EFI_ARMSTUB_DTB_LOADER
config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
bool "Enable the command line initrd loader" if !X86 bool "Enable the command line initrd loader" if !X86
depends on EFI_STUB && (EFI_GENERIC_STUB || X86) depends on EFI_STUB && (EFI_GENERIC_STUB || X86)
default y default y if X86
depends on !RISCV depends on !RISCV
help help
Select this config option to add support for the initrd= command Select this config option to add support for the initrd= command
...@@ -147,7 +147,7 @@ config EFI_BOOTLOADER_CONTROL ...@@ -147,7 +147,7 @@ config EFI_BOOTLOADER_CONTROL
config EFI_CAPSULE_LOADER config EFI_CAPSULE_LOADER
tristate "EFI capsule loader" tristate "EFI capsule loader"
depends on EFI depends on EFI && !IA64
help help
This option exposes a loader interface "/dev/efi_capsule_loader" for This option exposes a loader interface "/dev/efi_capsule_loader" for
users to load EFI capsules. This driver requires working runtime users to load EFI capsules. This driver requires working runtime
......
...@@ -12,7 +12,10 @@ KASAN_SANITIZE_runtime-wrappers.o := n ...@@ -12,7 +12,10 @@ KASAN_SANITIZE_runtime-wrappers.o := n
obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o tpm.o obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o tpm.o
obj-$(CONFIG_EFI) += capsule.o memmap.o obj-$(CONFIG_EFI) += memmap.o
ifneq ($(CONFIG_EFI_CAPSULE_LOADER),)
obj-$(CONFIG_EFI) += capsule.o
endif
obj-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdtparams.o obj-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdtparams.o
obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_VARS) += efivars.o
obj-$(CONFIG_EFI_ESRT) += esrt.o obj-$(CONFIG_EFI_ESRT) += esrt.o
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <asm/efi.h>
#include <asm/io.h> #include <asm/io.h>
typedef struct { typedef struct {
...@@ -244,7 +245,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages) ...@@ -244,7 +245,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages)
for (i = 0; i < sg_count; i++) { for (i = 0; i < sg_count; i++) {
efi_capsule_block_desc_t *sglist; efi_capsule_block_desc_t *sglist;
sglist = kmap(sg_pages[i]); sglist = kmap_atomic(sg_pages[i]);
for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) { for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) {
u64 sz = min_t(u64, imagesize, u64 sz = min_t(u64, imagesize,
...@@ -265,7 +266,18 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages) ...@@ -265,7 +266,18 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages)
else else
sglist[j].data = page_to_phys(sg_pages[i + 1]); sglist[j].data = page_to_phys(sg_pages[i + 1]);
kunmap(sg_pages[i]); #if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
/*
* At runtime, the firmware has no way to find out where the
* sglist elements are mapped, if they are mapped in the first
* place. Therefore, on architectures that can only perform
* cache maintenance by virtual address, the firmware is unable
* to perform this maintenance, and so it is up to the OS to do
* it instead.
*/
efi_capsule_flush_cache_range(sglist, PAGE_SIZE);
#endif
kunmap_atomic(sglist);
} }
mutex_lock(&capsule_mutex); mutex_lock(&capsule_mutex);
......
...@@ -273,7 +273,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -273,7 +273,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
install_memreserve_table(); install_memreserve_table();
status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr, status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr,
efi_get_max_fdt_addr(image_addr),
initrd_addr, initrd_size, initrd_addr, initrd_size,
cmdline_ptr, fdt_addr, fdt_size); cmdline_ptr, fdt_addr, fdt_size);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
......
...@@ -750,7 +750,6 @@ efi_status_t efi_exit_boot_services(void *handle, ...@@ -750,7 +750,6 @@ efi_status_t efi_exit_boot_services(void *handle,
efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
unsigned long *new_fdt_addr, unsigned long *new_fdt_addr,
unsigned long max_addr,
u64 initrd_addr, u64 initrd_size, u64 initrd_addr, u64 initrd_size,
char *cmdline_ptr, char *cmdline_ptr,
unsigned long fdt_addr, unsigned long fdt_addr,
...@@ -848,4 +847,6 @@ asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint, ...@@ -848,4 +847,6 @@ asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint,
void efi_handle_post_ebs_state(void); void efi_handle_post_ebs_state(void);
enum efi_secureboot_mode efi_get_secureboot(void);
#endif #endif
...@@ -238,7 +238,6 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, ...@@ -238,7 +238,6 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
unsigned long *new_fdt_addr, unsigned long *new_fdt_addr,
unsigned long max_addr,
u64 initrd_addr, u64 initrd_size, u64 initrd_addr, u64 initrd_size,
char *cmdline_ptr, char *cmdline_ptr,
unsigned long fdt_addr, unsigned long fdt_addr,
...@@ -275,7 +274,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, ...@@ -275,7 +274,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
efi_info("Exiting boot services and installing virtual address map...\n"); efi_info("Exiting boot services and installing virtual address map...\n");
map.map = &memory_map; map.map = &memory_map;
status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, max_addr); status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, ULONG_MAX);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
efi_err("Unable to allocate memory for new device tree.\n"); efi_err("Unable to allocate memory for new device tree.\n");
goto fail; goto fail;
......
...@@ -12,44 +12,34 @@ ...@@ -12,44 +12,34 @@
#include "efistub.h" #include "efistub.h"
/* BIOS variables */
static const efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
static const efi_char16_t efi_SecureBoot_name[] = L"SecureBoot";
static const efi_char16_t efi_SetupMode_name[] = L"SetupMode";
/* SHIM variables */ /* SHIM variables */
static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID; static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
static const efi_char16_t shim_MokSBState_name[] = L"MokSBState"; static const efi_char16_t shim_MokSBState_name[] = L"MokSBState";
static efi_status_t get_var(efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
unsigned long *data_size, void *data)
{
return get_efi_var(name, vendor, attr, data_size, data);
}
/* /*
* Determine whether we're in secure boot mode. * Determine whether we're in secure boot mode.
*
* Please keep the logic in sync with
* arch/x86/xen/efi.c:xen_efi_get_secureboot().
*/ */
enum efi_secureboot_mode efi_get_secureboot(void) enum efi_secureboot_mode efi_get_secureboot(void)
{ {
u32 attr; u32 attr;
u8 secboot, setupmode, moksbstate;
unsigned long size; unsigned long size;
enum efi_secureboot_mode mode;
efi_status_t status; efi_status_t status;
u8 moksbstate;
size = sizeof(secboot); mode = efi_get_secureboot_mode(get_var);
status = get_efi_var(efi_SecureBoot_name, &efi_variable_guid, if (mode == efi_secureboot_mode_unknown) {
NULL, &size, &secboot); efi_err("Could not determine UEFI Secure Boot status.\n");
if (status == EFI_NOT_FOUND) return efi_secureboot_mode_unknown;
return efi_secureboot_mode_disabled; }
if (status != EFI_SUCCESS) if (mode != efi_secureboot_mode_enabled)
goto out_efi_err; return mode;
size = sizeof(setupmode);
status = get_efi_var(efi_SetupMode_name, &efi_variable_guid,
NULL, &size, &setupmode);
if (status != EFI_SUCCESS)
goto out_efi_err;
if (secboot == 0 || setupmode == 1)
return efi_secureboot_mode_disabled;
/* /*
* See if a user has put the shim into insecure mode. If so, and if the * See if a user has put the shim into insecure mode. If so, and if the
...@@ -69,8 +59,4 @@ enum efi_secureboot_mode efi_get_secureboot(void) ...@@ -69,8 +59,4 @@ enum efi_secureboot_mode efi_get_secureboot(void)
secure_boot_enabled: secure_boot_enabled:
efi_info("UEFI Secure Boot is enabled.\n"); efi_info("UEFI Secure Boot is enabled.\n");
return efi_secureboot_mode_enabled; return efi_secureboot_mode_enabled;
out_efi_err:
efi_err("Could not determine UEFI Secure Boot status.\n");
return efi_secureboot_mode_unknown;
} }
...@@ -715,8 +715,11 @@ unsigned long efi_main(efi_handle_t handle, ...@@ -715,8 +715,11 @@ unsigned long efi_main(efi_handle_t handle,
(IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE) || (IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE) ||
(IS_ENABLED(CONFIG_X86_64) && buffer_end > MAXMEM_X86_64_4LEVEL) || (IS_ENABLED(CONFIG_X86_64) && buffer_end > MAXMEM_X86_64_4LEVEL) ||
(image_offset == 0)) { (image_offset == 0)) {
extern char _bss[];
status = efi_relocate_kernel(&bzimage_addr, status = efi_relocate_kernel(&bzimage_addr,
hdr->init_size, hdr->init_size, (unsigned long)_bss - bzimage_addr,
hdr->init_size,
hdr->pref_address, hdr->pref_address,
hdr->kernel_alignment, hdr->kernel_alignment,
LOAD_PHYSICAL_ADDR); LOAD_PHYSICAL_ADDR);
......
...@@ -663,6 +663,19 @@ static long efi_runtime_query_capsulecaps(unsigned long arg) ...@@ -663,6 +663,19 @@ static long efi_runtime_query_capsulecaps(unsigned long arg)
return rv; return rv;
} }
static long efi_runtime_get_supported_mask(unsigned long arg)
{
unsigned int __user *supported_mask;
int rv = 0;
supported_mask = (unsigned int *)arg;
if (put_user(efi.runtime_supported_mask, supported_mask))
rv = -EFAULT;
return rv;
}
static long efi_test_ioctl(struct file *file, unsigned int cmd, static long efi_test_ioctl(struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
...@@ -699,6 +712,9 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd, ...@@ -699,6 +712,9 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd,
case EFI_RUNTIME_RESET_SYSTEM: case EFI_RUNTIME_RESET_SYSTEM:
return efi_runtime_reset_system(arg); return efi_runtime_reset_system(arg);
case EFI_RUNTIME_GET_SUPPORTED_MASK:
return efi_runtime_get_supported_mask(arg);
} }
return -ENOTTY; return -ENOTTY;
......
...@@ -118,4 +118,7 @@ struct efi_resetsystem { ...@@ -118,4 +118,7 @@ struct efi_resetsystem {
#define EFI_RUNTIME_RESET_SYSTEM \ #define EFI_RUNTIME_RESET_SYSTEM \
_IOW('p', 0x0B, struct efi_resetsystem) _IOW('p', 0x0B, struct efi_resetsystem)
#define EFI_RUNTIME_GET_SUPPORTED_MASK \
_IOR('p', 0x0C, unsigned int)
#endif /* _DRIVERS_FIRMWARE_EFI_TEST_H_ */ #endif /* _DRIVERS_FIRMWARE_EFI_TEST_H_ */
...@@ -817,12 +817,6 @@ static inline bool efi_enabled(int feature) ...@@ -817,12 +817,6 @@ static inline bool efi_enabled(int feature)
static inline void static inline void
efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {} efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {}
static inline bool
efi_capsule_pending(int *reset_type)
{
return false;
}
static inline bool efi_soft_reserve_enabled(void) static inline bool efi_soft_reserve_enabled(void)
{ {
return false; return false;
...@@ -1038,6 +1032,7 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data, ...@@ -1038,6 +1032,7 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
bool efivar_variable_is_removable(efi_guid_t vendor, const char *name, bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
size_t len); size_t len);
#if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER)
extern bool efi_capsule_pending(int *reset_type); extern bool efi_capsule_pending(int *reset_type);
extern int efi_capsule_supported(efi_guid_t guid, u32 flags, extern int efi_capsule_supported(efi_guid_t guid, u32 flags,
...@@ -1045,6 +1040,9 @@ extern int efi_capsule_supported(efi_guid_t guid, u32 flags, ...@@ -1045,6 +1040,9 @@ extern int efi_capsule_supported(efi_guid_t guid, u32 flags,
extern int efi_capsule_update(efi_capsule_header_t *capsule, extern int efi_capsule_update(efi_capsule_header_t *capsule,
phys_addr_t *pages); phys_addr_t *pages);
#else
static inline bool efi_capsule_pending(int *reset_type) { return false; }
#endif
#ifdef CONFIG_EFI_RUNTIME_MAP #ifdef CONFIG_EFI_RUNTIME_MAP
int efi_runtime_map_init(struct kobject *); int efi_runtime_map_init(struct kobject *);
...@@ -1089,7 +1087,28 @@ enum efi_secureboot_mode { ...@@ -1089,7 +1087,28 @@ enum efi_secureboot_mode {
efi_secureboot_mode_disabled, efi_secureboot_mode_disabled,
efi_secureboot_mode_enabled, efi_secureboot_mode_enabled,
}; };
enum efi_secureboot_mode efi_get_secureboot(void);
static inline
enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var)
{
u8 secboot, setupmode = 0;
efi_status_t status;
unsigned long size;
size = sizeof(secboot);
status = get_var(L"SecureBoot", &EFI_GLOBAL_VARIABLE_GUID, NULL, &size,
&secboot);
if (status == EFI_NOT_FOUND)
return efi_secureboot_mode_disabled;
if (status != EFI_SUCCESS)
return efi_secureboot_mode_unknown;
size = sizeof(setupmode);
get_var(L"SetupMode", &EFI_GLOBAL_VARIABLE_GUID, NULL, &size, &setupmode);
if (secboot == 0 || setupmode == 1)
return efi_secureboot_mode_disabled;
return efi_secureboot_mode_enabled;
}
#ifdef CONFIG_RESET_ATTACK_MITIGATION #ifdef CONFIG_RESET_ATTACK_MITIGATION
void efi_enable_reset_attack_mitigation(void); void efi_enable_reset_attack_mitigation(void);
......
...@@ -14,3 +14,7 @@ ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o ...@@ -14,3 +14,7 @@ ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
ima-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o ima-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
ima-$(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) += ima_asymmetric_keys.o ima-$(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) += ima_asymmetric_keys.o
ima-$(CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS) += ima_queue_keys.o ima-$(CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS) += ima_queue_keys.o
ifeq ($(CONFIG_EFI),y)
ima-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_efi.o
endif
...@@ -5,50 +5,29 @@ ...@@ -5,50 +5,29 @@
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ima.h> #include <linux/ima.h>
#include <asm/efi.h>
extern struct boot_params boot_params; #ifndef arch_ima_efi_boot_mode
#define arch_ima_efi_boot_mode efi_secureboot_mode_unset
#endif
static enum efi_secureboot_mode get_sb_mode(void) static enum efi_secureboot_mode get_sb_mode(void)
{ {
efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; enum efi_secureboot_mode mode;
efi_status_t status;
unsigned long size;
u8 secboot, setupmode;
size = sizeof(secboot);
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) { if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) {
pr_info("ima: secureboot mode unknown, no efi\n"); pr_info("ima: secureboot mode unknown, no efi\n");
return efi_secureboot_mode_unknown; return efi_secureboot_mode_unknown;
} }
/* Get variable contents into buffer */ mode = efi_get_secureboot_mode(efi.get_variable);
status = efi.get_variable(L"SecureBoot", &efi_variable_guid, if (mode == efi_secureboot_mode_disabled)
NULL, &size, &secboot);
if (status == EFI_NOT_FOUND) {
pr_info("ima: secureboot mode disabled\n"); pr_info("ima: secureboot mode disabled\n");
return efi_secureboot_mode_disabled; else if (mode == efi_secureboot_mode_unknown)
}
if (status != EFI_SUCCESS) {
pr_info("ima: secureboot mode unknown\n"); pr_info("ima: secureboot mode unknown\n");
return efi_secureboot_mode_unknown; else
} pr_info("ima: secureboot mode enabled\n");
return mode;
size = sizeof(setupmode);
status = efi.get_variable(L"SetupMode", &efi_variable_guid,
NULL, &size, &setupmode);
if (status != EFI_SUCCESS) /* ignore unknown SetupMode */
setupmode = 0;
if (secboot == 0 || setupmode == 1) {
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) bool arch_ima_get_secureboot(void)
...@@ -57,7 +36,7 @@ bool arch_ima_get_secureboot(void) ...@@ -57,7 +36,7 @@ bool arch_ima_get_secureboot(void)
static bool initialized; static bool initialized;
if (!initialized && efi_enabled(EFI_BOOT)) { if (!initialized && efi_enabled(EFI_BOOT)) {
sb_mode = boot_params.secure_boot; sb_mode = arch_ima_efi_boot_mode;
if (sb_mode == efi_secureboot_mode_unset) if (sb_mode == efi_secureboot_mode_unset)
sb_mode = get_sb_mode(); sb_mode = get_sb_mode();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment