History log of /linux-master/drivers/firmware/efi/libstub/zboot-header.S
Revision Date Author Comments
# 538bc0f4 18-Apr-2023 Ard Biesheuvel <ardb@kernel.org>

efi/zboot: Set forward edge CFI compat header flag if supported

Add some plumbing to the zboot EFI header generation to set the newly
introduced DllCharacteristicsEx flag associated with forward edge CFI
enforcement instructions (BTI on arm64, IBT on x86)

x86 does not currently uses the zboot infrastructure, so let's wire it
up only for arm64.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>


# bca2f3a9 18-Apr-2023 Ard Biesheuvel <ardb@kernel.org>

efi/zboot: Add BSS padding before compression

We don't really care about the size of the decompressed image - what
matters is how much space needs to be allocated for the image to
execute, and this includes space for BSS that is not part of the
loadable image and so it is not accounted for in the decompressed size.

So let's add some zero padding to the end of the image: this compresses
well, and it ensures that BSS is accounted for, and as a bonus, it will
be zeroed before launching the image.

Since all architectures that implement support for EFI zboot carry this
value in the header in the same location, we can just grab it from the
binary that is being compressed.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>


# c7d9e628 09-Mar-2023 Ard Biesheuvel <ardb@kernel.org>

efi/libstub: zboot: Mark zboot EFI application as NX compatible

Now that the zboot loader will invoke the EFI memory attributes protocol
to remap the decompressed code and rodata as read-only/executable, we
can set the PE/COFF header flag that indicates to the firmware that the
application does not rely on writable memory being executable at the
same time.

Cc: <stable@vger.kernel.org> # v6.2+
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>


# 29636a5c 09-Nov-2022 Ard Biesheuvel <ardb@kernel.org>

efi: Put Linux specific magic number in the DOS header

GRUB currently relies on the magic number in the image header of ARM and
arm64 EFI kernel images to decide whether or not the image in question
is a bootable kernel.

However, the purpose of the magic number is to identify the image as one
that implements the bare metal boot protocol, and so GRUB, which only
does EFI boot, is limited unnecessarily to booting images that could
potentially be booted in a non-EFI manner as well.

This is problematic for the new zboot decompressor image format, as it
can only boot in EFI mode, and must therefore not use the bare metal
boot magic number in its header.

For this reason, the strict magic number was dropped from GRUB, to
permit essentially any kind of EFI executable to be booted via the
'linux' command, blurring the line between the linux loader and the
chainloader.

So let's use the same field in the DOS header that RISC-V and arm64
already use for their 'bare metal' magic numbers to store a 'generic
Linux kernel' magic number, which can be used to identify bootable
kernel images in PE format which don't necessarily implement a bare
metal boot protocol in the same binary. Note that, in the context of
EFI, the MS-DOS header is only described in terms of the fields that it
shares with the hybrid PE/COFF image format, (i.e., the MS-DOS EXE magic
number at offset #0 and the PE header offset at byte offset #0x3c).
Since we aim for compatibility with EFI only, and not with MS-DOS or
MS-Windows, we can use the remaining space in the MS-DOS header however
we want.

Let's set the generic magic number for x86 images as well: existing
bootloaders already have their own methods to identify x86 Linux images
that can be booted in a non-EFI manner, and having the magic number in
place there will ease any future transitions in loader implementations
to merge the x86 and non-x86 EFI boot paths.

Note that 32-bit ARM already uses the same location in the header for a
different purpose, but the ARM support is already widely implemented and
the EFI zboot decompressor is not available on ARM anyway, so we just
disregard it here.

Acked-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>


# 1f1ba325 12-Oct-2022 Ard Biesheuvel <ardb@kernel.org>

efi: libstub: Add image code and data size to the zimage metadata

In order to be able to switch from LoadImage() [which treats the
supplied PE/COFF image as file input only, and reconstructs the memory
image based on the section descriptors] to a mode where we allocate the
memory directly, and invoke the image in place, we need to now how much
memory to allocate beyond the end of the image. So copy this information
from the payload's PE/COFF header to the end of the compressed version
of the payload, so that the decompressor app can access it before
performing the decompression itself.

We'll also need to size of the code region once we switch arm64 to
jumping to the kernel proper with MMU and caches enabled, so let's
capture that information as well. Note that SizeOfCode does not account
for the header, so we need SizeOfHeaders as well.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>


# a0509109 01-May-2022 Ard Biesheuvel <ardb@kernel.org>

efi/libstub: implement generic EFI zboot

Implement a minimal EFI app that decompresses the real kernel image and
launches it using the firmware's LoadImage and StartImage boot services.
This removes the need for any arch-specific hacks.

Note that on systems that have UEFI secure boot policies enabled,
LoadImage/StartImage require images to be signed, or their hashes known
a priori, in order to be permitted to boot.

There are various possible strategies to work around this requirement,
but they all rely either on overriding internal PI/DXE protocols (which
are not part of the EFI spec) or omitting the firmware provided
LoadImage() and StartImage() boot services, which is also undesirable,
given that they encapsulate platform specific policies related to secure
boot and measured boot, but also related to memory permissions (whether
or not and which types of heap allocations have both write and execute
permissions.)

The only generic and truly portable way around this is to simply sign
both the inner and the outer image with the same key/cert pair, so this
is what is implemented here.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>