arrfab / rpms / shim

Forked from rpms/shim 4 years ago
Clone

Blame SOURCES/0029-Fetch-the-netboot-image-from-the-same-device.patch

4210fa
From f500a8742c19be604d33907b56ab9597fe448b65 Mon Sep 17 00:00:00 2001
4210fa
From: Gary Ching-Pang Lin <glin@suse.com>
4210fa
Date: Tue, 27 May 2014 14:12:32 +0800
4210fa
Subject: [PATCH 29/74] Fetch the netboot image from the same device
4210fa
4210fa
The previous strategy is to locate the first available PXE_BASE_CODE
4210fa
protocol and to fetch the second stage image from it, and this may
4210fa
cause shim to fetch the wrong second stage image, i.e. grub.efi.
4210fa
4210fa
Consider the machine with the following boot order:
4210fa
1. PXE Boot
4210fa
2. Hard Drive
4210fa
4210fa
Assume that the EFI image, e.g. bootx64.efi, in the PXE server is
4210fa
broken, then "PXE Boot" will fail and fallback to "Hard Drive". While
4210fa
shim.efi in "Hard Drive" is loaded, it will find the PXE protocol is
4210fa
available and fetch grub.efi from the PXE server, not grub.efi in the
4210fa
disk.
4210fa
4210fa
This commit checks the DeviceHandle from Loaded Image. If the device
4210fa
supports PXE, then shim fetches grub.efi with the PXE protocol. Otherwise,
4210fa
shim loads grub.efi from the disk.
4210fa
4210fa
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
4210fa
---
4210fa
 netboot.c | 77 +++++++++++++--------------------------------------------------
4210fa
 shim.c    |  2 +-
4210fa
 2 files changed, 17 insertions(+), 62 deletions(-)
4210fa
4210fa
diff --git a/netboot.c b/netboot.c
4210fa
index 07e2773..5ef53f7 100644
4210fa
--- a/netboot.c
4210fa
+++ b/netboot.c
4210fa
@@ -85,78 +85,33 @@ translate_slashes(char *str)
4210fa
  * Returns TRUE if we identify a protocol that is enabled and Providing us with
4210fa
  * the needed information to fetch a grubx64.efi image
4210fa
  */
4210fa
-BOOLEAN findNetboot(EFI_HANDLE image_handle)
4210fa
+BOOLEAN findNetboot(EFI_HANDLE device)
4210fa
 {
4210fa
-	UINTN bs = sizeof(EFI_HANDLE);
4210fa
-	EFI_GUID pxe_base_code_protocol = EFI_PXE_BASE_CODE_PROTOCOL;
4210fa
-	EFI_HANDLE *hbuf;
4210fa
-	BOOLEAN rc = FALSE;
4210fa
-	void *buffer = AllocatePool(bs);
4210fa
-	UINTN errcnt = 0;
4210fa
-	UINTN i;
4210fa
 	EFI_STATUS status;
4210fa
 
4210fa
-	if (!buffer)
4210fa
+	status = uefi_call_wrapper(BS->HandleProtocol, 3, device,
4210fa
+				   &PxeBaseCodeProtocol, (VOID **)&pxe);
4210fa
+	if (status != EFI_SUCCESS) {
4210fa
+		pxe = NULL;
4210fa
 		return FALSE;
4210fa
-
4210fa
-try_again:
4210fa
-	status = uefi_call_wrapper(BS->LocateHandle,5, ByProtocol, 
4210fa
-				   &pxe_base_code_protocol, NULL, &bs,
4210fa
-				   buffer);
4210fa
-
4210fa
-	if (status == EFI_BUFFER_TOO_SMALL) {
4210fa
-		errcnt++;
4210fa
-		FreePool(buffer);
4210fa
-		if (errcnt > 1)
4210fa
-			return FALSE;
4210fa
-		buffer = AllocatePool(bs);
4210fa
-		if (!buffer)
4210fa
-			return FALSE;
4210fa
-		goto try_again;
4210fa
 	}
4210fa
 
4210fa
-	if (status == EFI_NOT_FOUND) {
4210fa
-		FreePool(buffer);
4210fa
+	if (!pxe || !pxe->Mode) {
4210fa
+		pxe = NULL;
4210fa
 		return FALSE;
4210fa
 	}
4210fa
 
4210fa
-	/*
4210fa
- 	 * We have a list of pxe supporting protocols, lets see if any are
4210fa
- 	 * active
4210fa
- 	 */
4210fa
-	hbuf = buffer;
4210fa
-	pxe = NULL;
4210fa
-	for (i=0; i < (bs / sizeof(EFI_HANDLE)); i++) {
4210fa
-		status = uefi_call_wrapper(BS->OpenProtocol, 6, hbuf[i],
4210fa
-					   &pxe_base_code_protocol,
4210fa
-					   (void **)&pxe, image_handle, NULL,
4210fa
-					   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
4210fa
-
4210fa
-		if (status != EFI_SUCCESS) {
4210fa
-			pxe = NULL;
4210fa
-			continue;
4210fa
-		}
4210fa
-
4210fa
-		if (!pxe || !pxe->Mode) {
4210fa
-			pxe = NULL;
4210fa
-			continue;
4210fa
-		}
4210fa
-
4210fa
-		if (pxe->Mode->Started && pxe->Mode->DhcpAckReceived) {
4210fa
-			/*
4210fa
- 			 * We've located a pxe protocol handle thats been 
4210fa
- 			 * started and has received an ACK, meaning its
4210fa
- 			 * something we'll be able to get tftp server info
4210fa
- 			 * out of
4210fa
- 			 */
4210fa
-			rc = TRUE;
4210fa
-			break;
4210fa
-		}
4210fa
-			
4210fa
+	if (!pxe->Mode->Started || !pxe->Mode->DhcpAckReceived) {
4210fa
+		pxe = NULL;
4210fa
+		return FALSE;
4210fa
 	}
4210fa
 
4210fa
-	FreePool(buffer);
4210fa
-	return rc;
4210fa
+	/*
4210fa
+	 * We've located a pxe protocol handle thats been started and has
4210fa
+	 * received an ACK, meaning its something we'll be able to get
4210fa
+	 * tftp server info out of
4210fa
+	 */
4210fa
+	return TRUE;
4210fa
 }
4210fa
 
4210fa
 static CHAR8 *get_v6_bootfile_url(EFI_PXE_BASE_CODE_DHCPV6_PACKET *pkt)
4210fa
diff --git a/shim.c b/shim.c
4210fa
index 48a6f2f..d8699f9 100644
4210fa
--- a/shim.c
4210fa
+++ b/shim.c
4210fa
@@ -1373,7 +1373,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
4210fa
 		goto done;
4210fa
 	}
4210fa
 
4210fa
-	if (findNetboot(image_handle)) {
4210fa
+	if (findNetboot(li->DeviceHandle)) {
4210fa
 		efi_status = parseNetbootinfo(image_handle);
4210fa
 		if (efi_status != EFI_SUCCESS) {
4210fa
 			Print(L"Netboot parsing failed: %r\n", efi_status);
4210fa
-- 
4210fa
1.9.3
4210fa