Skip to content

Commit d7156b9

Browse files
ardbiesheuvelbp3tk0v
authored andcommitted
x86/efistub: Clear BSS in EFI handover protocol entrypoint
The so-called EFI handover protocol is value-add from the distros that permits a loader to simply copy a PE kernel image into memory and call an alternative entrypoint that is described by an embedded boot_params structure. Most implementations of this protocol do not bother to check the PE header for minimum alignment, section placement, etc, and therefore also don't clear the image's BSS, or even allocate enough memory for it. Allocating more memory on the fly is rather difficult, but at least clear the BSS region explicitly when entering in this manner, so that the EFI stub code does not get confused by global variables that were not zero-initialized correctly. When booting in mixed mode, this BSS clearing must occur before any global state is created, so clear it in the 32-bit asm entry point. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 1279206 commit d7156b9

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

arch/x86/boot/compressed/efi_mixed.S

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,18 @@ SYM_FUNC_END(__efi64_thunk)
142142
.code32
143143
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
144144
SYM_FUNC_START(efi32_stub_entry)
145+
call 1f
146+
1: popl %ecx
147+
148+
/* Clear BSS */
149+
xorl %eax, %eax
150+
leal (_bss - 1b)(%ecx), %edi
151+
leal (_ebss - 1b)(%ecx), %ecx
152+
subl %edi, %ecx
153+
shrl $2, %ecx
154+
cld
155+
rep stosl
156+
145157
add $0x4, %esp /* Discard return address */
146158
popl %ecx
147159
popl %edx
@@ -334,7 +346,7 @@ SYM_FUNC_END(efi32_pe_entry)
334346
.org efi32_stub_entry + 0x200
335347
.code64
336348
SYM_FUNC_START_NOALIGN(efi64_stub_entry)
337-
jmp efi_stub_entry
349+
jmp efi_handover_entry
338350
SYM_FUNC_END(efi64_stub_entry)
339351
#endif
340352

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,12 +970,21 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
970970
}
971971

972972
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
973+
void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
974+
struct boot_params *boot_params)
975+
{
976+
extern char _bss[], _ebss[];
977+
978+
memset(_bss, 0, _ebss - _bss);
979+
efi_stub_entry(handle, sys_table_arg, boot_params);
980+
}
981+
973982
#ifndef CONFIG_EFI_MIXED
974-
extern __alias(efi_stub_entry)
983+
extern __alias(efi_handover_entry)
975984
void efi32_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
976985
struct boot_params *boot_params);
977986

978-
extern __alias(efi_stub_entry)
987+
extern __alias(efi_handover_entry)
979988
void efi64_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
980989
struct boot_params *boot_params);
981990
#endif

0 commit comments

Comments
 (0)