Message ID | 20200206140352.6300-1-ardb@kernel.org (mailing list archive) |
---|---|
Headers | show |
Series | arch-agnostic initrd loading method for EFI systems | expand |
On 02/06/20 15:03, Ard Biesheuvel wrote: > This series introduces an arch agnostic way of loading the initrd into > memory from the EFI stub. This addresses a number of shortcomings that > affect the current implementations that exist across architectures: > > - The initrd=<file> command line option can only load files that reside > on the same file system that the kernel itself was loaded from, which > requires the bootloader or firmware to expose that file system via the > appropriate EFI protocol, which is not always feasible. From the kernel > side, this protocol is problematic since it is incompatible with mixed > mode on x86 (this is due to the fact that some of its methods have > prototypes that are difficult to marshall) > > - The approach that is ordinarily taken by GRUB is to load the initrd into > memory, and pass it to the kernel proper via the bootparams structure or > via the device tree. This requires the boot loader to have an understanding > of those structures, which are not always set in stone, and of the policies > around where the initrd may be loaded into memory. In the ARM case, it > requires GRUB to modify the hardware description provided by the firmware, > given that the initrd base and offset in memory are passed via the same > data structure. It also creates a time window where the initrd data sits > in memory, and can potentially be corrupted before the kernel is booted. > > Considering that we will soon have new users of these interfaces (EFI for > kvmtool on ARM, RISC-V in u-boot, etc), it makes sense to add a generic > interface now, before having another wave of bespoke arch specific code > coming in. > > Another aspect to take into account is that support for UEFI secure boot > and measured boot is being taken into the upstream, and being able to > rely on the PE entry point for booting any architecture makes the GRUB > vs shim story much cleaner, as we should be able to rely on LoadImage > and StartImage on all architectures, while retaining the ability to > load initrds from anywhere. > > Note that these patches depend on a fair amount of cleanup work that I > am targetting for v5.7. Branch can be found at: > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efistub-unification2 > > An implementation for ArmVirtQemu (OVMF for ARM aka AAVMF) can be found > at https://github.com/ardbiesheuvel/edk2/commits/linux-efi-generic. > The change is for ARM only, but the exact same code could be used on x86. I like this ArmVirtQemu feature, but I think it should be implemented as an addition, rather than a replacement. Older kernels (older EFI stubs) will try to fetch the initrd from the same fs where grub loaded the kernel from (exactly as you describe in the blurb). For example, virt-install's "--location" option "can recognize certain distribution trees and fetches a bootable kernel/initrd pair to launch the install". It would be nice to keep that working for older distros. I think LoadFile[2] can co-exist with SimpleFs. I also think that the "try SimpleFs first, fall back to LoadFile[2] second" requirement applies only to the UEFI boot manager, and not to the kernel's EFI stub. IOW in the new approach the kernel is free to ignore (abandon) the old approach for good. Thanks Laszlo > > Cc: lersek@redhat.com > Cc: leif@nuviainc.com > Cc: pjones@redhat.com > Cc: mjg59@google.com > Cc: agraf@csgraf.de > Cc: ilias.apalodimas@linaro.org > Cc: xypron.glpk@gmx.de > Cc: daniel.kiper@oracle.com > > Ard Biesheuvel (2): > efi/libstub: add support for loading the initrd from a device path > efi/libstub: take noinitrd cmdline argument into account for devpath > initrd > > drivers/firmware/efi/libstub/arm-stub.c | 21 ++++-- > .../firmware/efi/libstub/efi-stub-helper.c | 74 +++++++++++++++++++ > drivers/firmware/efi/libstub/efistub.h | 13 ++++ > drivers/firmware/efi/libstub/x86-stub.c | 51 ++++++++++--- > include/linux/efi.h | 1 + > 5 files changed, 146 insertions(+), 14 deletions(-) >
On 02/07/20 10:09, Laszlo Ersek wrote: > On 02/06/20 15:03, Ard Biesheuvel wrote: >> This series introduces an arch agnostic way of loading the initrd into >> memory from the EFI stub. This addresses a number of shortcomings that >> affect the current implementations that exist across architectures: >> >> - The initrd=<file> command line option can only load files that reside >> on the same file system that the kernel itself was loaded from, which >> requires the bootloader or firmware to expose that file system via the >> appropriate EFI protocol, which is not always feasible. From the kernel >> side, this protocol is problematic since it is incompatible with mixed >> mode on x86 (this is due to the fact that some of its methods have >> prototypes that are difficult to marshall) >> >> - The approach that is ordinarily taken by GRUB is to load the initrd into >> memory, and pass it to the kernel proper via the bootparams structure or >> via the device tree. This requires the boot loader to have an understanding >> of those structures, which are not always set in stone, and of the policies >> around where the initrd may be loaded into memory. In the ARM case, it >> requires GRUB to modify the hardware description provided by the firmware, >> given that the initrd base and offset in memory are passed via the same >> data structure. It also creates a time window where the initrd data sits >> in memory, and can potentially be corrupted before the kernel is booted. >> >> Considering that we will soon have new users of these interfaces (EFI for >> kvmtool on ARM, RISC-V in u-boot, etc), it makes sense to add a generic >> interface now, before having another wave of bespoke arch specific code >> coming in. >> >> Another aspect to take into account is that support for UEFI secure boot >> and measured boot is being taken into the upstream, and being able to >> rely on the PE entry point for booting any architecture makes the GRUB >> vs shim story much cleaner, as we should be able to rely on LoadImage >> and StartImage on all architectures, while retaining the ability to >> load initrds from anywhere. >> >> Note that these patches depend on a fair amount of cleanup work that I >> am targetting for v5.7. Branch can be found at: >> https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efistub-unification2 >> >> An implementation for ArmVirtQemu (OVMF for ARM aka AAVMF) can be found >> at https://github.com/ardbiesheuvel/edk2/commits/linux-efi-generic. >> The change is for ARM only, but the exact same code could be used on x86. > > I like this ArmVirtQemu feature, but I think it should be implemented as > an addition, rather than a replacement. Older kernels (older EFI stubs) > will try to fetch the initrd from the same fs where grub loaded the > kernel from (exactly as you describe in the blurb). > > For example, virt-install's "--location" option "can recognize certain > distribution trees and fetches a bootable kernel/initrd pair to launch > the install". It would be nice to keep that working for older distros. > > I think LoadFile[2] can co-exist with SimpleFs. > > I also think that the "try SimpleFs first, fall back to LoadFile[2] > second" requirement applies only to the UEFI boot manager, and not to > the kernel's EFI stub. IOW in the new approach the kernel is free to > ignore (abandon) the old approach for good. ... But that might not be good for compatibility with grub and/or the platform firmware, from the kernel's own perspective, perhaps?... Who is supposed to produce LoadFile2 with the new VenMedia devpath? Thanks Laszlo >> >> Cc: lersek@redhat.com >> Cc: leif@nuviainc.com >> Cc: pjones@redhat.com >> Cc: mjg59@google.com >> Cc: agraf@csgraf.de >> Cc: ilias.apalodimas@linaro.org >> Cc: xypron.glpk@gmx.de >> Cc: daniel.kiper@oracle.com >> >> Ard Biesheuvel (2): >> efi/libstub: add support for loading the initrd from a device path >> efi/libstub: take noinitrd cmdline argument into account for devpath >> initrd >> >> drivers/firmware/efi/libstub/arm-stub.c | 21 ++++-- >> .../firmware/efi/libstub/efi-stub-helper.c | 74 +++++++++++++++++++ >> drivers/firmware/efi/libstub/efistub.h | 13 ++++ >> drivers/firmware/efi/libstub/x86-stub.c | 51 ++++++++++--- >> include/linux/efi.h | 1 + >> 5 files changed, 146 insertions(+), 14 deletions(-) >> >
On Fri, 7 Feb 2020 at 09:22, Laszlo Ersek <lersek@redhat.com> wrote: > > On 02/07/20 10:09, Laszlo Ersek wrote: > > On 02/06/20 15:03, Ard Biesheuvel wrote: > >> This series introduces an arch agnostic way of loading the initrd into > >> memory from the EFI stub. This addresses a number of shortcomings that > >> affect the current implementations that exist across architectures: > >> > >> - The initrd=<file> command line option can only load files that reside > >> on the same file system that the kernel itself was loaded from, which > >> requires the bootloader or firmware to expose that file system via the > >> appropriate EFI protocol, which is not always feasible. From the kernel > >> side, this protocol is problematic since it is incompatible with mixed > >> mode on x86 (this is due to the fact that some of its methods have > >> prototypes that are difficult to marshall) > >> > >> - The approach that is ordinarily taken by GRUB is to load the initrd into > >> memory, and pass it to the kernel proper via the bootparams structure or > >> via the device tree. This requires the boot loader to have an understanding > >> of those structures, which are not always set in stone, and of the policies > >> around where the initrd may be loaded into memory. In the ARM case, it > >> requires GRUB to modify the hardware description provided by the firmware, > >> given that the initrd base and offset in memory are passed via the same > >> data structure. It also creates a time window where the initrd data sits > >> in memory, and can potentially be corrupted before the kernel is booted. > >> > >> Considering that we will soon have new users of these interfaces (EFI for > >> kvmtool on ARM, RISC-V in u-boot, etc), it makes sense to add a generic > >> interface now, before having another wave of bespoke arch specific code > >> coming in. > >> > >> Another aspect to take into account is that support for UEFI secure boot > >> and measured boot is being taken into the upstream, and being able to > >> rely on the PE entry point for booting any architecture makes the GRUB > >> vs shim story much cleaner, as we should be able to rely on LoadImage > >> and StartImage on all architectures, while retaining the ability to > >> load initrds from anywhere. > >> > >> Note that these patches depend on a fair amount of cleanup work that I > >> am targetting for v5.7. Branch can be found at: > >> https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efistub-unification2 > >> > >> An implementation for ArmVirtQemu (OVMF for ARM aka AAVMF) can be found > >> at https://github.com/ardbiesheuvel/edk2/commits/linux-efi-generic. > >> The change is for ARM only, but the exact same code could be used on x86. > > > > I like this ArmVirtQemu feature, but I think it should be implemented as > > an addition, rather than a replacement. Older kernels (older EFI stubs) > > will try to fetch the initrd from the same fs where grub loaded the > > kernel from (exactly as you describe in the blurb). > > Agreed. The ArmVirtQemu change is not intended for merging, but primarily as a test rig for the kernel changes. > > For example, virt-install's "--location" option "can recognize certain > > distribution trees and fetches a bootable kernel/initrd pair to launch > > the install". It would be nice to keep that working for older distros. > > > > I think LoadFile[2] can co-exist with SimpleFs. > > > > I also think that the "try SimpleFs first, fall back to LoadFile[2] > > second" requirement applies only to the UEFI boot manager, and not to > > the kernel's EFI stub. IOW in the new approach the kernel is free to > > ignore (abandon) the old approach for good. > > ... But that might not be good for compatibility with grub and/or the > platform firmware, from the kernel's own perspective, perhaps?... > > Who is supposed to produce LoadFile2 with the new VenMedia devpath? > What I am ultimately after is a generic GRUB that uses LoadImage+Startimage for starting the kernel on all architectures, and is able to load the initrd from anywhere in an arch agnostic manner. Additionally, we might have - an implementation for OVMF/AAVMF, - a EDK2 UEFI Shell command that takes a shell file path to provide the Linux initrd - a uboot implementation that passes the initrd this way. This series is the first step, to align between all the stakeholders on the approach for this aspect, before taking it any further.
On Fri, 2020-02-07 at 12:23 +0000, Ard Biesheuvel wrote: > On Fri, 7 Feb 2020 at 09:22, Laszlo Ersek <lersek@redhat.com> wrote: > > > > On 02/07/20 10:09, Laszlo Ersek wrote: [...] > > > For example, virt-install's "--location" option "can recognize > > > certain distribution trees and fetches a bootable kernel/initrd > > > pair to launch the install". It would be nice to keep that > > > working for older distros. > > > > > > I think LoadFile[2] can co-exist with SimpleFs. > > > > > > I also think that the "try SimpleFs first, fall back to > > > LoadFile[2] second" requirement applies only to the UEFI boot > > > manager, and not to the kernel's EFI stub. IOW in the new > > > approach the kernel is free to ignore (abandon) the old approach > > > for good. > > > > ... But that might not be good for compatibility with grub and/or > > the platform firmware, from the kernel's own perspective, > > perhaps?... > > > > Who is supposed to produce LoadFile2 with the new VenMedia devpath? > > > > What I am ultimately after is a generic GRUB that uses > LoadImage+Startimage for starting the kernel on all architectures, For most boots, we need to pivot to the MoK. A long time ago, I proposed updating the platform security policy to do an override to allow MoK to become the security verifier (actually principally so I could get the gummiboot bootloader to work with the MoK method): https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/tree/lib/security_policy.c And I believe all the pivot bootloaders now do this, but the fear was always this looks a bit like hackery that might not work in some UEFI implementations. Since we don't really rely on it (shim link loads after signature verification) we don't know whether the assumption does break or not. We'll need to get much more comfortable with the security override before we can let grub do a simple load+start. > and is able to load the initrd from anywhere in an arch agnostic > manner. I think the use case might not really be grub, it's gummiboot, or systemd-boot as its now called: https://wiki.archlinux.org/index.php/systemd-boot The standard way of using grub and EFI is to put grub on the EFI parition but have the kernel and the initrd on the root parition (which won't be EFI readable). This means we can keep the EFI partition small and only needing modification when grub is updated, meaning it doesn't even need mounting at all usually. Don't get me wrong, I like the gummiboot way of doing the LoadImage+StartImage: it's small and clean and doesn't need the shim protocol, but people like the sophistication grub provides including its ability to read kernel filesystems, so they're unlikely to change that. James
On Fri, 7 Feb 2020 at 16:20, James Bottomley <James.Bottomley@hansenpartnership.com> wrote: > > On Fri, 2020-02-07 at 12:23 +0000, Ard Biesheuvel wrote: > > On Fri, 7 Feb 2020 at 09:22, Laszlo Ersek <lersek@redhat.com> wrote: > > > > > > On 02/07/20 10:09, Laszlo Ersek wrote: > [...] > > > > For example, virt-install's "--location" option "can recognize > > > > certain distribution trees and fetches a bootable kernel/initrd > > > > pair to launch the install". It would be nice to keep that > > > > working for older distros. > > > > > > > > I think LoadFile[2] can co-exist with SimpleFs. > > > > > > > > I also think that the "try SimpleFs first, fall back to > > > > LoadFile[2] second" requirement applies only to the UEFI boot > > > > manager, and not to the kernel's EFI stub. IOW in the new > > > > approach the kernel is free to ignore (abandon) the old approach > > > > for good. > > > > > > ... But that might not be good for compatibility with grub and/or > > > the platform firmware, from the kernel's own perspective, > > > perhaps?... > > > > > > Who is supposed to produce LoadFile2 with the new VenMedia devpath? > > > > > > > What I am ultimately after is a generic GRUB that uses > > LoadImage+Startimage for starting the kernel on all architectures, > > For most boots, we need to pivot to the MoK. A long time ago, I > proposed updating the platform security policy to do an override to > allow MoK to become the security verifier (actually principally so I > could get the gummiboot bootloader to work with the MoK method): > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/tree/lib/security_policy.c > > And I believe all the pivot bootloaders now do this, but the fear was > always this looks a bit like hackery that might not work in some UEFI > implementations. Since we don't really rely on it (shim link loads > after signature verification) we don't know whether the assumption does > break or not. We'll need to get much more comfortable with the > security override before we can let grub do a simple load+start. > I'd like to do something much simpler: let shim override LoadImage and StartImage, and in their implementations, fall back to the firmware ones if necessary. > > and is able to load the initrd from anywhere in an arch agnostic > > manner. > > I think the use case might not really be grub, it's gummiboot, or > systemd-boot as its now called: > No it is definitely GRUB. GRUB today needs to attach to the shim protocol, perform the authentication, measure the payload etc etc, which means it knows far too much about the internals of shim or the fact that it even exists. My ideal bootflow would be where the OS installer looks at the firmware's db/dbx, doesn't bother to install shim if the OS vendor's cert is there, and uses the exact same GRUB regardless of whether shim is part of the bootflow or not. One of the things impeding this is the fact that we cannot load the initrd from anywhere when using loadimage+startimage. > https://wiki.archlinux.org/index.php/systemd-boot > > The standard way of using grub and EFI is to put grub on the EFI > parition but have the kernel and the initrd on the root parition (which > won't be EFI readable). This means we can keep the EFI partition small > and only needing modification when grub is updated, meaning it doesn't > even need mounting at all usually. > > Don't get me wrong, I like the gummiboot way of doing the > LoadImage+StartImage: it's small and clean and doesn't need the shim > protocol, but people like the sophistication grub provides including > its ability to read kernel filesystems, so they're unlikely to change > that. >
On Thu, Feb 06, 2020 at 02:03:50PM +0000, Ard Biesheuvel wrote: > data structure. It also creates a time window where the initrd data sits > in memory, and can potentially be corrupted before the kernel is booted. > I don't quite understand the time window aspect -- can you expand on that? It seems like the same time window exists between when the kernel is loaded and when it actually runs, no? Why is this more important for initrd?
On Fri, 7 Feb 2020 at 18:45, Arvind Sankar <nivedita@alum.mit.edu> wrote: > > On Thu, Feb 06, 2020 at 02:03:50PM +0000, Ard Biesheuvel wrote: > > data structure. It also creates a time window where the initrd data sits > > in memory, and can potentially be corrupted before the kernel is booted. > > > > I don't quite understand the time window aspect -- can you expand on > that? It seems like the same time window exists between when the kernel > is loaded and when it actually runs, no? Why is this more important for > initrd? When using loadimage+startimage, the authentication and measurement of the kernel image occur during the call to loadimage(), even if the source of the load is memory itself, and startimage() is typically called right after. The assumption is that it may help to make this time as short as possible for the initrd as well.
On Fri, 2020-02-07 at 18:31 +0000, Ard Biesheuvel wrote: > On Fri, 7 Feb 2020 at 16:20, James Bottomley > <James.Bottomley@hansenpartnership.com> wrote: > > > > On Fri, 2020-02-07 at 12:23 +0000, Ard Biesheuvel wrote: > > > On Fri, 7 Feb 2020 at 09:22, Laszlo Ersek <lersek@redhat.com> > > > wrote: > > > > > > > > On 02/07/20 10:09, Laszlo Ersek wrote: > > > > [...] > > > > > For example, virt-install's "--location" option "can > > > > > recognize certain distribution trees and fetches a bootable > > > > > kernel/initrd pair to launch the install". It would be nice > > > > > to keep that working for older distros. > > > > > > > > > > I think LoadFile[2] can co-exist with SimpleFs. > > > > > > > > > > I also think that the "try SimpleFs first, fall back to > > > > > LoadFile[2] second" requirement applies only to the UEFI boot > > > > > manager, and not to the kernel's EFI stub. IOW in the new > > > > > approach the kernel is free to ignore (abandon) the old > > > > > approach for good. > > > > > > > > ... But that might not be good for compatibility with grub > > > > and/or the platform firmware, from the kernel's own > > > > perspective, perhaps?... > > > > > > > > Who is supposed to produce LoadFile2 with the new VenMedia > > > > devpath? > > > > > > > > > > What I am ultimately after is a generic GRUB that uses > > > LoadImage+Startimage for starting the kernel on all > > > architectures, > > > > For most boots, we need to pivot to the MoK. A long time ago, I > > proposed updating the platform security policy to do an override to > > allow MoK to become the security verifier (actually principally so > > I could get the gummiboot bootloader to work with the MoK method): > > > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/t > > ree/lib/security_policy.c > > > > And I believe all the pivot bootloaders now do this, but the fear > > was always this looks a bit like hackery that might not work in > > some UEFI implementations. Since we don't really rely on it (shim > > link loads after signature verification) we don't know whether the > > assumption does break or not. We'll need to get much more > > comfortable with the security override before we can let grub do a > > simple load+start. > > > > I'd like to do something much simpler: let shim override LoadImage > and StartImage, Actually, the non-shim bootloaders really don't want to do that: the whole point of being able to use LoadImage is that you don't need to know how to load a PECOFF binary or check its signature. Overriding the security protocol allows updating the signature check, but if you look at the current efitools implementation it uses the pkcs7 protocol to avoid having to include crypto code. I've got the pecoff code they'd need in my uefi library: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/tree/lib/pecoff.c But it's a lot of code for things that pride themselves on being tiny. > and in their implementations, fall back to the firmware > ones if necessary. > > > > and is able to load the initrd from anywhere in an arch agnostic > > > manner. > > > > I think the use case might not really be grub, it's gummiboot, or > > systemd-boot as its now called: > > > > No it is definitely GRUB. GRUB today needs to attach to the shim > protocol, perform the authentication, measure the payload etc etc, > which means it knows far too much about the internals of shim or the > fact that it even exists. The shim protocol and shim are fairly separate. I agree it means grub has to load and know the two entry points for context and verify but they're very far removed for the inner workings of shim. Obviously, my non-shim loader has to supply them for grub, so this is the implementation: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/tree/lib/shim_protocol.c It's only 50 lines. The other thing to consider is that crypto code is huge. Shim currently includes it (although it could avoid this by using the pkcs7 verifier protocol trick I use ... I should push that harder) and it adds about 1M of static code. Grub does not have this code, so either grub uses shim and its code to do the signature verification or grub will have to include the additional 1M as well ... I think using shim via the protocol is preferable. > My ideal bootflow would be where the OS installer looks at the > firmware's db/dbx, doesn't bother to install shim if the OS vendor's > cert is there, and uses the exact same GRUB regardless of whether > shim is part of the bootflow or not. That's not enough. The whole point of MoK is that the user may have done their own key addition, so you could be in the situation where the vendor cert is present in db but the user has a MoK override for boot and if you assume presence of the vendor cert means you can use loadimage, this will fail because the MoK cert isn't in db ... unless you've added the MoK key via the security protocol override. > One of the things impeding this is the fact that we cannot load the > initrd from anywhere when using loadimage+startimage. unless initrd becomes a PECOFF binary, it can never be loaded by loadimage ... I thought you were still letting the kernel load it via LoadFile2? (assuming you are and that the above is just a typo). James
On Fri, 7 Feb 2020 at 19:54, James Bottomley <James.Bottomley@hansenpartnership.com> wrote: > > On Fri, 2020-02-07 at 18:31 +0000, Ard Biesheuvel wrote: > > On Fri, 7 Feb 2020 at 16:20, James Bottomley > > <James.Bottomley@hansenpartnership.com> wrote: > > > > > > On Fri, 2020-02-07 at 12:23 +0000, Ard Biesheuvel wrote: > > > > On Fri, 7 Feb 2020 at 09:22, Laszlo Ersek <lersek@redhat.com> > > > > wrote: > > > > > > > > > > On 02/07/20 10:09, Laszlo Ersek wrote: > > > > > > [...] > > > > > > For example, virt-install's "--location" option "can > > > > > > recognize certain distribution trees and fetches a bootable > > > > > > kernel/initrd pair to launch the install". It would be nice > > > > > > to keep that working for older distros. > > > > > > > > > > > > I think LoadFile[2] can co-exist with SimpleFs. > > > > > > > > > > > > I also think that the "try SimpleFs first, fall back to > > > > > > LoadFile[2] second" requirement applies only to the UEFI boot > > > > > > manager, and not to the kernel's EFI stub. IOW in the new > > > > > > approach the kernel is free to ignore (abandon) the old > > > > > > approach for good. > > > > > > > > > > ... But that might not be good for compatibility with grub > > > > > and/or the platform firmware, from the kernel's own > > > > > perspective, perhaps?... > > > > > > > > > > Who is supposed to produce LoadFile2 with the new VenMedia > > > > > devpath? > > > > > > > > > > > > > What I am ultimately after is a generic GRUB that uses > > > > LoadImage+Startimage for starting the kernel on all > > > > architectures, > > > > > > For most boots, we need to pivot to the MoK. A long time ago, I > > > proposed updating the platform security policy to do an override to > > > allow MoK to become the security verifier (actually principally so > > > I could get the gummiboot bootloader to work with the MoK method): > > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/t > > > ree/lib/security_policy.c > > > > > > And I believe all the pivot bootloaders now do this, but the fear > > > was always this looks a bit like hackery that might not work in > > > some UEFI implementations. Since we don't really rely on it (shim > > > link loads after signature verification) we don't know whether the > > > assumption does break or not. We'll need to get much more > > > comfortable with the security override before we can let grub do a > > > simple load+start. > > > > > > > I'd like to do something much simpler: let shim override LoadImage > > and StartImage, > > Actually, the non-shim bootloaders really don't want to do that: the > whole point of being able to use LoadImage is that you don't need to > know how to load a PECOFF binary or check its signature. Overriding > the security protocol allows updating the signature check, but if you > look at the current efitools implementation it uses the pkcs7 protocol > to avoid having to include crypto code. > > I've got the pecoff code they'd need in my uefi library: > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/tree/lib/pecoff.c > > But it's a lot of code for things that pride themselves on being tiny. > I think you are missing the point. GRUB will only use loadimage+startimage, no matter what is backing it (the firmware or shim). The same applies to gummiboot or even the uefi shell if you wanted to. So all loaders use LoadImage/StartImage as usual, but shim inserts itself into the call chain if it was loaded first. > > and in their implementations, fall back to the firmware > > ones if necessary. > > > > > > and is able to load the initrd from anywhere in an arch agnostic > > > > manner. > > > > > > I think the use case might not really be grub, it's gummiboot, or > > > systemd-boot as its now called: > > > > > > > No it is definitely GRUB. GRUB today needs to attach to the shim > > protocol, perform the authentication, measure the payload etc etc, > > which means it knows far too much about the internals of shim or the > > fact that it even exists. > > The shim protocol and shim are fairly separate. I agree it means grub > has to load and know the two entry points for context and verify but > they're very far removed for the inner workings of shim. Obviously, my > non-shim loader has to supply them for grub, so this is the > implementation: > > https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git/tree/lib/shim_protocol.c > > It's only 50 lines. > > The other thing to consider is that crypto code is huge. Shim > currently includes it (although it could avoid this by using the pkcs7 > verifier protocol trick I use ... I should push that harder) and it > adds about 1M of static code. Grub does not have this code, so either > grub uses shim and its code to do the signature verification or grub > will have to include the additional 1M as well ... I think using shim > via the protocol is preferable. > No. GRUB will call loadimage+startimage, and will end up hitting the implementation exposed by shim. > > My ideal bootflow would be where the OS installer looks at the > > firmware's db/dbx, doesn't bother to install shim if the OS vendor's > > cert is there, and uses the exact same GRUB regardless of whether > > shim is part of the bootflow or not. > > That's not enough. The whole point of MoK is that the user may have > done their own key addition, so you could be in the situation where the > vendor cert is present in db but the user has a MoK override for boot > and if you assume presence of the vendor cert means you can use > loadimage, this will fail because the MoK cert isn't in db ... unless > you've added the MoK key via the security protocol override. > No. The LoadImage you are hitting is shim's loadimage not the firmware's loadimage in this case. > > One of the things impeding this is the fact that we cannot load the > > initrd from anywhere when using loadimage+startimage. > > unless initrd becomes a PECOFF binary, it can never be loaded by > loadimage ... I thought you were still letting the kernel load it via > LoadFile2? (assuming you are and that the above is just a typo). > No it is not a typo. If you load the kernel vis LoadImage, you need to use initrd= to load the initrd, which required that file to be hosted on a file system that EFI understands. The alternative is to load the initrd into memory, store the address and size into a bootparams structure or DT, and invoke the kernel via some other entry point that allows you to carry this metadata. I want to get rid of the latter, which means I need a way to load the initrd that is not limited to loading from the same [EFI supported] file system as the kernel. *That* is what this series is about.
On Fri, Feb 07, 2020 at 07:47:46PM +0000, Ard Biesheuvel wrote: > On Fri, 7 Feb 2020 at 18:45, Arvind Sankar <nivedita@alum.mit.edu> wrote: > > > > On Thu, Feb 06, 2020 at 02:03:50PM +0000, Ard Biesheuvel wrote: > > > data structure. It also creates a time window where the initrd data sits > > > in memory, and can potentially be corrupted before the kernel is booted. > > > > > > > I don't quite understand the time window aspect -- can you expand on > > that? It seems like the same time window exists between when the kernel > > is loaded and when it actually runs, no? Why is this more important for > > initrd? > > When using loadimage+startimage, the authentication and measurement of > the kernel image occur during the call to loadimage(), even if the > source of the load is memory itself, and startimage() is typically > called right after. > > The assumption is that it may help to make this time as short as > possible for the initrd as well. Ok, this is for when we can use LoadImage, that makes sense.