mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
UefiPayloadPkg/BaseSerialPortLibHob: Close EBS event in destructor
DxeBaseSerialPortLibHobConstructor() creates an EVT_SIGNAL_EXIT_BOOT_SERVICES event so that SerialPortWrite() can stop touching the UART once the OS owns the hardware. The library comes in through the DebugLib -> SerialPortLib chain of every DXE driver, so every driver registers such an event during ProcessLibraryConstructorList(). Drivers whose entry point returns an error leave that event behind: _ModuleEntryPoint() runs ProcessLibraryDestructorList() and the DXE core unloads the image, but this library declares no destructor, so the ExitBootServices event stays registered with a NotifyFunction pointing into the freed image. When the OS loader eventually calls ExitBootServices, the DXE core dispatches the stale event and branches into whatever now occupies that address. On the AArch64 chainloaded payload this crashes: GraphicsOutputDxe fails its entry point (no framebuffer HOB), leaks the event, and DiskIoDxe is loaded into the freed pages at a slightly higher base. The stale NotifyFunction then targets DiskIoDxe's PE header page, which image protection has marked non-executable, and the resulting instruction abort takes the system down right after "EFI stub: Exiting boot services...". Store the event handle in a module-scope variable and add a matching destructor that closes it. That way an unloaded driver no longer leaves a dangling ExitBootServices callback behind. Cc: Benjamin Doron <benjamin.doron@9elements.com> Cc: Gua Guo <gua.guo@intel.com> Cc: Guo Dong <guo.dong@intel.com> Cc: James Lu <james.lu@intel.com> Cc: Sean Rhodes <sean@starlabs.systems> Cc: Shuo Liu <shuo.liu@intel.com> Assisted-by: claude-opus-5 Signed-off-by: Alexander Graf <graf@amazon.com>
This commit is contained in:
parent
3a17aa8196
commit
339e8221af
2 changed files with 39 additions and 3 deletions
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
extern BOOLEAN mBaseSerialPortLibHobAtRuntime;
|
||||
|
||||
STATIC EFI_EVENT mBaseSerialPortLibHobExitBootServicesEvent;
|
||||
|
||||
/**
|
||||
Set mSerialIoUartLibAtRuntime flag as TRUE after ExitBootServices.
|
||||
|
||||
|
|
@ -44,13 +46,46 @@ DxeBaseSerialPortLibHobConstructor (
|
|||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_EVENT SerialPortLibHobExitBootServicesEvent;
|
||||
|
||||
return SystemTable->BootServices->CreateEvent (
|
||||
EVT_SIGNAL_EXIT_BOOT_SERVICES,
|
||||
TPL_NOTIFY,
|
||||
BaseSerialPortLibHobExitBootServicesEvent,
|
||||
NULL,
|
||||
&SerialPortLibHobExitBootServicesEvent
|
||||
&mBaseSerialPortLibHobExitBootServicesEvent
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
The destructor closes the ExitBootServices event.
|
||||
|
||||
A driver that fails its entry point is unloaded again by the DXE core, but
|
||||
this library has already registered its ExitBootServices callback by then.
|
||||
Close the event in the destructor so that a stale notification function
|
||||
pointing into the unloaded image is not left behind.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS No event was registered, or it was closed.
|
||||
@retval other CloseEvent () failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DxeBaseSerialPortLibHobDestructor (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (mBaseSerialPortLibHobExitBootServicesEvent == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = SystemTable->BootServices->CloseEvent (mBaseSerialPortLibHobExitBootServicesEvent);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
mBaseSerialPortLibHobExitBootServicesEvent = NULL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SerialPortLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
|
||||
CONSTRUCTOR = DxeBaseSerialPortLibHobConstructor
|
||||
DESTRUCTOR = DxeBaseSerialPortLibHobDestructor
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue