Skip to content

efi: add protocol: efi_handover for firmware-native chainloading#578

Draft
alexvoste wants to merge 1 commit into
Limine-Bootloader:trunkfrom
alexvoste:efi-handover
Draft

efi: add protocol: efi_handover for firmware-native chainloading#578
alexvoste wants to merge 1 commit into
Limine-Bootloader:trunkfrom
alexvoste:efi-handover

Conversation

@alexvoste
Copy link
Copy Markdown

Description

This PR implements the new protocol: efi_handover option proposed in the active BitLocker/TPM issue.

Why this is needed:

Currently, the standard protocol: efi reads the target binary into a memory buffer before passing it to gBS->LoadImage(). This execution from an anonymous RAM buffer alters the TPM PCR 4 measurement because Limine leaves its active footprint in the boot chain. As a result, Windows BitLocker detects a "tampered" boot path and forces the user into the recovery key screen on every dual-boot start.

What this PR does:

Instead of allocating memory and parsing the image manually, efi_handover uses native UEFI firmware services:

  1. It resolves the relative EFI_DEVICE_PATH (efi_file_path) and partition handle of the target image.
  2. It closes the file handle in Limine immediately, keeping the RAM clean.
  3. It passes the raw EFI_DEVICE_PATH directly to gBS->LoadImage(FALSE, ...), allowing the motherboard's native filesystem drivers to handle the load and signature checks natively.
  4. It starts the image cleanly via gBS->StartImage().

This keeps the TPM measurements clean, allowing seamless dual-booting with Windows BitLocker active, without requiring double-POST reboots via efi_boot_entry.

Testing status:

  • The code builds flawlessly under clang -target x86_64-unknown-none-elf.
  • I am running a pure Arch Linux system on my bare-metal machine without Windows, so I was unable to personally test the BitLocker bypass.
  • I am opening this as a Draft PR so the author of the issue or other contributors with dual-boot Windows + TPM configurations can test the compiled binary and confirm the fix.

Add optional EFI handover protocol that uses firmware-native LoadImage() with a DevicePath instead of loading EFI images via an intermediate RAM buffer.
This makes image execution closer to native UEFI boot behavior and avoids bootloader-mediated image loading paths.
May improve compatibility in dual-boot setups involving Windows Boot Manager and TPM-based measurements (e.g. BitLocker), where differences in the measured boot chain can trigger recovery prompts.
This is implemented as a separate optional protocol and does not change existing chainload behavior.
@alexvoste alexvoste closed this May 29, 2026
@alexvoste alexvoste reopened this May 29, 2026
@alexvoste alexvoste changed the base branch from v12.x to trunk May 29, 2026 23:47
@Mintsuki
Copy link
Copy Markdown
Member

Mintsuki commented May 30, 2026

Hey, thanks for the PR!

First off let me mention issue #576 so the author can get notified about this PR.

Second, I would frankly prefer to avoid adding yet another completely sepearate efi_* protocol. I already thought efi_boot_entry might have been a bit much, but this seems completely redundant to add.

If anything, I'd change the efi protocol itself to use this method rather than adding a completely new protocol. I'd be okay with that after careful consideration about potential breakages that might happen by doing this (something that comes to mind is that the $-prefixed transparent decompression would no longer work, for the few-to-no users actually using that with the efi protocol).

If needed it could also be made into a flag/modifier option inside the efi protocol itself, to preserve backwards compatibility while still avoiding a lot of code duplication.

In any case @valiukasd should confirm that it actually does achieve what we intend it to, before moving on.

@alexvoste
Copy link
Copy Markdown
Author

Hey! Thanks for the quick feedback, Mintsuki.

I completely agree with keeping the protocol list clean and avoiding config bloating. Integrating this behavior directly into the existing efi protocol makes total sense.

Personally, I think Option 2 (adding a flag/modifier option inside the existing efi protocol) is the safest bet. It keeps the codebase clean, avoids duplication, and preserves backwards compatibility (including that transparent $-decompression feature for the few users who rely on it).

If we go with a flag, what name would you prefer? Something like efi_handover: yes in the config, or maybe a path modifier?

I'll refactor the code as soon as we agree on the design. Let's also wait for @valiukasd to confirm the BitLocker/TPM bypass on their machine!

@valiukasd
Copy link
Copy Markdown

Hey, I will test the feature as soon as I figure out how to build and use the local version of the bootloader. As for the flag or protocol, from a user standpoint, a flag seems more logical since the protocol is still the same. Will report here after I confirm if the changes solve the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants