From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <bounce+27952+114260+7686176+12367111@groups.io>
Received: from mail02.groups.io (mail02.groups.io [66.175.222.108])
	by spool.mail.gandi.net (Postfix) with ESMTPS id E9EFC7803CC
	for <rebecca@openfw.io>; Wed, 24 Jan 2024 05:20:36 +0000 (UTC)
DKIM-Signature: a=rsa-sha256; bh=p79p4ffEnsh0LYLb7MkyQlJa2C2whNYOX6MDME8n48Q=;
 c=relaxed/simple; d=groups.io;
 h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding;
 s=20140610; t=1706073635; v=1;
 b=ZPhP+Bu9YSdEeEiIyZ9DsfOxgJIFB6Xt0Rb/URXlSFUM2roaHn7fW3TiMDhK+YrUW4Ds7hsQ
 cJd7sNBvPfQzlv17Jeqy37lPL+aAM+2tytvsH+Qbdyw5/JoBqEgAWjoEKQcpNE8Bzoz8OfoONPW
 SgSTkq4HawlNhHmiMvpncOFI=
X-Received: by 127.0.0.2 with SMTP id ypgQYY7687511xnPfdqWUfbZ; Tue, 23 Jan 2024 21:20:35 -0800
X-Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180])
 by mx.groups.io with SMTP id smtpd.web10.16102.1706073633462009143
 for <devel@edk2.groups.io>;
 Tue, 23 Jan 2024 21:20:33 -0800
X-Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-1d74dce86f7so24121555ad.2
        for <devel@edk2.groups.io>; Tue, 23 Jan 2024 21:20:33 -0800 (PST)
X-Gm-Message-State: OIS587JUhnC2TN9NKuLNr0mrx7686176AA=
X-Google-Smtp-Source: AGHT+IF3wwVFg2/PdtJhGm1ynaPlAwtu45VkoSNZP7ENIxcrOL8cX0ypuB3mRfc2xbY/M+OICxOl/w==
X-Received: by 2002:a17:902:c946:b0:1d7:8553:35c with SMTP id i6-20020a170902c94600b001d78553035cmr256117pla.13.1706073632491;
        Tue, 23 Jan 2024 21:20:32 -0800 (PST)
X-Received: from localhost.localdomain ([24.17.138.83])
        by smtp.gmail.com with ESMTPSA id w2-20020a170902c78200b001d71f10aa42sm7831709pla.11.2024.01.23.21.20.31
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Tue, 23 Jan 2024 21:20:32 -0800 (PST)
From: "Doug Flick via groups.io" <dougflick=microsoft.com@groups.io>
To: devel@edk2.groups.io
Cc: Doug Flick <dougflick@microsoft.com>,
	Saloni Kasbekar <saloni.kasbekar@intel.com>,
	Zachary Clark-williams <zachary.clark-williams@intel.com>,
	"Doug Flick [MSFT]" <doug.edk2@gmail.com>
