Commit 1de3a1be authored by Hans de Goede's avatar Hans de Goede Committed by Ingo Molnar

efi/x86: Ignore unrealistically large option ROMs

setup_efi_pci() tries to save a copy of each PCI option ROM as this may
be necessary for the device driver for the PCI device to have access too.

On some systems the efi_pci_io_protocol's romimage and romsize fields
contain invalid data, which looks a bit like pointers pointing back into
other EFI code or data. Interpreting these pointers as romsize leads to
a very large value and if we then try to alloc this amount of memory to
save a copy the alloc call fails.

This leads to a "Failed to alloc mem for rom" error being printed on the
EFI console for each PCI device.

This commit avoids the printing of these errors, by checking romsize before
doing the alloc and if it is larger then the EFI spec limit of 16 MiB
silently ignore the ROM fields instead of trying to alloc mem and fail.
Tested-by: default avatarHans de Goede <hdegoede@redhat.com>
[ardb: deduplicate 32/64 bit changes, use SZ_16M symbolic constant]
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20180504060003.19618-16-ard.biesheuvel@linaro.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 2c3625cb
...@@ -123,10 +123,17 @@ __setup_efi_pci(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) ...@@ -123,10 +123,17 @@ __setup_efi_pci(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
/*
* Some firmware images contain EFI function pointers at the place where the
* romimage and romsize fields are supposed to be. Typically the EFI
* code is mapped at high addresses, translating to an unrealistically
* large romsize. The UEFI spec limits the size of option ROMs to 16
* MiB so we reject any ROMs over 16 MiB in size to catch this.
*/
romimage = (void *)(unsigned long)efi_table_attr(efi_pci_io_protocol, romimage = (void *)(unsigned long)efi_table_attr(efi_pci_io_protocol,
romimage, pci); romimage, pci);
romsize = efi_table_attr(efi_pci_io_protocol, romsize, pci); romsize = efi_table_attr(efi_pci_io_protocol, romsize, pci);
if (!romimage || !romsize) if (!romimage || !romsize || romsize > SZ_16M)
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
size = romsize + sizeof(*rom); size = romsize + sizeof(*rom);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment