Skip to content

Commit 7e50262

Browse files
ardbiesheuvelIngo Molnar
authored and
Ingo Molnar
committed
x86/efi: Disregard setup header of loaded image
The native EFI entrypoint does not take a struct boot_params from the loader, but instead, it constructs one from scratch, using the setup header data placed at the start of the image. This setup header is placed in a way that permits legacy loaders to manipulate the contents (i.e., to pass the kernel command line or the address and size of an initial ramdisk), but EFI boot does not use it in that way - it only copies the contents that were placed there at build time, but EFI loaders will not (and should not) manipulate the setup header to configure the boot. (Commit 63bf28c "efi: x86: Wipe setup_data on pure EFI boot" deals with some of the fallout of using setup_data in a way that breaks EFI boot.) Given that none of the non-zero values that are copied from the setup header into the EFI stub's struct boot_params are relevant to the boot now that the EFI stub no longer enters via the legacy decompressor, the copy can be omitted altogether. Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5f51c5d commit 7e50262

File tree

1 file changed

+6
-40
lines changed

1 file changed

+6
-40
lines changed

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

+6-40
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,8 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
449449
efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
450450
efi_system_table_t *sys_table_arg)
451451
{
452-
struct boot_params *boot_params;
453-
struct setup_header *hdr;
454-
void *image_base;
452+
static struct boot_params boot_params __page_aligned_bss;
453+
struct setup_header *hdr = &boot_params.hdr;
455454
efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
456455
int options_size = 0;
457456
efi_status_t status;
@@ -469,30 +468,9 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
469468
efi_exit(handle, status);
470469
}
471470

472-
image_base = efi_table_attr(image, image_base);
473-
474-
status = efi_allocate_pages(sizeof(struct boot_params),
475-
(unsigned long *)&boot_params, ULONG_MAX);
476-
if (status != EFI_SUCCESS) {
477-
efi_err("Failed to allocate lowmem for boot params\n");
478-
efi_exit(handle, status);
479-
}
480-
481-
memset(boot_params, 0x0, sizeof(struct boot_params));
482-
483-
hdr = &boot_params->hdr;
484-
485-
/* Copy the setup header from the second sector to boot_params */
486-
memcpy(&hdr->jump, image_base + 512,
487-
sizeof(struct setup_header) - offsetof(struct setup_header, jump));
488-
489-
/*
490-
* Fill out some of the header fields ourselves because the
491-
* EFI firmware loader doesn't load the first sector.
492-
*/
471+
/* Assign the setup_header fields that the kernel actually cares about */
493472
hdr->root_flags = 1;
494473
hdr->vid_mode = 0xffff;
495-
hdr->boot_flag = 0xAA55;
496474

497475
hdr->type_of_loader = 0x21;
498476

@@ -501,25 +479,13 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
501479
if (!cmdline_ptr)
502480
goto fail;
503481

504-
efi_set_u64_split((unsigned long)cmdline_ptr,
505-
&hdr->cmd_line_ptr, &boot_params->ext_cmd_line_ptr);
506-
507-
hdr->ramdisk_image = 0;
508-
hdr->ramdisk_size = 0;
509-
510-
/*
511-
* Disregard any setup data that was provided by the bootloader:
512-
* setup_data could be pointing anywhere, and we have no way of
513-
* authenticating or validating the payload.
514-
*/
515-
hdr->setup_data = 0;
482+
efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr,
483+
&boot_params.ext_cmd_line_ptr);
516484

517-
efi_stub_entry(handle, sys_table_arg, boot_params);
485+
efi_stub_entry(handle, sys_table_arg, &boot_params);
518486
/* not reached */
519487

520488
fail:
521-
efi_free(sizeof(struct boot_params), (unsigned long)boot_params);
522-
523489
efi_exit(handle, status);
524490
}
525491

0 commit comments

Comments
 (0)