summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Carriere <etienne.carriere@linaro.org>2022-09-07 10:20:13 +0200
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2022-09-09 16:07:54 +0200
commit793254893954dc96437b5b5541aab84485bf78b1 (patch)
treeabaf72581621bac835b2033392783209c5e2b9cf
parent1e30e377a62fad6e22cdfabf9847662695f68ba8 (diff)
lib: efi_loader: don't delete invalid handles
Change efi_delete_handle() to not free EFI handles twice. This change tries to resolved an issue seen since U-Boot v2022.07 in which ExitBootService() attempts to release some EFI handles twice. The issue was seen booting a EFI shell that invokes 'connect -r' and then boots a Linux kernel. Execution of connect command makes EFI subsystem to bind a block device for each root block devices EFI handles. However these EFI device handles are already bound to a driver and we can have 2 registered devices relating to the same EFI handler. On ExitBootService(), the loop removing the devices makes these EFI handles to be released twice which corrupts memory. This patch prevents the memory release operation caused by the issue but but does not resolve the underlying problem. Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org> Add log message. Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r--lib/efi_loader/efi_boottime.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 4da64b5d29..6f7333638a 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -619,9 +619,14 @@ efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
*/
void efi_delete_handle(efi_handle_t handle)
{
- if (!handle)
+ efi_status_t ret;
+
+ ret = efi_remove_all_protocols(handle);
+ if (ret == EFI_INVALID_PARAMETER) {
+ log_err("Can't remove invalid handle %p\n", handle);
return;
- efi_remove_all_protocols(handle);
+ }
+
list_del(&handle->link);
free(handle);
}