Skip to content

Commit 1107887

Browse files
ardbiesheuvelbp3tk0v
authored andcommitted
x86/efistub: Prefer EFI memory attributes protocol over DXE services
Currently, the EFI stub relies on DXE services in some cases to clear non-execute restrictions from page allocations that need to be executable. This is dodgy, because DXE services are not specified by UEFI but by PI, and they are not intended for consumption by OS loaders. However, no alternative existed at the time. Now, there is a new UEFI protocol that should be used instead, so if it exists, prefer it over the DXE services calls. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Link: https://lore.kernel.org/r/20230807162720.545787-18-ardb@kernel.org
1 parent cb1c9e0 commit 1107887

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

drivers/firmware/efi/libstub/x86-stub.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const efi_system_table_t *efi_system_table;
2626
const efi_dxe_services_table_t *efi_dxe_table;
2727
u32 image_offset __section(".data");
2828
static efi_loaded_image_t *image = NULL;
29+
static efi_memory_attribute_protocol_t *memattr;
2930

3031
typedef union sev_memory_acceptance_protocol sev_memory_acceptance_protocol_t;
3132
union sev_memory_acceptance_protocol {
@@ -233,12 +234,18 @@ void efi_adjust_memory_range_protection(unsigned long start,
233234
unsigned long rounded_start, rounded_end;
234235
unsigned long unprotect_start, unprotect_size;
235236

236-
if (efi_dxe_table == NULL)
237-
return;
238-
239237
rounded_start = rounddown(start, EFI_PAGE_SIZE);
240238
rounded_end = roundup(start + size, EFI_PAGE_SIZE);
241239

240+
if (memattr != NULL) {
241+
efi_call_proto(memattr, clear_memory_attributes, rounded_start,
242+
rounded_end - rounded_start, EFI_MEMORY_XP);
243+
return;
244+
}
245+
246+
if (efi_dxe_table == NULL)
247+
return;
248+
242249
/*
243250
* Don't modify memory region attributes, they are
244251
* already suitable, to lower the possibility to
@@ -801,6 +808,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
801808
efi_system_table_t *sys_table_arg,
802809
struct boot_params *boot_params)
803810
{
811+
efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
804812
unsigned long bzimage_addr = (unsigned long)startup_32;
805813
unsigned long buffer_start, buffer_end;
806814
struct setup_header *hdr = &boot_params->hdr;
@@ -812,13 +820,18 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
812820
if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
813821
efi_exit(handle, EFI_INVALID_PARAMETER);
814822

815-
efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID);
816-
if (efi_dxe_table &&
817-
efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) {
818-
efi_warn("Ignoring DXE services table: invalid signature\n");
819-
efi_dxe_table = NULL;
823+
if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) {
824+
efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID);
825+
if (efi_dxe_table &&
826+
efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) {
827+
efi_warn("Ignoring DXE services table: invalid signature\n");
828+
efi_dxe_table = NULL;
829+
}
820830
}
821831

832+
/* grab the memory attributes protocol if it exists */
833+
efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr);
834+
822835
status = efi_setup_5level_paging();
823836
if (status != EFI_SUCCESS) {
824837
efi_err("efi_setup_5level_paging() failed!\n");

0 commit comments

Comments
 (0)