summaryrefslogtreecommitdiffstats
path: root/src/interface/efi/efi_pxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface/efi/efi_pxe.c')
-rw-r--r--src/interface/efi/efi_pxe.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/interface/efi/efi_pxe.c b/src/interface/efi/efi_pxe.c
index a1f81df59..15224a5e4 100644
--- a/src/interface/efi/efi_pxe.c
+++ b/src/interface/efi/efi_pxe.c
@@ -41,6 +41,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_pxe.h>
+#include <ipxe/efi/efi_null.h>
#include <ipxe/efi/Protocol/PxeBaseCode.h>
#include <ipxe/efi/Protocol/AppleNetBoot.h>
#include <usr/ifmgmt.h>
@@ -755,7 +756,8 @@ static EFI_STATUS EFIAPI efi_pxe_start ( EFI_PXE_BASE_CODE_PROTOCOL *base,
sa_family_t family = ( use_ipv6 ? AF_INET6 : AF_INET );
int rc;
- DBGC ( pxe, "PXE %s START %s\n", pxe->name, ( ipv6 ? "IPv6" : "IPv4" ));
+ DBGC ( pxe, "PXE %s START %s\n",
+ pxe->name, ( use_ipv6 ? "IPv6" : "IPv4" ) );
/* Initialise mode structure */
memset ( mode, 0, sizeof ( *mode ) );
@@ -1591,6 +1593,7 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
struct efi_pxe *pxe;
struct in_addr ip;
BOOLEAN use_ipv6;
+ int leak = 0;
EFI_STATUS efirc;
int rc;
@@ -1643,14 +1646,23 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
pxe->name, efi_handle_name ( handle ) );
return 0;
- bs->UninstallMultipleProtocolInterfaces (
+ if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
handle,
&efi_pxe_base_code_protocol_guid, &pxe->base,
&efi_apple_net_boot_protocol_guid, &pxe->apple,
- NULL );
+ NULL ) ) != 0 ) {
+ DBGC ( pxe, "PXE %s could not uninstall: %s\n",
+ pxe->name, strerror ( -EEFI ( efirc ) ) );
+ leak = 1;
+ }
+ efi_nullify_pxe ( &pxe->base );
+ efi_nullify_apple ( &pxe->apple );
err_install_protocol:
- ref_put ( &pxe->refcnt );
+ if ( ! leak )
+ ref_put ( &pxe->refcnt );
err_alloc:
+ if ( leak )
+ DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
return rc;
}
@@ -1662,6 +1674,8 @@ int efi_pxe_install ( EFI_HANDLE handle, struct net_device *netdev ) {
void efi_pxe_uninstall ( EFI_HANDLE handle ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_pxe *pxe;
+ int leak = efi_shutdown_in_progress;
+ EFI_STATUS efirc;
/* Locate PXE base code */
pxe = efi_pxe_find ( handle );
@@ -1675,13 +1689,25 @@ void efi_pxe_uninstall ( EFI_HANDLE handle ) {
efi_pxe_stop ( &pxe->base );
/* Uninstall PXE base code protocol */
- bs->UninstallMultipleProtocolInterfaces (
+ if ( ( ! efi_shutdown_in_progress ) &&
+ ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
handle,
&efi_pxe_base_code_protocol_guid, &pxe->base,
&efi_apple_net_boot_protocol_guid, &pxe->apple,
- NULL );
+ NULL ) ) != 0 ) ) {
+ DBGC ( pxe, "PXE %s could not uninstall: %s\n",
+ pxe->name, strerror ( -EEFI ( efirc ) ) );
+ leak = 1;
+ }
+ efi_nullify_pxe ( &pxe->base );
+ efi_nullify_apple ( &pxe->apple );
/* Remove from list and drop list's reference */
list_del ( &pxe->list );
- ref_put ( &pxe->refcnt );
+ if ( ! leak )
+ ref_put ( &pxe->refcnt );
+
+ /* Report leakage, if applicable */
+ if ( leak && ( ! efi_shutdown_in_progress ) )
+ DBGC ( pxe, "PXE %s nullified and leaked\n", pxe->name );
}