2022-05-02 01:08:16 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
|
|
|
|
|
#include <linux/efi.h>
|
|
|
|
|
#include <linux/pe.h>
|
|
|
|
|
#include <asm/efi.h>
|
|
|
|
|
#include <asm/unaligned.h>
|
|
|
|
|
|
|
|
|
|
#include "efistub.h"
|
|
|
|
|
|
|
|
|
|
static unsigned char zboot_heap[SZ_256K] __aligned(64);
|
|
|
|
|
static unsigned long free_mem_ptr, free_mem_end_ptr;
|
|
|
|
|
|
|
|
|
|
#define STATIC static
|
|
|
|
|
#if defined(CONFIG_KERNEL_GZIP)
|
|
|
|
|
#include "../../../../lib/decompress_inflate.c"
|
|
|
|
|
#elif defined(CONFIG_KERNEL_LZ4)
|
|
|
|
|
#include "../../../../lib/decompress_unlz4.c"
|
|
|
|
|
#elif defined(CONFIG_KERNEL_LZMA)
|
|
|
|
|
#include "../../../../lib/decompress_unlzma.c"
|
|
|
|
|
#elif defined(CONFIG_KERNEL_LZO)
|
|
|
|
|
#include "../../../../lib/decompress_unlzo.c"
|
|
|
|
|
#elif defined(CONFIG_KERNEL_XZ)
|
|
|
|
|
#undef memcpy
|
|
|
|
|
#define memcpy memcpy
|
|
|
|
|
#undef memmove
|
|
|
|
|
#define memmove memmove
|
|
|
|
|
#include "../../../../lib/decompress_unxz.c"
|
|
|
|
|
#elif defined(CONFIG_KERNEL_ZSTD)
|
|
|
|
|
#include "../../../../lib/decompress_unzstd.c"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern char efi_zboot_header[];
|
|
|
|
|
extern char _gzdata_start[], _gzdata_end[];
|
|
|
|
|
|
|
|
|
|
static void error(char *x)
|
|
|
|
|
{
|
2022-10-11 15:27:45 +02:00
|
|
|
efi_err("EFI decompressor: %s\n", x);
|
2022-05-02 01:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
static unsigned long alloc_preferred_address(unsigned long alloc_size)
|
2022-05-02 01:08:16 +02:00
|
|
|
{
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
#ifdef EFI_KIMG_PREFERRED_ADDRESS
|
|
|
|
|
efi_physical_addr_t efi_addr = EFI_KIMG_PREFERRED_ADDRESS;
|
2022-05-02 01:08:16 +02:00
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
if (efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
|
|
|
|
|
alloc_size / EFI_PAGE_SIZE, &efi_addr) == EFI_SUCCESS)
|
|
|
|
|
return efi_addr;
|
|
|
|
|
#endif
|
|
|
|
|
return ULONG_MAX;
|
2022-05-02 01:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
void __weak efi_cache_sync_image(unsigned long image_base,
|
|
|
|
|
unsigned long alloc_size,
|
|
|
|
|
unsigned long code_size)
|
2022-05-02 01:08:16 +02:00
|
|
|
{
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
// Provided by the arch to perform the cache maintenance necessary for
|
|
|
|
|
// executable code loaded into memory to be safe for execution.
|
2022-05-02 01:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
asmlinkage efi_status_t __efiapi
|
|
|
|
|
efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
|
|
|
|
|
{
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
unsigned long compressed_size = _gzdata_end - _gzdata_start;
|
|
|
|
|
unsigned long image_base, alloc_size, code_size;
|
|
|
|
|
efi_loaded_image_t *image;
|
2022-05-02 01:08:16 +02:00
|
|
|
efi_status_t status;
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
char *cmdline_ptr;
|
|
|
|
|
int ret;
|
2022-05-02 01:08:16 +02:00
|
|
|
|
|
|
|
|
WRITE_ONCE(efi_system_table, systab);
|
|
|
|
|
|
|
|
|
|
free_mem_ptr = (unsigned long)&zboot_heap;
|
|
|
|
|
free_mem_end_ptr = free_mem_ptr + sizeof(zboot_heap);
|
|
|
|
|
|
|
|
|
|
status = efi_bs_call(handle_protocol, handle,
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
&LOADED_IMAGE_PROTOCOL_GUID, (void **)&image);
|
2022-05-02 01:08:16 +02:00
|
|
|
if (status != EFI_SUCCESS) {
|
2022-10-11 15:27:45 +02:00
|
|
|
error("Failed to locate parent's loaded image protocol");
|
2022-05-02 01:08:16 +02:00
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
status = efi_handle_cmdline(image, &cmdline_ptr);
|
|
|
|
|
if (status != EFI_SUCCESS)
|
2022-05-02 01:08:16 +02:00
|
|
|
return status;
|
|
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
efi_info("Decompressing Linux Kernel...\n");
|
|
|
|
|
|
|
|
|
|
// SizeOfImage from the compressee's PE/COFF header
|
|
|
|
|
alloc_size = round_up(get_unaligned_le32(_gzdata_end - 4),
|
|
|
|
|
EFI_ALLOC_ALIGN);
|
|
|
|
|
|
|
|
|
|
// SizeOfHeaders and SizeOfCode from the compressee's PE/COFF header
|
|
|
|
|
code_size = get_unaligned_le32(_gzdata_end - 8) +
|
|
|
|
|
get_unaligned_le32(_gzdata_end - 12);
|
|
|
|
|
|
|
|
|
|
// If the architecture has a preferred address for the image,
|
|
|
|
|
// try that first.
|
|
|
|
|
image_base = alloc_preferred_address(alloc_size);
|
|
|
|
|
if (image_base == ULONG_MAX) {
|
|
|
|
|
unsigned long min_kimg_align = efi_get_kimg_min_align();
|
|
|
|
|
u32 seed = U32_MAX;
|
|
|
|
|
|
|
|
|
|
if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
|
|
|
|
|
// Setting the random seed to 0x0 is the same as
|
|
|
|
|
// allocating as low as possible
|
|
|
|
|
seed = 0;
|
|
|
|
|
} else if (efi_nokaslr) {
|
|
|
|
|
efi_info("KASLR disabled on kernel command line\n");
|
|
|
|
|
} else {
|
|
|
|
|
status = efi_get_random_bytes(sizeof(seed), (u8 *)&seed);
|
|
|
|
|
if (status == EFI_NOT_FOUND) {
|
|
|
|
|
efi_info("EFI_RNG_PROTOCOL unavailable\n");
|
|
|
|
|
efi_nokaslr = true;
|
|
|
|
|
} else if (status != EFI_SUCCESS) {
|
|
|
|
|
efi_err("efi_get_random_bytes() failed (0x%lx)\n",
|
|
|
|
|
status);
|
|
|
|
|
efi_nokaslr = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-02 01:08:16 +02:00
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
status = efi_random_alloc(alloc_size, min_kimg_align, &image_base,
|
|
|
|
|
seed, EFI_LOADER_CODE);
|
|
|
|
|
if (status != EFI_SUCCESS) {
|
|
|
|
|
efi_err("Failed to allocate memory\n");
|
|
|
|
|
goto free_cmdline;
|
|
|
|
|
}
|
2022-05-02 01:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
// Decompress the payload into the newly allocated buffer.
|
|
|
|
|
ret = __decompress(_gzdata_start, compressed_size, NULL, NULL,
|
|
|
|
|
(void *)image_base, alloc_size, NULL, error);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
error("Decompression failed");
|
|
|
|
|
status = EFI_DEVICE_ERROR;
|
|
|
|
|
goto free_image;
|
2022-05-02 01:08:16 +02:00
|
|
|
}
|
|
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
efi_cache_sync_image(image_base, alloc_size, code_size);
|
2022-05-02 01:08:16 +02:00
|
|
|
|
2023-01-30 13:11:53 +01:00
|
|
|
efi_remap_image(image_base, alloc_size, code_size);
|
|
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
status = efi_stub_common(handle, image, image_base, cmdline_ptr);
|
2022-05-02 01:08:16 +02:00
|
|
|
|
efi: libstub: Merge zboot decompressor with the ordinary stub
Even though our EFI zboot decompressor is pedantically spec compliant
and idiomatic for EFI image loaders, calling LoadImage() and
StartImage() for the nested image is a bit of a burden. Not only does it
create workflow issues for the distros (as both the inner and outer
PE/COFF images need to be signed for secure boot), it also copies the
image around in memory numerous times:
- first, the image is decompressed into a buffer;
- the buffer is consumed by LoadImage(), which copies the sections into
a newly allocated memory region to hold the executable image;
- once the EFI stub is invoked by StartImage(), it will also move the
image in memory in case of KASLR, mirrored memory or if the image must
execute from a certain a priori defined address.
There are only two EFI spec compliant ways to load code into memory and
execute it:
- use LoadImage() and StartImage(),
- call ExitBootServices() and take ownership of the entire system, after
which anything goes.
Given that the EFI zboot decompressor always invokes the EFI stub, and
given that both are built from the same set of objects, let's merge the
two, so that we can avoid LoadImage()/StartImage but still load our
image into memory without breaking the above rules.
This also means we can decompress the image directly into its final
location, which could be randomized or meet other platform specific
constraints that LoadImage() does not know how to adhere to. It also
means that, even if the encapsulated image still has the EFI stub
incorporated as well, it does not need to be signed for secure boot when
wrapping it in the EFI zboot decompressor.
In the future, we might decide to retire the EFI stub attached to the
decompressed image, but for the time being, they can happily coexist.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2022-10-13 12:42:07 +02:00
|
|
|
free_image:
|
|
|
|
|
efi_free(alloc_size, image_base);
|
|
|
|
|
free_cmdline:
|
|
|
|
|
efi_bs_call(free_pool, cmdline_ptr);
|
2022-05-02 01:08:16 +02:00
|
|
|
return status;
|
|
|
|
|
}
|