]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
ovmf: Fix CVE-2023-45234
authorSoumya Sambu <soumya.sambu@windriver.com>
Fri, 28 Jun 2024 09:23:45 +0000 (09:23 +0000)
committerHongxu Jia <hongxu.jia@windriver.com>
Wed, 4 Dec 2024 03:30:12 +0000 (11:30 +0800)
EDK2's Network Package is susceptible to a buffer overflow vulnerability
when processing DNS Servers option from a DHCPv6 Advertise message. This
vulnerability can be exploited by an attacker to gain unauthorized access
and potentially lead to a loss of Confidentiality, Integrity and/or
Availability.

References:
https://nvd.nist.gov/vuln/detail/CVE-2023-45234

Upstream-patches:
https://github.com/tianocore/edk2/commit/1b53515d53d303166b2bbd31e2cc7f16fd0aecd7
https://github.com/tianocore/edk2/commit/458c582685fc0e8057d2511c5a0394078d988c17

Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0001.patch [new file with mode: 0644]
meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0002.patch [new file with mode: 0644]
meta/recipes-core/ovmf/ovmf_git.bb

diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0001.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0001.patch
new file mode 100644 (file)
index 0000000..463b4b8
--- /dev/null
@@ -0,0 +1,154 @@
+From 1b53515d53d303166b2bbd31e2cc7f16fd0aecd7 Mon Sep 17 00:00:00 2001
+From: Doug Flick <dougflick@microsoft.com>
+Date: Fri, 26 Jan 2024 05:54:52 +0800
+Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch
+
+REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539
+
+Bug Details:
+PixieFail Bug #6
+CVE-2023-45234
+CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
+CWE-119 Improper Restriction of Operations within the Bounds of
+ a Memory Buffer
+
+Buffer overflow when processing DNS Servers option in a DHCPv6
+Advertise message
+
+Change Overview:
+
+Introduces a function to cache the Dns Server and perform sanitizing
+on the incoming DnsServerLen to ensure that the length is valid
+
+> + EFI_STATUS
+> + PxeBcCacheDnsServerAddresses (
+> +  IN PXEBC_PRIVATE_DATA        *Private,
+> +  IN PXEBC_DHCP6_PACKET_CACHE  *Cache6
+> +  )
+
+Additional code cleanup
+
+Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
+Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
+
+Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
+Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
+
+CVE: CVE-2023-45234
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1b53515d53d303166b2bbd31e2cc7f16fd0aecd7]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 71 +++++++++++++++++++++++++---
+ 1 file changed, 65 insertions(+), 6 deletions(-)
+
+diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+index 425e0cf806..2b2d372889 100644
+--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+@@ -3,6 +3,7 @@
\r
+   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
+   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
++  Copyright (c) Microsoft Corporation\r
\r
+   SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
+@@ -1312,6 +1313,65 @@ PxeBcSelectDhcp6Offer (
+   }\r
+ }\r
\r
++/**\r
++  Cache the DHCPv6 DNS Server addresses\r
++\r
++  @param[in] Private               The pointer to PXEBC_PRIVATE_DATA.\r
++  @param[in] Cache6                The pointer to PXEBC_DHCP6_PACKET_CACHE.\r
++\r
++  @retval    EFI_SUCCESS           Cache the DHCPv6 DNS Server address successfully.\r
++  @retval    EFI_OUT_OF_RESOURCES  Failed to allocate resources.\r
++  @retval    EFI_DEVICE_ERROR      The DNS Server Address Length provided by a untrusted\r
++                                   option is not a multiple of 16 bytes (sizeof (EFI_IPv6_ADDRESS)).\r
++**/\r
++EFI_STATUS\r
++PxeBcCacheDnsServerAddresses (\r
++  IN PXEBC_PRIVATE_DATA        *Private,\r
++  IN PXEBC_DHCP6_PACKET_CACHE  *Cache6\r
++  )\r
++{\r
++  UINT16  DnsServerLen;\r
++\r
++  DnsServerLen = NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen);\r
++  //\r
++  // Make sure that the number is nonzero\r
++  //\r
++  if (DnsServerLen == 0) {\r
++    return EFI_DEVICE_ERROR;\r
++  }\r
++\r
++  //\r
++  // Make sure the DnsServerlen is a multiple of EFI_IPv6_ADDRESS (16)\r
++  //\r
++  if (DnsServerLen % sizeof (EFI_IPv6_ADDRESS) != 0) {\r
++    return EFI_DEVICE_ERROR;\r
++  }\r
++\r
++  //\r
++  // This code is currently written to only support a single DNS Server instead\r
++  // of multiple such as is spec defined (RFC3646, Section 3). The proper behavior\r
++  // would be to allocate the full space requested, CopyMem all of the data,\r
++  // and then add a DnsServerCount field to Private and update additional code\r
++  // that depends on this.\r
++  //\r
++  // To support multiple DNS servers the `AllocationSize` would need to be changed to DnsServerLen\r
++  //\r
++  // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886\r
++  //\r
++  Private->DnsServer = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));\r
++  if (Private->DnsServer == NULL) {\r
++    return EFI_OUT_OF_RESOURCES;\r
++  }\r
++\r
++  //\r
++  // Intentionally only copy over the first server address.\r
++  // To support multiple DNS servers, the `Length` would need to be changed to DnsServerLen\r
++  //\r
++  CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS));\r
++\r
++  return EFI_SUCCESS;\r
++}\r
++\r
+ /**\r
+   Handle the DHCPv6 offer packet.\r
\r
+@@ -1335,6 +1395,7 @@ PxeBcHandleDhcp6Offer (
+   UINT32                    SelectIndex;\r
+   UINT32                    Index;\r
\r
++  ASSERT (Private != NULL);\r
+   ASSERT (Private->SelectIndex > 0);\r
+   SelectIndex = (UINT32)(Private->SelectIndex - 1);\r
+   ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM);\r
+@@ -1342,15 +1403,13 @@ PxeBcHandleDhcp6Offer (
+   Status = EFI_SUCCESS;\r
\r
+   //\r
+-  // First try to cache DNS server address if DHCP6 offer provides.\r
++  // First try to cache DNS server addresses if DHCP6 offer provides.\r
+   //\r
+   if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] != NULL) {\r
+-    Private->DnsServer = AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen));\r
+-    if (Private->DnsServer == NULL) {\r
+-      return EFI_OUT_OF_RESOURCES;\r
++    Status = PxeBcCacheDnsServerAddresses (Private, Cache6);\r
++    if (EFI_ERROR (Status)) {\r
++      return Status;\r
+     }\r
+-\r
+-    CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS));\r
+   }\r
\r
+   if (Cache6->OfferType == PxeOfferTypeDhcpBinl) {\r
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0002.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0002.patch
new file mode 100644 (file)
index 0000000..4bc7ac1
--- /dev/null
@@ -0,0 +1,485 @@
+From 458c582685fc0e8057d2511c5a0394078d988c17 Mon Sep 17 00:00:00 2001
+From: Doug Flick <dougflick@microsoft.com>
+Date: Fri, 26 Jan 2024 05:54:53 +0800
+Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Unit 
+ Tests
+
+REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539
+
+Unit tests to that the bug..
+
+Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise
+message
+
+..has been patched
+
+This contains tests for the following functions:
+PxeBcHandleDhcp6Offer
+PxeBcCacheDnsServerAddresses
+
+Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
+Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
+
+Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
+Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
+
+CVE: CVE-2023-45234
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/458c582685fc0e8057d2511c5a0394078d988c17]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ .../GoogleTest/PxeBcDhcp6GoogleTest.cpp       | 300 ++++++++++++++++++
+ .../GoogleTest/PxeBcDhcp6GoogleTest.h         |  50 +++
+ .../GoogleTest/UefiPxeBcDxeGoogleTest.cpp     |  19 ++
+ .../GoogleTest/UefiPxeBcDxeGoogleTest.inf     |  48 +++
+ 4 files changed, 417 insertions(+)
+ create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
+ create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
+ create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp
+ create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
+
+diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
+new file mode 100644
+index 0000000000..8260eeee50
+--- /dev/null
++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
+@@ -0,0 +1,300 @@
++/** @file\r
++  Host based unit test for PxeBcDhcp6.c.\r
++\r
++  Copyright (c) Microsoft Corporation\r
++  SPDX-License-Identifier: BSD-2-Clause-Patent\r
++**/\r
++#include <gtest/gtest.h>\r
++\r
++extern "C" {\r
++  #include <Uefi.h>\r
++  #include <Library/BaseLib.h>\r
++  #include <Library/DebugLib.h>\r
++  #include "../PxeBcImpl.h"\r
++  #include "../PxeBcDhcp6.h"\r
++  #include "PxeBcDhcp6GoogleTest.h"\r
++}\r
++\r
++///////////////////////////////////////////////////////////////////////////////\r
++// Definitions\r
++///////////////////////////////////////////////////////////////////////////////\r
++\r
++#define PACKET_SIZE  (1500)\r
++\r
++typedef struct {\r
++  UINT16    OptionCode;   // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03)\r
++  UINT16    OptionLen;    // The length of the option (e.g., 16 bytes)\r
++  UINT8     ServerId[16]; // The 16-byte DHCPv6 Server Identifier\r
++} DHCP6_OPTION_SERVER_ID;\r
++\r
++///////////////////////////////////////////////////////////////////////////////\r
++/// Symbol Definitions\r
++///////////////////////////////////////////////////////////////////////////////\r
++\r
++EFI_STATUS\r
++MockUdpWrite (\r
++  IN EFI_PXE_BASE_CODE_PROTOCOL      *This,\r
++  IN UINT16                          OpFlags,\r
++  IN EFI_IP_ADDRESS                  *DestIp,\r
++  IN EFI_PXE_BASE_CODE_UDP_PORT      *DestPort,\r
++  IN EFI_IP_ADDRESS                  *GatewayIp   OPTIONAL,\r
++  IN EFI_IP_ADDRESS                  *SrcIp       OPTIONAL,\r
++  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *SrcPort     OPTIONAL,\r
++  IN UINTN                           *HeaderSize  OPTIONAL,\r
++  IN VOID                            *HeaderPtr   OPTIONAL,\r
++  IN UINTN                           *BufferSize,\r
++  IN VOID                            *BufferPtr\r
++  )\r
++{\r
++  return EFI_SUCCESS;\r
++}\r
++\r
++EFI_STATUS\r
++MockUdpRead (\r
++  IN EFI_PXE_BASE_CODE_PROTOCOL      *This,\r
++  IN UINT16                          OpFlags,\r
++  IN OUT EFI_IP_ADDRESS              *DestIp      OPTIONAL,\r
++  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *DestPort    OPTIONAL,\r
++  IN OUT EFI_IP_ADDRESS              *SrcIp       OPTIONAL,\r
++  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *SrcPort     OPTIONAL,\r
++  IN UINTN                           *HeaderSize  OPTIONAL,\r
++  IN VOID                            *HeaderPtr   OPTIONAL,\r
++  IN OUT UINTN                       *BufferSize,\r
++  IN VOID                            *BufferPtr\r
++  )\r
++{\r
++  return EFI_SUCCESS;\r
++}\r
++\r
++EFI_STATUS\r
++MockConfigure (\r
++  IN EFI_UDP6_PROTOCOL     *This,\r
++  IN EFI_UDP6_CONFIG_DATA  *UdpConfigData OPTIONAL\r
++  )\r
++{\r
++  return EFI_SUCCESS;\r
++}\r
++\r
++// Needed by PxeBcSupport\r
++EFI_STATUS\r
++EFIAPI\r
++QueueDpc (\r
++  IN EFI_TPL            DpcTpl,\r
++  IN EFI_DPC_PROCEDURE  DpcProcedure,\r
++  IN VOID               *DpcContext    OPTIONAL\r
++  )\r
++{\r
++  return EFI_SUCCESS;\r
++}\r
++\r
++///////////////////////////////////////////////////////////////////////////////\r
++// PxeBcHandleDhcp6OfferTest Tests\r
++///////////////////////////////////////////////////////////////////////////////\r
++\r
++class PxeBcHandleDhcp6OfferTest : public ::testing::Test {\r
++public:\r
++  PXEBC_PRIVATE_DATA Private = { 0 };\r
++  EFI_UDP6_PROTOCOL Udp6Read;\r
++  EFI_PXE_BASE_CODE_MODE Mode = { 0 };\r
++\r
++protected:\r
++  // Add any setup code if needed\r
++  virtual void\r
++  SetUp (\r
++    )\r
++  {\r
++    Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);\r
++\r
++    // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL\r
++    // The function under test really only needs the following:\r
++    //  UdpWrite\r
++    //  UdpRead\r
++\r
++    Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite;\r
++    Private.PxeBc.UdpRead  = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead;\r
++\r
++    // Need to setup EFI_UDP6_PROTOCOL\r
++    // The function under test really only needs the following:\r
++    //  Configure\r
++\r
++    Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure;\r
++    Private.Udp6Read   = &Udp6Read;\r
++\r
++    // Need to setup the EFI_PXE_BASE_CODE_MODE\r
++    Private.PxeBc.Mode = &Mode;\r
++\r
++    // for this test it doesn't really matter what the Dhcpv6 ack is set to\r
++  }\r
++\r
++  // Add any cleanup code if needed\r
++  virtual void\r
++  TearDown (\r
++    )\r
++  {\r
++    if (Private.Dhcp6Request != NULL) {\r
++      FreePool (Private.Dhcp6Request);\r
++    }\r
++\r
++    // Clean up any resources or variables\r
++  }\r
++};\r
++\r
++// Note:\r
++// Testing PxeBcHandleDhcp6Offer() is difficult because it depends on a\r
++// properly setup Private structure. Attempting to properly test this function\r
++// without a signficant refactor is a fools errand. Instead, we will test\r
++// that we can prevent an overflow in the function.\r
++TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) {\r
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;\r
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };\r
++\r
++  Private.SelectIndex = 1; // SelectIndex is 1-based\r
++  Cache6              = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;\r
++\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;\r
++  // Setup the DHCPv6 offer packet\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen  = NTOHS (1337);\r
++\r
++  ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR);\r
++}\r
++\r
++class PxeBcCacheDnsServerAddressesTest : public ::testing::Test {\r
++public:\r
++  PXEBC_PRIVATE_DATA Private = { 0 };\r
++\r
++protected:\r
++  // Add any setup code if needed\r
++  virtual void\r
++  SetUp (\r
++    )\r
++  {\r
++  }\r
++\r
++  // Add any cleanup code if needed\r
++  virtual void\r
++  TearDown (\r
++    )\r
++  {\r
++  }\r
++};\r
++\r
++// Test Description\r
++// Test that we cache the DNS server address from the DHCPv6 offer packet\r
++TEST_F (PxeBcCacheDnsServerAddressesTest, BasicUsageTest) {\r
++  UINT8                     SearchPattern[16] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF };\r
++  EFI_DHCP6_PACKET_OPTION   *Option;\r
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;\r
++\r
++  Option = (EFI_DHCP6_PACKET_OPTION *)AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + sizeof (SearchPattern));\r
++  ASSERT_NE (Option, nullptr);\r
++\r
++  Option->OpCode = DHCP6_OPT_SERVER_ID;\r
++  Option->OpLen  = NTOHS (sizeof (SearchPattern));\r
++  CopyMem (Option->Data, SearchPattern, sizeof (SearchPattern));\r
++\r
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based\r
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option;\r
++\r
++  Private.DnsServer = nullptr;\r
++\r
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS);\r
++  ASSERT_NE (Private.DnsServer, nullptr);\r
++  ASSERT_EQ (CompareMem (Private.DnsServer, SearchPattern, sizeof (SearchPattern)), 0);\r
++\r
++  if (Private.DnsServer) {\r
++    FreePool (Private.DnsServer);\r
++  }\r
++\r
++  if (Option) {\r
++    FreePool (Option);\r
++  }\r
++}\r
++// Test Description\r
++// Test that we can prevent an overflow in the function\r
++TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptOverflowTest) {\r
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };\r
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;\r
++\r
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based\r
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;\r
++  // Setup the DHCPv6 offer packet\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen  = NTOHS (1337);\r
++\r
++  Private.DnsServer = NULL;\r
++\r
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR);\r
++  ASSERT_EQ (Private.DnsServer, nullptr);\r
++\r
++  if (Private.DnsServer) {\r
++    FreePool (Private.DnsServer);\r
++  }\r
++}\r
++\r
++// Test Description\r
++// Test that we can prevent an underflow in the function\r
++TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) {\r
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };\r
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;\r
++\r
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based\r
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;\r
++  // Setup the DHCPv6 offer packet\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen  = NTOHS (2);\r
++\r
++  Private.DnsServer = NULL;\r
++\r
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR);\r
++  ASSERT_EQ (Private.DnsServer, nullptr);\r
++\r
++  if (Private.DnsServer) {\r
++    FreePool (Private.DnsServer);\r
++  }\r
++}\r
++\r
++// Test Description\r
++// Test that we can handle recursive dns (multiple dns entries)\r
++TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {\r
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };\r
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;\r
++\r
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based\r
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;\r
++  // Setup the DHCPv6 offer packet\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;\r
++\r
++  EFI_IPv6_ADDRESS  addresses[2] = {\r
++    // 2001:db8:85a3::8a2e:370:7334\r
++    { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 },\r
++    // fe80::d478:91c3:ecd7:4ff9\r
++    { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 }\r
++  };\r
++\r
++  CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses));\r
++\r
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses));\r
++\r
++  Private.DnsServer = NULL;\r
++\r
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS);\r
++\r
++  ASSERT_NE (Private.DnsServer, nullptr);\r
++\r
++  //\r
++  // This is expected to fail until DnsServer supports multiple DNS servers\r
++  //\r
++  // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886\r
++  //\r
++  // Disabling:\r
++  // ASSERT_EQ (CompareMem(Private.DnsServer, &addresses, sizeof(addresses)), 0);\r
++\r
++  if (Private.DnsServer) {\r
++    FreePool (Private.DnsServer);\r
++  }\r
++}\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
+new file mode 100644
+index 0000000000..b17c314791
+--- /dev/null
++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
+@@ -0,0 +1,50 @@
++/** @file\r
++  This file exposes the internal interfaces which may be unit tested\r
++  for the PxeBcDhcp6Dxe driver.\r
++\r
++  Copyright (c) Microsoft Corporation.<BR>\r
++  SPDX-License-Identifier: BSD-2-Clause-Patent\r
++**/\r
++\r
++#ifndef PXE_BC_DHCP6_GOOGLE_TEST_H_\r
++#define PXE_BC_DHCP6_GOOGLE_TEST_H_\r
++\r
++//\r
++// Minimal includes needed to compile\r
++//\r
++#include <Uefi.h>\r
++#include "../PxeBcImpl.h"\r
++\r
++/**\r
++  Handle the DHCPv6 offer packet.\r
++\r
++  @param[in]  Private             The pointer to PXEBC_PRIVATE_DATA.\r
++\r
++  @retval     EFI_SUCCESS           Handled the DHCPv6 offer packet successfully.\r
++  @retval     EFI_NO_RESPONSE       No response to the following request packet.\r
++  @retval     EFI_OUT_OF_RESOURCES  Failed to allocate resources.\r
++  @retval     EFI_BUFFER_TOO_SMALL  Can't cache the offer pacet.\r
++\r
++**/\r
++EFI_STATUS\r
++PxeBcHandleDhcp6Offer (\r
++  IN PXEBC_PRIVATE_DATA  *Private\r
++  );\r
++\r
++/**\r
++  Cache the DHCPv6 Server address\r
++\r
++  @param[in] Private               The pointer to PXEBC_PRIVATE_DATA.\r
++  @param[in] Cache6                The pointer to PXEBC_DHCP6_PACKET_CACHE.\r
++\r
++  @retval    EFI_SUCCESS           Cache the DHCPv6 Server address successfully.\r
++  @retval    EFI_OUT_OF_RESOURCES  Failed to allocate resources.\r
++  @retval    EFI_DEVICE_ERROR      Failed to cache the DHCPv6 Server address.\r
++**/\r
++EFI_STATUS\r
++PxeBcCacheDnsServerAddresses (\r
++  IN PXEBC_PRIVATE_DATA        *Private,\r
++  IN PXEBC_DHCP6_PACKET_CACHE  *Cache6\r
++  );\r
++\r
++#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp
+new file mode 100644
+index 0000000000..cc4fdf525b
+--- /dev/null
++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp
+@@ -0,0 +1,19 @@
++/** @file\r
++  Acts as the main entry point for the tests for the UefiPxeBcDxe module.\r
++  Copyright (c) Microsoft Corporation\r
++  SPDX-License-Identifier: BSD-2-Clause-Patent\r
++**/\r
++#include <gtest/gtest.h>\r
++\r
++////////////////////////////////////////////////////////////////////////////////\r
++// Run the tests\r
++////////////////////////////////////////////////////////////////////////////////\r
++int\r
++main (\r
++  int   argc,\r
++  char  *argv[]\r
++  )\r
++{\r
++  testing::InitGoogleTest (&argc, argv);\r
++  return RUN_ALL_TESTS ();\r
++}\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
+new file mode 100644
+index 0000000000..301dcdf611
+--- /dev/null
++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
+@@ -0,0 +1,48 @@
++## @file\r
++# Unit test suite for the UefiPxeBcDxe using Google Test\r
++#\r
++# Copyright (c) Microsoft Corporation.<BR>\r
++# SPDX-License-Identifier: BSD-2-Clause-Patent\r
++##\r
++[Defines]\r
++INF_VERSION    = 0x00010005\r
++BASE_NAME      = UefiPxeBcDxeGoogleTest\r
++FILE_GUID      = 77D45C64-EC1E-4174-887B-886E89FD1EDF\r
++MODULE_TYPE    = HOST_APPLICATION\r
++VERSION_STRING = 1.0\r
++\r
++#\r
++# The following information is for reference only and not required by the build tools.\r
++#\r
++#  VALID_ARCHITECTURES           = IA32 X64\r
++#\r
++\r
++[Sources]\r
++  UefiPxeBcDxeGoogleTest.cpp\r
++  PxeBcDhcp6GoogleTest.cpp\r
++  PxeBcDhcp6GoogleTest.h\r
++  ../PxeBcDhcp6.c\r
++  ../PxeBcSupport.c\r
++\r
++[Packages]\r
++  MdePkg/MdePkg.dec\r
++  MdeModulePkg/MdeModulePkg.dec\r
++  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec\r
++  NetworkPkg/NetworkPkg.dec\r
++\r
++[LibraryClasses]\r
++  GoogleTestLib\r
++  DebugLib\r
++  NetLib\r
++  PcdLib\r
++\r
++[Protocols]\r
++  gEfiDhcp6ServiceBindingProtocolGuid\r
++  gEfiDns6ServiceBindingProtocolGuid\r
++  gEfiDns6ProtocolGuid\r
++\r
++[Pcd]\r
++  gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType\r
++\r
++[Guids]\r
++  gZeroGuid\r
+-- 
+2.40.0
+
index fc87cdf441d5afdeb755d9c464e88a12749a6ac1..ac6a0a40e72306f74265d953b3455d8ddcca79cd 100644 (file)
@@ -39,6 +39,8 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
            file://CVE-2023-45231-0002.patch \
            file://CVE-2023-45232-CVE-2023-45233-0001.patch \
            file://CVE-2023-45232-CVE-2023-45233-0002.patch \
+           file://CVE-2023-45234-0001.patch \
+           file://CVE-2023-45234-0002.patch \
            "
 
 PV = "edk2-stable202202"