diff options
| -rw-r--r-- | meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0001.patch | 243 | ||||
| -rw-r--r-- | meta/recipes-core/ovmf/ovmf/CVE-2023-45235-0002.patch | 379 | ||||
| -rw-r--r-- | meta/recipes-core/ovmf/ovmf_git.bb | 2 |
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 @@ | |||
| 1 | From fac297724e6cc343430cd0104e55cd7a96d1151e Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Doug Flick <dougflick@microsoft.com> | ||
| 3 | Date: Fri, 26 Jan 2024 05:54:55 +0800 | ||
| 4 | Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch | ||
| 5 | |||
| 6 | REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540 | ||
| 7 | |||
| 8 | Bug Details: | ||
| 9 | PixieFail Bug #7 | ||
| 10 | CVE-2023-45235 | ||
| 11 | CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H | ||
| 12 | CWE-119 Improper Restriction of Operations within the Bounds of | ||
| 13 | a Memory Buffer | ||
| 14 | |||
| 15 | Buffer overflow when handling Server ID option from a DHCPv6 proxy | ||
| 16 | Advertise message | ||
| 17 | |||
| 18 | Change Overview: | ||
| 19 | |||
| 20 | Performs two checks | ||
| 21 | |||
| 22 | 1. 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 | |||
| 32 | 2. Ensures that the amount of data written to the buffer is tracked and | ||
| 33 | never 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 | |||
| 43 | Additional code clean up and fix for memory leak in case Option was NULL | ||
| 44 | |||
| 45 | Cc: Saloni Kasbekar <saloni.kasbekar@intel.com> | ||
| 46 | Cc: Zachary Clark-williams <zachary.clark-williams@intel.com> | ||
| 47 | |||
| 48 | Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com> | ||
| 49 | Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com> | ||
| 50 | |||
| 51 | CVE: CVE-2023-45235 | ||
| 52 | |||
| 53 | Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/fac297724e6cc343430cd0104e55cd7a96d1151e] | ||
| 54 | |||
| 55 | Signed-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 | |||
| 61 | diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | ||
| 62 | index 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 ( | ||
| 213 | diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | ||
| 214 | index 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 | -- | ||
| 242 | 2.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 @@ | |||
| 1 | From ff2986358f75d8f58ef08a66fe673539c9c48f41 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Doug Flick <dougflick@microsoft.com> | ||
| 3 | Date: Fri, 26 Jan 2024 05:54:56 +0800 | ||
| 4 | Subject: [PATCH] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit | ||
| 5 | Tests | ||
| 6 | |||
| 7 | REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540 | ||
| 8 | |||
| 9 | Unit tests to confirm that the bug.. | ||
| 10 | |||
| 11 | Buffer overflow when handling Server ID option from a DHCPv6 proxy | ||
| 12 | Advertise message | ||
| 13 | |||
| 14 | ..has been patched. | ||
| 15 | |||
| 16 | This patch contains unit tests for the following functions: | ||
| 17 | PxeBcRequestBootService | ||
| 18 | PxeBcDhcp6Discover | ||
| 19 | |||
| 20 | Cc: Saloni Kasbekar <saloni.kasbekar@intel.com> | ||
| 21 | Cc: Zachary Clark-williams <zachary.clark-williams@intel.com> | ||
| 22 | |||
| 23 | Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com> | ||
| 24 | Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com> | ||
| 25 | |||
| 26 | CVE: CVE-2023-45235 | ||
| 27 | |||
| 28 | Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/ff2986358f75d8f58ef08a66fe673539c9c48f41] | ||
| 29 | |||
| 30 | Signed-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 | |||
| 36 | diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp | ||
| 37 | index 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 | +} | ||
| 350 | diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h | ||
| 351 | index 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 | -- | ||
| 378 | 2.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 | ||
| 46 | PV = "edk2-stable202202" | 48 | PV = "edk2-stable202202" |
