#
ccc27ae7 |
| 16-Apr-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub: Drop __pure getter for efi_system_table
The practice of using __pure getter functions to access global variables in the EFI stub dates back to the time when we had to carefully prevent
efi/libstub: Drop __pure getter for efi_system_table
The practice of using __pure getter functions to access global variables in the EFI stub dates back to the time when we had to carefully prevent GOT entries from being emitted, because we could not rely on the toolchain to do this for us.
Today, we use the hidden visibility pragma for all EFI stub source files, which now all live in the same subdirectory, and we apply a sanity check on the objects, so we can get rid of these getter functions and simply refer to global data objects directly.
Start with efi_system_table(), and convert it into a global variable. While at it, make it a pointer-to-const, because we can.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
54439370 |
| 16-Apr-2020 |
Arvind Sankar <nivedita@alum.mit.edu> |
efi: Kill __efistub_global
Now that both arm and x86 are using the linker script to place the EFI stub's global variables in the correct section, remove __efistub_global.
Signed-off-by: Arvind Sank
efi: Kill __efistub_global
Now that both arm and x86 are using the linker script to place the EFI stub's global variables in the correct section, remove __efistub_global.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Link: https://lore.kernel.org/r/20200416151227.3360778-4-nivedita@alum.mit.edu Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
21cb9b41 |
| 09-Apr-2020 |
Arvind Sankar <nivedita@alum.mit.edu> |
efi/x86: Always relocate the kernel for EFI handover entry
Commit
d5cdf4cfeac9 ("efi/x86: Don't relocate the kernel unless necessary")
tries to avoid relocating the kernel in the EFI stub as far
efi/x86: Always relocate the kernel for EFI handover entry
Commit
d5cdf4cfeac9 ("efi/x86: Don't relocate the kernel unless necessary")
tries to avoid relocating the kernel in the EFI stub as far as possible.
However, when systemd-boot is used to boot a unified kernel image [1], the image is constructed by embedding the bzImage as a .linux section in a PE executable that contains a small stub loader from systemd that will call the EFI stub handover entry, together with additional sections and potentially an initrd. When this image is constructed, by for example dracut, the initrd is placed after the bzImage without ensuring that at least init_size bytes are available for the bzImage. If the kernel is not relocated by the EFI stub, this could result in the compressed kernel's startup code in head_{32,64}.S overwriting the initrd.
To prevent this, unconditionally relocate the kernel if the EFI stub was entered via the handover entry point.
[1] https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
Fixes: d5cdf4cfeac9 ("efi/x86: Don't relocate the kernel unless necessary") Reported-by: Sergey Shatunov <me@prok.pw> Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200406180614.429454-2-nivedita@alum.mit.edu Link: https://lore.kernel.org/r/20200409130434.6736-5-ardb@kernel.org
show more ...
|
#
105cb954 |
| 09-Apr-2020 |
Arvind Sankar <nivedita@alum.mit.edu> |
efi/x86: Move efi stub globals from .bss to .data
Commit
3ee372ccce4d ("x86/boot/compressed/64: Remove .bss/.pgtable from bzImage")
removed the .bss section from the bzImage.
However, while a P
efi/x86: Move efi stub globals from .bss to .data
Commit
3ee372ccce4d ("x86/boot/compressed/64: Remove .bss/.pgtable from bzImage")
removed the .bss section from the bzImage.
However, while a PE loader is required to zero-initialize the .bss section before calling the PE entry point, the EFI handover protocol does not currently document any requirement that .bss be initialized by the bootloader prior to calling the handover entry.
When systemd-boot is used to boot a unified kernel image [1], the image is constructed by embedding the bzImage as a .linux section in a PE executable that contains a small stub loader from systemd together with additional sections and potentially an initrd. As the .bss section within the bzImage is no longer explicitly present as part of the file, it is not initialized before calling the EFI handover entry. Furthermore, as the size of the embedded .linux section is only the size of the bzImage file itself, the .bss section's memory may not even have been allocated.
In particular, this can result in efi_disable_pci_dma being true even when it was not specified via the command line or configuration option, which in turn causes crashes while booting on some systems.
To avoid issues, place all EFI stub global variables into the .data section instead of .bss. As of this writing, only boolean flags for a few command line arguments and the sys_table pointer were in .bss and will now move into the .data section.
[1] https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
Fixes: 3ee372ccce4d ("x86/boot/compressed/64: Remove .bss/.pgtable from bzImage") Reported-by: Sergey Shatunov <me@prok.pw> Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200406180614.429454-1-nivedita@alum.mit.edu Link: https://lore.kernel.org/r/20200409130434.6736-4-ardb@kernel.org
show more ...
|
#
05a08796 |
| 09-Apr-2020 |
Colin Ian King <colin.king@canonical.com> |
efi/libstub/x86: Remove redundant assignment to pointer hdr
The pointer hdr is being assigned a value that is never read and it is being updated later with a new value. The assignment is redundant a
efi/libstub/x86: Remove redundant assignment to pointer hdr
The pointer hdr is being assigned a value that is never read and it is being updated later with a new value. The assignment is redundant and can be removed.
Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200402102537.503103-1-colin.king@canonical.com Link: https://lore.kernel.org/r/20200409130434.6736-3-ardb@kernel.org
show more ...
|
#
0347d8c2 |
| 08-Mar-2020 |
Arvind Sankar <nivedita@alum.mit.edu> |
efi/x86: Fix cast of image argument
handle_protocol() expects void **, not void *.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by
efi/x86: Fix cast of image argument
handle_protocol() expects void **, not void *.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200305143642.820865-1-nivedita@alum.mit.edu Link: https://lore.kernel.org/r/20200308080859.21568-28-ardb@kernel.org
show more ...
|
#
ac82d356 |
| 08-Mar-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub/x86: Use ULONG_MAX as upper bound for all allocations
The header flag XLF_CAN_BE_LOADED_ABOVE_4G will inform us whether allocations above 4 GiB for kernel, command line, etc are permitte
efi/libstub/x86: Use ULONG_MAX as upper bound for all allocations
The header flag XLF_CAN_BE_LOADED_ABOVE_4G will inform us whether allocations above 4 GiB for kernel, command line, etc are permitted, so we take it into account when calling efi_allocate_pages() etc.
However, CONFIG_EFI_STUB implies CONFIG_RELOCATABLE, and so the flag is guaranteed to be set on x86_64 builds, whereas i386 builds are guaranteed to run under firmware that will not allocate above 4 GB in the first place.
So drop the check, and just pass ULONG_MAX as the upper bound for all allocations.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200303225054.28741-1-ardb@kernel.org Link: https://lore.kernel.org/r/20200308080859.21568-27-ardb@kernel.org
show more ...
|
#
d5cdf4cf |
| 08-Mar-2020 |
Arvind Sankar <nivedita@alum.mit.edu> |
efi/x86: Don't relocate the kernel unless necessary
Add alignment slack to the PE image size, so that we can realign the decompression buffer within the space allocated for the image.
Only relocate
efi/x86: Don't relocate the kernel unless necessary
Add alignment slack to the PE image size, so that we can realign the decompression buffer within the space allocated for the image.
Only relocate the kernel if it has been loaded at an unsuitable address:
- Below LOAD_PHYSICAL_ADDR, or - Above 64T for 64-bit and 512MiB for 32-bit
For 32-bit, the upper limit is conservative, but the exact limit can be difficult to calculate.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200303221205.4048668-6-nivedita@alum.mit.edu Link: https://lore.kernel.org/r/20200308080859.21568-20-ardb@kernel.org
show more ...
|
#
1887c9b6 |
| 08-Mar-2020 |
Arvind Sankar <nivedita@alum.mit.edu> |
efi/x86: Decompress at start of PE image load address
When booted via PE loader, define image_offset to hold the offset of startup_32() from the start of the PE image, and use it as the start of the
efi/x86: Decompress at start of PE image load address
When booted via PE loader, define image_offset to hold the offset of startup_32() from the start of the PE image, and use it as the start of the decompression buffer.
[ mingo: Fixed the grammar in the comments. ]
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200303221205.4048668-3-nivedita@alum.mit.edu Link: https://lore.kernel.org/r/20200308080859.21568-17-ardb@kernel.org
show more ...
|
#
f3fa0efc |
| 08-Mar-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub/x86: Deal with exit() boot service returning
Even though it is uncommon, there are cases where the Exit() EFI boot service might return, e.g., when we were booted via the EFI handover pr
efi/libstub/x86: Deal with exit() boot service returning
Even though it is uncommon, there are cases where the Exit() EFI boot service might return, e.g., when we were booted via the EFI handover protocol from OVMF and the kernel image was specified on the command line, in which case Exit() attempts to terminate the boot manager, which is not an EFI application itself.
So let's drop into an infinite loop instead of randomly executing code that isn't expecting it.
Tested-by: Nathan Chancellor <natechancellor@gmail.com> # build Signed-off-by: Ard Biesheuvel <ardb@kernel.org> [ardb: put 'hlt' in deadloop] Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200303080648.21427-1-ardb@kernel.org Link: https://lore.kernel.org/r/20200308080859.21568-15-ardb@kernel.org
show more ...
|
#
8acf63ef |
| 08-Mar-2020 |
Arvind Sankar <nivedita@alum.mit.edu> |
efi/x86: Avoid using code32_start
code32_start is meant for 16-bit real-mode bootloaders to inform the kernel where the 32-bit protected mode code starts. Nothing in the protected mode kernel except
efi/x86: Avoid using code32_start
code32_start is meant for 16-bit real-mode bootloaders to inform the kernel where the 32-bit protected mode code starts. Nothing in the protected mode kernel except the EFI stub uses it.
efi_main() currently returns boot_params, with code32_start set inside it to tell efi_stub_entry() where startup_32 is located. Since it was invoked by efi_stub_entry() in the first place, boot_params is already known. Return the address of startup_32 instead.
This will allow a 64-bit kernel to live above 4Gb, for example, and it's cleaner as well.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200301230436.2246909-5-nivedita@alum.mit.edu Link: https://lore.kernel.org/r/20200308080859.21568-13-ardb@kernel.org
show more ...
|
#
17054f49 |
| 12-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/x86: Implement mixed mode boot without the handover protocol
Add support for booting 64-bit x86 kernels from 32-bit firmware running on 64-bit capable CPUs without requiring the bootloader to im
efi/x86: Implement mixed mode boot without the handover protocol
Add support for booting 64-bit x86 kernels from 32-bit firmware running on 64-bit capable CPUs without requiring the bootloader to implement the EFI handover protocol or allocate the setup block, etc etc, all of which can be done by the stub itself, using code that already exists.
Instead, create an ordinary EFI application entrypoint but implemented in 32-bit code [so that it can be invoked by 32-bit firmware], and stash the address of this 32-bit entrypoint in the .compat section where the bootloader can find it.
Note that we use the setup block embedded in the binary to go through startup_32(), but it gets reallocated and copied in efi_pe_entry(), using the same code that runs when the x86 kernel is booted in EFI mode from native firmware. This requires the loaded image protocol to be installed on the kernel image's EFI handle, and point to the kernel image itself and not to its loader. This, in turn, requires the bootloader to use the LoadImage() boot service to load the 64-bit image from 32-bit firmware, which is in fact supported by firmware based on EDK2. (Only StartImage() will fail, and instead, the newly added entrypoint needs to be invoked)
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
3b8f44fc |
| 15-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub/x86: Use Exit() boot service to exit the stub on errors
Currently, we either return with an error [from efi_pe_entry()] or enter a deadloop [in efi_main()] if any fatal errors occur duri
efi/libstub/x86: Use Exit() boot service to exit the stub on errors
Currently, we either return with an error [from efi_pe_entry()] or enter a deadloop [in efi_main()] if any fatal errors occur during execution of the EFI stub. Let's switch to calling the Exit() EFI boot service instead in both cases, so that we a) can get rid of the deadloop, and simply return to the boot manager if any errors occur during execution of the stub, including during the call to ExitBootServices(), b) can also return cleanly from efi_pe_entry() or efi_main() in mixed mode, once we introduce support for LoadImage/StartImage based mixed mode in the next patch.
Note that on systems running downstream GRUBs [which do not use LoadImage or StartImage to boot the kernel, and instead, pass their own image handle as the loaded image handle], calling Exit() will exit from GRUB rather than from the kernel, but this is a tolerable side effect.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
f7b85b33 |
| 14-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub/x86: Make loaded_image protocol handling mixed mode safe
Add the definitions and use the special wrapper so that the loaded_image UEFI protocol can be safely used from mixed mode.
Signe
efi/libstub/x86: Make loaded_image protocol handling mixed mode safe
Add the definitions and use the special wrapper so that the loaded_image UEFI protocol can be safely used from mixed mode.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
79d3219d |
| 04-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub: Take noinitrd cmdline argument into account for devpath initrd
One of the advantages of using what basically amounts to a callback interface into the bootloader for loading the initrd i
efi/libstub: Take noinitrd cmdline argument into account for devpath initrd
One of the advantages of using what basically amounts to a callback interface into the bootloader for loading the initrd is that it provides a natural place for the bootloader or firmware to measure the initrd contents while they are being passed to the kernel.
Unfortunately, this is not a guarantee that the initrd will in fact be loaded and its /init invoked by the kernel, since the command line may contain the 'noinitrd' option, in which case the initrd is ignored, but this will not be reflected in the PCR that covers the initrd measurement.
This could be addressed by measuring the command line as well, and including that PCR in the attestation policy, but this locks down the command line completely, which may be too restrictive.
So let's take the noinitrd argument into account in the stub, too. This forces any PCR that covers the initrd to assume a different value when noinitrd is passed, allowing an attestation policy to disregard the command line if there is no need to take its measurement into account for other reasons.
As Peter points out, this would still require the agent that takes the measurements to measure a separator event into the PCR in question at ExitBootServices() time, to prevent replay attacks using the known measurement from the TPM log.
Cc: Peter Jones <pjones@redhat.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
ec93fc37 |
| 03-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub: Add support for loading the initrd from a device path
There are currently two ways to specify the initrd to be passed to the Linux kernel when booting via the EFI stub: - it can be pass
efi/libstub: Add support for loading the initrd from a device path
There are currently two ways to specify the initrd to be passed to the Linux kernel when booting via the EFI stub: - it can be passed as a initrd= command line option when doing a pure PE boot (as opposed to the EFI handover protocol that exists for x86) - otherwise, the bootloader or firmware can load the initrd into memory, and pass the address and size via the bootparams struct (x86) or device tree (ARM)
In the first case, we are limited to loading from the same file system that the kernel was loaded from, and it is also problematic in a trusted boot context, given that we cannot easily protect the command line from tampering without either adding complicated white/blacklisting of boot arguments or locking down the command line altogether.
In the second case, we force the bootloader to duplicate knowledge about the boot protocol which is already encoded in the stub, and which may be subject to change over time, e.g., bootparams struct definitions, memory allocation/alignment requirements for the placement of the initrd etc etc. In the ARM case, it also requires the bootloader to modify the hardware description provided by the firmware, as it is passed in the same file. On systems where the initrd is measured after loading, it creates a time window where the initrd contents might be manipulated in memory before handing over to the kernel.
Address these concerns by adding support for loading the initrd into memory by invoking the EFI LoadFile2 protocol installed on a vendor GUIDed device path that specifically designates a Linux initrd. This addresses the above concerns, by putting the EFI stub in charge of placement in memory and of passing the base and size to the kernel proper (via whatever means it desires) while still leaving it up to the firmware or bootloader to obtain the file contents, potentially from other file systems than the one the kernel itself was loaded from. On platforms that implement measured boot, it permits the firmware to take the measurement right before the kernel actually consumes the contents.
Acked-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
91d150c0 |
| 10-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub: Clean up command line parsing routine
We currently parse the command non-destructively, to avoid having to allocate memory for a copy before passing it to the standard parsing routines
efi/libstub: Clean up command line parsing routine
We currently parse the command non-destructively, to avoid having to allocate memory for a copy before passing it to the standard parsing routines that are used by the core kernel, and which modify the input to delineate the parsed tokens with NUL characters.
Instead, we call strstr() and strncmp() to go over the input multiple times, and match prefixes rather than tokens, which implies that we would match, e.g., 'nokaslrfoo' in the stub and disable KASLR, while the kernel would disregard the option and run with KASLR enabled.
In order to avoid having to reason about whether and how this behavior may be abused, let's clean up the parsing routines, and rebuild them on top of the existing helpers.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
31f5e546 |
| 10-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub: Take soft and hard memory limits into account for initrd loading
On x86, the preferred load address of the initrd is still below 4 GB, even though in some cases, we can cope with an ini
efi/libstub: Take soft and hard memory limits into account for initrd loading
On x86, the preferred load address of the initrd is still below 4 GB, even though in some cases, we can cope with an initrd that is loaded above that.
To simplify the code, and to make it more straightforward to introduce other ways to load the initrd, pass the soft and hard memory limits at the same time, and let the code handling the initrd= command line option deal with this.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
9302c1bb |
| 10-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub: Rewrite file I/O routine
The file I/O routine that is used to load initrd or dtb files from the EFI system partition suffers from a few issues: - it converts the u8[] command line back
efi/libstub: Rewrite file I/O routine
The file I/O routine that is used to load initrd or dtb files from the EFI system partition suffers from a few issues: - it converts the u8[] command line back to a UTF-16 string, which is pointless since we only handle initrd or dtb arguments provided via the loaded image protocol anyway, which is where we got the UTF-16[] command line from in the first place when booting via the PE entry point, - in the far majority of cases, only a single initrd= option is present, but it optimizes for multiple options, by going over the command line twice, allocating heap buffers for dynamically sized arrays, etc. - the coding style is hard to follow, with few comments, and all logic including string parsing etc all combined in a single routine.
Let's fix this by rewriting most of it, based on the idea that in the case of multiple initrds, we can just allocate a new, bigger buffer and copy over the data before freeing the old one.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
1e45bf73 |
| 10-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub/x86: Permit cmdline data to be allocated above 4 GB
We now support cmdline data that is located in memory that is not 32-bit addressable, so relax the allocation limit on systems where t
efi/libstub/x86: Permit cmdline data to be allocated above 4 GB
We now support cmdline data that is located in memory that is not 32-bit addressable, so relax the allocation limit on systems where this feature is enabled.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
6a4db9bf |
| 10-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub/x86: Permit bootparams struct to be allocated above 4 GB
We now support bootparams structures that are located in memory that is not 32-bit addressable, so relax the allocation limit on
efi/libstub/x86: Permit bootparams struct to be allocated above 4 GB
We now support bootparams structures that are located in memory that is not 32-bit addressable, so relax the allocation limit on systems where this feature is enabled.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|
#
c2d0b470 |
| 10-Feb-2020 |
Ard Biesheuvel <ardb@kernel.org> |
efi/libstub/x86: Incorporate eboot.c into libstub
Most of the EFI stub source files of all architectures reside under drivers/firmware/efi/libstub, where they share a Makefile with special CFLAGS an
efi/libstub/x86: Incorporate eboot.c into libstub
Most of the EFI stub source files of all architectures reside under drivers/firmware/efi/libstub, where they share a Makefile with special CFLAGS and an include file with declarations that are only relevant for stub code.
Currently, we carry a lot of stub specific stuff in linux/efi.h only because eboot.c in arch/x86 needs them as well. So let's move eboot.c into libstub/, and move the contents of eboot.h that we still care about into efistub.h
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
show more ...
|