431 lines
17 KiB
Diff
431 lines
17 KiB
Diff
|
From dab03ad5334af1c93797119f2eeda6ce757461f8 Mon Sep 17 00:00:00 2001
|
||
|
From: Jon Maloy <jmaloy@redhat.com>
|
||
|
Date: Wed, 14 Feb 2024 20:25:29 -0500
|
||
|
Subject: [PATCH 09/18] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit
|
||
|
Tests
|
||
|
|
||
|
RH-Author: Jon Maloy <jmaloy@redhat.com>
|
||
|
RH-MergeRequest: 54: NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch
|
||
|
RH-Jira: RHEL-21841 RHEL-21843 RHEL-21845 RHEL-21847 RHEL-21849 RHEL-21851 RHEL-21853
|
||
|
RH-Acked-by: Gerd Hoffmann <None>
|
||
|
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
||
|
RH-Commit: [9/18] f68829a7f34f5a09a02d28cc5cfd109f90c442da
|
||
|
|
||
|
JIRA: https://issues.redhat.com/browse/RHEL-21847
|
||
|
CVE: CVE-2022-45232
|
||
|
Upstream: Merged
|
||
|
|
||
|
commit c9c87f08dd6ace36fa843424522c3558a8374cac
|
||
|
Author: Doug Flick <dougflick@microsoft.com>
|
||
|
Date: Fri Jan 26 05:54:51 2024 +0800
|
||
|
|
||
|
NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests
|
||
|
|
||
|
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537
|
||
|
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538
|
||
|
|
||
|
Unit tests to confirm that..
|
||
|
Infinite loop when parsing unknown options in the Destination Options
|
||
|
header
|
||
|
|
||
|
and
|
||
|
|
||
|
Infinite loop when parsing a PadN option in the Destination Options
|
||
|
header
|
||
|
|
||
|
... have been patched
|
||
|
|
||
|
This patch tests the following functions:
|
||
|
Ip6IsOptionValid
|
||
|
|
||
|
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>
|
||
|
|
||
|
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
|
||
|
---
|
||
|
.../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 10 +-
|
||
|
.../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 278 ++++++++++++++++++
|
||
|
.../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h | 40 +++
|
||
|
3 files changed, 324 insertions(+), 4 deletions(-)
|
||
|
create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
|
||
|
|
||
|
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
|
||
|
index 6e4de0745f..ba29dbabad 100644
|
||
|
--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
|
||
|
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
|
||
|
@@ -1,13 +1,13 @@
|
||
|
## @file
|
||
|
-# Unit test suite for the Ip6Dxe using Google Test
|
||
|
+# Unit test suite for the Ip6DxeGoogleTest using Google Test
|
||
|
#
|
||
|
# Copyright (c) Microsoft Corporation.<BR>
|
||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||
|
##
|
||
|
[Defines]
|
||
|
INF_VERSION = 0x00010017
|
||
|
- BASE_NAME = Ip6DxeUnitTest
|
||
|
- FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A
|
||
|
+ BASE_NAME = Ip6DxeGoogleTest
|
||
|
+ FILE_GUID = AE39981C-B7FE-41A8-A9C2-F41910477CA3
|
||
|
VERSION_STRING = 1.0
|
||
|
MODULE_TYPE = HOST_APPLICATION
|
||
|
#
|
||
|
@@ -16,9 +16,11 @@
|
||
|
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||
|
#
|
||
|
[Sources]
|
||
|
+ ../Ip6Option.c
|
||
|
+ Ip6OptionGoogleTest.h
|
||
|
Ip6DxeGoogleTest.cpp
|
||
|
Ip6OptionGoogleTest.cpp
|
||
|
- ../Ip6Option.c
|
||
|
+ Ip6OptionGoogleTest.h
|
||
|
|
||
|
[Packages]
|
||
|
MdePkg/MdePkg.dec
|
||
|
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
|
||
|
index f2cd90e1a9..29f8a4a96e 100644
|
||
|
--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
|
||
|
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
|
||
|
@@ -12,6 +12,7 @@ extern "C" {
|
||
|
#include <Library/DebugLib.h>
|
||
|
#include "../Ip6Impl.h"
|
||
|
#include "../Ip6Option.h"
|
||
|
+ #include "Ip6OptionGoogleTest.h"
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////
|
||
|
@@ -127,3 +128,280 @@ TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse)
|
||
|
|
||
|
EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen));
|
||
|
}
|
||
|
+
|
||
|
+////////////////////////////////////////////////////////////////////////
|
||
|
+// Ip6IsOptionValid Tests
|
||
|
+////////////////////////////////////////////////////////////////////////
|
||
|
+
|
||
|
+// Define a fixture for your tests if needed
|
||
|
+class Ip6IsOptionValidTest : public ::testing::Test {
|
||
|
+protected:
|
||
|
+ // Add any setup code if needed
|
||
|
+ virtual void
|
||
|
+ SetUp (
|
||
|
+ )
|
||
|
+ {
|
||
|
+ // Initialize any resources or variables
|
||
|
+ }
|
||
|
+
|
||
|
+ // Add any cleanup code if needed
|
||
|
+ virtual void
|
||
|
+ TearDown (
|
||
|
+ )
|
||
|
+ {
|
||
|
+ // Clean up any resources or variables
|
||
|
+ }
|
||
|
+};
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify that a NULL option is Invalid
|
||
|
+TEST_F (Ip6IsOptionValidTest, NullOptionShouldReturnTrue) {
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ IP6_SERVICE *IpSb = NULL;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ EXPECT_FALSE (Ip6IsOptionValid (IpSb, &Packet, NULL, 0, 0));
|
||
|
+}
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify that an unknown option with a length of 0 and type of <unknown> does not cause an infinite loop
|
||
|
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength0) {
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ UINT32 DeadCode = 0xDeadC0de;
|
||
|
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
|
||
|
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ IP6_OPTION_HEADER optionHeader;
|
||
|
+
|
||
|
+ optionHeader.Type = 23; // Unknown Option
|
||
|
+ optionHeader.Length = 0; // This will cause an infinite loop if the function is not working correctly
|
||
|
+
|
||
|
+ // This should be a valid option even though the length is 0
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+}
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify that an unknown option with a length of 1 and type of <unknown> does not cause an infinite loop
|
||
|
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength1) {
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ UINT32 DeadCode = 0xDeadC0de;
|
||
|
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
|
||
|
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ IP6_OPTION_HEADER optionHeader;
|
||
|
+
|
||
|
+ optionHeader.Type = 23; // Unknown Option
|
||
|
+ optionHeader.Length = 1; // This will cause an infinite loop if the function is not working correctly
|
||
|
+
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+}
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify that an unknown option with a length of 2 and type of <unknown> does not cause an infinite loop
|
||
|
+TEST_F (Ip6IsOptionValidTest, VerifyIpSkipUnknownOption) {
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ UINT32 DeadCode = 0xDeadC0de;
|
||
|
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
|
||
|
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ IP6_OPTION_HEADER optionHeader;
|
||
|
+
|
||
|
+ optionHeader.Type = 23; // Unknown Option
|
||
|
+ optionHeader.Length = 2; // Valid length for an unknown option
|
||
|
+
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+}
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify that Ip6OptionPad1 is valid with a length of 0
|
||
|
+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPad1) {
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ UINT32 DeadCode = 0xDeadC0de;
|
||
|
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
|
||
|
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ IP6_OPTION_HEADER optionHeader;
|
||
|
+
|
||
|
+ optionHeader.Type = Ip6OptionPad1;
|
||
|
+ optionHeader.Length = 0;
|
||
|
+
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+}
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify that Ip6OptionPadN doesn't overflow with various lengths
|
||
|
+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPadN) {
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ UINT32 DeadCode = 0xDeadC0de;
|
||
|
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
|
||
|
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ IP6_OPTION_HEADER optionHeader;
|
||
|
+
|
||
|
+ optionHeader.Type = Ip6OptionPadN;
|
||
|
+ optionHeader.Length = 0xFF;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+
|
||
|
+ optionHeader.Length = 0xFE;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+
|
||
|
+ optionHeader.Length = 0xFD;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+
|
||
|
+ optionHeader.Length = 0xFC;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+}
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify an unknown option doesn't cause an infinite loop with various lengths
|
||
|
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLengthAttemptOverflow) {
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ UINT32 DeadCode = 0xDeadC0de;
|
||
|
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
|
||
|
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ IP6_OPTION_HEADER optionHeader;
|
||
|
+
|
||
|
+ optionHeader.Type = 23; // Unknown Option
|
||
|
+ optionHeader.Length = 0xFF;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+
|
||
|
+ optionHeader.Length = 0xFE;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+
|
||
|
+ optionHeader.Length = 0xFD;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+
|
||
|
+ optionHeader.Length = 0xFC;
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
|
||
|
+}
|
||
|
+
|
||
|
+// Test Description
|
||
|
+// Verify that the function supports multiple options
|
||
|
+TEST_F (Ip6IsOptionValidTest, MultiOptionSupport) {
|
||
|
+ UINT16 HdrLen;
|
||
|
+ NET_BUF Packet = { 0 };
|
||
|
+ // we need to define enough of the packet to make the function work
|
||
|
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
|
||
|
+ UINT32 DeadCode = 0xDeadC0de;
|
||
|
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
|
||
|
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
|
||
|
+
|
||
|
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
|
||
|
+ EFI_IP6_HEADER Ip6Header = { 0 };
|
||
|
+
|
||
|
+ Ip6Header.SourceAddress = SourceAddress;
|
||
|
+ Ip6Header.DestinationAddress = DestinationAddress;
|
||
|
+ Packet.Ip.Ip6 = &Ip6Header;
|
||
|
+
|
||
|
+ UINT8 ExtHdr[1024] = { 0 };
|
||
|
+ UINT8 *Cursor = ExtHdr;
|
||
|
+ IP6_OPTION_HEADER *Option = (IP6_OPTION_HEADER *)ExtHdr;
|
||
|
+
|
||
|
+ // Let's start chaining options
|
||
|
+
|
||
|
+ Option->Type = 23; // Unknown Option
|
||
|
+ Option->Length = 0xFC;
|
||
|
+
|
||
|
+ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC;
|
||
|
+
|
||
|
+ Option = (IP6_OPTION_HEADER *)Cursor;
|
||
|
+ Option->Type = Ip6OptionPad1;
|
||
|
+
|
||
|
+ Cursor += sizeof (1);
|
||
|
+
|
||
|
+ // Type and length aren't processed, instead it just moves the pointer forward by 4 bytes
|
||
|
+ Option = (IP6_OPTION_HEADER *)Cursor;
|
||
|
+ Option->Type = Ip6OptionRouterAlert;
|
||
|
+ Option->Length = 4;
|
||
|
+
|
||
|
+ Cursor += sizeof (IP6_OPTION_HEADER) + 4;
|
||
|
+
|
||
|
+ Option = (IP6_OPTION_HEADER *)Cursor;
|
||
|
+ Option->Type = Ip6OptionPadN;
|
||
|
+ Option->Length = 0xFC;
|
||
|
+
|
||
|
+ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC;
|
||
|
+
|
||
|
+ Option = (IP6_OPTION_HEADER *)Cursor;
|
||
|
+ Option->Type = Ip6OptionRouterAlert;
|
||
|
+ Option->Length = 4;
|
||
|
+
|
||
|
+ Cursor += sizeof (IP6_OPTION_HEADER) + 4;
|
||
|
+
|
||
|
+ // Total 524
|
||
|
+
|
||
|
+ HdrLen = (UINT16)(Cursor - ExtHdr);
|
||
|
+
|
||
|
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, ExtHdr, HdrLen, 0));
|
||
|
+}
|
||
|
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
|
||
|
new file mode 100644
|
||
|
index 0000000000..0509b6ae30
|
||
|
--- /dev/null
|
||
|
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
|
||
|
@@ -0,0 +1,40 @@
|
||
|
+/** @file
|
||
|
+ Exposes the functions needed to test the Ip6Option module.
|
||
|
+
|
||
|
+ Copyright (c) Microsoft Corporation
|
||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||
|
+**/
|
||
|
+
|
||
|
+#ifndef IP6_OPTION_HEADER_GOOGLE_TEST_H_
|
||
|
+#define IP6_OPTION_HEADER_GOOGLE_TEST_H_
|
||
|
+
|
||
|
+#include <Uefi.h>
|
||
|
+#include "../Ip6Impl.h"
|
||
|
+
|
||
|
+/**
|
||
|
+ Validate the IP6 option format for both the packets we received
|
||
|
+ and that we will transmit. It will compute the ICMPv6 error message fields
|
||
|
+ if the option is malformatted.
|
||
|
+
|
||
|
+ @param[in] IpSb The IP6 service data.
|
||
|
+ @param[in] Packet The to be validated packet.
|
||
|
+ @param[in] Option The first byte of the option.
|
||
|
+ @param[in] OptionLen The length of the whole option.
|
||
|
+ @param[in] Pointer Identifies the octet offset within
|
||
|
+ the invoking packet where the error was detected.
|
||
|
+
|
||
|
+
|
||
|
+ @retval TRUE The option is properly formatted.
|
||
|
+ @retval FALSE The option is malformatted.
|
||
|
+
|
||
|
+**/
|
||
|
+BOOLEAN
|
||
|
+Ip6IsOptionValid (
|
||
|
+ IN IP6_SERVICE *IpSb,
|
||
|
+ IN NET_BUF *Packet,
|
||
|
+ IN UINT8 *Option,
|
||
|
+ IN UINT16 OptionLen,
|
||
|
+ IN UINT32 Pointer
|
||
|
+ );
|
||
|
+
|
||
|
+#endif // __IP6_OPTION_HEADER_GOOGLE_TEST_H__
|
||
|
--
|
||
|
2.39.3
|
||
|
|