grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot


From: Daniel Kiper
Subject: Re: [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot
Date: Thu, 14 Sep 2023 18:09:03 +0200
User-agent: NeoMutt/20170113 (1.7.2)

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]