]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
ovmf: Fix CVE-2023-45235
authorSoumya Sambu <soumya.sambu@windriver.com>
Fri, 28 Jun 2024 09:35:16 +0000 (09:35 +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 handling Server ID option from a DHCPv6 proxy 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-45235

Upstream-patches:
https://github.com/tianocore/edk2/commit/fac297724e6cc343430cd0104e55cd7a96d1151e
https://github.com/tianocore/edk2/commit/ff2986358f75d8f58ef08a66fe673539c9c48f41

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

diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0001.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0001.patch
new file mode 100644 (file)
index 0000000..264172f
--- /dev/null
@@ -0,0 +1,243 @@
+From fac297724e6cc343430cd0104e55cd7a96d1151e Mon Sep 17 00:00:00 2001
+From: Doug Flick <dougflick@microsoft.com>
+Date: Fri, 26 Jan 2024 05:54:55 +0800
+Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch
+
+REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540
+
+Bug Details:
+PixieFail Bug #7
+CVE-2023-45235
+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 handling Server ID option from a DHCPv6 proxy
+Advertise message
+
+Change Overview:
+
+Performs two checks
+
+1. Checks that the length of the duid is accurate
+> + //
+> + // Check that the minimum and maximum requirements are met
+> + //
+> + if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) ||
+(OpLen > PXEBC_MAX_SIZE_OF_DUID)) {
+> +  Status = EFI_INVALID_PARAMETER;
+> +  goto ON_ERROR;
+> + }
+
+2. Ensures that the amount of data written to the buffer is tracked and
+never exceeds that
+> + //
+> + // Check that the option length is valid.
+> + //
+> + if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN)
+ > DiscoverLenNeeded) {
+> +     Status = EFI_OUT_OF_RESOURCES;
+> +     goto ON_ERROR;
+> + }
+
+Additional code clean up and fix for memory leak in case Option was NULL
+
+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-45235
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/fac297724e6cc343430cd0104e55cd7a96d1151e]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 77 ++++++++++++++++++++++------
+ NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 ++++++
+ 2 files changed, 78 insertions(+), 16 deletions(-)
+
+diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+index 2b2d372889..7fd1281c11 100644
+--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+@@ -887,6 +887,7 @@ PxeBcRequestBootService (
+   EFI_STATUS                       Status;\r
+   EFI_DHCP6_PACKET                 *IndexOffer;\r
+   UINT8                            *Option;\r
++  UINTN                            DiscoverLenNeeded;\r
\r
+   PxeBc      = &Private->PxeBc;\r
+   Request    = Private->Dhcp6Request;\r
+@@ -899,7 +900,8 @@ PxeBcRequestBootService (
+     return EFI_DEVICE_ERROR;\r
+   }\r
\r
+-  Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));\r
++  DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);\r
++  Discover          = AllocateZeroPool (DiscoverLenNeeded);\r
+   if (Discover == NULL) {\r
+     return EFI_OUT_OF_RESOURCES;\r
+   }\r
+@@ -924,16 +926,34 @@ PxeBcRequestBootService (
+                DHCP6_OPT_SERVER_ID\r
+                );\r
+     if (Option == NULL) {\r
+-      return EFI_NOT_FOUND;\r
++      Status = EFI_NOT_FOUND;\r
++      goto ON_ERROR;\r
+     }\r
\r
+     //\r
+     // Add Server ID Option.\r
+     //\r
+     OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen);\r
+-    CopyMem (DiscoverOpt, Option, OpLen + 4);\r
+-    DiscoverOpt += (OpLen + 4);\r
+-    DiscoverLen += (OpLen + 4);\r
++\r
++    //\r
++    // Check that the minimum and maximum requirements are met\r
++    //\r
++    if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) {\r
++      Status = EFI_INVALID_PARAMETER;\r
++      goto ON_ERROR;\r
++    }\r
++\r
++    //\r
++    // Check that the option length is valid.\r
++    //\r
++    if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) {\r
++      Status = EFI_OUT_OF_RESOURCES;\r
++      goto ON_ERROR;\r
++    }\r
++\r
++    CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++    DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++    DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
+   }\r
\r
+   while (RequestLen < Request->Length) {\r
+@@ -944,16 +964,24 @@ PxeBcRequestBootService (
+         (OpCode != DHCP6_OPT_SERVER_ID)\r
+         )\r
+     {\r
++      //\r
++      // Check that the option length is valid.\r
++      //\r
++      if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {\r
++        Status = EFI_OUT_OF_RESOURCES;\r
++        goto ON_ERROR;\r
++      }\r
++\r
+       //\r
+       // Copy all the options except IA option and Server ID\r
+       //\r
+-      CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);\r
+-      DiscoverOpt += (OpLen + 4);\r
+-      DiscoverLen += (OpLen + 4);\r
++      CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++      DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++      DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
+     }\r
\r
+-    RequestOpt += (OpLen + 4);\r
+-    RequestLen += (OpLen + 4);\r
++    RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++    RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
+   }\r
\r
+   //\r
+@@ -2154,6 +2182,7 @@ PxeBcDhcp6Discover (
+   UINT16                           OpLen;\r
+   UINT32                           Xid;\r
+   EFI_STATUS                       Status;\r
++  UINTN                            DiscoverLenNeeded;\r
\r
+   PxeBc    = &Private->PxeBc;\r
+   Mode     = PxeBc->Mode;\r
+@@ -2169,7 +2198,8 @@ PxeBcDhcp6Discover (
+     return EFI_DEVICE_ERROR;\r
+   }\r
\r
+-  Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));\r
++  DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);\r
++  Discover          = AllocateZeroPool (DiscoverLenNeeded);\r
+   if (Discover == NULL) {\r
+     return EFI_OUT_OF_RESOURCES;\r
+   }\r
+@@ -2185,22 +2215,37 @@ PxeBcDhcp6Discover (
+   DiscoverLen             = sizeof (EFI_DHCP6_HEADER);\r
+   RequestLen              = DiscoverLen;\r
\r
++  //\r
++  // The request packet is generated by the UEFI network stack. In the DHCP4 DORA and DHCP6 SARR sequence,\r
++  // the first (discover in DHCP4 and solicit in DHCP6) and third (request in both DHCP4 and DHCP6) are\r
++  // generated by the DHCP client (the UEFI network stack in this case). By the time this function executes,\r
++  // the DHCP sequence already has been executed once (see UEFI Specification Figures 24.2 and 24.3), with\r
++  // Private->Dhcp6Request being a cached copy of the DHCP6 request packet that UEFI network stack previously\r
++  // generated and sent.\r
++  //\r
++  // Therefore while this code looks like it could overflow, in practice it's not possible.\r
++  //\r
+   while (RequestLen < Request->Length) {\r
+     OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpCode);\r
+     OpLen  = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpLen);\r
+     if ((OpCode != EFI_DHCP6_IA_TYPE_NA) &&\r
+         (OpCode != EFI_DHCP6_IA_TYPE_TA))\r
+     {\r
++      if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {\r
++        Status = EFI_OUT_OF_RESOURCES;\r
++        goto ON_ERROR;\r
++      }\r
++\r
+       //\r
+       // Copy all the options except IA option.\r
+       //\r
+-      CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);\r
+-      DiscoverOpt += (OpLen + 4);\r
+-      DiscoverLen += (OpLen + 4);\r
++      CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++      DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++      DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
+     }\r
\r
+-    RequestOpt += (OpLen + 4);\r
+-    RequestLen += (OpLen + 4);\r
++    RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
++    RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);\r
+   }\r
\r
+   Status = PxeBc->UdpWrite (\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
+index c86f6d391b..6357d27fae 100644
+--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
+@@ -34,6 +34,23 @@
+ #define PXEBC_ADDR_START_DELIMITER        '['\r
+ #define PXEBC_ADDR_END_DELIMITER          ']'\r
\r
++//\r
++// A DUID consists of a 2-octet type code represented in network byte\r
++// order, followed by a variable number of octets that make up the\r
++// actual identifier.  The length of the DUID (not including the type\r
++// code) is at least 1 octet and at most 128 octets.\r
++//\r
++#define PXEBC_MIN_SIZE_OF_DUID  (sizeof(UINT16) + 1)\r
++#define PXEBC_MAX_SIZE_OF_DUID  (sizeof(UINT16) + 128)\r
++\r
++//\r
++// This define represents the combineds code and length field from\r
++// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1\r
++//\r
++#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN  \\r
++      (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \\r
++      sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen))\r
++\r
+ #define GET_NEXT_DHCP6_OPTION(Opt) \\r
+   (EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \\r
+   sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1)\r
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0002.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0002.patch
new file mode 100644 (file)
index 0000000..0e814a0
--- /dev/null
@@ -0,0 +1,379 @@
+From ff2986358f75d8f58ef08a66fe673539c9c48f41 Mon Sep 17 00:00:00 2001
+From: Doug Flick <dougflick@microsoft.com>
+Date: Fri, 26 Jan 2024 05:54:56 +0800
+Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit 
+ Tests
+
+REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540
+
+Unit tests to confirm that the bug..
+
+Buffer overflow when handling Server ID option from a DHCPv6 proxy
+Advertise message
+
+..has been patched.
+
+This patch contains unit tests for the following functions:
+PxeBcRequestBootService
+PxeBcDhcp6Discover
+
+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-45235
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/ff2986358f75d8f58ef08a66fe673539c9c48f41]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ .../GoogleTest/PxeBcDhcp6GoogleTest.cpp       | 278 +++++++++++++++++-
+ .../GoogleTest/PxeBcDhcp6GoogleTest.h         |  18 ++
+ 2 files changed, 294 insertions(+), 2 deletions(-)
+
+diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
+index 8260eeee50..bd423ebadf 100644
+--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
+@@ -4,7 +4,9 @@
+   Copyright (c) Microsoft Corporation\r
+   SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ **/\r
+-#include <gtest/gtest.h>\r
++#include <Library/GoogleTestLib.h>\r
++#include <GoogleTest/Library/MockUefiLib.h>\r
++#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>\r
\r
+ extern "C" {\r
+   #include <Uefi.h>\r
+@@ -19,7 +21,8 @@ extern "C" {
+ // Definitions\r
+ ///////////////////////////////////////////////////////////////////////////////\r
\r
+-#define PACKET_SIZE  (1500)\r
++#define PACKET_SIZE            (1500)\r
++#define REQUEST_OPTION_LENGTH  (120)\r
\r
+ typedef struct {\r
+   UINT16    OptionCode;   // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03)\r
+@@ -76,6 +79,26 @@ MockConfigure (
+ }\r
\r
+ // Needed by PxeBcSupport\r
++EFI_STATUS\r
++PxeBcDns6 (\r
++  IN PXEBC_PRIVATE_DATA  *Private,\r
++  IN     CHAR16          *HostName,\r
++  OUT EFI_IPv6_ADDRESS   *IpAddress\r
++  )\r
++{\r
++  return EFI_SUCCESS;\r
++}\r
++\r
++UINT32\r
++PxeBcBuildDhcp6Options (\r
++  IN  PXEBC_PRIVATE_DATA       *Private,\r
++  OUT EFI_DHCP6_PACKET_OPTION  **OptList,\r
++  IN  UINT8                    *Buffer\r
++  )\r
++{\r
++  return EFI_SUCCESS;\r
++}\r
++\r
+ EFI_STATUS\r
+ EFIAPI\r
+ QueueDpc (\r
+@@ -159,6 +182,10 @@ TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) {
+   ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR);\r
+ }\r
\r
++///////////////////////////////////////////////////////////////////////////////\r
++// PxeBcCacheDnsServerAddresses Tests\r
++///////////////////////////////////////////////////////////////////////////////\r
++\r
+ class PxeBcCacheDnsServerAddressesTest : public ::testing::Test {\r
+ public:\r
+   PXEBC_PRIVATE_DATA Private = { 0 };\r
+@@ -298,3 +325,250 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
+     FreePool (Private.DnsServer);\r
+   }\r
+ }\r
++\r
++///////////////////////////////////////////////////////////////////////////////\r
++// PxeBcRequestBootServiceTest Test Cases\r
++///////////////////////////////////////////////////////////////////////////////\r
++\r
++class PxeBcRequestBootServiceTest : public ::testing::Test {\r
++public:\r
++  PXEBC_PRIVATE_DATA Private = { 0 };\r
++  EFI_UDP6_PROTOCOL Udp6Read;\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
++\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
++TEST_F (PxeBcRequestBootServiceTest, ServerDiscoverBasicUsageTest) {\r
++  PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;\r
++\r
++  DHCP6_OPTION_SERVER_ID  Server = { 0 };\r
++\r
++  Server.OptionCode =  HTONS (DHCP6_OPT_SERVER_ID);\r
++  Server.OptionLen  = HTONS (16); // valid length\r
++  UINT8  Index = 0;\r
++\r
++  EFI_DHCP6_PACKET  *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;\r
++\r
++  UINT8  *Cursor = (UINT8 *)(Packet->Dhcp6.Option);\r
++\r
++  CopyMem (Cursor, &Server, sizeof (Server));\r
++  Cursor += sizeof (Server);\r
++\r
++  // Update the packet length\r
++  Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);\r
++  Packet->Size   = PACKET_SIZE;\r
++\r
++  ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);\r
++}\r
++\r
++TEST_F (PxeBcRequestBootServiceTest, AttemptDiscoverOverFlowExpectFailure) {\r
++  PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;\r
++\r
++  DHCP6_OPTION_SERVER_ID  Server = { 0 };\r
++\r
++  Server.OptionCode =  HTONS (DHCP6_OPT_SERVER_ID);\r
++  Server.OptionLen  = HTONS (1500); // This length would overflow without a check\r
++  UINT8  Index = 0;\r
++\r
++  EFI_DHCP6_PACKET  *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;\r
++\r
++  UINT8  *Cursor = (UINT8 *)(Packet->Dhcp6.Option);\r
++\r
++  CopyMem (Cursor, &Server, sizeof (Server));\r
++  Cursor += sizeof (Server);\r
++\r
++  // Update the packet length\r
++  Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);\r
++  Packet->Size   = PACKET_SIZE;\r
++\r
++  // This is going to be stopped by the duid overflow check\r
++  ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_INVALID_PARAMETER);\r
++}\r
++\r
++TEST_F (PxeBcRequestBootServiceTest, RequestBasicUsageTest) {\r
++  EFI_DHCP6_PACKET_OPTION  RequestOpt = { 0 }; // the data section doesn't really matter\r
++\r
++  RequestOpt.OpCode = HTONS (0x1337);\r
++  RequestOpt.OpLen  = 0; // valid length\r
++\r
++  UINT8  Index = 0;\r
++\r
++  EFI_DHCP6_PACKET  *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];\r
++\r
++  UINT8  *Cursor = (UINT8 *)(Packet->Dhcp6.Option);\r
++\r
++  CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));\r
++  Cursor += sizeof (RequestOpt);\r
++\r
++  // Update the packet length\r
++  Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);\r
++  Packet->Size   = PACKET_SIZE;\r
++\r
++  ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);\r
++}\r
++\r
++TEST_F (PxeBcRequestBootServiceTest, AttemptRequestOverFlowExpectFailure) {\r
++  EFI_DHCP6_PACKET_OPTION  RequestOpt = { 0 }; // the data section doesn't really matter\r
++\r
++  RequestOpt.OpCode = HTONS (0x1337);\r
++  RequestOpt.OpLen  = 1500; // this length would overflow without a check\r
++\r
++  UINT8  Index = 0;\r
++\r
++  EFI_DHCP6_PACKET  *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];\r
++\r
++  UINT8  *Cursor = (UINT8 *)(Packet->Dhcp6.Option);\r
++\r
++  CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));\r
++  Cursor += sizeof (RequestOpt);\r
++\r
++  // Update the packet length\r
++  Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);\r
++  Packet->Size   = PACKET_SIZE;\r
++\r
++  ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_OUT_OF_RESOURCES);\r
++}\r
++\r
++///////////////////////////////////////////////////////////////////////////////\r
++// PxeBcDhcp6Discover Test\r
++///////////////////////////////////////////////////////////////////////////////\r
++\r
++class PxeBcDhcp6DiscoverTest : public ::testing::Test {\r
++public:\r
++  PXEBC_PRIVATE_DATA Private = { 0 };\r
++  EFI_UDP6_PROTOCOL Udp6Read;\r
++\r
++protected:\r
++  MockUefiRuntimeServicesTableLib RtServicesMock;\r
++\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
++\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
++// Test Description\r
++// This will cause an overflow by an untrusted packet during the option parsing\r
++TEST_F (PxeBcDhcp6DiscoverTest, BasicOverflowTest) {\r
++  EFI_IPv6_ADDRESS         DestIp     = { 0 };\r
++  EFI_DHCP6_PACKET_OPTION  RequestOpt = { 0 }; // the data section doesn't really matter\r
++\r
++  RequestOpt.OpCode = HTONS (0x1337);\r
++  RequestOpt.OpLen  = HTONS (0xFFFF); // overflow\r
++\r
++  UINT8  *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);\r
++\r
++  CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));\r
++  Cursor += sizeof (RequestOpt);\r
++\r
++  Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);\r
++\r
++  EXPECT_CALL (RtServicesMock, gRT_GetTime)\r
++    .WillOnce (::testing::Return (0));\r
++\r
++  ASSERT_EQ (\r
++    PxeBcDhcp6Discover (\r
++      &(PxeBcDhcp6DiscoverTest::Private),\r
++      0,\r
++      NULL,\r
++      FALSE,\r
++      (EFI_IP_ADDRESS *)&DestIp\r
++      ),\r
++    EFI_OUT_OF_RESOURCES\r
++    );\r
++}\r
++\r
++// Test Description\r
++// This will test that we can handle a packet with a valid option length\r
++TEST_F (PxeBcDhcp6DiscoverTest, BasicUsageTest) {\r
++  EFI_IPv6_ADDRESS         DestIp     = { 0 };\r
++  EFI_DHCP6_PACKET_OPTION  RequestOpt = { 0 }; // the data section doesn't really matter\r
++\r
++  RequestOpt.OpCode = HTONS (0x1337);\r
++  RequestOpt.OpLen  = HTONS (0x30);\r
++\r
++  UINT8  *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);\r
++\r
++  CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));\r
++  Cursor += sizeof (RequestOpt);\r
++\r
++  Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);\r
++\r
++  EXPECT_CALL (RtServicesMock, gRT_GetTime)\r
++    .WillOnce (::testing::Return (0));\r
++\r
++  ASSERT_EQ (\r
++    PxeBcDhcp6Discover (\r
++      &(PxeBcDhcp6DiscoverTest::Private),\r
++      0,\r
++      NULL,\r
++      FALSE,\r
++      (EFI_IP_ADDRESS *)&DestIp\r
++      ),\r
++    EFI_SUCCESS\r
++    );\r
++}\r
+diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
+index b17c314791..0d825e4425 100644
+--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
++++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
+@@ -47,4 +47,22 @@ PxeBcCacheDnsServerAddresses (
+   IN PXEBC_DHCP6_PACKET_CACHE  *Cache6\r
+   );\r
\r
++/**\r
++  Build and send out the request packet for the bootfile, and parse the reply.\r
++\r
++  @param[in]  Private               The pointer to PxeBc private data.\r
++  @param[in]  Index                 PxeBc option boot item type.\r
++\r
++  @retval     EFI_SUCCESS           Successfully discovered the boot file.\r
++  @retval     EFI_OUT_OF_RESOURCES  Failed to allocate resources.\r
++  @retval     EFI_NOT_FOUND         Can't get the PXE reply packet.\r
++  @retval     Others                Failed to discover the boot file.\r
++\r
++**/\r
++EFI_STATUS\r
++PxeBcRequestBootService (\r
++  IN  PXEBC_PRIVATE_DATA  *Private,\r
++  IN  UINT32              Index\r
++  );\r
++\r
+ #endif // PXE_BC_DHCP6_GOOGLE_TEST_H_\r
+-- 
+2.40.0
+
index ac6a0a40e72306f74265d953b3455d8ddcca79cd..ceebb53438bbe4288b8249569dcb3a3cc44c50fa 100644 (file)
@@ -41,6 +41,8 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
            file://CVE-2023-45232-CVE-2023-45233-0002.patch \
            file://CVE-2023-45234-0001.patch \
            file://CVE-2023-45234-0002.patch \
+           file://CVE-2023-45235-0001.patch \
+           file://CVE-2023-45235-0002.patch \
            "
 
 PV = "edk2-stable202202"