-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
[systemd-boot >= 258] Kernel 5.15 does not boot from UKI #40342
Description
systemd version the issue has been seen with
258.2
Used distribution
NixOS
Linux kernel version used
5.15.197
CPU architectures issue was seen on
x86_64
Component
systemd-boot
Expected behaviour you didn't see
A UKI with a Kernel 5.15 (or other 5.x kernels) binary boots correctly with systemd-boot 258.2.
With systemd 257, a 5.x Kernel UKI boots correctly.
Unexpected behaviour you saw
systemd-boot crashes with ../src/boot/linux.c:279@linux_exec: Section would write outside of memory.
Steps to reproduce the problem
I'm not entirely sure how to easily reproduce this. I saw this issue with a UKI I built with a NixOS system and a NixOS 5.15 kernel. If you have any pointers on how to build a system with something like mkosi that uses a specific Kernel + UKI build, I'm happy to build a reproducer.
I already did a first root-cause analysis (though take this with a grain of salt as PE binaries are outside my area of expertise.)
I think this issue was introduced by #37372.
The line that triggers this error is https://github.com/systemd/systemd/blob/main/src/boot/linux.c#L279.
VirtualAddress is compared to image_base here.
Since this PR, when systemd-boot loads the Kernel PE binary inside a UKI it seems to assume that the ImageBase pointer inside the PE binary is set to 0.
Using readpe on an extracted 5.15 Kernel PE, we see:
<snip>
ImageBase: 0x1000000
<snip>
Sections
Section
Name: .setup
Virtual Size: 0x3bc0 (15296 bytes)
Virtual Address: 0x200
Size Of Raw Data: 0x3bc0 (15296 bytes)
<snip>
So the VirtualAddress of the first section is already smaller than the ImageBase value, triggering the mentioned error.
While any 6.x Kernel looks like this:
<snip>
ImageBase: 0
<snip>
Sections
Section
Name: .setup
Virtual Size: 0x3000 (12288 bytes)
Virtual Address: 0x1000
Size Of Raw Data: 0x3000 (12288 bytes)
<snip>
Here, the VirtualAddress is always larger than the ImageBase.
The change of the ImageBase address was introduced in the Linux Kernel in torvalds/linux@8eace5b - so only for 6.x+ kernels.
By simply applying this patch (only the header.S file) to the Kernel source for my 5.15 kernel, systemd-boot happily boots the kernel. That feels like it would have some ugly side-effects, so don't do this in prod ;).
Additional program output to the terminal or log subsystem illustrating the issue
../src/boot/linux.c:279@linux_exec: Section would write outside of memory
../src/boot/boot.c:2714@call_image_start: Failed to execute OS (\EFI\Linux\OS.efi): Load error
Failed to start boot entry. Rebooting in 5s.