From 81fe5bce9e1e002e3a4eda4bcb5cdcb8b5a0c86e54f7d2dd43e002d80cce27be Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Fri, 5 Jan 2018 09:03:39 +0000 Subject: [PATCH] Accepting request 561805 from home:gary_lin:branches:devel:openSUSE:Factory Amend the device path matching rule for httpboot (bsc#1065370) OBS-URL: https://build.opensuse.org/request/show/561805 OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=137 --- shim-httpboot-amend-device-path.patch | 155 ++++++++++++++++++++++++++ shim.changes | 6 + shim.spec | 3 + 3 files changed, 164 insertions(+) create mode 100644 shim-httpboot-amend-device-path.patch diff --git a/shim-httpboot-amend-device-path.patch b/shim-httpboot-amend-device-path.patch new file mode 100644 index 0000000..5a09855 --- /dev/null +++ b/shim-httpboot-amend-device-path.patch @@ -0,0 +1,155 @@ +From 9fcc5c93c4cad02927ecb318bafe2335f1026df3 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Fri, 27 Oct 2017 11:36:40 +0800 +Subject: [PATCH 1/2] httpboot: Amend the device path matching rule + +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 +--- + httpboot.c | 67 ++++++++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 39 insertions(+), 28 deletions(-) + +diff --git a/httpboot.c b/httpboot.c +index e4657c1..ccff5aa 100644 +--- a/httpboot.c ++++ b/httpboot.c +@@ -105,10 +105,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); +@@ -128,50 +129,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 +-- +2.15.1 + + +From 2da4f7a9c97f7fed1cbacc37af8895cf1f90150f Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Fri, 5 Jan 2018 16:51:39 +0800 +Subject: [PATCH 2/2] httpboot: fix the infinite loop + +We should get out of the loop once the uri node is not the last node in +the device path. + +Signed-off-by: Gary Lin +--- + httpboot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/httpboot.c b/httpboot.c +index ccff5aa..d865dca 100644 +--- a/httpboot.c ++++ b/httpboot.c +@@ -164,7 +164,7 @@ find_httpboot (EFI_HANDLE device) + /* to download the second stage loader in that case. */ + NextNode = NextDevicePathNode(Node); + if (!IsDevicePathEnd(NextNode)) +- continue; ++ goto out; + + /* Save the current URI */ + UriNode = (URI_DEVICE_PATH *)Node; +-- +2.15.1 + diff --git a/shim.changes b/shim.changes index 9b937b2..b4d8b35 100644 --- a/shim.changes +++ b/shim.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Jan 5 08:41:42 UTC 2018 - glin@suse.com + +- Add shim-httpboot-amend-device-path.patch to amend the device + path matching rule for httpboot (bsc#1065370) + ------------------------------------------------------------------- Thu Jan 4 08:17:44 UTC 2018 - glin@suse.com diff --git a/shim.spec b/shim.spec index 0ef68a4..19d9d84 100644 --- a/shim.spec +++ b/shim.spec @@ -52,6 +52,8 @@ Patch2: shim-arch-independent-names.patch Patch3: shim-httpboot-include-console.h.patch # PATCH-FIX-UPSTREAM shim-remove-cryptpem.patch glin@suse.com -- Replace the functions in CryptPem.c with the null function Patch4: shim-remove-cryptpem.patch +# PATCH-FIX-UPSTREAM shim-httpboot-amend-device-path.patch bsc#1065370 glin@suse.com -- Amend the device path matching rule for httpboot +Patch5: shim-httpboot-amend-device-path.patch # PATCH-FIX-OPENSUSE shim-change-debug-file-path.patch glin@suse.com -- Change the default debug file path Patch50: shim-change-debug-file-path.patch # PATCH-FIX-OPENSUSE shim-opensuse-cert-prompt.patch glin@suse.com -- Show the prompt to ask whether the user trusts openSUSE certificate or not @@ -100,6 +102,7 @@ The source code of UEFI shim loader %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 %patch50 -p1 %if 0%{?is_opensuse} == 1 %patch100 -p1