Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Ard Biesheuvel and committed by
Borislav Petkov (AMD)
11078876 cb1c9e02

+21 -8
+21 -8
drivers/firmware/efi/libstub/x86-stub.c
··· 26 26 const efi_dxe_services_table_t *efi_dxe_table; 27 27 u32 image_offset __section(".data"); 28 28 static efi_loaded_image_t *image = NULL; 29 + static efi_memory_attribute_protocol_t *memattr; 29 30 30 31 typedef union sev_memory_acceptance_protocol sev_memory_acceptance_protocol_t; 31 32 union sev_memory_acceptance_protocol { ··· 234 233 unsigned long rounded_start, rounded_end; 235 234 unsigned long unprotect_start, unprotect_size; 236 235 237 - if (efi_dxe_table == NULL) 238 - return; 239 - 240 236 rounded_start = rounddown(start, EFI_PAGE_SIZE); 241 237 rounded_end = roundup(start + size, EFI_PAGE_SIZE); 238 + 239 + if (memattr != NULL) { 240 + efi_call_proto(memattr, clear_memory_attributes, rounded_start, 241 + rounded_end - rounded_start, EFI_MEMORY_XP); 242 + return; 243 + } 244 + 245 + if (efi_dxe_table == NULL) 246 + return; 242 247 243 248 /* 244 249 * Don't modify memory region attributes, they are ··· 808 801 efi_system_table_t *sys_table_arg, 809 802 struct boot_params *boot_params) 810 803 { 804 + efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; 811 805 unsigned long bzimage_addr = (unsigned long)startup_32; 812 806 unsigned long buffer_start, buffer_end; 813 807 struct setup_header *hdr = &boot_params->hdr; ··· 820 812 if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 821 813 efi_exit(handle, EFI_INVALID_PARAMETER); 822 814 823 - efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); 824 - if (efi_dxe_table && 825 - efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { 826 - efi_warn("Ignoring DXE services table: invalid signature\n"); 827 - efi_dxe_table = NULL; 815 + if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) { 816 + efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); 817 + if (efi_dxe_table && 818 + efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { 819 + efi_warn("Ignoring DXE services table: invalid signature\n"); 820 + efi_dxe_table = NULL; 821 + } 828 822 } 823 + 824 + /* grab the memory attributes protocol if it exists */ 825 + efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr); 829 826 830 827 status = efi_setup_5level_paging(); 831 828 if (status != EFI_SUCCESS) {