All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] efi: Ignore unrealistically large option roms
@ 2018-04-27 21:35 Hans de Goede
  2018-04-28  6:40 ` Ard Biesheuvel
  0 siblings, 1 reply; 5+ messages in thread
From: Hans de Goede @ 2018-04-27 21:35 UTC (permalink / raw)
  To: Ard Biesheuvel, Thomas Gleixner, Ingo Molnar, H . Peter Anvin
  Cc: Hans de Goede, x86, linux-efi, linux-kernel

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_64'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 256M silently ignore the
ROM fields instead of trying to alloc mem and fail.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
-Add the check to both __setup_efi_pci32 and __setup_efi_pci64 instead of
 only to __setup_efi_pci64, some CHT devices which need this still use a
 32 bit UEFI
---
 arch/x86/boot/compressed/eboot.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 47d3efff6805..6d3257a459c8 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -122,7 +122,13 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
 	if (status != EFI_SUCCESS)
 		return status;
 
-	if (!pci->romimage || !pci->romsize)
+	/*
+	 * Some firmwares 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. We reject any roms over 256M in size to catch this.
+	 */
+	if (!pci->romimage || !pci->romsize || pci->romsize > 0x10000000)
 		return EFI_INVALID_PARAMETER;
 
 	size = pci->romsize + sizeof(*rom);
@@ -230,7 +236,13 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
 	if (status != EFI_SUCCESS)
 		return status;
 
-	if (!pci->romimage || !pci->romsize)
+	/*
+	 * Some firmwares 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. We reject any roms over 256M in size to catch this.
+	 */
+	if (!pci->romimage || !pci->romsize || pci->romsize > 0x10000000)
 		return EFI_INVALID_PARAMETER;
 
 	size = pci->romsize + sizeof(*rom);
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] efi: Ignore unrealistically large option roms
  2018-04-27 21:35 [PATCH v2] efi: Ignore unrealistically large option roms Hans de Goede
@ 2018-04-28  6:40 ` Ard Biesheuvel
  2018-04-28 20:11   ` Hans de Goede
  2018-05-01 13:52   ` David Laight
  0 siblings, 2 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2018-04-28  6:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	the arch/x86 maintainers, linux-efi, Linux Kernel Mailing List

Hi Hans,

On 27 April 2018 at 23:35, Hans de Goede <hdegoede@redhat.com> wrote:
> 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_64'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 256M silently ignore the
> ROM fields instead of trying to alloc mem and fail.
>

The UEFI spec limits the size of option ROMs to 16 MiB, so I'd prefer
we use that as the upper bound instead.

With that changed,

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

or I can take it via the EFI tree if desired.

-- 
Ard.


> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v2:
> -Add the check to both __setup_efi_pci32 and __setup_efi_pci64 instead of
>  only to __setup_efi_pci64, some CHT devices which need this still use a
>  32 bit UEFI
> ---
>  arch/x86/boot/compressed/eboot.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> index 47d3efff6805..6d3257a459c8 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -122,7 +122,13 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom)
>         if (status != EFI_SUCCESS)
>                 return status;
>
> -       if (!pci->romimage || !pci->romsize)
> +       /*
> +        * Some firmwares 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. We reject any roms over 256M in size to catch this.
> +        */
> +       if (!pci->romimage || !pci->romsize || pci->romsize > 0x10000000)
>                 return EFI_INVALID_PARAMETER;
>
>         size = pci->romsize + sizeof(*rom);
> @@ -230,7 +236,13 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom)
>         if (status != EFI_SUCCESS)
>                 return status;
>
> -       if (!pci->romimage || !pci->romsize)
> +       /*
> +        * Some firmwares 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. We reject any roms over 256M in size to catch this.
> +        */
> +       if (!pci->romimage || !pci->romsize || pci->romsize > 0x10000000)
>                 return EFI_INVALID_PARAMETER;
>
>         size = pci->romsize + sizeof(*rom);
> --
> 2.16.2
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] efi: Ignore unrealistically large option roms
  2018-04-28  6:40 ` Ard Biesheuvel
@ 2018-04-28 20:11   ` Hans de Goede
  2018-05-01 13:52   ` David Laight
  1 sibling, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2018-04-28 20:11 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	the arch/x86 maintainers, linux-efi, Linux Kernel Mailing List

Hi,

On 28-04-18 08:40, Ard Biesheuvel wrote:
> Hi Hans,
> 
> On 27 April 2018 at 23:35, Hans de Goede <hdegoede@redhat.com> wrote:
>> 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_64'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 256M silently ignore the
>> ROM fields instead of trying to alloc mem and fail.
>>
> 
> The UEFI spec limits the size of option ROMs to 16 MiB, so I'd prefer
> we use that as the upper bound instead.
> 
> With that changed,
> 
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Thanks for the review, fixed for v3 which I'm about to send.

> or I can take it via the EFI tree if desired.

I've no preference for how this goes upstream. x86 folks, please let
us know if you will take this, or if you would prefer for this to
go upstream through the EFI tree.

Regards,

Hans

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH v2] efi: Ignore unrealistically large option roms
  2018-04-28  6:40 ` Ard Biesheuvel
  2018-04-28 20:11   ` Hans de Goede
@ 2018-05-01 13:52   ` David Laight
  2018-05-01 13:57     ` Ard Biesheuvel
  1 sibling, 1 reply; 5+ messages in thread
From: David Laight @ 2018-05-01 13:52 UTC (permalink / raw)
  To: 'Ard Biesheuvel', Hans de Goede
  Cc: Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	the arch/x86 maintainers, linux-efi, Linux Kernel Mailing List

From: Ard Biesheuvel
> Sent: 28 April 2018 07:41
> On 27 April 2018 at 23:35, Hans de Goede <hdegoede@redhat.com> wrote:
> > 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_64'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 256M silently ignore the
> > ROM fields instead of trying to alloc mem and fail.
> >
> 
> The UEFI spec limits the size of option ROMs to 16 MiB, so I'd prefer
> we use that as the upper bound instead.

Copying even 16MB of rom data into physical memory on the 'off chance' that
the kernel might need it seems a waste of memory.

I can't help feeling that some kind of caching would be more appropriate.

	David

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] efi: Ignore unrealistically large option roms
  2018-05-01 13:52   ` David Laight
@ 2018-05-01 13:57     ` Ard Biesheuvel
  0 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2018-05-01 13:57 UTC (permalink / raw)
  To: David Laight
  Cc: Hans de Goede, Thomas Gleixner, Ingo Molnar, H . Peter Anvin,
	the arch/x86 maintainers, linux-efi, Linux Kernel Mailing List

On 1 May 2018 at 15:52, David Laight <David.Laight@aculab.com> wrote:
> From: Ard Biesheuvel
>> Sent: 28 April 2018 07:41
>> On 27 April 2018 at 23:35, Hans de Goede <hdegoede@redhat.com> wrote:
>> > 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_64'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 256M silently ignore the
>> > ROM fields instead of trying to alloc mem and fail.
>> >
>>
>> The UEFI spec limits the size of option ROMs to 16 MiB, so I'd prefer
>> we use that as the upper bound instead.
>
> Copying even 16MB of rom data into physical memory on the 'off chance' that
> the kernel might need it seems a waste of memory.
>

16 MB is the smallest number we can use that still guarantees that we
will not misidentify a valid option ROM as bogus. But in reality,
option ROMs are rarely that large.

> I can't help feeling that some kind of caching would be more appropriate.
>

Could you elaborate?

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-05-01 13:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-27 21:35 [PATCH v2] efi: Ignore unrealistically large option roms Hans de Goede
2018-04-28  6:40 ` Ard Biesheuvel
2018-04-28 20:11   ` Hans de Goede
2018-05-01 13:52   ` David Laight
2018-05-01 13:57     ` Ard Biesheuvel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.