* [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot
@ 2023-08-07 12:21 Ard Biesheuvel
2023-08-08 15:33 ` Dimitri John Ledkov
0 siblings, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2023-08-07 12:21 UTC (permalink / raw)
To: grub-devel
Cc: Ard Biesheuvel, Daniel Kiper, Steve McIntyre, Julian Andres Klode
Recent mixed-mode Linux kernels (i.e., v4.0 or newer) can access EFI
runtime services at OS runtime even when the OS was not entered via the
EFI stub. This is because, instead of reverting back to the firmware's
segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit
runtime services using compatilibity mode (i.e., the same mode used for
32-bit user space) without taking down all interrupt handling, exception
handling etc.
This means that GRUB's legacy x86 boot mode is sufficient to make use of
this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI
enlightened mode (but without going via the EFI stub), and provide all
the metadata that the OS needs to map the EFI runtime regions and call
EFI runtime services successfully.
It does mean that GRUB should not attempt to invoke the firmware's
LoadImage/StartImage methods on kernel builds that it knows cannot be
started natively. So add a check for this in the native EFI boot path,
and fall back to legacy x86 mode in such cases.
Note that in the general case, booting non-native images of the same
native word size (e.g., X64 EFI apps on arm64 firmware) might be
supported by means of emulation, so let's only disallow images that use
a non-native word size. This will also permit booting i686 kernels on
x86_64 builds, although without access to runtime services, as this is
not supported by Linux.
This change on top of 2.12-rc1 is sufficient to boot ordinary Linux
mixed mode builds and get full access to the EFI runtime services.
Cc: Daniel Kiper <daniel.kiper@oracle.com>
Cc: Steve McIntyre <steve@einval.com>
Cc: Julian Andres Klode <julian.klode@canonical.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
grub-core/loader/efi/linux.c | 5 +++++
include/grub/efi/pe32.h | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index ed325f2b0aae2d6f..1d0734e295043df7 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -120,6 +120,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
}
+ if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC)
+ {
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported");
+ }
+
/*
* Linux kernels built for any architecture are guaranteed to support the
* LoadFile2 based initrd loading protocol if the image version is >= 1.
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 101859af1ea64237..4e6e9d254bd35c9b 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -267,6 +267,12 @@ struct grub_pe32_section_table
#define GRUB_PE32_SIGNATURE_SIZE 4
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC
+#else
+#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC
+#endif
+
struct grub_pe_image_header
{
/* This is always PE\0\0. */
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot
2023-08-07 12:21 [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot Ard Biesheuvel
@ 2023-08-08 15:33 ` Dimitri John Ledkov
2023-08-08 16:27 ` Ard Biesheuvel
0 siblings, 1 reply; 5+ messages in thread
From: Dimitri John Ledkov @ 2023-08-08 15:33 UTC (permalink / raw)
To: The development of GNU GRUB
Cc: Ard Biesheuvel, Daniel Kiper, Steve McIntyre, Julian Andres Klode
On Mon, 7 Aug 2023, 13:23 Ard Biesheuvel, <ardb@kernel.org> wrote:
>
> Recent mixed-mode Linux kernels (i.e., v4.0 or newer) can access EFI
> runtime services at OS runtime even when the OS was not entered via the
> EFI stub. This is because, instead of reverting back to the firmware's
> segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit
> runtime services using compatilibity mode (i.e., the same mode used for
> 32-bit user space) without taking down all interrupt handling, exception
> handling etc.
>
> This means that GRUB's legacy x86 boot mode is sufficient to make use of
> this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI
> enlightened mode (but without going via the EFI stub), and provide all
> the metadata that the OS needs to map the EFI runtime regions and call
> EFI runtime services successfully.
I'm not sure I understand the target combination here, and I'm not
sure we want to support it.
For now, we keep shipping both 32bit and 64bit x86 revocations
together. However, the time will come that we will want or need to
drop the 32bit revocations. Ubuntu has never signed a 32bit build of
grub for secureboot, nor have we ever signed 32bit kernels to boot
either. Most distributions have also stopped 32bit x86 builds, and/or
don't support them to the same feature level (there are some that
enable lots of combinations, i.e. debian, but even there i am not sure
such hardware exists).
I see this as a bug that 32-bit i686 build of Grub can launch 64-bit
kernels - potentially without using shim / shim-lock / sbat
verification.
I would feel much better if under shim-lock/secureboot only matching
bitness was allowed to be booted and supported. Meaning no mixing &
matching i686 grub builds launching x86_64 kernels, or vice versa, and
ditoo on any other arches too (i.e. no mixing between
riscv32/riscv64/riscv128, nor armhf/arm64).
I am impressed it is technologically possible, but do we really want
to implement/design/support/encourage that?
I'm not even sure if 32-bit x86 EFI grub platform even makes sense
anymore, and maybe it should be ripped out altogether? and leave i686
boot to pc-bios only. i686 EFI was a short lived experiment that died
without ever taking off.
>
> It does mean that GRUB should not attempt to invoke the firmware's
> LoadImage/StartImage methods on kernel builds that it knows cannot be
> started natively. So add a check for this in the native EFI boot path,
> and fall back to legacy x86 mode in such cases.
>
> Note that in the general case, booting non-native images of the same
> native word size (e.g., X64 EFI apps on arm64 firmware) might be
> supported by means of emulation, so let's only disallow images that use
> a non-native word size. This will also permit booting i686 kernels on
> x86_64 builds, although without access to runtime services, as this is
> not supported by Linux.
>
> This change on top of 2.12-rc1 is sufficient to boot ordinary Linux
> mixed mode builds and get full access to the EFI runtime services.
>
> Cc: Daniel Kiper <daniel.kiper@oracle.com>
> Cc: Steve McIntyre <steve@einval.com>
> Cc: Julian Andres Klode <julian.klode@canonical.com>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> grub-core/loader/efi/linux.c | 5 +++++
> include/grub/efi/pe32.h | 6 ++++++
> 2 files changed, 11 insertions(+)
>
> diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> index ed325f2b0aae2d6f..1d0734e295043df7 100644
> --- a/grub-core/loader/efi/linux.c
> +++ b/grub-core/loader/efi/linux.c
> @@ -120,6 +120,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
> return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
> }
>
> + if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC)
> + {
> + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported");
> + }
> +
> /*
> * Linux kernels built for any architecture are guaranteed to support the
> * LoadFile2 based initrd loading protocol if the image version is >= 1.
> diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
> index 101859af1ea64237..4e6e9d254bd35c9b 100644
> --- a/include/grub/efi/pe32.h
> +++ b/include/grub/efi/pe32.h
> @@ -267,6 +267,12 @@ struct grub_pe32_section_table
>
> #define GRUB_PE32_SIGNATURE_SIZE 4
>
> +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC
> +#else
> +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC
> +#endif
> +
> struct grub_pe_image_header
> {
> /* This is always PE\0\0. */
> --
> 2.39.2
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot
2023-08-08 15:33 ` Dimitri John Ledkov
@ 2023-08-08 16:27 ` Ard Biesheuvel
2023-08-08 16:42 ` Dimitri John Ledkov
0 siblings, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2023-08-08 16:27 UTC (permalink / raw)
To: Dimitri John Ledkov
Cc: The development of GNU GRUB, Daniel Kiper, Steve McIntyre,
Julian Andres Klode
On Tue, 8 Aug 2023 at 17:34, Dimitri John Ledkov
<dimitri.ledkov@canonical.com> wrote:
>
> On Mon, 7 Aug 2023, 13:23 Ard Biesheuvel, <ardb@kernel.org> wrote:
> >
> > Recent mixed-mode Linux kernels (i.e., v4.0 or newer) can access EFI
> > runtime services at OS runtime even when the OS was not entered via the
> > EFI stub. This is because, instead of reverting back to the firmware's
> > segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit
> > runtime services using compatilibity mode (i.e., the same mode used for
> > 32-bit user space) without taking down all interrupt handling, exception
> > handling etc.
> >
> > This means that GRUB's legacy x86 boot mode is sufficient to make use of
> > this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI
> > enlightened mode (but without going via the EFI stub), and provide all
> > the metadata that the OS needs to map the EFI runtime regions and call
> > EFI runtime services successfully.
>
> I'm not sure I understand the target combination here, and I'm not
> sure we want to support it.
>
The point is not what we /want/ to support - it is what we already
supported in the past, and the recent EFI changes result in
regressions for those scenarios.
> For now, we keep shipping both 32bit and 64bit x86 revocations
> together. However, the time will come that we will want or need to
> drop the 32bit revocations. Ubuntu has never signed a 32bit build of
> grub for secureboot, nor have we ever signed 32bit kernels to boot
> either. Most distributions have also stopped 32bit x86 builds, and/or
> don't support them to the same feature level (there are some that
> enable lots of combinations, i.e. debian, but even there i am not sure
> such hardware exists).
>
> I see this as a bug that 32-bit i686 build of Grub can launch 64-bit
> kernels - potentially without using shim / shim-lock / sbat
> verification.
>
A 32-bit *EFI* build of GRUB, which you will never be able to boot on
anything other than 32-bit EFI, i.e., systems that nobody cares about
wrt secure boot.
> I would feel much better if under shim-lock/secureboot only matching
> bitness was allowed to be booted and supported. Meaning no mixing &
> matching i686 grub builds launching x86_64 kernels, or vice versa, and
> ditoo on any other arches too (i.e. no mixing between
> riscv32/riscv64/riscv128, nor armhf/arm64).
>
AFAICT, the non-EFIstub x86 boot path in GRUB has always supported
booting kernels of any bitness (provided, of course, that the CPU is
long mode capable)
With adding the EFI support, we broke this which may potentially harm users.
> I am impressed it is technologically possible, but do we really want
> to implement/design/support/encourage that?
>
Distros already do, that is the whole point. It is called mixed mode,
and it is something I am trying to get rid of.
The current mixed-mode implementation has elaborate plumbing so that
the 64-bit EFI stub can make use of 32-bit boot services. This was
presented to me in the past as a prerequisite for being able to
support mixed mode (and therefore a justification for upstreaming the
EFI handover protocol). However, I realized that the current mixed
mode support in Linux does not actually rely on this: the only thing
you need is a bootloader that implements the x86 Linux boot protocol
directly but also passes EFI memory map, system table, etc. GRUB
already did this. IOW, mainline i386-efi GRUB already supported mixed
mode, and the recent EFI changes broke that.
> I'm not even sure if 32-bit x86 EFI grub platform even makes sense
> anymore, and maybe it should be ripped out altogether? and leave i686
> boot to pc-bios only. i686 EFI was a short lived experiment that died
> without ever taking off.
>
Not for mixed-mode - i.e., 'netbooks' with 64-bit Atom CPUs that
shipped with 32-bit Windows and therefore 32-bit EFI. Not sure how
many are still in circulation running Linux.
Ideally, we'd drop this altogether. However, by making this change,
which is arguably a regression fix, we can phase out the EFI stub part
of mixed mode, and only retain the EFI runtime support.
> >
> > It does mean that GRUB should not attempt to invoke the firmware's
> > LoadImage/StartImage methods on kernel builds that it knows cannot be
> > started natively. So add a check for this in the native EFI boot path,
> > and fall back to legacy x86 mode in such cases.
> >
> > Note that in the general case, booting non-native images of the same
> > native word size (e.g., X64 EFI apps on arm64 firmware) might be
> > supported by means of emulation, so let's only disallow images that use
> > a non-native word size. This will also permit booting i686 kernels on
> > x86_64 builds, although without access to runtime services, as this is
> > not supported by Linux.
> >
> > This change on top of 2.12-rc1 is sufficient to boot ordinary Linux
> > mixed mode builds and get full access to the EFI runtime services.
> >
> > Cc: Daniel Kiper <daniel.kiper@oracle.com>
> > Cc: Steve McIntyre <steve@einval.com>
> > Cc: Julian Andres Klode <julian.klode@canonical.com>
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > ---
> > grub-core/loader/efi/linux.c | 5 +++++
> > include/grub/efi/pe32.h | 6 ++++++
> > 2 files changed, 11 insertions(+)
> >
> > diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> > index ed325f2b0aae2d6f..1d0734e295043df7 100644
> > --- a/grub-core/loader/efi/linux.c
> > +++ b/grub-core/loader/efi/linux.c
> > @@ -120,6 +120,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
> > return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
> > }
> >
> > + if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC)
> > + {
> > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported");
> > + }
> > +
> > /*
> > * Linux kernels built for any architecture are guaranteed to support the
> > * LoadFile2 based initrd loading protocol if the image version is >= 1.
> > diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
> > index 101859af1ea64237..4e6e9d254bd35c9b 100644
> > --- a/include/grub/efi/pe32.h
> > +++ b/include/grub/efi/pe32.h
> > @@ -267,6 +267,12 @@ struct grub_pe32_section_table
> >
> > #define GRUB_PE32_SIGNATURE_SIZE 4
> >
> > +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> > +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC
> > +#else
> > +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC
> > +#endif
> > +
> > struct grub_pe_image_header
> > {
> > /* This is always PE\0\0. */
> > --
> > 2.39.2
> >
> >
> > _______________________________________________
> > Grub-devel mailing list
> > Grub-devel@gnu.org
> > https://lists.gnu.org/mailman/listinfo/grub-devel
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot
2023-08-08 16:27 ` Ard Biesheuvel
@ 2023-08-08 16:42 ` Dimitri John Ledkov
2023-09-14 16:09 ` Daniel Kiper
0 siblings, 1 reply; 5+ messages in thread
From: Dimitri John Ledkov @ 2023-08-08 16:42 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: The development of GNU GRUB, Daniel Kiper, Steve McIntyre,
Julian Andres Klode
#include ascii art of can of worms here
On Tue, 8 Aug 2023 at 17:27, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Tue, 8 Aug 2023 at 17:34, Dimitri John Ledkov
> <dimitri.ledkov@canonical.com> wrote:
> >
> > On Mon, 7 Aug 2023, 13:23 Ard Biesheuvel, <ardb@kernel.org> wrote:
> > >
> > > Recent mixed-mode Linux kernels (i.e., v4.0 or newer) can access EFI
> > > runtime services at OS runtime even when the OS was not entered via the
> > > EFI stub. This is because, instead of reverting back to the firmware's
> > > segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit
> > > runtime services using compatilibity mode (i.e., the same mode used for
> > > 32-bit user space) without taking down all interrupt handling, exception
> > > handling etc.
> > >
> > > This means that GRUB's legacy x86 boot mode is sufficient to make use of
> > > this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI
> > > enlightened mode (but without going via the EFI stub), and provide all
> > > the metadata that the OS needs to map the EFI runtime regions and call
> > > EFI runtime services successfully.
> >
> > I'm not sure I understand the target combination here, and I'm not
> > sure we want to support it.
> >
>
> The point is not what we /want/ to support - it is what we already
> supported in the past, and the recent EFI changes result in
> regressions for those scenarios.
>
> > For now, we keep shipping both 32bit and 64bit x86 revocations
> > together. However, the time will come that we will want or need to
> > drop the 32bit revocations. Ubuntu has never signed a 32bit build of
> > grub for secureboot, nor have we ever signed 32bit kernels to boot
> > either. Most distributions have also stopped 32bit x86 builds, and/or
> > don't support them to the same feature level (there are some that
> > enable lots of combinations, i.e. debian, but even there i am not sure
> > such hardware exists).
> >
> > I see this as a bug that 32-bit i686 build of Grub can launch 64-bit
> > kernels - potentially without using shim / shim-lock / sbat
> > verification.
> >
>
> A 32-bit *EFI* build of GRUB, which you will never be able to boot on
> anything other than 32-bit EFI, i.e., systems that nobody cares about
> wrt secure boot.
>
> > I would feel much better if under shim-lock/secureboot only matching
> > bitness was allowed to be booted and supported. Meaning no mixing &
> > matching i686 grub builds launching x86_64 kernels, or vice versa, and
> > ditoo on any other arches too (i.e. no mixing between
> > riscv32/riscv64/riscv128, nor armhf/arm64).
> >
>
> AFAICT, the non-EFIstub x86 boot path in GRUB has always supported
> booting kernels of any bitness (provided, of course, that the CPU is
> long mode capable)
>
> With adding the EFI support, we broke this which may potentially harm users.
>
> > I am impressed it is technologically possible, but do we really want
> > to implement/design/support/encourage that?
> >
>
> Distros already do, that is the whole point. It is called mixed mode,
> and it is something I am trying to get rid of.
>
> The current mixed-mode implementation has elaborate plumbing so that
> the 64-bit EFI stub can make use of 32-bit boot services. This was
> presented to me in the past as a prerequisite for being able to
> support mixed mode (and therefore a justification for upstreaming the
> EFI handover protocol).
I believe the only platform that shipped that out of the box, most
recently was https://www.minnowboard.org/
It had an alternative 64-bit boot service firmware download file,
which most people did flash and use, but out of the factory it was
shipped in 32-bit boot services mode, and yet expected to
boot/load/run 64-bit kernels.
Conveniently it wasn't too popular, was taken off the market
https://www.silicom-usa.com/wp-content/uploads/2020/07/EOL_MinnowBoard-Turbot.pdf
on 27th of July 2020, with all support & warranty for it seizing two
weeks ago. Thus I can see why there was a strong push in the past to
keep this commercial failure still working, as it was still shipping.
> However, I realized that the current mixed
> mode support in Linux does not actually rely on this: the only thing
> you need is a bootloader that implements the x86 Linux boot protocol
> directly but also passes EFI memory map, system table, etc. GRUB
> already did this. IOW, mainline i386-efi GRUB already supported mixed
> mode, and the recent EFI changes broke that.
>
> > I'm not even sure if 32-bit x86 EFI grub platform even makes sense
> > anymore, and maybe it should be ripped out altogether? and leave i686
> > boot to pc-bios only. i686 EFI was a short lived experiment that died
> > without ever taking off.
> >
>
> Not for mixed-mode - i.e., 'netbooks' with 64-bit Atom CPUs that
> shipped with 32-bit Windows and therefore 32-bit EFI. Not sure how
> many are still in circulation running Linux.
>
> Ideally, we'd drop this altogether. However, by making this change,
> which is arguably a regression fix, we can phase out the EFI stub part
> of mixed mode, and only retain the EFI runtime support.
>
Sure, land this fix, and then later we will rip it all out. We have to
start dropping platforms from grub, freezing them in time, as museum
pieces support code.
> > >
> > > It does mean that GRUB should not attempt to invoke the firmware's
> > > LoadImage/StartImage methods on kernel builds that it knows cannot be
> > > started natively. So add a check for this in the native EFI boot path,
> > > and fall back to legacy x86 mode in such cases.
> > >
> > > Note that in the general case, booting non-native images of the same
> > > native word size (e.g., X64 EFI apps on arm64 firmware) might be
> > > supported by means of emulation, so let's only disallow images that use
> > > a non-native word size. This will also permit booting i686 kernels on
> > > x86_64 builds, although without access to runtime services, as this is
> > > not supported by Linux.
> > >
> > > This change on top of 2.12-rc1 is sufficient to boot ordinary Linux
> > > mixed mode builds and get full access to the EFI runtime services.
> > >
> > > Cc: Daniel Kiper <daniel.kiper@oracle.com>
> > > Cc: Steve McIntyre <steve@einval.com>
> > > Cc: Julian Andres Klode <julian.klode@canonical.com>
> > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > > ---
> > > grub-core/loader/efi/linux.c | 5 +++++
> > > include/grub/efi/pe32.h | 6 ++++++
> > > 2 files changed, 11 insertions(+)
> > >
> > > diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> > > index ed325f2b0aae2d6f..1d0734e295043df7 100644
> > > --- a/grub-core/loader/efi/linux.c
> > > +++ b/grub-core/loader/efi/linux.c
> > > @@ -120,6 +120,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
> > > return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
> > > }
> > >
> > > + if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC)
> > > + {
> > > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported");
> > > + }
> > > +
> > > /*
> > > * Linux kernels built for any architecture are guaranteed to support the
> > > * LoadFile2 based initrd loading protocol if the image version is >= 1.
> > > diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
> > > index 101859af1ea64237..4e6e9d254bd35c9b 100644
> > > --- a/include/grub/efi/pe32.h
> > > +++ b/include/grub/efi/pe32.h
> > > @@ -267,6 +267,12 @@ struct grub_pe32_section_table
> > >
> > > #define GRUB_PE32_SIGNATURE_SIZE 4
> > >
> > > +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> > > +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC
> > > +#else
> > > +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC
> > > +#endif
> > > +
Acked-by: Dimitri John Ledkov <dimitri.ledkov@canonical.com>
> > > struct grub_pe_image_header
> > > {
> > > /* This is always PE\0\0. */
> > > --
> > > 2.39.2
> > >
> > >
> > > _______________________________________________
> > > Grub-devel mailing list
> > > Grub-devel@gnu.org
> > > https://lists.gnu.org/mailman/listinfo/grub-devel
--
okurrr,
Dimitri
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot
2023-08-08 16:42 ` Dimitri John Ledkov
@ 2023-09-14 16:09 ` Daniel Kiper
0 siblings, 0 replies; 5+ messages in thread
From: Daniel Kiper @ 2023-09-14 16:09 UTC (permalink / raw)
To: Dimitri John Ledkov
Cc: Ard Biesheuvel, The development of GNU GRUB, Daniel Kiper,
Steve McIntyre, Julian Andres Klode
On Tue, Aug 08, 2023 at 05:42:57PM +0100, Dimitri John Ledkov wrote:
> #include ascii art of can of worms here
:-)
> On Tue, 8 Aug 2023 at 17:27, Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Tue, 8 Aug 2023 at 17:34, Dimitri John Ledkov
> > <dimitri.ledkov@canonical.com> wrote:
> > >
> > > On Mon, 7 Aug 2023, 13:23 Ard Biesheuvel, <ardb@kernel.org> wrote:
> > > >
> > > > Recent mixed-mode Linux kernels (i.e., v4.0 or newer) can access EFI
> > > > runtime services at OS runtime even when the OS was not entered via the
> > > > EFI stub. This is because, instead of reverting back to the firmware's
> > > > segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit
> > > > runtime services using compatilibity mode (i.e., the same mode used for
> > > > 32-bit user space) without taking down all interrupt handling, exception
> > > > handling etc.
> > > >
> > > > This means that GRUB's legacy x86 boot mode is sufficient to make use of
> > > > this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI
> > > > enlightened mode (but without going via the EFI stub), and provide all
> > > > the metadata that the OS needs to map the EFI runtime regions and call
> > > > EFI runtime services successfully.
> > >
> > > I'm not sure I understand the target combination here, and I'm not
> > > sure we want to support it.
> >
> > The point is not what we /want/ to support - it is what we already
> > supported in the past, and the recent EFI changes result in
> > regressions for those scenarios.
> >
> > > For now, we keep shipping both 32bit and 64bit x86 revocations
> > > together. However, the time will come that we will want or need to
> > > drop the 32bit revocations. Ubuntu has never signed a 32bit build of
> > > grub for secureboot, nor have we ever signed 32bit kernels to boot
> > > either. Most distributions have also stopped 32bit x86 builds, and/or
> > > don't support them to the same feature level (there are some that
> > > enable lots of combinations, i.e. debian, but even there i am not sure
> > > such hardware exists).
> > >
> > > I see this as a bug that 32-bit i686 build of Grub can launch 64-bit
> > > kernels - potentially without using shim / shim-lock / sbat
> > > verification.
> >
> > A 32-bit *EFI* build of GRUB, which you will never be able to boot on
> > anything other than 32-bit EFI, i.e., systems that nobody cares about
> > wrt secure boot.
> >
> > > I would feel much better if under shim-lock/secureboot only matching
> > > bitness was allowed to be booted and supported. Meaning no mixing &
> > > matching i686 grub builds launching x86_64 kernels, or vice versa, and
> > > ditoo on any other arches too (i.e. no mixing between
> > > riscv32/riscv64/riscv128, nor armhf/arm64).
> >
> > AFAICT, the non-EFIstub x86 boot path in GRUB has always supported
> > booting kernels of any bitness (provided, of course, that the CPU is
> > long mode capable)
> >
> > With adding the EFI support, we broke this which may potentially harm users.
> >
> > > I am impressed it is technologically possible, but do we really want
> > > to implement/design/support/encourage that?
> >
> > Distros already do, that is the whole point. It is called mixed mode,
> > and it is something I am trying to get rid of.
> >
> > The current mixed-mode implementation has elaborate plumbing so that
> > the 64-bit EFI stub can make use of 32-bit boot services. This was
> > presented to me in the past as a prerequisite for being able to
> > support mixed mode (and therefore a justification for upstreaming the
> > EFI handover protocol).
>
> I believe the only platform that shipped that out of the box, most
> recently was https://www.minnowboard.org/
> It had an alternative 64-bit boot service firmware download file,
> which most people did flash and use, but out of the factory it was
> shipped in 32-bit boot services mode, and yet expected to
> boot/load/run 64-bit kernels.
>
> Conveniently it wasn't too popular, was taken off the market
> https://www.silicom-usa.com/wp-content/uploads/2020/07/EOL_MinnowBoard-Turbot.pdf
> on 27th of July 2020, with all support & warranty for it seizing two
> weeks ago. Thus I can see why there was a strong push in the past to
> keep this commercial failure still working, as it was still shipping.
>
> > However, I realized that the current mixed
> > mode support in Linux does not actually rely on this: the only thing
> > you need is a bootloader that implements the x86 Linux boot protocol
> > directly but also passes EFI memory map, system table, etc. GRUB
> > already did this. IOW, mainline i386-efi GRUB already supported mixed
> > mode, and the recent EFI changes broke that.
> >
> > > I'm not even sure if 32-bit x86 EFI grub platform even makes sense
> > > anymore, and maybe it should be ripped out altogether? and leave i686
> > > boot to pc-bios only. i686 EFI was a short lived experiment that died
> > > without ever taking off.
> >
> > Not for mixed-mode - i.e., 'netbooks' with 64-bit Atom CPUs that
> > shipped with 32-bit Windows and therefore 32-bit EFI. Not sure how
> > many are still in circulation running Linux.
> >
> > Ideally, we'd drop this altogether. However, by making this change,
> > which is arguably a regression fix, we can phase out the EFI stub part
> > of mixed mode, and only retain the EFI runtime support.
>
> Sure, land this fix, and then later we will rip it all out. We have to
> start dropping platforms from grub, freezing them in time, as museum
> pieces support code.
I concur. I hope we will be able to rip at least some code from the
GRUB after the release...
> > > > It does mean that GRUB should not attempt to invoke the firmware's
> > > > LoadImage/StartImage methods on kernel builds that it knows cannot be
> > > > started natively. So add a check for this in the native EFI boot path,
> > > > and fall back to legacy x86 mode in such cases.
> > > >
> > > > Note that in the general case, booting non-native images of the same
> > > > native word size (e.g., X64 EFI apps on arm64 firmware) might be
> > > > supported by means of emulation, so let's only disallow images that use
> > > > a non-native word size. This will also permit booting i686 kernels on
> > > > x86_64 builds, although without access to runtime services, as this is
> > > > not supported by Linux.
> > > >
> > > > This change on top of 2.12-rc1 is sufficient to boot ordinary Linux
> > > > mixed mode builds and get full access to the EFI runtime services.
> > > >
> > > > Cc: Daniel Kiper <daniel.kiper@oracle.com>
> > > > Cc: Steve McIntyre <steve@einval.com>
> > > > Cc: Julian Andres Klode <julian.klode@canonical.com>
> > > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > > > ---
> > > > grub-core/loader/efi/linux.c | 5 +++++
> > > > include/grub/efi/pe32.h | 6 ++++++
> > > > 2 files changed, 11 insertions(+)
> > > >
> > > > diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> > > > index ed325f2b0aae2d6f..1d0734e295043df7 100644
> > > > --- a/grub-core/loader/efi/linux.c
> > > > +++ b/grub-core/loader/efi/linux.c
> > > > @@ -120,6 +120,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
> > > > return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
> > > > }
> > > >
> > > > + if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC)
> > > > + {
> > > > + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported");
> > > > + }
> > > > +
> > > > /*
> > > > * Linux kernels built for any architecture are guaranteed to support the
> > > > * LoadFile2 based initrd loading protocol if the image version is >= 1.
> > > > diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
> > > > index 101859af1ea64237..4e6e9d254bd35c9b 100644
> > > > --- a/include/grub/efi/pe32.h
> > > > +++ b/include/grub/efi/pe32.h
> > > > @@ -267,6 +267,12 @@ struct grub_pe32_section_table
> > > >
> > > > #define GRUB_PE32_SIGNATURE_SIZE 4
> > > >
> > > > +#if GRUB_TARGET_SIZEOF_VOID_P == 8
> > > > +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC
> > > > +#else
> > > > +#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC
> > > > +#endif
> > > > +
>
> Acked-by: Dimitri John Ledkov <dimitri.ledkov@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Daniel
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-09-14 16:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-07 12:21 [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot Ard Biesheuvel
2023-08-08 15:33 ` Dimitri John Ledkov
2023-08-08 16:27 ` Ard Biesheuvel
2023-08-08 16:42 ` Dimitri John Ledkov
2023-09-14 16:09 ` Daniel Kiper
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.