[PATCH v2 5/6] efi/runtime-wrappers: honour EFI_RUNTIME_SERVICES in the non-blocking paths
Breno Leitao <[email protected]> Fri, 12 Jun 2026 04:01:32 -0700
| Newsgroups | org.kernel.vger.linux-efi,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Three wrappers call firmware directly instead of going through __efi_queue_work(), and none of them check whether runtime services are still enabled: virt_efi_set_variable_nb(), virt_efi_query_variable_info_nb() and virt_efi_reset_system(). Once a hang has cleared EFI_RUNTIME_SERVICES - or efi_recover_from_page_fault() has cleared it on a firmware page fault - these paths still enter the (possibly wedged) firmware, e.g. an EFI pstore write through the non-blocking SetVariable() variant, in violation of UEFI's non-reentrancy rules. reset_system() is reachable too: efi_reboot() only gates it on the static efi_rt_services_supported() mask, which does not track the runtime disable. Check efi_enabled(EFI_RUNTIME_SERVICES) at the top of each before taking efi_runtime_lock and calling into firmware. Suggested-by: Ard Biesheuvel <[email protected]> Signed-off-by: Breno Leitao <[email protected]> --- drivers/firmware/efi/runtime-wrappers.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 8badf0419a148..842f72d44211f 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -461,6 +461,9 @@ virt_efi_set_variable_nb(efi_char16_t *name, efi_guid_t *vendor, u32 attr, { efi_status_t status; + if (!efi_enabled(EFI_RUNTIME_SERVICES)) + return EFI_DEVICE_ERROR; + if (down_trylock(&efi_runtime_lock)) return EFI_NOT_READY; @@ -500,6 +503,9 @@ virt_efi_query_variable_info_nb(u32 attr, u64 *storage_space, if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) return EFI_UNSUPPORTED; + if (!efi_enabled(EFI_RUNTIME_SERVICES)) + return EFI_DEVICE_ERROR; + if (down_trylock(&efi_runtime_lock)) return EFI_NOT_READY; @@ -527,6 +533,11 @@ static void __nocfi virt_efi_reset_system(int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data) { + if (!efi_enabled(EFI_RUNTIME_SERVICES)) { + pr_warn("EFI Runtime Services are disabled, not invoking reset_system()\n"); + return; + } + if (down_trylock(&efi_runtime_lock)) { pr_warn("failed to invoke the reset_system() runtime service:\n" "could not get exclusive access to the firmware\n"); -- 2.53.0-Meta