diff options
author | Ilias Apalodimas <ilias.apalodimas@linaro.org> | 2023-06-20 09:19:29 +0300 |
---|---|---|
committer | Heinrich Schuchardt <heinrich.schuchardt@canonical.com> | 2023-07-15 11:20:41 +0200 |
commit | 747d16d93c3b03e835925dd9ecb8f8d0b8d1ad22 (patch) | |
tree | bcd3faba48c5f3dfbc3cd8fbecfefe45456eed68 | |
parent | 239d59a65e203171fb94d0ab935ced35902fed1b (diff) | |
download | u-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.c | 10 |
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); |