From: Ard Biesheuvel ardb@kernel.org
commit 63bf28ceb3ebbe76048c3fb2987996ca1ae64f83 upstream.
When booting the x86 kernel via EFI using the LoadImage/StartImage boot services [as opposed to the deprecated EFI handover protocol], the setup header is taken from the image directly, and given that EFI's LoadImage has no Linux/x86 specific knowledge regarding struct bootparams or struct setup_header, any absolute addresses in the setup header must originate from the file and not from a prior loading stage.
Since we cannot generally predict where LoadImage() decides to load an image (*), such absolute addresses must be treated as suspect: even if a prior boot stage intended to make them point somewhere inside the [signed] image, there is no way to validate that, and if they point at an arbitrary location in memory, the setup_data nodes will not be covered by any signatures or TPM measurements either, and could be made to contain an arbitrary sequence of SETUP_xxx nodes, which could interfere quite badly with the early x86 boot sequence.
(*) Note that, while LoadImage() does take a buffer/size tuple in addition to a device path, which can be used to provide the image contents directly, it will re-allocate such images, as the memory footprint of an image is generally larger than the PE/COFF file representation.
Cc: stable@vger.kernel.org # v5.10+ Link: https://lore.kernel.org/all/20220904165321.1140894-1-Jason@zx2c4.com/ Signed-off-by: Ard Biesheuvel ardb@kernel.org Acked-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/firmware/efi/libstub/x86-stub.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -414,6 +414,13 @@ efi_status_t __efiapi efi_pe_entry(efi_h hdr->ramdisk_image = 0; hdr->ramdisk_size = 0;
+ /* + * Disregard any setup data that was provided by the bootloader: + * setup_data could be pointing anywhere, and we have no way of + * authenticating or validating the payload. + */ + hdr->setup_data = 0; + efi_stub_entry(handle, sys_table_arg, boot_params); /* not reached */