First batch of EFI fixes for v6.1

- A pair of fixes for the EFI variable store refactor that landed in
   v6.0
 - A couple of fixes for issue that were introduced during the merge
   window
 - Back out some changes related to EFI zboot signing - we'll add a
   better solution for this during the next cycle
 -----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE+9lifEBpyUIVN1cpw08iOZLZjyQFAmNSs/cACgkQw08iOZLZ
 jySlPgv/Zfwdbg7b+0Y2wkevUh3shwSH5/fzRAxxFa9dt1D1DcSr+JAqGslSS0Uo
 Hq9GEnEVGhGqzd6JC/0X5jCSZFJCbfA8F6v082Qg1sJwr1cbualVcyYY0KL5GCk5
 pyIfjHfotaTyS7mzQnjlxT9NQVzJEnZcEP9sxxIny5FRwS0KqhbtGN2V0xovDB/4
 2b9w9a7zg1YZVH/IJdeLZFzG5TMQzg8X5WPWVqKHNpqMC9gOW3V3R4Gxy0RCp85Q
 9j8PY5CI3KABeYwCDKB+sw7GFYSDK9e+4qEwdcC9Fp1+K0g35ELd8xDr98aMMyyw
 pl5qdsJz6XY7i9IfgZq4YhSlMA1+Ab7hAsweoQ7tYofs0TRtuNGzLTT2scU5Pws1
 67smMKxlfXTUSB7+1aH5qkV9sKM2uB/Rbib9qIkSyIeTN8Mo/290nimOIilhpsz8
 EQC0mIAsieoF7svy5HFgDsxFi7m6jxwYqlGZt3QCF3ULdlEDQYOA5boJh9OgbR6C
 3e1kMHR8
 =q3Qj
 -----END PGP SIGNATURE-----

Merge tag 'efi-fixes-for-v6.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull EFI fixes from Ard Biesheuvel:

 - fixes for the EFI variable store refactor that landed in v6.0

 - fixes for issues that were introduced during the merge window

 - back out some changes related to EFI zboot signing - we'll add a
   better solution for this during the next cycle

* tag 'efi-fixes-for-v6.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  efi: runtime: Don't assume virtual mappings are missing if VA == PA == 0
  efi: libstub: Fix incorrect payload size in zboot header
  efi: libstub: Give efi_main() asmlinkage qualification
  efi: efivars: Fix variable writes without query_variable_store()
  efi: ssdt: Don't free memory if ACPI table was loaded successfully
  efi: libstub: Remove zboot signing from build options
This commit is contained in:
Linus Torvalds 2022-10-21 18:02:36 -07:00
commit ec4cf5dbb1
11 changed files with 22 additions and 81 deletions

View file

@ -124,28 +124,6 @@ config EFI_ZBOOT
is supported by the encapsulated image. (The compression algorithm is supported by the encapsulated image. (The compression algorithm
used is described in the zboot image header) used is described in the zboot image header)
config EFI_ZBOOT_SIGNED
def_bool y
depends on EFI_ZBOOT_SIGNING_CERT != ""
depends on EFI_ZBOOT_SIGNING_KEY != ""
config EFI_ZBOOT_SIGNING
bool "Sign the EFI decompressor for UEFI secure boot"
depends on EFI_ZBOOT
help
Use the 'sbsign' command line tool (which must exist on the host
path) to sign both the EFI decompressor PE/COFF image, as well as the
encapsulated PE/COFF image, which is subsequently compressed and
wrapped by the former image.
config EFI_ZBOOT_SIGNING_CERT
string "Certificate to use for signing the compressed EFI boot image"
depends on EFI_ZBOOT_SIGNING
config EFI_ZBOOT_SIGNING_KEY
string "Private key to use for signing the compressed EFI boot image"
depends on EFI_ZBOOT_SIGNING
config EFI_ARMSTUB_DTB_LOADER config EFI_ARMSTUB_DTB_LOADER
bool "Enable the DTB loader" bool "Enable the DTB loader"
depends on EFI_GENERIC_STUB && !RISCV && !LOONGARCH depends on EFI_GENERIC_STUB && !RISCV && !LOONGARCH

View file

@ -63,7 +63,7 @@ static bool __init efi_virtmap_init(void)
if (!(md->attribute & EFI_MEMORY_RUNTIME)) if (!(md->attribute & EFI_MEMORY_RUNTIME))
continue; continue;
if (md->virt_addr == 0) if (md->virt_addr == U64_MAX)
return false; return false;
ret = efi_create_mapping(&efi_mm, md); ret = efi_create_mapping(&efi_mm, md);

