@@ -137,12 +137,6 @@ SYM_FUNC_START(startup_32)
jmp *%eax
SYM_FUNC_END(startup_32)
-#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
-SYM_FUNC_START(efi32_stub_entry)
- jmp efi_main
-SYM_FUNC_END(efi32_stub_entry)
-#endif
-
.text
SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
@@ -458,7 +458,7 @@ SYM_CODE_END(startup_64)
.org 0x390
SYM_FUNC_START(efi64_stub_entry)
and $~0xf, %rsp /* realign the stack */
- call efi_main
+ call efi_handover_entry
SYM_FUNC_END(efi64_stub_entry)
#endif
@@ -891,9 +891,9 @@ static void __noreturn enter_kernel(unsigned long kernel_addr,
* On success, we jump to the relocated kernel directly and never return.
* On failure, we exit to the firmware via efi_exit instead of returning.
*/
-asmlinkage void __noreturn efi_main(efi_handle_t handle,
- efi_system_table_t *sys_table_arg,
- struct boot_params *boot_params)
+static void __noreturn efi_main(efi_handle_t handle,
+ efi_system_table_t *sys_table_arg,
+ struct boot_params *boot_params)
{
efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
struct setup_header *hdr = &boot_params->hdr;
@@ -1002,3 +1002,21 @@ asmlinkage void __noreturn efi_main(efi_handle_t handle,
efi_exit(handle, status);
}
+
+#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
+void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
+ struct boot_params *boot_params)
+{
+ extern char _bss[], _ebss[];
+
+ /* Ensure that BSS is zeroed when booting via the handover protocol */
+ memset(_bss, 0, _ebss - _bss);
+ efi_main(handle, sys_table_arg, boot_params);
+}
+
+#ifdef CONFIG_X86_32
+extern __alias(efi_handover_entry)
+void efi32_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
+ struct boot_params *boot_params);
+#endif
+#endif
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 let's at least clear the BSS explicitly when entering in this manner, so that the decompressor's pseudo-malloc() does not get confused by global variables that were not zero-initialized correctly. Note that we shouldn't clear BSS before calling efi_main() if we are not booting via the handover protocol, but this entrypoint is no longer shared with the pure EFI entrypoint so we can ignore that case here. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- arch/x86/boot/compressed/head_32.S | 6 ----- arch/x86/boot/compressed/head_64.S | 2 +- drivers/firmware/efi/libstub/x86-stub.c | 24 +++++++++++++++++--- 3 files changed, 22 insertions(+), 10 deletions(-)