aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlias Apalodimas <ilias.apalodimas@linaro.org>2023-06-20 09:19:29 +0300
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2023-07-15 11:20:41 +0200
commit747d16d93c3b03e835925dd9ecb8f8d0b8d1ad22 (patch)
treebcd3faba48c5f3dfbc3cd8fbecfefe45456eed68
parent239d59a65e203171fb94d0ab935ced35902fed1b (diff)
downloadu-boot-747d16d93c3b03e835925dd9ecb8f8d0b8d1ad22.zip
u-boot-747d16d93c3b03e835925dd9ecb8f8d0b8d1ad22.tar.gz
u-boot-747d16d93c3b03e835925dd9ecb8f8d0b8d1ad22.tar.bz2
efi_loader: check the status of disconnected drivers
efi_uninstall_protocol() calls efi_disconnect_all_drivers() but never checks the return value. Instead it tries to identify protocols that are still open after closing the ones that were opened with EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL, EFI_OPEN_PROTOCOL_GET_PROTOCOL and EFI_OPEN_PROTOCOL_TEST_PROTOCOL. Instead of doing that, check the return value early and exit if disconnecting the drivers failed. Also reconnect all the drivers of a handle if protocols are still found on the handle after disconnecting controllers and closing the remaining protocols. While at it fix a memory leak and properly free the opened protocol information when closing a protocol. Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-rw-r--r--lib/efi_loader/efi_boottime.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 5e932ee..d294db9 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1374,17 +1374,23 @@ static efi_status_t efi_uninstall_protocol
if (r != EFI_SUCCESS)
goto out;
/* Disconnect controllers */
- efi_disconnect_all_drivers(efiobj, protocol, NULL);
+ r = efi_disconnect_all_drivers(efiobj, protocol, NULL);
+ if (r != EFI_SUCCESS) {
+ r = EFI_ACCESS_DENIED;
+ goto out;
+ }
/* Close protocol */
list_for_each_entry_safe(item, pos, &handler->open_infos, link) {
if (item->info.attributes ==
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL ||
item->info.attributes == EFI_OPEN_PROTOCOL_GET_PROTOCOL ||
item->info.attributes == EFI_OPEN_PROTOCOL_TEST_PROTOCOL)
- list_del(&item->link);
+ efi_delete_open_info(item);
}
+ /* if agents didn't close the protocols properly */
if (!list_empty(&handler->open_infos)) {
r = EFI_ACCESS_DENIED;
+ EFI_CALL(efi_connect_controller(handle, NULL, NULL, true));
goto out;
}
r = efi_remove_protocol(handle, protocol, protocol_interface);