Message ID | 20230620061932.113292-3-ilias.apalodimas@linaro.org |
---|---|
State | Accepted |
Commit | 747d16d93c3b03e835925dd9ecb8f8d0b8d1ad22 |
Headers | show |
Series | Reconnect controllers on failues | expand |
Am 20. Juni 2023 08:19:29 MESZ schrieb Ilias Apalodimas <ilias.apalodimas@linaro.org>: >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. We talk about a single protocol but possibly multiple open prototocol information records. Othrwise looks good. Best regards Heinrich > >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> >--- > lib/efi_loader/efi_boottime.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > >diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c >index d44562d8f4e0..bfcd913dfad9 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); >-- >2.40.1 >
On 6/20/23 08:19, Ilias Apalodimas wrote: > 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>
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index d44562d8f4e0..bfcd913dfad9 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);
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> --- lib/efi_loader/efi_boottime.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) -- 2.40.1