Module Name: src
Committed By: rin
Date: Wed Dec 27 09:28:04 UTC 2023
Modified Files:
src/sys/stand/efiboot: efinet.c
Log Message:
MI efiboot: Stop using efi_bootdp after exclusive open for PXE
Once boot device is exclusively opened for Simple Network Protocol,
further access via device path (efi_bootdp) is illegal.
For some implementations, boot device path gets corrupted by
exclusive open, and subsequent access by efi_device_path_depth(),
e.g., causes infinite recursion.
Fix PXE boot for QEMU/aarch64 with EDK2 on some Linux distributions.
Thanks yamaguchi@ for comments and tests.
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/stand/efiboot/efinet.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/stand/efiboot/efinet.c
diff -u src/sys/stand/efiboot/efinet.c:1.6 src/sys/stand/efiboot/efinet.c:1.7
--- src/sys/stand/efiboot/efinet.c:1.6 Sun Mar 31 22:24:41 2019
+++ src/sys/stand/efiboot/efinet.c Wed Dec 27 09:28:04 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: efinet.c,v 1.6 2019/03/31 22:24:41 jmcneill Exp $ */
+/* $NetBSD: efinet.c,v 1.7 2023/12/27 09:28:04 rin Exp $ */
/*-
* Copyright (c) 2001 Doug Rabson
@@ -333,7 +333,7 @@ efi_net_probe(void)
EFI_STATUS status;
UINTN i, nhandles;
int nifs, depth = -1;
- bool found;
+ bool found, is_bootdp;
status = LibLocateHandle(ByProtocol, &SimpleNetworkProtocol, NULL,
&nhandles, &handles);
@@ -369,6 +369,9 @@ efi_net_probe(void)
if (!found)
continue;
+ is_bootdp = depth > 0 &&
+ efi_device_path_ncmp(efi_bootdp, dp0, depth) == 0;
+
status = uefi_call_wrapper(BS->OpenProtocol, 6, handles[i],
&SimpleNetworkProtocol, (void **)&net, IH, NULL,
EFI_OPEN_PROTOCOL_EXCLUSIVE);
@@ -396,10 +399,21 @@ efi_net_probe(void)
return;
}
- if (depth > 0 && efi_device_path_ncmp(efi_bootdp, dp0, depth) == 0) {
+ if (is_bootdp) {
+ /*
+ * This is boot device...
+ */
char devname[9];
+
snprintf(devname, sizeof(devname), "net%u", nifs);
set_default_device(devname);
+
+ /*
+ * and now opened for us excluively. Therefore,
+ * access via device path is illegal.
+ */
+ efi_bootdp = NULL;
+ depth = -1;
}
nifs++;