View file

@ -271,6 +271,8 @@ static __init int efivar_ssdt_load(void)
acpi_status ret = acpi_load_table(data, NULL); acpi_status ret = acpi_load_table(data, NULL);
if (ret) if (ret)
pr_err("failed to load table: %u\n", ret); pr_err("failed to load table: %u\n", ret);
else
continue;
} else { } else {
pr_err("failed to get var data: 0x%lx\n", status); pr_err("failed to get var data: 0x%lx\n", status);
} }

View file

@ -20,22 +20,11 @@ zboot-size-len-y := 4
zboot-method-$(CONFIG_KERNEL_GZIP) := gzip zboot-method-$(CONFIG_KERNEL_GZIP) := gzip
zboot-size-len-$(CONFIG_KERNEL_GZIP) := 0 zboot-size-len-$(CONFIG_KERNEL_GZIP) := 0
quiet_cmd_sbsign = SBSIGN $@ $(obj)/vmlinuz: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE
cmd_sbsign = sbsign --out $@ $< \
--key $(CONFIG_EFI_ZBOOT_SIGNING_KEY) \
--cert $(CONFIG_EFI_ZBOOT_SIGNING_CERT)
$(obj)/$(EFI_ZBOOT_PAYLOAD).signed: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE
$(call if_changed,sbsign)
ZBOOT_PAYLOAD-y := $(EFI_ZBOOT_PAYLOAD)
ZBOOT_PAYLOAD-$(CONFIG_EFI_ZBOOT_SIGNED) := $(EFI_ZBOOT_PAYLOAD).signed
$(obj)/vmlinuz: $(obj)/$(ZBOOT_PAYLOAD-y) FORCE
$(call if_changed,$(zboot-method-y)) $(call if_changed,$(zboot-method-y))
OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \ OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \
--rename-section .data=.gzdata,load,alloc,readonly,contents --rename-section .data=.gzdata,load,alloc,readonly,contents
$(obj)/vmlinuz.o: $(obj)/vmlinuz FORCE $(obj)/vmlinuz.o: $(obj)/vmlinuz FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
@ -53,18 +42,8 @@ LDFLAGS_vmlinuz.efi.elf := -T $(srctree)/drivers/firmware/efi/libstub/zboot.lds
$(obj)/vmlinuz.efi.elf: $(obj)/vmlinuz.o $(ZBOOT_DEPS) FORCE $(obj)/vmlinuz.efi.elf: $(obj)/vmlinuz.o $(ZBOOT_DEPS) FORCE
$(call if_changed,ld) $(call if_changed,ld)
ZBOOT_EFI-y := vmlinuz.efi OBJCOPYFLAGS_vmlinuz.efi := -O binary
ZBOOT_EFI-$(CONFIG_EFI_ZBOOT_SIGNED) := vmlinuz.efi.unsigned $(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.elf FORCE
OBJCOPYFLAGS_$(ZBOOT_EFI-y) := -O binary
$(obj)/$(ZBOOT_EFI-y): $(obj)/vmlinuz.efi.elf FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
targets += zboot-header.o vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi targets += zboot-header.o vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi
ifneq ($(CONFIG_EFI_ZBOOT_SIGNED),)
$(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.unsigned FORCE
$(call if_changed,sbsign)
endif
targets += $(EFI_ZBOOT_PAYLOAD).signed vmlinuz.efi.unsigned

View file

@ -313,16 +313,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
/* /*
* Set the virtual address field of all * Set the virtual address field of all
* EFI_MEMORY_RUNTIME entries to 0. This will signal * EFI_MEMORY_RUNTIME entries to U64_MAX. This will
* the incoming kernel that no virtual translation has * signal the incoming kernel that no virtual
* been installed. * translation has been installed.
*/ */
for (l = 0; l < priv.boot_memmap->map_size; for (l = 0; l < priv.boot_memmap->map_size;
l += priv.boot_memmap->desc_size) { l += priv.boot_memmap->desc_size) {
p = (void *)priv.boot_memmap->map + l; p = (void *)priv.boot_memmap->map + l;
if (p->attribute & EFI_MEMORY_RUNTIME) if (p->attribute & EFI_MEMORY_RUNTIME)
p->virt_addr = 0; p->virt_addr = U64_MAX;
} }
} }
return EFI_SUCCESS; return EFI_SUCCESS;

