Skip to content

[systemd-boot >= 258] Kernel 5.15 does not boot from UKI #40342

@0xf09f95b4

Description

@0xf09f95b4

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🐛Programming errors, that need preferential fixingregression ⚠️A bug in something that used to work correctly and broke through some recent commitsd-boot/sd-stub/bootctl

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions