Skip to content

UEFI shell hang after iPXE boot under Secure Boot #800

Description

@Insyde-RexChen

Symptom

  • UEFI shell hangs when running dh after booting iPXE under Secure Boot.
  • Reproducible regardless of whether the downloaded boot image(download during iPXE flow) is signed or unsigned.
  • Reproducibility rate: 100%.

iPXE version

Firmware Environment

  1. UEFI x86_64
  2. EDK2-based BIOS firmware
  3. Secure Boot enabled

Steps to Reproduce

  1. Boot an x86_64 system from an iPXE USB image under UEFI Secure Boot.
  2. Let iPXE download and attempt to boot a network image.
  3. Return to the firmware/BIOS environment (for example, by using a returnable image path or another method that makes iPXE hand control back to the firmware).
  4. Launch the UEFI shell from there.
  5. Run the dh command.
  6. The system hangs.

Root Cause

  1. The iPXE shim uses the shim loader path from rhboot/shim, which hooks LoadImage(), StartImage(), and UnloadImage() in the EFI Boot Services table when Secure Boot is enabled.
  2. In loader-proto.c, shim_load_image() installs LoadedImage, LoadedImageDevicePath, and SHIM_LOADED_IMAGE_GUID on a newly created image handle via InstallMultipleProtocolInterfaces(ImageHandle, ...).
  3. On the error cleanup path, the code calls UninstallMultipleProtocolInterfaces(ImageHandle, ...) instead of UninstallMultipleProtocolInterfaces(*ImageHandle, ...).
  4. As a result, the installed protocols are not properly uninstalled, and the image handle is leaked.

Also Found

  • The iPXE boot flow uses the following image lifecycle sequence: efi_image_probe() -> LoadImage() -> UnloadImage() -> efi_image_exec() -> LoadImage() -> StartImage(). See ipxe/src/image/efi_image.c for details
  • When Secure Boot is enabled, the shim loader hooks these EFI Boot Services calls, which is where the issue is exposed.
  • The first UnloadImage() happens before StartImage(), so if cleanup is only expected in shim_start_image(), the first image handle will be leaked.

Additional Debug Observations

Debug logs captured during LoadImage() show the protocol install/uninstall flow in both successful (boot image signed) and failed (boot image not signed) cases. You can find that image handle seems to be leaked in both cases.

Failed case:
Image
Success case:
Image
Image

Suggested Solution

  1. Fix the error cleanup in shim_load_image() to uninstall using *ImageHandle.
  2. Remove the protocol uninstall / image free logic from shim_start_image().
  3. Move the cleanup work into shim_unload_image().

loader-proto-fix.patch

Notes

  1. The proposed fix has not yet been verified in the current test environment and should be treated as a suggested remediation, not as a confirmed resolution.
  2. This issue is not specific to PXE vs HTTP, nor to a particular hardware platform such as CRB.
  3. This appears to be a shim-side issue in the loader path used by the iPXE shim, not an iPXE core bug in the main iPXE code path. See System hang(CPU exception) occurs in UEFI shell after iPXE returns control when secure boot enabled. ipxe/ipxe#1730 for more information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions