Commit Graph
21 Commits
Author SHA1 Message Date
Luca Boccassi feeba8fa3b boot: bound PE section VirtualSize before zeroing the inner kernel
The inner-kernel section loader checks VirtualAddress + SizeOfRawData
against kernel_size_in_memory (for the memcpy), but the memzero right
after it clears up to VirtualAddress + VirtualSize, and VirtualSize is
only constrained to be >= SizeOfRawData.

Reject a VirtualAddress + VirtualSize that overflows or exceeds
kernel_size_in_memory, mirroring the existing SizeOfRawData checks.

Follow-up for cab9c7b5a4
2026-07-03 15:19:39 +01:00
Josh Hoffer e641f37499 boot/stub: honor PE SectionAlignment when loading inner kernel
The stub copies the embedded kernel PE into an xmalloc_pages()
allocation with AllocateAnyPages, which only guarantees EFI_PAGE_SIZE
(4 KiB) alignment.

The arm64 kernel declares SectionAlignment = SZ_64K. When _text is not
64K-aligned the kernel's EFI stub reallocates and copies the image,
which can fail with EFI_OUT_OF_RESOURCES on memory-constrained firmware
(e.g. U-Boot, bounded by CONFIG_SYS_MALLOC_LEN rather than full DRAM).
The failure is non-deterministic since AllocateAnyPages returns whatever
page the allocator finds first.

Plumb SectionAlignment through pe_kernel_info() and allocate via
xmalloc_aligned_pages(). For alignment <= EFI_PAGE_SIZE (e.g. x86_64) it
reduces to a plain AllocatePages(), so the change is free there.

SectionAlignment comes from the PE header, which the spec requires to be
a power of 2. Sanitize it in pe_kernel_info() right where it is parsed:
a non-conforming value falls back to plain page alignment (matching the
behavior of older systemd-stub versions that ignored the field) rather
than propagate something that would break xmalloc_aligned_pages()'s
over-alignment maths, with a log_warning() so the fallback stays
diagnosable.

Co-developed-by: Claude <claude@anthropic.com>

Closes: #42443
Reported-By: Agathe Porte <agathe.porte@oss.qualcomm.com>
Tested-By: Agathe Porte <agathe.porte@oss.qualcomm.com>
2026-06-19 22:16:28 +02:00
Luca Boccassi 1cd2ff3cca stub: more hardening against malformed images
Avoid issues with malformed images.

Reported on various yeswehack.com reports

YWH-PGM9780-73
YWH-PGM9780-68
YWH-PGM9780-67
YWH-PGM9780-87
2026-02-18 15:05:44 +00:00
Zbigniew Jędrzejewski-Szmek 353701b07e boot: drop now-unused image_base param 2026-02-17 18:21:45 +01:00
cdown d9d300dc4c boot: Fix UKI boot for kernels with non-zero ImageBase
The current code incorrectly subtracts ImageBase from section
VirtualAddress values when loading sections into memory. This is based
on a misunderstanding of the PE specification.

VirtualAddress in section headers is the address of the first byte of
the section relative to the image base when the section is loaded into
memory. In other words, VirtualAddress is already an RVA measured from
the image base, it is definitely NOT an absolute address that needs to
be adjusted.

So when loading a PE image into a newly allocated buffer, sections
should be copied to buffer + VirtualAddress, regardless of what
ImageBase says. The ImageBase field merely indicates the *preferred*
load address, it does not affect how section RVAs are interpreted.

This happens to not cause issues when ImageBase was 0 (since
VirtualAddress - 0 = VirtualAddress), which is why this bug went
undetected on modern kernels. However, it fails with kernels that have
non-zero ImageBase values.

So let's remove the nonsensical VirtualAddress < ImageBase check, and
remove the ImageBase subtractions from section loading offsets. This
lets all kernel UKIs work properly again.

Fixes: #40342
2026-01-23 00:18:25 +08:00
Lennart Poettering 80ab99d4d2 efi: use 'struct iovec' more, pass initrds down with it 2026-01-15 11:32:33 +01:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Luca Boccassi 56d19b633d boot: coding style cleanups 2025-11-12 23:44:06 +01:00
Tobias Heider f405165065 stub: fix file path handling for loaded kernel
- Actually pass the new memory file path to parent_loaded_image->FilePath
- Restore old parent_loaded_image if Linux returns
- Pass the same kernel_file_path in load_via_boot_services path
- s/Re-use/Patch in comment explaining what we are doing

Fixes #38566
2025-09-18 11:40:43 +09:00
Felix Pehla ddc9d2a836 systemd-boot: don't always log NX_COMPAT info
Commit 70b7e03 introduced 3 calls to log_debug() about the presence or
absence of NX_COMPAT support. Since sd-boot does not yet have the
ability to only print messages above a certain loglevel, these will
always be printed, even on top of the configured splash screen. This
commit removes the log_debug() call after a success and only prints
those for missing firmware support if the UEFI should support them in
the first place (i.e. starting with version 2.10).
2025-08-25 13:40:54 +01:00
Luca Boccassi 70b7e03ebb sd-stub: use memory proto if available and set kernel memory to RX with NX_COMPAT
When NX_COMPAT gets enabled, firmwares will enforce that executable
memory is either writable or executable.
This needs kernel compatibility, when it will happen the kernel will
have the NX_COMPAT bit set. If it is, set the memory buffer to RO.

Note that this must be undone on failure, as EDK2 in some configurations
overwrites memory ranges that are returned with FreePages() with a
fixed pattern, so if the pages are RO it will crash.

This is only an issue with the new custom PE loader, as LoadImage()
and StartImage() will always do the right thing automatically.

https://microsoft.github.io/mu/WhatAndWhy/enhancedmemoryprotection/
https://www.kraxel.org/blog/2023/12/uefi-nx-linux-boot/

Follow-up for cab9c7b5a4

Fixes https://github.com/systemd/systemd/issues/38545
2025-08-19 17:16:57 +02:00
Mate KukriandTobias Heider 428cd7bfba Reuse the parent_image handle and parent_loaded_image
- Reuse parent_image instead of allocating new ones. Firmware might cast
  EFI_LOADED_IMAGE_PROTOCOL * to a larger struct causing issues
- Remove loaded image protocol installation and uninstallation which are no
  longer required

Fixes a bug introduced by cab9c7b5a4.
Fixes #38567.

Co-authored-by: Tobias Heider <tobias.heider@canonical.com>
2025-08-14 19:59:37 +09:00
Luca Boccassi bef244392b stub: fix passing kernel cmdline when loading via shim
This was mistakenly dropped when the custom PE loader was added.
Add it back, otherwise no smbios/addon cmdline options are passed
through.

Fixes https://github.com/systemd/systemd/issues/38349

Follow-up for 40aabfae72
2025-07-27 22:44:05 +01:00
Luca Boccassi 5115710528 stub: check if security override is available before using it
Avoids fallback that requires it if it is not available. Can
be dropped once support for shim < 16 is no longer needed

Follow-up for 23d56ae890
2025-07-23 10:29:19 +01:00
Luca Boccassi 23d56ae890 stub: restore compatibility for shim (< 16.0) -> UKI case
It is possible to boot directly a UKI from shim, and Fedora Cloud Base UKI
does exactly this.
This used to work fine until https://github.com/systemd/systemd/pull/37372
which broke compatibility when shim < 16.0 (no loader protocol override) is
used. Shim 15.8 is still in use in several distributions, and will be for
a long time.

Restore a part of the previous implementation, and if running with secure
boot enabled, and with shim but < 16.0, apply a security override.

Follow-up for cab9c7b5a4

Fixes https://github.com/systemd/systemd/issues/38104
2025-07-23 09:54:09 +02:00
Zbigniew Jędrzejewski-Szmek e884fcb6b5 boot: move/adjust comments
The comment in linux_exec() was based on Lennart's comment in
https://github.com/systemd/systemd/pull/37372#discussion_r2142340582, but
shortened. The original wording is more direct and at least for me easier to
grok, so adjust the comment to be more verbose again.

Also, move the comment from shim_loader_available() to the place where it used.
This function is for checking if the new thing is available, no need to describe
the old thing there.
2025-07-17 17:10:18 +02:00
Yu Watanabe aeac400d1b boot: fix typo
Follow-up for cab9c7b5a4.
2025-06-18 01:47:49 +09:00
Valentin David 40aabfae72 stub: call LoadImage/StartImage from boot services when provided by shim 2025-06-13 13:53:02 +02:00
Valentin David cab9c7b5a4 stub: call inner kernel directly
Since shim 16, it is not possible anymore to override the security arch
protocol to avoid signature check and measurements.

Also on Dell servers, EFI_SECURITY2_ARCH_PROTOCOL is not implemented, so
unexpected measurements on PCR 4 were still happening.

This just loads and run the kernel pe. We verify that there is no relocation
needed. Also for simplification, we assume and verify that the base address is
expected to be 0.
2025-06-11 13:04:53 +02:00
Daan De Meyer c60a8c72d1 boot: Clean up includes
Instead of introducing efi-forward.h, we use efi.h for the same purpose
in the boot/ folder.
2025-05-22 11:10:20 +02:00
Zbigniew Jędrzejewski-Szmek 97318131fd Rename src/boot/efi to just src/boot
I very much dislike the approach in which we were mixing Linux and UEFI C code
in the same subdirectory. No code was shared between two environments. This
layout was created in e7dd673d1e, with the
justification of "being more consistent with the rest of systemd", but I don't
see how it's supposed to be so.

Originally, when the C code was just a single bootctl.c file, this wasn't so
bad. But over time the userspace code grew quite a bit. With the moves done in
previuos commits, the intermediate subdirectory is now empty except for the
efi/ subdir, and this additional subdirectory level doesn't have a good
justification. The components is called "systemd-boot", not "systemd-efi", and
we can remove one level of indentation.
2024-11-07 14:52:06 +01:00