View file

@ -765,9 +765,9 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle)
* relocated by efi_relocate_kernel. * relocated by efi_relocate_kernel.
* On failure, we exit to the firmware via efi_exit instead of returning. * On failure, we exit to the firmware via efi_exit instead of returning.
*/ */
unsigned long efi_main(efi_handle_t handle, asmlinkage unsigned long efi_main(efi_handle_t handle,
efi_system_table_t *sys_table_arg, efi_system_table_t *sys_table_arg,
struct boot_params *boot_params) struct boot_params *boot_params)
{ {
unsigned long bzimage_addr = (unsigned long)startup_32; unsigned long bzimage_addr = (unsigned long)startup_32;
unsigned long buffer_start, buffer_end; unsigned long buffer_start, buffer_end;

View file

@ -38,7 +38,8 @@ SECTIONS
} }
} }
PROVIDE(__efistub__gzdata_size = ABSOLUTE(. - __efistub__gzdata_start)); PROVIDE(__efistub__gzdata_size =
ABSOLUTE(__efistub__gzdata_end - __efistub__gzdata_start));
PROVIDE(__data_rawsize = ABSOLUTE(_edata - _etext)); PROVIDE(__data_rawsize = ABSOLUTE(_edata - _etext));
PROVIDE(__data_size = ABSOLUTE(_end - _etext)); PROVIDE(__data_size = ABSOLUTE(_end - _etext));

View file

@ -41,7 +41,7 @@ static bool __init efi_virtmap_init(void)
if (!(md->attribute & EFI_MEMORY_RUNTIME)) if (!(md->attribute & EFI_MEMORY_RUNTIME))
continue; continue;
if (md->virt_addr == 0) if (md->virt_addr == U64_MAX)
return false; return false;
ret = efi_create_mapping(&efi_mm, md); ret = efi_create_mapping(&efi_mm, md);

View file

@ -7,6 +7,7 @@
*/ */
#include <linux/types.h> #include <linux/types.h>
#include <linux/sizes.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
@ -20,19 +21,19 @@ static struct efivars *__efivars;
static DEFINE_SEMAPHORE(efivars_lock); static DEFINE_SEMAPHORE(efivars_lock);
efi_status_t check_var_size(u32 attributes, unsigned long size) static efi_status_t check_var_size(u32 attributes, unsigned long size)
{ {
const struct efivar_operations *fops; const struct efivar_operations *fops;
fops = __efivars->ops; fops = __efivars->ops;
if (!fops->query_variable_store) if (!fops->query_variable_store)
return EFI_UNSUPPORTED; return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
return fops->query_variable_store(attributes, size, false); return fops->query_variable_store(attributes, size, false);
} }
EXPORT_SYMBOL_NS_GPL(check_var_size, EFIVAR);
static
efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size) efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
{ {
const struct efivar_operations *fops; const struct efivar_operations *fops;
@ -40,11 +41,10 @@ efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
fops = __efivars->ops; fops = __efivars->ops;
if (!fops->query_variable_store) if (!fops->query_variable_store)
return EFI_UNSUPPORTED; return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
return fops->query_variable_store(attributes, size, true); return fops->query_variable_store(attributes, size, true);
} }
EXPORT_SYMBOL_NS_GPL(check_var_size_nonblocking, EFIVAR);
/** /**
* efivars_kobject - get the kobject for the registered efivars * efivars_kobject - get the kobject for the registered efivars

View file

@ -651,22 +651,6 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
if (err) if (err)
return err; return err;
/*
* Ensure that the available space hasn't shrunk below the safe level
*/
status = check_var_size(attributes, *size + ucs2_strsize(name, 1024));
if (status != EFI_SUCCESS) {
if (status != EFI_UNSUPPORTED) {
err = efi_status_to_err(status);
goto out;
}
if (*size > 65536) {
err = -ENOSPC;
goto out;
}
}
status = efivar_set_variable_locked(name, vendor, attributes, *size, status = efivar_set_variable_locked(name, vendor, attributes, *size,
data, false); data, false);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {

View file

@ -1085,9 +1085,6 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor, efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
u32 attr, unsigned long data_size, void *data); u32 attr, unsigned long data_size, void *data);
efi_status_t check_var_size(u32 attributes, unsigned long size);
efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size);
#if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER) #if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER)
extern bool efi_capsule_pending(int *reset_type); extern bool efi_capsule_pending(int *reset_type);