summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0001.patch243
-rw-r--r--meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0002.patch379
-rw-r--r--meta/recipes-core/ovmf/ovmf_git.bb2
3 files changed, 624 insertions, 0 deletions
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
index 0000000000..264172f623
--- /dev/null
+++ b/meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0001.patch
@@ -0,0 +1,243 @@
1From fac297724e6cc343430cd0104e55cd7a96d1151e Mon Sep 17 00:00:00 2001
2From: Doug Flick <dougflick@microsoft.com>
3Date: Fri, 26 Jan 2024 05:54:55 +0800
4Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch
5
6REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540
7
8Bug Details:
9PixieFail Bug #7
10CVE-2023-45235
11CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
12CWE-119 Improper Restriction of Operations within the Bounds of
13 a Memory Buffer
14
15Buffer overflow when handling Server ID option from a DHCPv6 proxy
16Advertise message
17
18Change Overview:
19
20Performs two checks
21
221. Checks that the length of the duid is accurate
23> + //
24> + // Check that the minimum and maximum requirements are met
25> + //
26> + if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) ||
27(OpLen > PXEBC_MAX_SIZE_OF_DUID)) {
28> + Status = EFI_INVALID_PARAMETER;
29> + goto ON_ERROR;
30> + }
31
322. Ensures that the amount of data written to the buffer is tracked and
33never exceeds that
34> + //
35> + // Check that the option length is valid.
36> + //
37> + if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN)
38 > DiscoverLenNeeded) {
39> + Status = EFI_OUT_OF_RESOURCES;
40> + goto ON_ERROR;
41> + }
42
43Additional code clean up and fix for memory leak in case Option was NULL
44
45Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
46Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
47
48Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
49Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
50
51CVE: CVE-2023-45235
52
53Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/fac297724e6cc343430cd0104e55cd7a96d1151e]
54
55Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
56---
57 NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 77 ++++++++++++++++++++++------
58 NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 ++++++
59 2 files changed, 78 insertions(+), 16 deletions(-)
60
61diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
62index 2b2d372889..7fd1281c11 100644
63--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
64+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
65@@ -887,6 +887,7 @@ PxeBcRequestBootService (
66 EFI_STATUS Status;
67 EFI_DHCP6_PACKET *IndexOffer;
68 UINT8 *Option;
69+ UINTN DiscoverLenNeeded;
70
71 PxeBc = &Private->PxeBc;
72 Request = Private->Dhcp6Request;
73@@ -899,7 +900,8 @@ PxeBcRequestBootService (
74 return EFI_DEVICE_ERROR;
75 }
76
77- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));
78+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);
79+ Discover = AllocateZeroPool (DiscoverLenNeeded);
80 if (Discover == NULL) {
81 return EFI_OUT_OF_RESOURCES;
82 }
83@@ -924,16 +926,34 @@ PxeBcRequestBootService (
84 DHCP6_OPT_SERVER_ID
85 );
86 if (Option == NULL) {
87- return EFI_NOT_FOUND;
88+ Status = EFI_NOT_FOUND;
89+ goto ON_ERROR;
90 }
91
92 //
93 // Add Server ID Option.
94 //
95 OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen);
96- CopyMem (DiscoverOpt, Option, OpLen + 4);
97- DiscoverOpt += (OpLen + 4);
98- DiscoverLen += (OpLen + 4);
99+
100+ //
101+ // Check that the minimum and maximum requirements are met
102+ //
103+ if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) {
104+ Status = EFI_INVALID_PARAMETER;
105+ goto ON_ERROR;
106+ }
107+
108+ //
109+ // Check that the option length is valid.
110+ //
111+ if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) {
112+ Status = EFI_OUT_OF_RESOURCES;
113+ goto ON_ERROR;
114+ }
115+
116+ CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
117+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
118+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
119 }
120
121 while (RequestLen < Request->Length) {
122@@ -944,16 +964,24 @@ PxeBcRequestBootService (
123 (OpCode != DHCP6_OPT_SERVER_ID)
124 )
125 {
126+ //
127+ // Check that the option length is valid.
128+ //
129+ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {
130+ Status = EFI_OUT_OF_RESOURCES;
131+ goto ON_ERROR;
132+ }
133+
134 //
135 // Copy all the options except IA option and Server ID
136 //
137- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);
138- DiscoverOpt += (OpLen + 4);
139- DiscoverLen += (OpLen + 4);
140+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
141+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
142+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
143 }
144
145- RequestOpt += (OpLen + 4);
146- RequestLen += (OpLen + 4);
147+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
148+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
149 }
150
151 //
152@@ -2154,6 +2182,7 @@ PxeBcDhcp6Discover (
153 UINT16 OpLen;
154 UINT32 Xid;
155 EFI_STATUS Status;
156+ UINTN DiscoverLenNeeded;
157
158 PxeBc = &Private->PxeBc;
159 Mode = PxeBc->Mode;
160@@ -2169,7 +2198,8 @@ PxeBcDhcp6Discover (
161 return EFI_DEVICE_ERROR;
162 }
163
164- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));
165+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);
166+ Discover = AllocateZeroPool (DiscoverLenNeeded);
167 if (Discover == NULL) {
168 return EFI_OUT_OF_RESOURCES;
169 }
170@@ -2185,22 +2215,37 @@ PxeBcDhcp6Discover (
171 DiscoverLen = sizeof (EFI_DHCP6_HEADER);
172 RequestLen = DiscoverLen;
173
174+ //
175+ // The request packet is generated by the UEFI network stack. In the DHCP4 DORA and DHCP6 SARR sequence,
176+ // the first (discover in DHCP4 and solicit in DHCP6) and third (request in both DHCP4 and DHCP6) are
177+ // generated by the DHCP client (the UEFI network stack in this case). By the time this function executes,
178+ // the DHCP sequence already has been executed once (see UEFI Specification Figures 24.2 and 24.3), with
179+ // Private->Dhcp6Request being a cached copy of the DHCP6 request packet that UEFI network stack previously
180+ // generated and sent.
181+ //
182+ // Therefore while this code looks like it could overflow, in practice it's not possible.
183+ //
184 while (RequestLen < Request->Length) {
185 OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpCode);
186 OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpLen);
187 if ((OpCode != EFI_DHCP6_IA_TYPE_NA) &&
188 (OpCode != EFI_DHCP6_IA_TYPE_TA))
189 {
190+ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {
191+ Status = EFI_OUT_OF_RESOURCES;
192+ goto ON_ERROR;
193+ }
194+
195 //
196 // Copy all the options except IA option.
197 //
198- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);
199- DiscoverOpt += (OpLen + 4);
200- DiscoverLen += (OpLen + 4);
201+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
202+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
203+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
204 }
205
206- RequestOpt += (OpLen + 4);
207- RequestLen += (OpLen + 4);
208+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
209+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
210 }
211
212 Status = PxeBc->UdpWrite (
213diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
214index c86f6d391b..6357d27fae 100644
215--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
216+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
217@@ -34,6 +34,23 @@
218 #define PXEBC_ADDR_START_DELIMITER '['
219 #define PXEBC_ADDR_END_DELIMITER ']'
220
221+//
222+// A DUID consists of a 2-octet type code represented in network byte
223+// order, followed by a variable number of octets that make up the
224+// actual identifier. The length of the DUID (not including the type
225+// code) is at least 1 octet and at most 128 octets.
226+//
227+#define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1)
228+#define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128)
229+
230+//
231+// This define represents the combineds code and length field from
232+// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1
233+//
234+#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \
235+ (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \
236+ sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen))
237+
238 #define GET_NEXT_DHCP6_OPTION(Opt) \
239 (EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \
240 sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1)
241--
2422.40.0
243
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
index 0000000000..0e814a0212
--- /dev/null
+++ b/meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0002.patch
@@ -0,0 +1,379 @@
1From ff2986358f75d8f58ef08a66fe673539c9c48f41 Mon Sep 17 00:00:00 2001
2From: Doug Flick <dougflick@microsoft.com>
3Date: Fri, 26 Jan 2024 05:54:56 +0800
4Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit
5 Tests
6
7REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540
8
9Unit tests to confirm that the bug..
10
11Buffer overflow when handling Server ID option from a DHCPv6 proxy
12Advertise message
13
14..has been patched.
15
16This patch contains unit tests for the following functions:
17PxeBcRequestBootService
18PxeBcDhcp6Discover
19
20Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
21Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
22
23Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
24Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
25
26CVE: CVE-2023-45235
27
28Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/ff2986358f75d8f58ef08a66fe673539c9c48f41]
29
30Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
31---
32 .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 278 +++++++++++++++++-
33 .../GoogleTest/PxeBcDhcp6GoogleTest.h | 18 ++
34 2 files changed, 294 insertions(+), 2 deletions(-)
35
36diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
37index 8260eeee50..bd423ebadf 100644
38--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
39+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
40@@ -4,7 +4,9 @@
41 Copyright (c) Microsoft Corporation
42 SPDX-License-Identifier: BSD-2-Clause-Patent
43 **/
44-#include <gtest/gtest.h>
45+#include <Library/GoogleTestLib.h>
46+#include <GoogleTest/Library/MockUefiLib.h>
47+#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
48
49 extern "C" {
50 #include <Uefi.h>
51@@ -19,7 +21,8 @@ extern "C" {
52 // Definitions
53 ///////////////////////////////////////////////////////////////////////////////
54
55-#define PACKET_SIZE (1500)
56+#define PACKET_SIZE (1500)
57+#define REQUEST_OPTION_LENGTH (120)
58
59 typedef struct {
60 UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03)
61@@ -76,6 +79,26 @@ MockConfigure (
62 }
63
64 // Needed by PxeBcSupport
65+EFI_STATUS
66+PxeBcDns6 (
67+ IN PXEBC_PRIVATE_DATA *Private,
68+ IN CHAR16 *HostName,
69+ OUT EFI_IPv6_ADDRESS *IpAddress
70+ )
71+{
72+ return EFI_SUCCESS;
73+}
74+
75+UINT32
76+PxeBcBuildDhcp6Options (
77+ IN PXEBC_PRIVATE_DATA *Private,
78+ OUT EFI_DHCP6_PACKET_OPTION **OptList,
79+ IN UINT8 *Buffer
80+ )
81+{
82+ return EFI_SUCCESS;
83+}
84+
85 EFI_STATUS
86 EFIAPI
87 QueueDpc (
88@@ -159,6 +182,10 @@ TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) {
89 ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR);
90 }
91
92+///////////////////////////////////////////////////////////////////////////////
93+// PxeBcCacheDnsServerAddresses Tests
94+///////////////////////////////////////////////////////////////////////////////
95+
96 class PxeBcCacheDnsServerAddressesTest : public ::testing::Test {
97 public:
98 PXEBC_PRIVATE_DATA Private = { 0 };
99@@ -298,3 +325,250 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
100 FreePool (Private.DnsServer);
101 }
102 }
103+
104+///////////////////////////////////////////////////////////////////////////////
105+// PxeBcRequestBootServiceTest Test Cases
106+///////////////////////////////////////////////////////////////////////////////
107+
108+class PxeBcRequestBootServiceTest : public ::testing::Test {
109+public:
110+ PXEBC_PRIVATE_DATA Private = { 0 };
111+ EFI_UDP6_PROTOCOL Udp6Read;
112+
113+protected:
114+ // Add any setup code if needed
115+ virtual void
116+ SetUp (
117+ )
118+ {
119+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);
120+
121+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL
122+ // The function under test really only needs the following:
123+ // UdpWrite
124+ // UdpRead
125+
126+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite;
127+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead;
128+
129+ // Need to setup EFI_UDP6_PROTOCOL
130+ // The function under test really only needs the following:
131+ // Configure
132+
133+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure;
134+ Private.Udp6Read = &Udp6Read;
135+ }
136+
137+ // Add any cleanup code if needed
138+ virtual void
139+ TearDown (
140+ )
141+ {
142+ if (Private.Dhcp6Request != NULL) {
143+ FreePool (Private.Dhcp6Request);
144+ }
145+
146+ // Clean up any resources or variables
147+ }
148+};
149+
150+TEST_F (PxeBcRequestBootServiceTest, ServerDiscoverBasicUsageTest) {
151+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;
152+
153+ DHCP6_OPTION_SERVER_ID Server = { 0 };
154+
155+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID);
156+ Server.OptionLen = HTONS (16); // valid length
157+ UINT8 Index = 0;
158+
159+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;
160+
161+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
162+
163+ CopyMem (Cursor, &Server, sizeof (Server));
164+ Cursor += sizeof (Server);
165+
166+ // Update the packet length
167+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
168+ Packet->Size = PACKET_SIZE;
169+
170+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);
171+}
172+
173+TEST_F (PxeBcRequestBootServiceTest, AttemptDiscoverOverFlowExpectFailure) {
174+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;
175+
176+ DHCP6_OPTION_SERVER_ID Server = { 0 };
177+
178+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID);
179+ Server.OptionLen = HTONS (1500); // This length would overflow without a check
180+ UINT8 Index = 0;
181+
182+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;
183+
184+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
185+
186+ CopyMem (Cursor, &Server, sizeof (Server));
187+ Cursor += sizeof (Server);
188+
189+ // Update the packet length
190+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
191+ Packet->Size = PACKET_SIZE;
192+
193+ // This is going to be stopped by the duid overflow check
194+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_INVALID_PARAMETER);
195+}
196+
197+TEST_F (PxeBcRequestBootServiceTest, RequestBasicUsageTest) {
198+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
199+
200+ RequestOpt.OpCode = HTONS (0x1337);
201+ RequestOpt.OpLen = 0; // valid length
202+
203+ UINT8 Index = 0;
204+
205+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];
206+
207+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
208+
209+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
210+ Cursor += sizeof (RequestOpt);
211+
212+ // Update the packet length
213+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
214+ Packet->Size = PACKET_SIZE;
215+
216+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);
217+}
218+
219+TEST_F (PxeBcRequestBootServiceTest, AttemptRequestOverFlowExpectFailure) {
220+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
221+
222+ RequestOpt.OpCode = HTONS (0x1337);
223+ RequestOpt.OpLen = 1500; // this length would overflow without a check
224+
225+ UINT8 Index = 0;
226+
227+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];
228+
229+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
230+
231+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
232+ Cursor += sizeof (RequestOpt);
233+
234+ // Update the packet length
235+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
236+ Packet->Size = PACKET_SIZE;
237+
238+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_OUT_OF_RESOURCES);
239+}
240+
241+///////////////////////////////////////////////////////////////////////////////
242+// PxeBcDhcp6Discover Test
243+///////////////////////////////////////////////////////////////////////////////
244+
245+class PxeBcDhcp6DiscoverTest : public ::testing::Test {
246+public:
247+ PXEBC_PRIVATE_DATA Private = { 0 };
248+ EFI_UDP6_PROTOCOL Udp6Read;
249+
250+protected:
251+ MockUefiRuntimeServicesTableLib RtServicesMock;
252+
253+ // Add any setup code if needed
254+ virtual void
255+ SetUp (
256+ )
257+ {
258+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);
259+
260+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL
261+ // The function under test really only needs the following:
262+ // UdpWrite
263+ // UdpRead
264+
265+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite;
266+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead;
267+
268+ // Need to setup EFI_UDP6_PROTOCOL
269+ // The function under test really only needs the following:
270+ // Configure
271+
272+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure;
273+ Private.Udp6Read = &Udp6Read;
274+ }
275+
276+ // Add any cleanup code if needed
277+ virtual void
278+ TearDown (
279+ )
280+ {
281+ if (Private.Dhcp6Request != NULL) {
282+ FreePool (Private.Dhcp6Request);
283+ }
284+
285+ // Clean up any resources or variables
286+ }
287+};
288+
289+// Test Description
290+// This will cause an overflow by an untrusted packet during the option parsing
291+TEST_F (PxeBcDhcp6DiscoverTest, BasicOverflowTest) {
292+ EFI_IPv6_ADDRESS DestIp = { 0 };
293+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
294+
295+ RequestOpt.OpCode = HTONS (0x1337);
296+ RequestOpt.OpLen = HTONS (0xFFFF); // overflow
297+
298+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);
299+
300+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
301+ Cursor += sizeof (RequestOpt);
302+
303+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);
304+
305+ EXPECT_CALL (RtServicesMock, gRT_GetTime)
306+ .WillOnce (::testing::Return (0));
307+
308+ ASSERT_EQ (
309+ PxeBcDhcp6Discover (
310+ &(PxeBcDhcp6DiscoverTest::Private),
311+ 0,
312+ NULL,
313+ FALSE,
314+ (EFI_IP_ADDRESS *)&DestIp
315+ ),
316+ EFI_OUT_OF_RESOURCES
317+ );
318+}
319+
320+// Test Description
321+// This will test that we can handle a packet with a valid option length
322+TEST_F (PxeBcDhcp6DiscoverTest, BasicUsageTest) {
323+ EFI_IPv6_ADDRESS DestIp = { 0 };
324+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
325+
326+ RequestOpt.OpCode = HTONS (0x1337);
327+ RequestOpt.OpLen = HTONS (0x30);
328+
329+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);
330+
331+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
332+ Cursor += sizeof (RequestOpt);
333+
334+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);
335+
336+ EXPECT_CALL (RtServicesMock, gRT_GetTime)
337+ .WillOnce (::testing::Return (0));
338+
339+ ASSERT_EQ (
340+ PxeBcDhcp6Discover (
341+ &(PxeBcDhcp6DiscoverTest::Private),
342+ 0,
343+ NULL,
344+ FALSE,
345+ (EFI_IP_ADDRESS *)&DestIp
346+ ),
347+ EFI_SUCCESS
348+ );
349+}
350diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
351index b17c314791..0d825e4425 100644
352--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
353+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
354@@ -47,4 +47,22 @@ PxeBcCacheDnsServerAddresses (
355 IN PXEBC_DHCP6_PACKET_CACHE *Cache6
356 );
357
358+/**
359+ Build and send out the request packet for the bootfile, and parse the reply.
360+
361+ @param[in] Private The pointer to PxeBc private data.
362+ @param[in] Index PxeBc option boot item type.
363+
364+ @retval EFI_SUCCESS Successfully discovered the boot file.
365+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
366+ @retval EFI_NOT_FOUND Can't get the PXE reply packet.
367+ @retval Others Failed to discover the boot file.
368+
369+**/
370+EFI_STATUS
371+PxeBcRequestBootService (
372+ IN PXEBC_PRIVATE_DATA *Private,
373+ IN UINT32 Index
374+ );
375+
376 #endif // PXE_BC_DHCP6_GOOGLE_TEST_H_
377--
3782.40.0
379
diff --git a/meta/recipes-core/ovmf/ovmf_git.bb b/meta/recipes-core/ovmf/ovmf_git.bb
index ac6a0a40e7..ceebb53438 100644
--- a/meta/recipes-core/ovmf/ovmf_git.bb
+++ b/meta/recipes-core/ovmf/ovmf_git.bb
@@ -41,6 +41,8 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
41 file://CVE-2023-45232-CVE-2023-45233-0002.patch \ 41 file://CVE-2023-45232-CVE-2023-45233-0002.patch \
42 file://CVE-2023-45234-0001.patch \ 42 file://CVE-2023-45234-0001.patch \
43 file://CVE-2023-45234-0002.patch \ 43 file://CVE-2023-45234-0002.patch \
44 file://CVE-2023-45235-0001.patch \
45 file://CVE-2023-45235-0002.patch \
44 " 46 "
45 47
46PV = "edk2-stable202202" 48PV = "edk2-stable202202"