Subject: [edk2-devel] [PATCH 08/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests
Date: Tue, 23 Jan 2024 19:33:31 -0800
Message-ID: <6acb5c2e7046f8d988b4475accac076d5728354c.1706062164.git.doug.edk2@gmail.com>
In-Reply-To: <cover.1706062164.git.doug.edk2@gmail.com>
References: <cover.1706062164.git.doug.edk2@gmail.com>
MIME-Version: 1.0
Precedence: Bulk
List-Subscribe: <mailto:devel+subscribe@edk2.groups.io>
List-Help: <mailto:devel+help@edk2.groups.io>
Sender: devel@edk2.groups.io
List-Id: <devel.edk2.groups.io>
Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io
Reply-To: devel@edk2.groups.io,dougflick@microsoft.com
List-Unsubscribe-Post: List-Unsubscribe=One-Click
List-Unsubscribe: <https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/plugh>
Content-Transfer-Encoding: quoted-printable
X-GND-Status: LEGIT
Authentication-Results: spool.mail.gandi.net;
	dkim=pass header.d=groups.io header.s=20140610 header.b=ZPhP+Bu9;
	dmarc=none;
	spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io

From: Doug Flick <dougflick@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4537
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4538

SECURITY PATCH - Unit Tests

TCBZ4537
CVE-2023-45232
CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')

TCBZ4538
CVE-2023-45233
CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')

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>
---
 .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf    |  10 +-
 .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h   |  40 +++
 .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 282 ++++++++++++++++++
 3 files changed, 328 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 6e4de0745fb5..ba29dbabadb9 100644
--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
@@ -1,13 +1,13 @@
 ## @file=0D
-# Unit test suite for the Ip6Dxe using Google Test=0D
+# Unit test suite for the Ip6DxeGoogleTest using Google Test=0D
 #=0D
 # Copyright (c) Microsoft Corporation.<BR>=0D
 # SPDX-License-Identifier: BSD-2-Clause-Patent=0D
 ##=0D
 [Defines]=0D
   INF_VERSION         =3D 0x00010017=0D
-  BASE_NAME           =3D Ip6DxeUnitTest=0D
-  FILE_GUID           =3D 4F05D17D-D3E7-4AAE-820C-576D46D2D34A=0D
+  BASE_NAME           =3D Ip6DxeGoogleTest=0D
+  FILE_GUID           =3D AE39981C-B7FE-41A8-A9C2-F41910477CA3=0D
   VERSION_STRING      =3D 1.0=0D
   MODULE_TYPE         =3D HOST_APPLICATION=0D
 #=0D
@@ -16,9 +16,11 @@ [Defines]
 #  VALID_ARCHITECTURES           =3D IA32 X64 AARCH64=0D
 #=0D
 [Sources]=0D
+  ../Ip6Option.c=0D
+  Ip6OptionGoogleTest.h=0D
   Ip6DxeGoogleTest.cpp=0D
   Ip6OptionGoogleTest.cpp=0D
-  ../Ip6Option.c=0D
+  Ip6OptionGoogleTest.h=0D
 =0D
 [Packages]=0D
   MdePkg/MdePkg.dec=0D
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h b/NetworkPk=
g/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
new file mode 100644
index 000000000000..618a7e658e5a
--- /dev/null
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
@@ -0,0 +1,40 @@
+/** @file=0D
+  Exposes the functions needed to test the Ip6Option module.=0D
+=0D
+  Copyright (c) Microsoft Corporation=0D
+  SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+**/=0D
+=0D
+#ifndef EFI_IP6_OPTION_GOOGLE_TEST_H_=0D
+#define EFI_IP6_OPTION_GOOGLE_TEST_H_=0D
+=0D
+#include <Uefi.h>=0D
+#include "../Ip6Impl.h"=0D
+=0D
+/**=0D
+  Validate the IP6 option format for both the packets we received=0D
+  and that we will transmit. It will compute the ICMPv6 error message fiel=
ds=0D
+  if the option is malformatted.=0D
+=0D
+  @param[in]  IpSb              The IP6 service data.=0D
+  @param[in]  Packet            The to be validated packet.=0D
+  @param[in]  Option            The first byte of the option.=0D
+  @param[in]  OptionLen         The length of the whole option.=0D
+  @param[in]  Pointer           Identifies the octet offset within=0D
+                                the invoking packet where the error was de=
tected.=0D
+=0D
+=0D
+  @retval TRUE     The option is properly formatted.=0D
+  @retval FALSE    The option is malformatted.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+Ip6IsOptionValid (=0D
+  IN IP6_SERVICE  *IpSb,=0D
+  IN NET_BUF      *Packet,=0D
+  IN UINT8        *Option,=0D
+  IN UINT16       OptionLen,=0D
+  IN UINT32       Pointer=0D
+  );=0D
+=0D
+#endif // __EFI_IP6_OPTION_GOOGLE_TEST_H__=0D
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/Network=
Pkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
index f2cd90e1a952..69eef4b98ed2 100644
--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
@@ -12,6 +12,7 @@ extern "C" {
   #include <Library/DebugLib.h>=0D
   #include "../Ip6Impl.h"=0D
   #include "../Ip6Option.h"=0D
+  #include "Ip6OptionGoogleTest.h"=0D
 }=0D
 =0D
 /////////////////////////////////////////////////////////////////////////=
=0D
@@ -127,3 +128,284 @@ TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOpt=
ionLengthShouldReturnFalse)
 =0D
   EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen));=0D
 }=0D
+=0D
+////////////////////////////////////////////////////////////////////////=0D
+// Ip6IsOptionValid Tests=0D
+////////////////////////////////////////////////////////////////////////=0D
+=0D
+// Define a fixture for your tests if needed=0D
+class Ip6IsOptionValidTest : public ::testing::Test {=0D
+protected:=0D
+  // Add any setup code if needed=0D
+  virtual void=0D
+  SetUp (=0D
+    )=0D
+  {=0D
+    // Initialize any resources or variables=0D
+  }=0D
+=0D
+  // Add any cleanup code if needed=0D
+  virtual void=0D
+  TearDown (=0D
+    )=0D
+  {=0D
+    // Clean up any resources or variables=0D
+  }=0D
+};=0D
+=0D
+//////////////////////////////////////////////////////////////////////////=
/////=0D
+// Ip6IsOptionValidTest Tests=0D
+//////////////////////////////////////////////////////////////////////////=
/////=0D
+=0D
+// Test Description=0D
+// Verify that a NULL option is Invalid=0D
+TEST_F (Ip6IsOptionValidTest, NullOptionShouldReturnTrue) {=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  IP6_SERVICE  *IpSb =3D NULL;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  EXPECT_FALSE (Ip6IsOptionValid (IpSb, &Packet, NULL, 0, 0));=0D
+}=0D
+=0D
+// Test Description=0D
+// Verify that an unknown option with a length of 0 and type of <unknown> =
does not cause an infinite loop=0D
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength0) =
{=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  UINT32  DeadCode =3D 0xDeadC0de;=0D
+  // Don't actually use this pointer, just pass it to the function, nothin=
g will be done with it=0D
+  IP6_SERVICE  *IpSb =3D (IP6_SERVICE *)&DeadCode;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  IP6_OPTION_HEADER  optionHeader;=0D
+=0D
+  optionHeader.Type   =3D 23;   // Unknown Option=0D
+  optionHeader.Length =3D 0;    // This will cause an infinite loop if the=
 function is not working correctly=0D
+=0D
+  // This should be a valid option even though the length is 0=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+}=0D
+=0D
+// Test Description=0D
+// Verify that an unknown option with a length of 1 and type of <unknown> =
does not cause an infinite loop=0D
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength1) =
{=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  UINT32  DeadCode =3D 0xDeadC0de;=0D
+  // Don't actually use this pointer, just pass it to the function, nothin=
g will be done with it=0D
+  IP6_SERVICE  *IpSb =3D (IP6_SERVICE *)&DeadCode;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  IP6_OPTION_HEADER  optionHeader;=0D
+=0D
+  optionHeader.Type   =3D 23;   // Unknown Option=0D
+  optionHeader.Length =3D 1;    // This will cause an infinite loop if the=
 function is not working correctly=0D
+=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+}=0D
+=0D
+// Test Description=0D
+// Verify that an unknown option with a length of 2 and type of <unknown> =
does not cause an infinite loop=0D
+TEST_F (Ip6IsOptionValidTest, VerifyIpSkipUnknownOption) {=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  UINT32  DeadCode =3D 0xDeadC0de;=0D
+  // Don't actually use this pointer, just pass it to the function, nothin=
g will be done with it=0D
+  IP6_SERVICE  *IpSb =3D (IP6_SERVICE *)&DeadCode;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  IP6_OPTION_HEADER  optionHeader;=0D
+=0D
+  optionHeader.Type   =3D 23;   // Unknown Option=0D
+  optionHeader.Length =3D 2;    // Valid length for an unknown option=0D
+=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+}=0D
+=0D
+// Test Description=0D
+// Verify that Ip6OptionPad1 is valid with a length of 0=0D
+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPad1) {=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  UINT32  DeadCode =3D 0xDeadC0de;=0D
+  // Don't actually use this pointer, just pass it to the function, nothin=
g will be done with it=0D
+  IP6_SERVICE  *IpSb =3D (IP6_SERVICE *)&DeadCode;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  IP6_OPTION_HEADER  optionHeader;=0D
+=0D
+  optionHeader.Type   =3D Ip6OptionPad1;=0D
+  optionHeader.Length =3D 0;=0D
+=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+}=0D
+=0D
+// Test Description=0D
+// Verify that Ip6OptionPadN doesn't overflow with various lengths=0D
+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPadN) {=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  UINT32  DeadCode =3D 0xDeadC0de;=0D
+  // Don't actually use this pointer, just pass it to the function, nothin=
g will be done with it=0D
+  IP6_SERVICE  *IpSb =3D (IP6_SERVICE *)&DeadCode;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  IP6_OPTION_HEADER  optionHeader;=0D
+=0D
+  optionHeader.Type   =3D Ip6OptionPadN;=0D
+  optionHeader.Length =3D 0xFF;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+=0D
+  optionHeader.Length =3D 0xFE;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+=0D
+  optionHeader.Length =3D 0xFD;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+=0D
+  optionHeader.Length =3D 0xFC;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+}=0D
+=0D
+// Test Description=0D
+// Verify an unknown option doesn't cause an infinite loop with various le=
ngths=0D
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLengthAtt=
emptOverflow) {=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  UINT32  DeadCode =3D 0xDeadC0de;=0D
+  // Don't actually use this pointer, just pass it to the function, nothin=
g will be done with it=0D
+  IP6_SERVICE  *IpSb =3D (IP6_SERVICE *)&DeadCode;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  IP6_OPTION_HEADER  optionHeader;=0D
+=0D
+  optionHeader.Type   =3D 23;   // Unknown Option=0D
+  optionHeader.Length =3D 0xFF;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+=0D
+  optionHeader.Length =3D 0xFE;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+=0D
+  optionHeader.Length =3D 0xFD;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+=0D
+  optionHeader.Length =3D 0xFC;=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si=
zeof (optionHeader), 0));=0D
+}=0D
+=0D
+// Test Description=0D
+// Verify that the function supports multiple options=0D
+TEST_F (Ip6IsOptionValidTest, MultiOptionSupport) {=0D
+  UINT16   HdrLen;=0D
+  NET_BUF  Packet =3D { 0 };=0D
+  // we need to define enough of the packet to make the function work=0D
+  // The function being tested will pass IpSb to Ip6SendIcmpError which is=
 defined above=0D
+  UINT32  DeadCode =3D 0xDeadC0de;=0D
+  // Don't actually use this pointer, just pass it to the function, nothin=
g will be done with it=0D
+  IP6_SERVICE  *IpSb =3D (IP6_SERVICE *)&DeadCode;=0D
+=0D
+  EFI_IPv6_ADDRESS  SourceAddress      =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IPv6_ADDRESS  DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,=
 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };=0D
+  EFI_IP6_HEADER    Ip6Header          =3D { 0 };=0D
+=0D
+  Ip6Header.SourceAddress      =3D SourceAddress;=0D
+  Ip6Header.DestinationAddress =3D DestinationAddress;=0D
+  Packet.Ip.Ip6                =3D &Ip6Header;=0D
+=0D
+  UINT8              ExtHdr[1024] =3D { 0 };=0D
+  UINT8              *Cursor      =3D ExtHdr;=0D
+  IP6_OPTION_HEADER  *Option      =3D (IP6_OPTION_HEADER *)ExtHdr;=0D
+=0D
+  // Let's start chaining options=0D
+=0D
+  Option->Type   =3D 23;   // Unknown Option=0D
+  Option->Length =3D 0xFC;=0D
+=0D
+  Cursor +=3D sizeof (IP6_OPTION_HEADER) + 0xFC;=0D
+=0D
+  Option       =3D (IP6_OPTION_HEADER *)Cursor;=0D
+  Option->Type =3D Ip6OptionPad1;=0D
+=0D
+  Cursor +=3D sizeof (1);=0D
+=0D
+  // Type and length aren't processed, instead it just moves the pointer f=
orward by 4 bytes=0D
+  Option         =3D (IP6_OPTION_HEADER *)Cursor;=0D
+  Option->Type   =3D Ip6OptionRouterAlert;=0D
+  Option->Length =3D 4;=0D
+=0D
+  Cursor +=3D sizeof (IP6_OPTION_HEADER) + 4;=0D
+=0D
+  Option         =3D (IP6_OPTION_HEADER *)Cursor;=0D
+  Option->Type   =3D Ip6OptionPadN;=0D
+  Option->Length =3D 0xFC;=0D
+=0D
+  Cursor +=3D sizeof (IP6_OPTION_HEADER) + 0xFC;=0D
+=0D
+  Option         =3D (IP6_OPTION_HEADER *)Cursor;=0D
+  Option->Type   =3D Ip6OptionRouterAlert;=0D
+  Option->Length =3D 4;=0D
+=0D
+  Cursor +=3D sizeof (IP6_OPTION_HEADER) + 4;=0D
+=0D
+  // Total 524=0D
+=0D
+  HdrLen =3D (UINT16)(Cursor - ExtHdr);=0D
+=0D
+  EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, ExtHdr, HdrLen, 0));=0D
+}=0D
--=20
2.43.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114260): https://edk2.groups.io/g/devel/message/114260
Mute This Topic: https://groups.io/mt/103926739/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-