Skip to content

Commit

Permalink
httpboot: Amend the device path matching rule
Browse files Browse the repository at this point in the history
Originally, we check if the last 2 nodes in the device path are
IPv4()/Uri() or IPv6()/Uri() to determine whether httpboot is used or
not. However, since UEFI 2.7, the DNS node will be inserted between the
IP node and the URI node if the server provides the DNS server address.
This commit changes the matching rule to search IP node and URI node
and ignore any node between those two nodes.

Signed-off-by: Gary Lin <[email protected]>
  • Loading branch information
lcp authored and vathpela committed Feb 28, 2018
1 parent c8ca1c5 commit a752290
Showing 1 changed file with 39 additions and 28 deletions.
67 changes: 39 additions & 28 deletions httpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,11 @@ find_httpboot (EFI_HANDLE device)
{
EFI_DEVICE_PATH *unpacked;
EFI_DEVICE_PATH *Node;
EFI_DEVICE_PATH *NextNode;
MAC_ADDR_DEVICE_PATH *MacNode;
URI_DEVICE_PATH *UriNode;
UINTN uri_size;
BOOLEAN ip_found = FALSE;
BOOLEAN ret = FALSE;

if (uri) {
FreePool(uri);
Expand All @@ -126,50 +127,60 @@ find_httpboot (EFI_HANDLE device)
}
Node = unpacked;

/* Traverse the device path to find IPv4()/Uri() or IPv6()/Uri() */
/* Traverse the device path to find IPv4()/.../Uri() or
* IPv6()/.../Uri() */
while (!IsDevicePathEnd(Node)) {
/* Save the MAC node so we can match the net card later */
if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
DevicePathSubType(Node) == MSG_MAC_ADDR_DP) {
MacNode = (MAC_ADDR_DEVICE_PATH *)Node;
CopyMem(&mac_addr, &MacNode->MacAddress, sizeof(EFI_MAC_ADDRESS));
}

if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
(DevicePathSubType(Node) == MSG_IPv4_DP ||
DevicePathSubType(Node) == MSG_IPv6_DP)) {
/* Save the IP node so we can set up the connection later */
CopyMem(&mac_addr, &MacNode->MacAddress,
sizeof(EFI_MAC_ADDRESS));
} else if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
(DevicePathSubType(Node) == MSG_IPv4_DP ||
DevicePathSubType(Node) == MSG_IPv6_DP)) {
/* Save the IP node so we can set up the connection */
/* later */
if (DevicePathSubType(Node) == MSG_IPv6_DP) {
CopyMem(&ip6_node, Node, sizeof(IPv6_DEVICE_PATH));
CopyMem(&ip6_node, Node,
sizeof(IPv6_DEVICE_PATH));
is_ip6 = TRUE;
} else {
CopyMem(&ip4_node, Node, sizeof(IPv4_DEVICE_PATH));
CopyMem(&ip4_node, Node,
sizeof(IPv4_DEVICE_PATH));
is_ip6 = FALSE;
}

Node = NextDevicePathNode(Node);
ip_found = TRUE;
} else if (ip_found == TRUE &&
(DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
DevicePathSubType(Node) == MSG_URI_DP)) {
EFI_DEVICE_PATH *NextNode;

/* Check if the URI node is the last node since the */
/* RAMDISK node could be appended, and we don't need */
/* to download the second stage loader in that case. */
NextNode = NextDevicePathNode(Node);
if (DevicePathType(Node) == MESSAGING_DEVICE_PATH &&
DevicePathSubType(Node) == MSG_URI_DP &&
IsDevicePathEnd(NextNode)) {
/* Save the current URI */
UriNode = (URI_DEVICE_PATH *)Node;
uri_size = strlena(UriNode->Uri);
uri = AllocatePool(uri_size + 1);
if (!uri) {
perror(L"Failed to allocate uri\n");
return FALSE;
}
CopyMem(uri, UriNode->Uri, uri_size + 1);
FreePool(unpacked);
return TRUE;
if (!IsDevicePathEnd(NextNode))
continue;

/* Save the current URI */
UriNode = (URI_DEVICE_PATH *)Node;
uri_size = strlena(UriNode->Uri);
uri = AllocatePool(uri_size + 1);
if (!uri) {
perror(L"Failed to allocate uri\n");
goto out;
}
CopyMem(uri, UriNode->Uri, uri_size + 1);
ret = TRUE;
goto out;
}
Node = NextDevicePathNode(Node);
}

out:
FreePool(unpacked);
return FALSE;
return ret;
}

static EFI_STATUS
Expand Down

0 comments on commit a752290

Please sign in to comment.