mirror of
https://git.yoctoproject.org/poky
synced 2026-05-30 00:20:08 +00:00
ovmf: Fix CVE-2023-45235
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 (From OE-Core rev: dd26902517c30f34cc661cf9f79fc589d0358412) Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
committed by
Steve Sakoman
parent
23e7248bd1
commit
5133058e11
@@ -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;
|
||||
EFI_DHCP6_PACKET *IndexOffer;
|
||||
UINT8 *Option;
|
||||
+ UINTN DiscoverLenNeeded;
|
||||
|
||||
PxeBc = &Private->PxeBc;
|
||||
Request = Private->Dhcp6Request;
|
||||
@@ -899,7 +900,8 @@ PxeBcRequestBootService (
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));
|
||||
+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);
|
||||
+ Discover = AllocateZeroPool (DiscoverLenNeeded);
|
||||
if (Discover == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
@@ -924,16 +926,34 @@ PxeBcRequestBootService (
|
||||
DHCP6_OPT_SERVER_ID
|
||||
);
|
||||
if (Option == NULL) {
|
||||
- return EFI_NOT_FOUND;
|
||||
+ Status = EFI_NOT_FOUND;
|
||||
+ goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Add Server ID Option.
|
||||
//
|
||||
OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen);
|
||||
- CopyMem (DiscoverOpt, Option, OpLen + 4);
|
||||
- DiscoverOpt += (OpLen + 4);
|
||||
- DiscoverLen += (OpLen + 4);
|
||||
+
|
||||
+ //
|
||||
+ // 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;
|
||||
+ }
|
||||
+
|
||||
+ //
|
||||
+ // 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;
|
||||
+ }
|
||||
+
|
||||
+ CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
}
|
||||
|
||||
while (RequestLen < Request->Length) {
|
||||
@@ -944,16 +964,24 @@ PxeBcRequestBootService (
|
||||
(OpCode != DHCP6_OPT_SERVER_ID)
|
||||
)
|
||||
{
|
||||
+ //
|
||||
+ // 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;
|
||||
+ }
|
||||
+
|
||||
//
|
||||
// Copy all the options except IA option and Server ID
|
||||
//
|
||||
- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);
|
||||
- DiscoverOpt += (OpLen + 4);
|
||||
- DiscoverLen += (OpLen + 4);
|
||||
+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
}
|
||||
|
||||
- RequestOpt += (OpLen + 4);
|
||||
- RequestLen += (OpLen + 4);
|
||||
+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2154,6 +2182,7 @@ PxeBcDhcp6Discover (
|
||||
UINT16 OpLen;
|
||||
UINT32 Xid;
|
||||
EFI_STATUS Status;
|
||||
+ UINTN DiscoverLenNeeded;
|
||||
|
||||
PxeBc = &Private->PxeBc;
|
||||
Mode = PxeBc->Mode;
|
||||
@@ -2169,7 +2198,8 @@ PxeBcDhcp6Discover (
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));
|
||||
+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);
|
||||
+ Discover = AllocateZeroPool (DiscoverLenNeeded);
|
||||
if (Discover == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
@@ -2185,22 +2215,37 @@ PxeBcDhcp6Discover (
|
||||
DiscoverLen = sizeof (EFI_DHCP6_HEADER);
|
||||
RequestLen = DiscoverLen;
|
||||
|
||||
+ //
|
||||
+ // The request packet is generated by the UEFI network stack. In the DHCP4 DORA and DHCP6 SARR sequence,
|
||||
+ // the first (discover in DHCP4 and solicit in DHCP6) and third (request in both DHCP4 and DHCP6) are
|
||||
+ // generated by the DHCP client (the UEFI network stack in this case). By the time this function executes,
|
||||
+ // the DHCP sequence already has been executed once (see UEFI Specification Figures 24.2 and 24.3), with
|
||||
+ // Private->Dhcp6Request being a cached copy of the DHCP6 request packet that UEFI network stack previously
|
||||
+ // generated and sent.
|
||||
+ //
|
||||
+ // Therefore while this code looks like it could overflow, in practice it's not possible.
|
||||
+ //
|
||||
while (RequestLen < Request->Length) {
|
||||
OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpCode);
|
||||
OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpLen);
|
||||
if ((OpCode != EFI_DHCP6_IA_TYPE_NA) &&
|
||||
(OpCode != EFI_DHCP6_IA_TYPE_TA))
|
||||
{
|
||||
+ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {
|
||||
+ Status = EFI_OUT_OF_RESOURCES;
|
||||
+ goto ON_ERROR;
|
||||
+ }
|
||||
+
|
||||
//
|
||||
// Copy all the options except IA option.
|
||||
//
|
||||
- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);
|
||||
- DiscoverOpt += (OpLen + 4);
|
||||
- DiscoverLen += (OpLen + 4);
|
||||
+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
}
|
||||
|
||||
- RequestOpt += (OpLen + 4);
|
||||
- RequestLen += (OpLen + 4);
|
||||
+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
|
||||
}
|
||||
|
||||
Status = PxeBc->UdpWrite (
|
||||
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 '['
|
||||
#define PXEBC_ADDR_END_DELIMITER ']'
|
||||
|
||||
+//
|
||||
+// A DUID consists of a 2-octet type code represented in network byte
|
||||
+// order, followed by a variable number of octets that make up the
|
||||
+// actual identifier. The length of the DUID (not including the type
|
||||
+// code) is at least 1 octet and at most 128 octets.
|
||||
+//
|
||||
+#define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1)
|
||||
+#define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128)
|
||||
+
|
||||
+//
|
||||
+// This define represents the combineds code and length field from
|
||||
+// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1
|
||||
+//
|
||||
+#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \
|
||||
+ (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \
|
||||
+ sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen))
|
||||
+
|
||||
#define GET_NEXT_DHCP6_OPTION(Opt) \
|
||||
(EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \
|
||||
sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1)
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -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
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
-#include <gtest/gtest.h>
|
||||
+#include <Library/GoogleTestLib.h>
|
||||
+#include <GoogleTest/Library/MockUefiLib.h>
|
||||
+#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
|
||||
|
||||
extern "C" {
|
||||
#include <Uefi.h>
|
||||
@@ -19,7 +21,8 @@ extern "C" {
|
||||
// Definitions
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
-#define PACKET_SIZE (1500)
|
||||
+#define PACKET_SIZE (1500)
|
||||
+#define REQUEST_OPTION_LENGTH (120)
|
||||
|
||||
typedef struct {
|
||||
UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03)
|
||||
@@ -76,6 +79,26 @@ MockConfigure (
|
||||
}
|
||||
|
||||
// Needed by PxeBcSupport
|
||||
+EFI_STATUS
|
||||
+PxeBcDns6 (
|
||||
+ IN PXEBC_PRIVATE_DATA *Private,
|
||||
+ IN CHAR16 *HostName,
|
||||
+ OUT EFI_IPv6_ADDRESS *IpAddress
|
||||
+ )
|
||||
+{
|
||||
+ return EFI_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+UINT32
|
||||
+PxeBcBuildDhcp6Options (
|
||||
+ IN PXEBC_PRIVATE_DATA *Private,
|
||||
+ OUT EFI_DHCP6_PACKET_OPTION **OptList,
|
||||
+ IN UINT8 *Buffer
|
||||
+ )
|
||||
+{
|
||||
+ return EFI_SUCCESS;
|
||||
+}
|
||||
+
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
QueueDpc (
|
||||
@@ -159,6 +182,10 @@ TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) {
|
||||
ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR);
|
||||
}
|
||||
|
||||
+///////////////////////////////////////////////////////////////////////////////
|
||||
+// PxeBcCacheDnsServerAddresses Tests
|
||||
+///////////////////////////////////////////////////////////////////////////////
|
||||
+
|
||||
class PxeBcCacheDnsServerAddressesTest : public ::testing::Test {
|
||||
public:
|
||||
PXEBC_PRIVATE_DATA Private = { 0 };
|
||||
@@ -298,3 +325,250 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
|
||||
FreePool (Private.DnsServer);
|
||||
}
|
||||
}
|
||||
+
|
||||
+///////////////////////////////////////////////////////////////////////////////
|
||||
+// PxeBcRequestBootServiceTest Test Cases
|
||||
+///////////////////////////////////////////////////////////////////////////////
|
||||
+
|
||||
+class PxeBcRequestBootServiceTest : public ::testing::Test {
|
||||
+public:
|
||||
+ PXEBC_PRIVATE_DATA Private = { 0 };
|
||||
+ EFI_UDP6_PROTOCOL Udp6Read;
|
||||
+
|
||||
+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;
|
||||
+ }
|
||||
+
|
||||
+ // Add any cleanup code if needed
|
||||
+ virtual void
|
||||
+ TearDown (
|
||||
+ )
|
||||
+ {
|
||||
+ if (Private.Dhcp6Request != NULL) {
|
||||
+ FreePool (Private.Dhcp6Request);
|
||||
+ }
|
||||
+
|
||||
+ // Clean up any resources or variables
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+TEST_F (PxeBcRequestBootServiceTest, ServerDiscoverBasicUsageTest) {
|
||||
+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;
|
||||
+
|
||||
+ DHCP6_OPTION_SERVER_ID Server = { 0 };
|
||||
+
|
||||
+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID);
|
||||
+ Server.OptionLen = HTONS (16); // valid length
|
||||
+ UINT8 Index = 0;
|
||||
+
|
||||
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;
|
||||
+
|
||||
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
|
||||
+
|
||||
+ CopyMem (Cursor, &Server, sizeof (Server));
|
||||
+ Cursor += sizeof (Server);
|
||||
+
|
||||
+ // Update the packet length
|
||||
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
|
||||
+ Packet->Size = PACKET_SIZE;
|
||||
+
|
||||
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);
|
||||
+}
|
||||
+
|
||||
+TEST_F (PxeBcRequestBootServiceTest, AttemptDiscoverOverFlowExpectFailure) {
|
||||
+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;
|
||||
+
|
||||
+ DHCP6_OPTION_SERVER_ID Server = { 0 };
|
||||
+
|
||||
+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID);
|
||||
+ Server.OptionLen = HTONS (1500); // This length would overflow without a check
|
||||
+ UINT8 Index = 0;
|
||||
+
|
||||
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;
|
||||
+
|
||||
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
|
||||
+
|
||||
+ CopyMem (Cursor, &Server, sizeof (Server));
|
||||
+ Cursor += sizeof (Server);
|
||||
+
|
||||
+ // Update the packet length
|
||||
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
|
||||
+ Packet->Size = PACKET_SIZE;
|
||||
+
|
||||
+ // This is going to be stopped by the duid overflow check
|
||||
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_INVALID_PARAMETER);
|
||||
+}
|
||||
+
|
||||
+TEST_F (PxeBcRequestBootServiceTest, RequestBasicUsageTest) {
|
||||
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
|
||||
+
|
||||
+ RequestOpt.OpCode = HTONS (0x1337);
|
||||
+ RequestOpt.OpLen = 0; // valid length
|
||||
+
|
||||
+ UINT8 Index = 0;
|
||||
+
|
||||
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];
|
||||
+
|
||||
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
|
||||
+
|
||||
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
|
||||
+ Cursor += sizeof (RequestOpt);
|
||||
+
|
||||
+ // Update the packet length
|
||||
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
|
||||
+ Packet->Size = PACKET_SIZE;
|
||||
+
|
||||
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);
|
||||
+}
|
||||
+
|
||||
+TEST_F (PxeBcRequestBootServiceTest, AttemptRequestOverFlowExpectFailure) {
|
||||
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
|
||||
+
|
||||
+ RequestOpt.OpCode = HTONS (0x1337);
|
||||
+ RequestOpt.OpLen = 1500; // this length would overflow without a check
|
||||
+
|
||||
+ UINT8 Index = 0;
|
||||
+
|
||||
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];
|
||||
+
|
||||
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
|
||||
+
|
||||
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
|
||||
+ Cursor += sizeof (RequestOpt);
|
||||
+
|
||||
+ // Update the packet length
|
||||
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
|
||||
+ Packet->Size = PACKET_SIZE;
|
||||
+
|
||||
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_OUT_OF_RESOURCES);
|
||||
+}
|
||||
+
|
||||
+///////////////////////////////////////////////////////////////////////////////
|
||||
+// PxeBcDhcp6Discover Test
|
||||
+///////////////////////////////////////////////////////////////////////////////
|
||||
+
|
||||
+class PxeBcDhcp6DiscoverTest : public ::testing::Test {
|
||||
+public:
|
||||
+ PXEBC_PRIVATE_DATA Private = { 0 };
|
||||
+ EFI_UDP6_PROTOCOL Udp6Read;
|
||||
+
|
||||
+protected:
|
||||
+ MockUefiRuntimeServicesTableLib RtServicesMock;
|
||||
+
|
||||
+ // 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;
|
||||
+ }
|
||||
+
|
||||
+ // Add any cleanup code if needed
|
||||
+ virtual void
|
||||
+ TearDown (
|
||||
+ )
|
||||
+ {
|
||||
+ if (Private.Dhcp6Request != NULL) {
|
||||
+ FreePool (Private.Dhcp6Request);
|
||||
+ }
|
||||
+
|
||||
+ // Clean up any resources or variables
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+// Test Description
|
||||
+// This will cause an overflow by an untrusted packet during the option parsing
|
||||
+TEST_F (PxeBcDhcp6DiscoverTest, BasicOverflowTest) {
|
||||
+ EFI_IPv6_ADDRESS DestIp = { 0 };
|
||||
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
|
||||
+
|
||||
+ RequestOpt.OpCode = HTONS (0x1337);
|
||||
+ RequestOpt.OpLen = HTONS (0xFFFF); // overflow
|
||||
+
|
||||
+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);
|
||||
+
|
||||
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
|
||||
+ Cursor += sizeof (RequestOpt);
|
||||
+
|
||||
+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);
|
||||
+
|
||||
+ EXPECT_CALL (RtServicesMock, gRT_GetTime)
|
||||
+ .WillOnce (::testing::Return (0));
|
||||
+
|
||||
+ ASSERT_EQ (
|
||||
+ PxeBcDhcp6Discover (
|
||||
+ &(PxeBcDhcp6DiscoverTest::Private),
|
||||
+ 0,
|
||||
+ NULL,
|
||||
+ FALSE,
|
||||
+ (EFI_IP_ADDRESS *)&DestIp
|
||||
+ ),
|
||||
+ EFI_OUT_OF_RESOURCES
|
||||
+ );
|
||||
+}
|
||||
+
|
||||
+// Test Description
|
||||
+// This will test that we can handle a packet with a valid option length
|
||||
+TEST_F (PxeBcDhcp6DiscoverTest, BasicUsageTest) {
|
||||
+ EFI_IPv6_ADDRESS DestIp = { 0 };
|
||||
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
|
||||
+
|
||||
+ RequestOpt.OpCode = HTONS (0x1337);
|
||||
+ RequestOpt.OpLen = HTONS (0x30);
|
||||
+
|
||||
+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);
|
||||
+
|
||||
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
|
||||
+ Cursor += sizeof (RequestOpt);
|
||||
+
|
||||
+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);
|
||||
+
|
||||
+ EXPECT_CALL (RtServicesMock, gRT_GetTime)
|
||||
+ .WillOnce (::testing::Return (0));
|
||||
+
|
||||
+ ASSERT_EQ (
|
||||
+ PxeBcDhcp6Discover (
|
||||
+ &(PxeBcDhcp6DiscoverTest::Private),
|
||||
+ 0,
|
||||
+ NULL,
|
||||
+ FALSE,
|
||||
+ (EFI_IP_ADDRESS *)&DestIp
|
||||
+ ),
|
||||
+ EFI_SUCCESS
|
||||
+ );
|
||||
+}
|
||||
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
|
||||
);
|
||||
|
||||
+/**
|
||||
+ Build and send out the request packet for the bootfile, and parse the reply.
|
||||
+
|
||||
+ @param[in] Private The pointer to PxeBc private data.
|
||||
+ @param[in] Index PxeBc option boot item type.
|
||||
+
|
||||
+ @retval EFI_SUCCESS Successfully discovered the boot file.
|
||||
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||
+ @retval EFI_NOT_FOUND Can't get the PXE reply packet.
|
||||
+ @retval Others Failed to discover the boot file.
|
||||
+
|
||||
+**/
|
||||
+EFI_STATUS
|
||||
+PxeBcRequestBootService (
|
||||
+ IN PXEBC_PRIVATE_DATA *Private,
|
||||
+ IN UINT32 Index
|
||||
+ );
|
||||
+
|
||||
#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user