|
| 1 | +From 6f77463d72807ec7f4ed6518c3dac29a1040df9f Mon Sep 17 00:00:00 2001 |
| 2 | +From: Doug Flick < [email protected]> |
| 3 | +Date: Fri, 26 Jan 2024 05:54:49 +0800 |
| 4 | +Subject: [PATCH] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Unit Tests |
| 5 | + |
| 6 | +REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4536 |
| 7 | + |
| 8 | +Validates that the patch for... |
| 9 | + |
| 10 | +Out-of-bounds read when handling a ND Redirect message with truncated |
| 11 | +options |
| 12 | + |
| 13 | +.. has been fixed |
| 14 | + |
| 15 | +Tests the following function to ensure that an out of bounds read does |
| 16 | +not occur |
| 17 | +Ip6OptionValidation |
| 18 | + |
| 19 | +Cc: Saloni Kasbekar < [email protected]> |
| 20 | +Cc: Zachary Clark-williams < [email protected]> |
| 21 | + |
| 22 | +Signed-off-by: Doug Flick [MSFT] < [email protected]> |
| 23 | +Reviewed-by: Saloni Kasbekar < [email protected]> |
| 24 | + |
| 25 | +CVE: CVE-2023-45231 |
| 26 | + |
| 27 | +Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/6f77463d72807ec7f4ed6518c3dac29a1040df9f] |
| 28 | + |
| 29 | +Signed-off-by: Soumya Sambu < [email protected]> |
| 30 | +--- |
| 31 | + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp | 20 +++ |
| 32 | + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 42 ++++++ |
| 33 | + .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 129 ++++++++++++++++++ |
| 34 | + 3 files changed, 191 insertions(+) |
| 35 | + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp |
| 36 | + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf |
| 37 | + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp |
| 38 | + |
| 39 | +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp |
| 40 | +new file mode 100644 |
| 41 | +index 0000000000..6ebfd5fdfb |
| 42 | +--- /dev/null |
| 43 | ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp |
| 44 | +@@ -0,0 +1,20 @@ |
| 45 | ++/** @file |
| 46 | ++ Acts as the main entry point for the tests for the Ip6Dxe module. |
| 47 | ++ |
| 48 | ++ Copyright (c) Microsoft Corporation |
| 49 | ++ SPDX-License-Identifier: BSD-2-Clause-Patent |
| 50 | ++**/ |
| 51 | ++#include <gtest/gtest.h> |
| 52 | ++ |
| 53 | ++//////////////////////////////////////////////////////////////////////////////// |
| 54 | ++// Run the tests |
| 55 | ++//////////////////////////////////////////////////////////////////////////////// |
| 56 | ++int |
| 57 | ++main ( |
| 58 | ++ int argc, |
| 59 | ++ char *argv[] |
| 60 | ++ ) |
| 61 | ++{ |
| 62 | ++ testing::InitGoogleTest (&argc, argv); |
| 63 | ++ return RUN_ALL_TESTS (); |
| 64 | ++} |
| 65 | +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf |
| 66 | +new file mode 100644 |
| 67 | +index 0000000000..6e4de0745f |
| 68 | +--- /dev/null |
| 69 | ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf |
| 70 | +@@ -0,0 +1,42 @@ |
| 71 | ++## @file |
| 72 | ++# Unit test suite for the Ip6Dxe using Google Test |
| 73 | ++# |
| 74 | ++# Copyright (c) Microsoft Corporation.<BR> |
| 75 | ++# SPDX-License-Identifier: BSD-2-Clause-Patent |
| 76 | ++## |
| 77 | ++[Defines] |
| 78 | ++ INF_VERSION = 0x00010017 |
| 79 | ++ BASE_NAME = Ip6DxeUnitTest |
| 80 | ++ FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A |
| 81 | ++ VERSION_STRING = 1.0 |
| 82 | ++ MODULE_TYPE = HOST_APPLICATION |
| 83 | ++# |
| 84 | ++# The following information is for reference only and not required by the build tools. |
| 85 | ++# |
| 86 | ++# VALID_ARCHITECTURES = IA32 X64 AARCH64 |
| 87 | ++# |
| 88 | ++[Sources] |
| 89 | ++ Ip6DxeGoogleTest.cpp |
| 90 | ++ Ip6OptionGoogleTest.cpp |
| 91 | ++ ../Ip6Option.c |
| 92 | ++ |
| 93 | ++[Packages] |
| 94 | ++ MdePkg/MdePkg.dec |
| 95 | ++ MdeModulePkg/MdeModulePkg.dec |
| 96 | ++ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec |
| 97 | ++ NetworkPkg/NetworkPkg.dec |
| 98 | ++ |
| 99 | ++[LibraryClasses] |
| 100 | ++ GoogleTestLib |
| 101 | ++ DebugLib |
| 102 | ++ NetLib |
| 103 | ++ PcdLib |
| 104 | ++ |
| 105 | ++[Protocols] |
| 106 | ++ gEfiDhcp6ServiceBindingProtocolGuid |
| 107 | ++ |
| 108 | ++[Pcd] |
| 109 | ++ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType |
| 110 | ++ |
| 111 | ++[Guids] |
| 112 | ++ gZeroGuid |
| 113 | +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp |
| 114 | +new file mode 100644 |
| 115 | +index 0000000000..f2cd90e1a9 |
| 116 | +--- /dev/null |
| 117 | ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp |
| 118 | +@@ -0,0 +1,129 @@ |
| 119 | ++/** @file |
| 120 | ++ Tests for Ip6Option.c. |
| 121 | ++ |
| 122 | ++ Copyright (c) Microsoft Corporation |
| 123 | ++ SPDX-License-Identifier: BSD-2-Clause-Patent |
| 124 | ++**/ |
| 125 | ++#include <gtest/gtest.h> |
| 126 | ++ |
| 127 | ++extern "C" { |
| 128 | ++ #include <Uefi.h> |
| 129 | ++ #include <Library/BaseLib.h> |
| 130 | ++ #include <Library/DebugLib.h> |
| 131 | ++ #include "../Ip6Impl.h" |
| 132 | ++ #include "../Ip6Option.h" |
| 133 | ++} |
| 134 | ++ |
| 135 | ++///////////////////////////////////////////////////////////////////////// |
| 136 | ++// Defines |
| 137 | ++/////////////////////////////////////////////////////////////////////// |
| 138 | ++ |
| 139 | ++#define IP6_PREFIX_INFO_OPTION_DATA_LEN 32 |
| 140 | ++#define OPTION_HEADER_IP6_PREFIX_DATA_LEN (sizeof (IP6_OPTION_HEADER) + IP6_PREFIX_INFO_OPTION_DATA_LEN) |
| 141 | ++ |
| 142 | ++//////////////////////////////////////////////////////////////////////// |
| 143 | ++// Symbol Definitions |
| 144 | ++// These functions are not directly under test - but required to compile |
| 145 | ++//////////////////////////////////////////////////////////////////////// |
| 146 | ++UINT32 mIp6Id; |
| 147 | ++ |
| 148 | ++EFI_STATUS |
| 149 | ++Ip6SendIcmpError ( |
| 150 | ++ IN IP6_SERVICE *IpSb, |
| 151 | ++ IN NET_BUF *Packet, |
| 152 | ++ IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, |
| 153 | ++ IN EFI_IPv6_ADDRESS *DestinationAddress, |
| 154 | ++ IN UINT8 Type, |
| 155 | ++ IN UINT8 Code, |
| 156 | ++ IN UINT32 *Pointer OPTIONAL |
| 157 | ++ ) |
| 158 | ++{ |
| 159 | ++ // .. |
| 160 | ++ return EFI_SUCCESS; |
| 161 | ++} |
| 162 | ++ |
| 163 | ++//////////////////////////////////////////////////////////////////////// |
| 164 | ++// Ip6OptionValidation Tests |
| 165 | ++//////////////////////////////////////////////////////////////////////// |
| 166 | ++ |
| 167 | ++// Define a fixture for your tests if needed |
| 168 | ++class Ip6OptionValidationTest : public ::testing::Test { |
| 169 | ++protected: |
| 170 | ++ // Add any setup code if needed |
| 171 | ++ virtual void |
| 172 | ++ SetUp ( |
| 173 | ++ ) |
| 174 | ++ { |
| 175 | ++ // Initialize any resources or variables |
| 176 | ++ } |
| 177 | ++ |
| 178 | ++ // Add any cleanup code if needed |
| 179 | ++ virtual void |
| 180 | ++ TearDown ( |
| 181 | ++ ) |
| 182 | ++ { |
| 183 | ++ // Clean up any resources or variables |
| 184 | ++ } |
| 185 | ++}; |
| 186 | ++ |
| 187 | ++// Test Description: |
| 188 | ++// Null option should return false |
| 189 | ++TEST_F (Ip6OptionValidationTest, NullOptionShouldReturnFalse) { |
| 190 | ++ UINT8 *option = nullptr; |
| 191 | ++ UINT16 optionLen = 10; // Provide a suitable length |
| 192 | ++ |
| 193 | ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); |
| 194 | ++} |
| 195 | ++ |
| 196 | ++// Test Description: |
| 197 | ++// Truncated option should return false |
| 198 | ++TEST_F (Ip6OptionValidationTest, TruncatedOptionShouldReturnFalse) { |
| 199 | ++ UINT8 option[] = { 0x01 }; // Provide a truncated option |
| 200 | ++ UINT16 optionLen = 1; |
| 201 | ++ |
| 202 | ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); |
| 203 | ++} |
| 204 | ++ |
| 205 | ++// Test Description: |
| 206 | ++// Ip6OptionPrefixInfo Option with zero length should return false |
| 207 | ++TEST_F (Ip6OptionValidationTest, OptionWithZeroLengthShouldReturnFalse) { |
| 208 | ++ IP6_OPTION_HEADER optionHeader; |
| 209 | ++ |
| 210 | ++ optionHeader.Type = Ip6OptionPrefixInfo; |
| 211 | ++ optionHeader.Length = 0; |
| 212 | ++ UINT8 option[sizeof (IP6_OPTION_HEADER)]; |
| 213 | ++ |
| 214 | ++ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); |
| 215 | ++ UINT16 optionLen = sizeof (IP6_OPTION_HEADER); |
| 216 | ++ |
| 217 | ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); |
| 218 | ++} |
| 219 | ++ |
| 220 | ++// Test Description: |
| 221 | ++// Ip6OptionPrefixInfo Option with valid length should return true |
| 222 | ++TEST_F (Ip6OptionValidationTest, ValidPrefixInfoOptionShouldReturnTrue) { |
| 223 | ++ IP6_OPTION_HEADER optionHeader; |
| 224 | ++ |
| 225 | ++ optionHeader.Type = Ip6OptionPrefixInfo; |
| 226 | ++ optionHeader.Length = 4; // Length 4 * 8 = 32 |
| 227 | ++ UINT8 option[OPTION_HEADER_IP6_PREFIX_DATA_LEN]; |
| 228 | ++ |
| 229 | ++ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); |
| 230 | ++ |
| 231 | ++ EXPECT_TRUE (Ip6IsNDOptionValid (option, IP6_PREFIX_INFO_OPTION_DATA_LEN)); |
| 232 | ++} |
| 233 | ++ |
| 234 | ++// Test Description: |
| 235 | ++// Ip6OptionPrefixInfo Option with invalid length should return false |
| 236 | ++TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse) { |
| 237 | ++ IP6_OPTION_HEADER optionHeader; |
| 238 | ++ |
| 239 | ++ optionHeader.Type = Ip6OptionPrefixInfo; |
| 240 | ++ optionHeader.Length = 3; // Length 3 * 8 = 24 (Invalid) |
| 241 | ++ UINT8 option[sizeof (IP6_OPTION_HEADER)]; |
| 242 | ++ |
| 243 | ++ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); |
| 244 | ++ UINT16 optionLen = sizeof (IP6_OPTION_HEADER); |
| 245 | ++ |
| 246 | ++ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); |
| 247 | ++} |
| 248 | +-- |
| 249 | +2.40.0 |
| 250 | + |
0 commit comments