diff mbox series

[kirkstone,06/11] ovmf: Fix CVE-2023-45234

Message ID 20240711045541.2155076-6-soumya.sambu@windriver.com
State Changes Requested
Delegated to: Steve Sakoman
Headers show
Series [kirkstone,01/11] ovmf: Fix CVE-2022-36763 | expand

Commit Message

ssambu July 11, 2024, 4:55 a.m. UTC
From: Soumya Sambu <soumya.sambu@windriver.com>

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>
---
 .../ovmf/ovmf/CVE-2023-45234-0001.patch       | 154 ++++++
 .../ovmf/ovmf/CVE-2023-45234-0002.patch       | 485 ++++++++++++++++++
 meta/recipes-core/ovmf/ovmf_git.bb            |   2 +
 3 files changed, 641 insertions(+)
 create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0001.patch
 create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0002.patch
diff mbox series

Patch

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
index 0000000000..463b4b824d
--- /dev/null
+++ b/meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0001.patch
@@ -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 @@
+ 
+   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
+   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
++  Copyright (c) Microsoft Corporation
+ 
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+ 
+@@ -1312,6 +1313,65 @@ PxeBcSelectDhcp6Offer (
+   }
+ }
+ 
++/**
++  Cache the DHCPv6 DNS Server addresses
++
++  @param[in] Private               The pointer to PXEBC_PRIVATE_DATA.
++  @param[in] Cache6                The pointer to PXEBC_DHCP6_PACKET_CACHE.
++
++  @retval    EFI_SUCCESS           Cache the DHCPv6 DNS Server address successfully.
++  @retval    EFI_OUT_OF_RESOURCES  Failed to allocate resources.
++  @retval    EFI_DEVICE_ERROR      The DNS Server Address Length provided by a untrusted
++                                   option is not a multiple of 16 bytes (sizeof (EFI_IPv6_ADDRESS)).
++**/
++EFI_STATUS
++PxeBcCacheDnsServerAddresses (
++  IN PXEBC_PRIVATE_DATA        *Private,
++  IN PXEBC_DHCP6_PACKET_CACHE  *Cache6
++  )
++{
++  UINT16  DnsServerLen;
++
++  DnsServerLen = NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen);
++  //
++  // Make sure that the number is nonzero
++  //
++  if (DnsServerLen == 0) {
++    return EFI_DEVICE_ERROR;
++  }
++
++  //
++  // Make sure the DnsServerlen is a multiple of EFI_IPv6_ADDRESS (16)
++  //
++  if (DnsServerLen % sizeof (EFI_IPv6_ADDRESS) != 0) {
++    return EFI_DEVICE_ERROR;
++  }
++
++  //
++  // This code is currently written to only support a single DNS Server instead
++  // of multiple such as is spec defined (RFC3646, Section 3). The proper behavior
++  // would be to allocate the full space requested, CopyMem all of the data,
++  // and then add a DnsServerCount field to Private and update additional code
++  // that depends on this.
++  //
++  // To support multiple DNS servers the `AllocationSize` would need to be changed to DnsServerLen
++  //
++  // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886
++  //
++  Private->DnsServer = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));
++  if (Private->DnsServer == NULL) {
++    return EFI_OUT_OF_RESOURCES;
++  }
++
++  //
++  // Intentionally only copy over the first server address.
++  // To support multiple DNS servers, the `Length` would need to be changed to DnsServerLen
++  //
++  CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS));
++
++  return EFI_SUCCESS;
++}
++
+ /**
+   Handle the DHCPv6 offer packet.
+ 
+@@ -1335,6 +1395,7 @@ PxeBcHandleDhcp6Offer (
+   UINT32                    SelectIndex;
+   UINT32                    Index;
+ 
++  ASSERT (Private != NULL);
+   ASSERT (Private->SelectIndex > 0);
+   SelectIndex = (UINT32)(Private->SelectIndex - 1);
+   ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM);
+@@ -1342,15 +1403,13 @@ PxeBcHandleDhcp6Offer (
+   Status = EFI_SUCCESS;
+ 
+   //
+-  // First try to cache DNS server address if DHCP6 offer provides.
++  // First try to cache DNS server addresses if DHCP6 offer provides.
+   //
+   if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] != NULL) {
+-    Private->DnsServer = AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen));
+-    if (Private->DnsServer == NULL) {
+-      return EFI_OUT_OF_RESOURCES;
++    Status = PxeBcCacheDnsServerAddresses (Private, Cache6);
++    if (EFI_ERROR (Status)) {
++      return Status;
+     }
+-
+-    CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS));
+   }
+ 
+   if (Cache6->OfferType == PxeOfferTypeDhcpBinl) {
+-- 
+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
index 0000000000..4bc7ac16d6
--- /dev/null
+++ b/meta/recipes-core/ovmf/ovmf/CVE-2023-45234-0002.patch
@@ -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
++  Host based unit test for PxeBcDhcp6.c.
++
++  Copyright (c) Microsoft Corporation
++  SPDX-License-Identifier: BSD-2-Clause-Patent
++**/
++#include <gtest/gtest.h>
++
++extern "C" {
++  #include <Uefi.h>
++  #include <Library/BaseLib.h>
++  #include <Library/DebugLib.h>
++  #include "../PxeBcImpl.h"
++  #include "../PxeBcDhcp6.h"
++  #include "PxeBcDhcp6GoogleTest.h"
++}
++
++///////////////////////////////////////////////////////////////////////////////
++// Definitions
++///////////////////////////////////////////////////////////////////////////////
++
++#define PACKET_SIZE  (1500)
++
++typedef struct {
++  UINT16    OptionCode;   // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03)
++  UINT16    OptionLen;    // The length of the option (e.g., 16 bytes)
++  UINT8     ServerId[16]; // The 16-byte DHCPv6 Server Identifier
++} DHCP6_OPTION_SERVER_ID;
++
++///////////////////////////////////////////////////////////////////////////////
++/// Symbol Definitions
++///////////////////////////////////////////////////////////////////////////////
++
++EFI_STATUS
++MockUdpWrite (
++  IN EFI_PXE_BASE_CODE_PROTOCOL      *This,
++  IN UINT16                          OpFlags,
++  IN EFI_IP_ADDRESS                  *DestIp,
++  IN EFI_PXE_BASE_CODE_UDP_PORT      *DestPort,
++  IN EFI_IP_ADDRESS                  *GatewayIp   OPTIONAL,
++  IN EFI_IP_ADDRESS                  *SrcIp       OPTIONAL,
++  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *SrcPort     OPTIONAL,
++  IN UINTN                           *HeaderSize  OPTIONAL,
++  IN VOID                            *HeaderPtr   OPTIONAL,
++  IN UINTN                           *BufferSize,
++  IN VOID                            *BufferPtr
++  )
++{
++  return EFI_SUCCESS;
++}
++
++EFI_STATUS
++MockUdpRead (
++  IN EFI_PXE_BASE_CODE_PROTOCOL      *This,
++  IN UINT16                          OpFlags,
++  IN OUT EFI_IP_ADDRESS              *DestIp      OPTIONAL,
++  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *DestPort    OPTIONAL,
++  IN OUT EFI_IP_ADDRESS              *SrcIp       OPTIONAL,
++  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *SrcPort     OPTIONAL,
++  IN UINTN                           *HeaderSize  OPTIONAL,
++  IN VOID                            *HeaderPtr   OPTIONAL,
++  IN OUT UINTN                       *BufferSize,
++  IN VOID                            *BufferPtr
++  )
++{
++  return EFI_SUCCESS;
++}
++
++EFI_STATUS
++MockConfigure (
++  IN EFI_UDP6_PROTOCOL     *This,
++  IN EFI_UDP6_CONFIG_DATA  *UdpConfigData OPTIONAL
++  )
++{
++  return EFI_SUCCESS;
++}
++
++// Needed by PxeBcSupport
++EFI_STATUS
++EFIAPI
++QueueDpc (
++  IN EFI_TPL            DpcTpl,
++  IN EFI_DPC_PROCEDURE  DpcProcedure,
++  IN VOID               *DpcContext    OPTIONAL
++  )
++{
++  return EFI_SUCCESS;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++// PxeBcHandleDhcp6OfferTest Tests
++///////////////////////////////////////////////////////////////////////////////
++
++class PxeBcHandleDhcp6OfferTest : public ::testing::Test {
++public:
++  PXEBC_PRIVATE_DATA Private = { 0 };
++  EFI_UDP6_PROTOCOL Udp6Read;
++  EFI_PXE_BASE_CODE_MODE Mode = { 0 };
++
++protected:
++  // Add any setup code if needed
++  virtual void
++  SetUp (
++    )
++  {
++    Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);
++
++    // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL
++    // The function under test really only needs the following:
++    //  UdpWrite
++    //  UdpRead
++
++    Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite;
++    Private.PxeBc.UdpRead  = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead;
++
++    // Need to setup EFI_UDP6_PROTOCOL
++    // The function under test really only needs the following:
++    //  Configure
++
++    Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure;
++    Private.Udp6Read   = &Udp6Read;
++
++    // Need to setup the EFI_PXE_BASE_CODE_MODE
++    Private.PxeBc.Mode = &Mode;
++
++    // for this test it doesn't really matter what the Dhcpv6 ack is set to
++  }
++
++  // Add any cleanup code if needed
++  virtual void
++  TearDown (
++    )
++  {
++    if (Private.Dhcp6Request != NULL) {
++      FreePool (Private.Dhcp6Request);
++    }
++
++    // Clean up any resources or variables
++  }
++};
++
++// Note:
++// Testing PxeBcHandleDhcp6Offer() is difficult because it depends on a
++// properly setup Private structure. Attempting to properly test this function
++// without a signficant refactor is a fools errand. Instead, we will test
++// that we can prevent an overflow in the function.
++TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) {
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };
++
++  Private.SelectIndex = 1; // SelectIndex is 1-based
++  Cache6              = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
++
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
++  // Setup the DHCPv6 offer packet
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen  = NTOHS (1337);
++
++  ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR);
++}
++
++class PxeBcCacheDnsServerAddressesTest : public ::testing::Test {
++public:
++  PXEBC_PRIVATE_DATA Private = { 0 };
++
++protected:
++  // Add any setup code if needed
++  virtual void
++  SetUp (
++    )
++  {
++  }
++
++  // Add any cleanup code if needed
++  virtual void
++  TearDown (
++    )
++  {
++  }
++};
++
++// Test Description
++// Test that we cache the DNS server address from the DHCPv6 offer packet
++TEST_F (PxeBcCacheDnsServerAddressesTest, BasicUsageTest) {
++  UINT8                     SearchPattern[16] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF };
++  EFI_DHCP6_PACKET_OPTION   *Option;
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;
++
++  Option = (EFI_DHCP6_PACKET_OPTION *)AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + sizeof (SearchPattern));
++  ASSERT_NE (Option, nullptr);
++
++  Option->OpCode = DHCP6_OPT_SERVER_ID;
++  Option->OpLen  = NTOHS (sizeof (SearchPattern));
++  CopyMem (Option->Data, SearchPattern, sizeof (SearchPattern));
++
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option;
++
++  Private.DnsServer = nullptr;
++
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS);
++  ASSERT_NE (Private.DnsServer, nullptr);
++  ASSERT_EQ (CompareMem (Private.DnsServer, SearchPattern, sizeof (SearchPattern)), 0);
++
++  if (Private.DnsServer) {
++    FreePool (Private.DnsServer);
++  }
++
++  if (Option) {
++    FreePool (Option);
++  }
++}
++// Test Description
++// Test that we can prevent an overflow in the function
++TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptOverflowTest) {
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;
++
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
++  // Setup the DHCPv6 offer packet
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen  = NTOHS (1337);
++
++  Private.DnsServer = NULL;
++
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR);
++  ASSERT_EQ (Private.DnsServer, nullptr);
++
++  if (Private.DnsServer) {
++    FreePool (Private.DnsServer);
++  }
++}
++
++// Test Description
++// Test that we can prevent an underflow in the function
++TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) {
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;
++
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
++  // Setup the DHCPv6 offer packet
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen  = NTOHS (2);
++
++  Private.DnsServer = NULL;
++
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR);
++  ASSERT_EQ (Private.DnsServer, nullptr);
++
++  if (Private.DnsServer) {
++    FreePool (Private.DnsServer);
++  }
++}
++
++// Test Description
++// Test that we can handle recursive dns (multiple dns entries)
++TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
++  EFI_DHCP6_PACKET_OPTION   Option  = { 0 };
++  PXEBC_DHCP6_PACKET_CACHE  *Cache6 = NULL;
++
++  Private.SelectIndex                         = 1; // SelectIndex is 1-based
++  Cache6                                      = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
++  // Setup the DHCPv6 offer packet
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
++
++  EFI_IPv6_ADDRESS  addresses[2] = {
++    // 2001:db8:85a3::8a2e:370:7334
++    { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 },
++    // fe80::d478:91c3:ecd7:4ff9
++    { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 }
++  };
++
++  CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses));
++
++  Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses));
++
++  Private.DnsServer = NULL;
++
++  ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS);
++
++  ASSERT_NE (Private.DnsServer, nullptr);
++
++  //
++  // This is expected to fail until DnsServer supports multiple DNS servers
++  //
++  // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886
++  //
++  // Disabling:
++  // ASSERT_EQ (CompareMem(Private.DnsServer, &addresses, sizeof(addresses)), 0);
++
++  if (Private.DnsServer) {
++    FreePool (Private.DnsServer);
++  }
++}
+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
++  This file exposes the internal interfaces which may be unit tested
++  for the PxeBcDhcp6Dxe driver.
++
++  Copyright (c) Microsoft Corporation.<BR>
++  SPDX-License-Identifier: BSD-2-Clause-Patent
++**/
++
++#ifndef PXE_BC_DHCP6_GOOGLE_TEST_H_
++#define PXE_BC_DHCP6_GOOGLE_TEST_H_
++
++//
++// Minimal includes needed to compile
++//
++#include <Uefi.h>
++#include "../PxeBcImpl.h"
++
++/**
++  Handle the DHCPv6 offer packet.
++
++  @param[in]  Private             The pointer to PXEBC_PRIVATE_DATA.
++
++  @retval     EFI_SUCCESS           Handled the DHCPv6 offer packet successfully.
++  @retval     EFI_NO_RESPONSE       No response to the following request packet.
++  @retval     EFI_OUT_OF_RESOURCES  Failed to allocate resources.
++  @retval     EFI_BUFFER_TOO_SMALL  Can't cache the offer pacet.
++
++**/
++EFI_STATUS
++PxeBcHandleDhcp6Offer (
++  IN PXEBC_PRIVATE_DATA  *Private
++  );
++
++/**
++  Cache the DHCPv6 Server address
++
++  @param[in] Private               The pointer to PXEBC_PRIVATE_DATA.
++  @param[in] Cache6                The pointer to PXEBC_DHCP6_PACKET_CACHE.
++
++  @retval    EFI_SUCCESS           Cache the DHCPv6 Server address successfully.
++  @retval    EFI_OUT_OF_RESOURCES  Failed to allocate resources.
++  @retval    EFI_DEVICE_ERROR      Failed to cache the DHCPv6 Server address.
++**/
++EFI_STATUS
++PxeBcCacheDnsServerAddresses (
++  IN PXEBC_PRIVATE_DATA        *Private,
++  IN PXEBC_DHCP6_PACKET_CACHE  *Cache6
++  );
++
++#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_
+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
++  Acts as the main entry point for the tests for the UefiPxeBcDxe module.
++  Copyright (c) Microsoft Corporation
++  SPDX-License-Identifier: BSD-2-Clause-Patent
++**/
++#include <gtest/gtest.h>
++
++////////////////////////////////////////////////////////////////////////////////
++// Run the tests
++////////////////////////////////////////////////////////////////////////////////
++int
++main (
++  int   argc,
++  char  *argv[]
++  )
++{
++  testing::InitGoogleTest (&argc, argv);
++  return RUN_ALL_TESTS ();
++}
+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
++# Unit test suite for the UefiPxeBcDxe using Google Test
++#
++# Copyright (c) Microsoft Corporation.<BR>
++# SPDX-License-Identifier: BSD-2-Clause-Patent
++##
++[Defines]
++INF_VERSION    = 0x00010005
++BASE_NAME      = UefiPxeBcDxeGoogleTest
++FILE_GUID      = 77D45C64-EC1E-4174-887B-886E89FD1EDF
++MODULE_TYPE    = HOST_APPLICATION
++VERSION_STRING = 1.0
++
++#
++# The following information is for reference only and not required by the build tools.
++#
++#  VALID_ARCHITECTURES           = IA32 X64
++#
++
++[Sources]
++  UefiPxeBcDxeGoogleTest.cpp
++  PxeBcDhcp6GoogleTest.cpp
++  PxeBcDhcp6GoogleTest.h
++  ../PxeBcDhcp6.c
++  ../PxeBcSupport.c
++
++[Packages]
++  MdePkg/MdePkg.dec
++  MdeModulePkg/MdeModulePkg.dec
++  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
++  NetworkPkg/NetworkPkg.dec
++
++[LibraryClasses]
++  GoogleTestLib
++  DebugLib
++  NetLib
++  PcdLib
++
++[Protocols]
++  gEfiDhcp6ServiceBindingProtocolGuid
++  gEfiDns6ServiceBindingProtocolGuid
++  gEfiDns6ProtocolGuid
++
++[Pcd]
++  gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType
++
++[Guids]
++  gZeroGuid
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf_git.bb b/meta/recipes-core/ovmf/ovmf_git.bb
index fc87cdf441..ac6a0a40e7 100644
--- a/meta/recipes-core/ovmf/ovmf_git.bb
+++ b/meta/recipes-core/ovmf/ovmf_git.bb
@@ -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"