From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114463+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114463+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223990; cv=none; d=zohomail.com; s=zohoarc; b=iHjLmORLdOdpzWNrrOKV7JAoRhiAFhcTwosIaCb6fdzFgow22WQphbgDVcHg6U9msA1wX6PManTWvaz/3BtjKY8NhiG+AABAgGrMCrC3GuDEG2cpA7O3BkKth1beaxgwlitrl/9u809IMVDAb5nyeVSpjcTCwt36YDU0WgJaCUI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223990; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=tlzDciuGZo3btyZjweIXDNtoUBjZYv9dIwKl7AYhE1Q=; b=cYYqABzvdIeY9kKobD0GZdkF+dyN7pigbgwe1TfGvL8m+vT/yL9JZWAnj2BuZTQW0SgzM/Yi3mlTdYf+R9jqWe80bo9sYfc6AJfiAgInmbtpj3+LvgAmMY25yrl6F5CrIJhmwpbXkAHEZd5mZY+szbzisDNpzUn7I4COmh66hmg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114463+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223990857908.3051521529579; Thu, 25 Jan 2024 15:06:30 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=8uDslYMk0Am23rt0ulIW9HT0sXO3LsM6o6pbeghiZT0=; 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=1706223990; v=1; b=NBeYgCYE/UElKEIfHZbDDe2LbcHp6lWNyu0DaCWkZqT/ayUU5qdctdFSVC3MDVK1QGQulucS Z98OkLH3iFRyh5Z/3WFsduQ2sxIu1ydBDsNc3Ygj9eBjFh96CO19SVE2BJBtMK51sBa32woO5PA 1Ez5FWQ0hKqQPR8EmKyeYFM0= X-Received: by 127.0.0.2 with SMTP id owRDYY1788612xU4XZxDipX7; Thu, 25 Jan 2024 15:06:30 -0800 X-Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) by mx.groups.io with SMTP id smtpd.web11.775.1706223989860706912 for ; Thu, 25 Jan 2024 15:06:29 -0800 X-Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-1d71207524dso33291685ad.1 for ; Thu, 25 Jan 2024 15:06:29 -0800 (PST) X-Gm-Message-State: JCX0NQmXwCRQMuCMwRqihNNSx1787277AA= X-Google-Smtp-Source: AGHT+IFL4v+d4MebddwKF2V4npjeknMt3tRMNdFCASQZD++GZAvknlnpKQTYvNKn7u14gPNW8eY7WA== X-Received: by 2002:a17:903:2592:b0:1d7:599d:ed25 with SMTP id jb18-20020a170903259200b001d7599ded25mr538361plb.39.1706223988397; Thu, 25 Jan 2024 15:06:28 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:27 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Saloni Kasbekar , Zachary Clark-williams Subject: [edk2-devel] [PATCH v2 01/15] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch Date: Thu, 25 Jan 2024 13:54:43 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223991867100006 Content-Type: text/plain; charset="utf-8" REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4535 Bug Details: PixieFail Bug #2 CVE-2023-45230 CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer Changes Overview: > -UINT8 * > +EFI_STATUS > Dhcp6AppendOption ( > - IN OUT UINT8 *Buf, > - IN UINT16 OptType, > - IN UINT16 OptLen, > - IN UINT8 *Data > + IN OUT EFI_DHCP6_PACKET *Packet, > + IN OUT UINT8 **PacketCursor, > + IN UINT16 OptType, > + IN UINT16 OptLen, > + IN UINT8 *Data > ); Dhcp6AppendOption() and variants can return errors now. All callsites are adapted accordingly. It gets passed in EFI_DHCP6_PACKET as additional parameter ... > + // > + // Verify the PacketCursor is within the packet > + // > + if ( (*PacketCursor < Packet->Dhcp6.Option) > + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) > + { > + return EFI_INVALID_PARAMETER; > + } ... so it can look at Packet->Size when checking buffer space. Also to allow Packet->Length updates. Lots of checks added. Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 43 +++ NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h | 78 +++--- NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 409 +++++++++++++++++++---------- NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 373 +++++++++++++++++++++----- 4 files changed, 666 insertions(+), 237 deletions(-) diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Imp= l.h index 0eb9c669b5a1..f2422c2f2827 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h @@ -45,6 +45,49 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S') #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I') =20 +// +// For more information on DHCP options see RFC 8415, Section 21.1 +// +// The format of DHCP options is: +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | option-code | option-len | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | option-data | +// | (option-len octets) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16)) +#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16)) + +// +// Combined size of Code and Length +// +#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \ + DHCP6_SIZE_OF_OPT_LEN) + +STATIC_ASSERT ( + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN =3D=3D 4, + "Combined size of Code and Length must be 4 per RFC 8415" + ); + +// +// Offset to the length is just past the code +// +#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE) +STATIC_ASSERT ( + DHCP6_OPT_LEN_OFFSET (0) =3D=3D 2, + "Offset of length is + 2 past start of option" + ); + +#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) +STATIC_ASSERT ( + DHCP6_OPT_DATA_OFFSET (0) =3D=3D 4, + "Offset to option data should be +4 from start of option" + ); + #define DHCP6_PACKET_ALL 0 #define DHCP6_PACKET_STATEFUL 1 #define DHCP6_PACKET_STATELESS 2 diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6= Utility.h index 046454ff4ac2..06947f6c1fcf 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h @@ -160,69 +160,85 @@ Dhcp6OnTransmitted ( ); =20 /** - Append the appointed option to the buf, and move the buf to the end. + Append the option to Buf, update the length of packet, and move Buf to t= he end. =20 - @param[in, out] Buf The pointer to buffer. - @param[in] OptType The option type. - @param[in] OptLen The length of option content.s - @param[in] Data The pointer to the option content. - - @return Buf The position to append the next option. + @param[in, out] Packet A pointer to the packet, on success Packe= t->Length + will be updated. + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor + will be moved to the end of the option. + @param[in] OptType The option type. + @param[in] OptLen The length of option contents. + @param[in] Data The pointer to the option content. =20 + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. **/ -UINT8 * +EFI_STATUS Dhcp6AppendOption ( - IN OUT UINT8 *Buf, - IN UINT16 OptType, - IN UINT16 OptLen, - IN UINT8 *Data + IN OUT EFI_DHCP6_PACKET *Packet, + IN OUT UINT8 **PacketCursor, + IN UINT16 OptType, + IN UINT16 OptLen, + IN UINT8 *Data ); =20 /** - Append the Ia option to Buf, and move Buf to the end. - - @param[in, out] Buf The pointer to the position to append. + Append the appointed Ia option to Buf, update the Ia option length, and = move Buf + to the end of the option. + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length + will be updated. + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor + will be moved to the end of the option. @param[in] Ia The pointer to the Ia. @param[in] T1 The time of T1. @param[in] T2 The time of T2. @param[in] MessageType Message type of DHCP6 package. =20 - @return Buf The position to append the next Ia option. - + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. **/ -UINT8 * +EFI_STATUS Dhcp6AppendIaOption ( - IN OUT UINT8 *Buf, - IN EFI_DHCP6_IA *Ia, - IN UINT32 T1, - IN UINT32 T2, - IN UINT32 MessageType + IN OUT EFI_DHCP6_PACKET *Packet, + IN OUT UINT8 **PacketCursor, + IN EFI_DHCP6_IA *Ia, + IN UINT32 T1, + IN UINT32 T2, + IN UINT32 MessageType ); =20 /** Append the appointed Elapsed time option to Buf, and move Buf to the end. =20 - @param[in, out] Buf The pointer to the position to append. + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor + will be moved to the end of the option. @param[in] Instance The pointer to the Dhcp6 instance. @param[out] Elapsed The pointer to the elapsed time value in the generated packet. =20 - @return Buf The position to append the next Ia option. + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. =20 **/ -UINT8 * +EFI_STATUS Dhcp6AppendETOption ( - IN OUT UINT8 *Buf, - IN DHCP6_INSTANCE *Instance, - OUT UINT16 **Elapsed + IN OUT EFI_DHCP6_PACKET *Packet, + IN OUT UINT8 **PacketCursor, + IN DHCP6_INSTANCE *Instance, + OUT UINT16 **Elapsed ); =20 /** Set the elapsed time based on the given instance and the pointer to the elapsed time option. =20 - @param[in] Elapsed The pointer to the position to append. - @param[in] Instance The pointer to the Dhcp6 instance. + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. **/ VOID SetElapsedTime ( diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c index dcd01e6268b1..bf5aa7a769de 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c @@ -3,9 +3,9 @@ =20 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation =20 SPDX-License-Identifier: BSD-2-Clause-Patent - **/ =20 #include "Dhcp6Impl.h" @@ -930,7 +930,8 @@ Dhcp6SendSolicitMsg ( // Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } =20 Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen; @@ -944,54 +945,64 @@ Dhcp6SendSolicitMsg ( Cursor =3D Packet->Dhcp6.Option; =20 Length =3D HTONS (ClientId->Length); - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendETOption ( - Cursor, + Status =3D Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendIaOption ( - Cursor, + Status =3D Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 // // Append user-defined when configurate Dhcp6 service. // for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) { UserOpt =3D Instance->Config->OptionList[Index]; - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } =20 - // - // Determine the size/length of packet. - // - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option); ASSERT (Packet->Size > Packet->Length + 8); =20 // // Callback to user with the packet to be sent and check the user's feed= back. // Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // @@ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg ( Instance->StartTime =3D 0; =20 Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // @@ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg ( Elapsed, Instance->Config->SolicitRetransmission ); + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } =20 /** @@ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg ( // Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } =20 Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen; @@ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg ( Cursor =3D Packet->Dhcp6.Option; =20 Length =3D HTONS (ClientId->Length); - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendETOption ( - Cursor, + Status =3D Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendIaOption ( - Cursor, + Status =3D Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 // // Append user-defined when configurate Dhcp6 service. // for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) { UserOpt =3D Instance->Config->OptionList[Index]; - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } =20 - // - // Determine the size/length of packet. - // - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option); ASSERT (Packet->Size > Packet->Length + 8); =20 // @@ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg ( Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); =20 if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // @@ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg ( Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed); =20 if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // // Enqueue the sent packet for the retransmission in case reply timeout. // return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } =20 /** @@ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg ( // Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); if (Packet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } =20 Packet->Size =3D DHCP6_BASE_PACKET_SIZE; @@ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg ( Cursor =3D Packet->Dhcp6.Option; =20 Length =3D HTONS (ClientId->Length); - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendETOption ( - Cursor, + Status =3D Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Heade= r.MessageType); + Status =3D Dhcp6AppendIaOption ( + Packet, + &Cursor, + DecIa, + 0, + 0, + Packet->Dhcp6.Header.MessageType + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - // - // Determine the size/length of packet. - // - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option); ASSERT (Packet->Size > Packet->Length + 8); =20 // // Callback to user with the packet to be sent and check the user's feed= back. // Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // @@ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg ( Instance->StartTime =3D 0; =20 Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // // Enqueue the sent packet for the retransmission in case reply timeout. // return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } =20 /** @@ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg ( // Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); if (Packet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } =20 Packet->Size =3D DHCP6_BASE_PACKET_SIZE; @@ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg ( Cursor =3D Packet->Dhcp6.Option; =20 Length =3D HTONS (ClientId->Length); - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 // // ServerId is extracted from packet, it's network order. // - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendETOption ( - Cursor, + Status =3D Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Heade= r.MessageType); + Status =3D Dhcp6AppendIaOption ( + Packet, + &Cursor, + RelIa, + 0, + 0, + Packet->Dhcp6.Header.MessageType + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - // - // Determine the size/length of packet - // - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option); ASSERT (Packet->Size > Packet->Length + 8); =20 // // Callback to user with the packet to be sent and check the user's feed= back. // Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // @@ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg ( Instance->IaCb.Ia->State =3D Dhcp6Releasing; =20 Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // // Enqueue the sent packet for the retransmission in case reply timeout. // return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } =20 /** @@ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg ( // Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } =20 Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen; @@ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg ( Cursor =3D Packet->Dhcp6.Option; =20 Length =3D HTONS (ClientId->Length); - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendETOption ( - Cursor, + Status =3D Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendIaOption ( - Cursor, + Status =3D Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 if (!RebindRequest) { // @@ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg ( Dhcp6OptServerId ); if (Option =3D=3D NULL) { - FreePool (Packet); - return EFI_DEVICE_ERROR; + Status =3D EFI_DEVICE_ERROR; + goto ON_ERROR; } =20 ServerId =3D (EFI_DHCP6_DUID *)(Option + 2); =20 - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } =20 // @@ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg ( // for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) { UserOpt =3D Instance->Config->OptionList[Index]; - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } =20 - // - // Determine the size/length of packet. - // - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option); ASSERT (Packet->Size > Packet->Length + 8); =20 // @@ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg ( Event =3D (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing; =20 Status =3D Dhcp6CallbackUser (Instance, Event, &Packet); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // @@ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg ( Instance->StartTime =3D 0; =20 Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // // Enqueue the sent packet for the retransmission in case reply timeout. // return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } =20 /** @@ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg ( // Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } =20 Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen; @@ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg ( =20 if (SendClientId) { Length =3D HTONS (ClientId->Length); - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } =20 - Cursor =3D Dhcp6AppendETOption ( - Cursor, + Status =3D Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, OptionRequest->OpCode, OptionRequest->OpLen, OptionRequest->Data ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 // // Append user-defined when configurate Dhcp6 service. // for (Index =3D 0; Index < OptionCount; Index++) { UserOpt =3D OptionList[Index]; - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } =20 - // - // Determine the size/length of packet. - // - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option); ASSERT (Packet->Size > Packet->Length + 8); =20 // @@ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg ( // Send info-request packet with no state. // Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // // Enqueue the sent packet for the retransmission in case reply timeout. // return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission); + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } =20 /** @@ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg ( // Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } =20 Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen; @@ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg ( Cursor =3D Packet->Dhcp6.Option; =20 Length =3D HTONS (ClientId->Length); - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendETOption ( - Cursor, + Status =3D Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 - Cursor =3D Dhcp6AppendIaOption ( - Cursor, + Status =3D Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } =20 // // Append user-defined when configurate Dhcp6 service. // for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) { UserOpt =3D Instance->Config->OptionList[Index]; - Cursor =3D Dhcp6AppendOption ( - Cursor, + Status =3D Dhcp6AppendOption ( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } =20 - // - // Determine the size/length of packet. - // - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option); ASSERT (Packet->Size > Packet->Length + 8); =20 // // Callback to user with the packet to be sent and check the user's feed= back. // Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // @@ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg ( Instance->StartTime =3D 0; =20 Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed); - if (EFI_ERROR (Status)) { - FreePool (Packet); - return Status; + goto ON_ERROR; } =20 // // Enqueue the sent packet for the retransmission in case reply timeout. // return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } =20 /** diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6= Utility.c index e6368b5b1c6c..705c665c519d 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c @@ -577,24 +577,33 @@ Dhcp6OnTransmitted ( } =20 /** - Append the option to Buf, and move Buf to the end. + Append the option to Buf, update the length of packet, and move Buf to t= he end. =20 - @param[in, out] Buf The pointer to the buffer. - @param[in] OptType The option type. - @param[in] OptLen The length of option contents. - @param[in] Data The pointer to the option content. + @param[in, out] Packet A pointer to the packet, on success Packe= t->Length + will be updated. + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor + will be moved to the end of the option. + @param[in] OptType The option type. + @param[in] OptLen The length of option contents. + @param[in] Data The pointer to the option content. =20 - @return Buf The position to append the next option. + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. =20 **/ -UINT8 * +EFI_STATUS Dhcp6AppendOption ( - IN OUT UINT8 *Buf, - IN UINT16 OptType, - IN UINT16 OptLen, - IN UINT8 *Data + IN OUT EFI_DHCP6_PACKET *Packet, + IN OUT UINT8 **PacketCursor, + IN UINT16 OptType, + IN UINT16 OptLen, + IN UINT8 *Data ) { + UINT32 Length; + UINT32 BytesNeeded; + // // The format of Dhcp6 option: // @@ -607,35 +616,95 @@ Dhcp6AppendOption ( // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // =20 - ASSERT (OptLen !=3D 0); + // + // Verify the arguments are valid + // + if (Packet =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } =20 - WriteUnaligned16 ((UINT16 *)Buf, OptType); - Buf +=3D 2; - WriteUnaligned16 ((UINT16 *)Buf, OptLen); - Buf +=3D 2; - CopyMem (Buf, Data, NTOHS (OptLen)); - Buf +=3D NTOHS (OptLen); + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } =20 - return Buf; + if (Data =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (OptLen =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Verify the PacketCursor is within the packet + // + if ( (*PacketCursor < Packet->Dhcp6.Option) + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER)))) + { + return EFI_INVALID_PARAMETER; + } + + // + // Calculate the bytes needed for the option + // + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen); + + // + // Space remaining in the packet + // + Length =3D Packet->Size - Packet->Length; + if (Length < BytesNeeded) { + return EFI_BUFFER_TOO_SMALL; + } + + // + // Verify the PacketCursor is within the packet + // + if ( (*PacketCursor < Packet->Dhcp6.Option) + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER)))) + { + return EFI_INVALID_PARAMETER; + } + + WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE; + WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN; + CopyMem (*PacketCursor, Data, NTOHS (OptLen)); + *PacketCursor +=3D NTOHS (OptLen); + + // Update the packet length by the length of the option + 4 bytes + Packet->Length +=3D BytesNeeded; + + return EFI_SUCCESS; } =20 /** Append the appointed IA Address option to Buf, and move Buf to the end. =20 - @param[in, out] Buf The pointer to the position to append. + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length + will be updated. + @param[in, out] PacketCursor The pointer in the packet, on success Pack= etCursor + will be moved to the end of the option. @param[in] IaAddr The pointer to the IA Address. @param[in] MessageType Message type of DHCP6 package. =20 - @return Buf The position to append the next option. + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. =20 **/ -UINT8 * +EFI_STATUS Dhcp6AppendIaAddrOption ( - IN OUT UINT8 *Buf, + IN OUT EFI_DHCP6_PACKET *Packet, + IN OUT UINT8 **PacketCursor, IN EFI_DHCP6_IA_ADDRESS *IaAddr, IN UINT32 MessageType ) { + UINT32 BytesNeeded; + UINT32 Length; + // The format of the IA Address option is: // // 0 1 2 3 @@ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption ( // . . // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ =20 + // + // Verify the arguments are valid + // + if (Packet =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (IaAddr =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Verify the PacketCursor is within the packet + // + if ( (*PacketCursor < Packet->Dhcp6.Option) + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER)))) + { + return EFI_INVALID_PARAMETER; + } + + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; + BytesNeeded +=3D sizeof (EFI_IPv6_ADDRESS); + // + // Even if the preferred-lifetime is 0, it still needs to store it. + // + BytesNeeded +=3D sizeof (IaAddr->PreferredLifetime); + // + // Even if the valid-lifetime is 0, it still needs to store it. + // + BytesNeeded +=3D sizeof (IaAddr->ValidLifetime); + + // + // Space remaining in the packet + // + Length =3D Packet->Size - Packet->Length; + if (Length < BytesNeeded) { + return EFI_BUFFER_TOO_SMALL; + } + // // Fill the value of Ia Address option type // - WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr)); - Buf +=3D 2; + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr)); + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE; =20 - WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); - Buf +=3D 2; + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_A= DDRESS))); + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN; =20 - CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); - Buf +=3D sizeof (EFI_IPv6_ADDRESS); + CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); + *PacketCursor +=3D sizeof (EFI_IPv6_ADDRESS); =20 // // Fill the value of preferred-lifetime and valid-lifetime. @@ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption ( // should set to 0 when initiate a Confirm message. // if (MessageType !=3D Dhcp6MsgConfirm) { - WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime)); + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLif= etime)); } =20 - Buf +=3D 4; + *PacketCursor +=3D sizeof (IaAddr->PreferredLifetime); =20 if (MessageType !=3D Dhcp6MsgConfirm) { - WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime)); + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetim= e)); } =20 - Buf +=3D 4; + *PacketCursor +=3D sizeof (IaAddr->ValidLifetime); =20 - return Buf; + // + // Update the packet length + // + Packet->Length +=3D BytesNeeded; + + return EFI_SUCCESS; } =20 /** Append the appointed Ia option to Buf, and move Buf to the end. =20 - @param[in, out] Buf The pointer to the position to append. + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length + will be updated. + @param[in, out] PacketCursor The pointer in the packet, on success Pack= etCursor + will be moved to the end of the option. @param[in] Ia The pointer to the Ia. @param[in] T1 The time of T1. @param[in] T2 The time of T2. @param[in] MessageType Message type of DHCP6 package. =20 - @return Buf The position to append the next Ia option. + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. =20 **/ -UINT8 * +EFI_STATUS Dhcp6AppendIaOption ( - IN OUT UINT8 *Buf, - IN EFI_DHCP6_IA *Ia, - IN UINT32 T1, - IN UINT32 T2, - IN UINT32 MessageType + IN OUT EFI_DHCP6_PACKET *Packet, + IN OUT UINT8 **PacketCursor, + IN EFI_DHCP6_IA *Ia, + IN UINT32 T1, + IN UINT32 T2, + IN UINT32 MessageType ) { - UINT8 *AddrOpt; - UINT16 *Len; - UINTN Index; + UINT8 *AddrOpt; + UINT16 *Len; + UINTN Index; + UINT32 BytesNeeded; + UINT32 Length; + EFI_STATUS Status; =20 // // The format of IA_NA and IA_TA option: @@ -733,32 +859,74 @@ Dhcp6AppendIaOption ( // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // =20 + // + // Verify the arguments are valid + // + if (Packet =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (Ia =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Verify the PacketCursor is within the packet + // + if ( (*PacketCursor < Packet->Dhcp6.Option) + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER)))) + { + return EFI_INVALID_PARAMETER; + } + + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; + BytesNeeded +=3D sizeof (Ia->Descriptor.IaId); + // + // + N for the IA_NA-options/IA_TA-options + // Dhcp6AppendIaAddrOption will need to check the length for each address + // + if (Ia->Descriptor.Type =3D=3D Dhcp6OptIana) { + BytesNeeded +=3D sizeof (T1) + sizeof (T2); + } + + // + // Space remaining in the packet + // + Length =3D (UINT16)(Packet->Size - Packet->Length); + if (Length < BytesNeeded) { + return EFI_BUFFER_TOO_SMALL; + } + // // Fill the value of Ia option type // - WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type)); - Buf +=3D 2; + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type)); + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE; =20 // // Fill the len of Ia option later, keep the pointer first // - Len =3D (UINT16 *)Buf; - Buf +=3D 2; + Len =3D (UINT16 *)*PacketCursor; + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN; =20 // // Fill the value of iaid // - WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId)); - Buf +=3D 4; + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId)); + *PacketCursor +=3D sizeof (Ia->Descriptor.IaId); =20 // // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specifi= ed. // if (Ia->Descriptor.Type =3D=3D Dhcp6OptIana) { - WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 !=3D 0) ? T1 : 0xffffffff)= ); - Buf +=3D 4; - WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 !=3D 0) ? T2 : 0xffffffff)= ); - Buf +=3D 4; + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 !=3D 0) ? T1 : 0= xffffffff)); + *PacketCursor +=3D sizeof (T1); + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 !=3D 0) ? T2 : 0= xffffffff)); + *PacketCursor +=3D sizeof (T2); } =20 // @@ -766,35 +934,51 @@ Dhcp6AppendIaOption ( // for (Index =3D 0; Index < Ia->IaAddressCount; Index++) { AddrOpt =3D (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDR= ESS); - Buf =3D Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)Addr= Opt, MessageType); + Status =3D Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_= IA_ADDRESS *)AddrOpt, MessageType); + if (EFI_ERROR (Status)) { + return Status; + } } =20 // // Fill the value of Ia option length // - *Len =3D HTONS ((UINT16)(Buf - (UINT8 *)Len - 2)); + *Len =3D HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); =20 - return Buf; + // + // Update the packet length + // + Packet->Length +=3D BytesNeeded; + + return EFI_SUCCESS; } =20 /** Append the appointed Elapsed time option to Buf, and move Buf to the end. =20 - @param[in, out] Buf The pointer to the position to append. + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length + @param[in, out] PacketCursor The pointer in the packet, on success Pack= etCursor + will be moved to the end of the option. @param[in] Instance The pointer to the Dhcp6 instance. @param[out] Elapsed The pointer to the elapsed time value in - the generated packet. + the generated packet. =20 - @return Buf The position to append the next Ia option. + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion. + @retval EFI_SUCCESS The option is appended successfully. =20 **/ -UINT8 * +EFI_STATUS Dhcp6AppendETOption ( - IN OUT UINT8 *Buf, - IN DHCP6_INSTANCE *Instance, - OUT UINT16 **Elapsed + IN OUT EFI_DHCP6_PACKET *Packet, + IN OUT UINT8 **PacketCursor, + IN DHCP6_INSTANCE *Instance, + OUT UINT16 **Elapsed ) { + UINT32 BytesNeeded; + UINT32 Length; + // // The format of elapsed time option: // @@ -806,27 +990,70 @@ Dhcp6AppendETOption ( // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // =20 + // + // Verify the arguments are valid + // + if (Packet =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (Instance =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((Elapsed =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Verify the PacketCursor is within the packet + // + if ( (*PacketCursor < Packet->Dhcp6.Option) + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER)))) + { + return EFI_INVALID_PARAMETER; + } + + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; + // + // + 2 for elapsed-time + // + BytesNeeded +=3D sizeof (UINT16); + // + // Space remaining in the packet + // + Length =3D Packet->Size - Packet->Length; + if (Length < BytesNeeded) { + return EFI_BUFFER_TOO_SMALL; + } + // // Fill the value of elapsed-time option type. // - WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime)); - Buf +=3D 2; + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime)); + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE; =20 // // Fill the len of elapsed-time option, which is fixed. // - WriteUnaligned16 ((UINT16 *)Buf, HTONS (2)); - Buf +=3D 2; + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2)); + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN; =20 // // Fill in elapsed time value with 0 value for now. The actual value is // filled in later just before the packet is transmitted. // - WriteUnaligned16 ((UINT16 *)Buf, HTONS (0)); - *Elapsed =3D (UINT16 *)Buf; - Buf +=3D 2; + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0)); + *Elapsed =3D (UINT16 *)*PacketCursor; + *PacketCursor +=3D sizeof (UINT16); =20 - return Buf; + Packet->Length +=3D BytesNeeded; + + return EFI_SUCCESS; } =20 /** --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114463): https://edk2.groups.io/g/devel/message/114463 Mute This Topic: https://groups.io/mt/103964976/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114464+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114464+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223991; cv=none; d=zohomail.com; s=zohoarc; b=Qy1tMuIhYg0ey4c1UbV6Tmk6yx47jMOAJJ32OYBrjaPrmtt46mXC3KU/LM+peEb4rbOeDlvZWrmWI2ADG9BtA1v1ejdO5yk95qXBDPjFNrc0DkibFw+poSSWQKPidvIP6+RwCZTMYkihd6Zv6wKnSHDPUVJn4VEcHaof4hdMFVA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223991; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=e7U4vVkLcLypyE9Zi+rdxjDzaCwUAQtKJ465og8xBeA=; b=MQWfwqCavoS4eLqxy4eSkqlg4U5p7lv3Edulw8cx6KBbJi79H/5XipSl9yVRex033/D3MGkxrdYQpQKKKd2AIykKAfyZM5OTcjKJ+g3WqocAzI1pF8o4M61XBwvF61SCvT3XMA/JlzaeAO3t0eT8hev8BTcl9DloQHAAKTaOiGk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114464+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223991336865.9871221828081; Thu, 25 Jan 2024 15:06:31 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=geh3OBY5QeA+ju4sUvvfHEIDjwV/Z0OBlDZfVKYUP9U=; 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=1706223991; v=1; b=ppnwy7xNzm6QEROUGXIfGY5nO3O66wNJjbuzKSHoZ1iWcLz1LzM8J4Fw6hbiLWqliMc47xrh F347AuACz3ANnAlwOT4AoHJlB+94mYmLh0oujQRaPV+tuq1vmwQRnvGc+m92c0I7GUv6X53OX9/ EibL/6QYzcPfnwSaMjaM/FUw= X-Received: by 127.0.0.2 with SMTP id A2dHYY1788612xKUxbRvXbcP; Thu, 25 Jan 2024 15:06:31 -0800 X-Received: from mail-pg1-f182.google.com (mail-pg1-f182.google.com [209.85.215.182]) by mx.groups.io with SMTP id smtpd.web11.776.1706223989993277994 for ; Thu, 25 Jan 2024 15:06:30 -0800 X-Received: by mail-pg1-f182.google.com with SMTP id 41be03b00d2f7-5cedfc32250so4264850a12.0 for ; Thu, 25 Jan 2024 15:06:29 -0800 (PST) X-Gm-Message-State: lvsJm7y2Kh0EAdSbPnLREkFBx1787277AA= X-Google-Smtp-Source: AGHT+IFdaotrjI+QR+uCXR5Fm+4wYt4h8kT+yh9mMtReWcjsZrg3+RoxuWME5a9SRPVQ8YMhWqP1vw== X-Received: by 2002:a05:6a21:32a4:b0:19a:1656:bc5f with SMTP id yt36-20020a056a2132a400b0019a1656bc5fmr464978pzb.2.1706223989037; Thu, 25 Jan 2024 15:06:29 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:28 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Saloni Kasbekar , Zachary Clark-williams Subject: [edk2-devel] [PATCH v2 02/15] NetworkPkg: : Add Unit tests to CI and create Host Test DSC Date: Thu, 25 Jan 2024 13:54:44 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223991829100005 Content-Type: text/plain; charset="utf-8" Adds Host Based testing to the NetworkPkg Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Test/NetworkPkgHostTest.dsc | 98 ++++++++++++++++++++++++++ NetworkPkg/NetworkPkg.ci.yaml | 7 +- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 NetworkPkg/Test/NetworkPkgHostTest.dsc diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/Netwo= rkPkgHostTest.dsc new file mode 100644 index 000000000000..1aeca5c5b353 --- /dev/null +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -0,0 +1,98 @@ +## @file +# NetworkPkgHostTest DSC file used to build host-based unit tests. +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] + PLATFORM_NAME =3D NetworkPkgHostTest + PLATFORM_GUID =3D 3b68324e-fc07-4d49-9520-9347ede65879 + PLATFORM_VERSION =3D 0.1 + DSC_SPECIFICATION =3D 0x00010005 + OUTPUT_DIRECTORY =3D Build/NetworkPkg/HostTest + SUPPORTED_ARCHITECTURES =3D IA32|X64|AARCH64 + BUILD_TARGETS =3D NOOPT + SKUID_IDENTIFIER =3D DEFAULT + +!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[Components] + # + # Build HOST_APPLICATION that tests NetworkPkg + # + +# Despite these library classes being listed in [LibraryClasses] below, th= ey are not needed for the host-based unit tests. +[LibraryClasses] + NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll= ocationLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry= Point.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiA= pplicationEntryPoint.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo= tServicesTableLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/U= efiRuntimeServicesTableLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServic= esLib.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManag= erLib.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibN= ull.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeC= offGetEntryPointLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableL= ib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf +!ifdef CONTINUOUS_INTEGRATION + BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf + TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf +!else + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf +!endif + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseD= ebugPrintErrorLevelLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + +!if $(TOOL_CHAIN_TAG) =3D=3D VS2019 or $(TOOL_CHAIN_TAG) =3D=3D VS2022 +[LibraryClasses.X64] + # Provide StackCookie support lib so that we can link to /GS exports for= VS builds + RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf +!endif + +[LibraryClasses.common.UEFI_DRIVER] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeRepor= tStatusCodeLib.inf + DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf +[LibraryClasses.common.UEFI_APPLICATION] + DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf +[LibraryClasses.ARM, LibraryClasses.AARCH64] + # + # It is not possible to prevent ARM compiler calls to generic intrinsic = functions. + # This library provides the instrinsic functions generated by a given co= mpiler. + # [LibraryClasses.ARM] and NULL mean link this library into all ARM imag= es. + # +!if $(TOOL_CHAIN_TAG) !=3D VS2017 and $(TOOL_CHAIN_TAG) !=3D VS2015 and $(= TOOL_CHAIN_TAG) !=3D VS2019 + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf +!endif + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf +[LibraryClasses.ARM] + RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf +[LibraryClasses.RISCV64] + RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf + +[PcdsFixedAtBuild] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2 + gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|0x4 diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml index 07dc7abd6938..076424eb6065 100644 --- a/NetworkPkg/NetworkPkg.ci.yaml +++ b/NetworkPkg/NetworkPkg.ci.yaml @@ -24,6 +24,9 @@ "CompilerPlugin": { "DscPath": "NetworkPkg.dsc" }, + "HostUnitTestCompilerPlugin": { + "DscPath": "Test/NetworkPkgHostTest.dsc" + }, "CharEncodingCheck": { "IgnoreFiles": [] }, @@ -35,7 +38,9 @@ "CryptoPkg/CryptoPkg.dec" ], # For host based unit tests - "AcceptableDependencies-HOST_APPLICATION":[], + "AcceptableDependencies-HOST_APPLICATION":[ + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + ], # For UEFI shell based apps "AcceptableDependencies-UEFI_APPLICATION":[ "ShellPkg/ShellPkg.dec" --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114464): https://edk2.groups.io/g/devel/message/114464 Mute This Topic: https://groups.io/mt/103964977/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114465+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114465+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223991; cv=none; d=zohomail.com; s=zohoarc; b=BJyPSNRz0uX8WyQOVcV78Uf7gXV6LTXOJWLhsz1jGl6oGcPiwaULp4qE+vlZND6Ap9ORWWz/sYdgMzotxjB+qt0/IZEa4NpKJH1KjpKCjTKBsn6hayvVZc+FwISsJfzSwW5CQSwCLrJxf1QcrQGyK0F2dCqAbV0zMW2Z5LWAhwo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223991; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=59+Ua61SDyVepShHRdR2s8u3s96uD4lc1f5L12rYkB8=; b=S4NURYq7KiqE+NX7RMpxm22DUvy7G+V7Jqz/g4Tvq87ev6XW7R13OMb6pTv1KETCyd7YJgvFbc9PevLNx/yuowGZgmGzlVGWmvkFjhxPmbEHDJ7KEaVIjfWKQYHThZRcbCmSqNN7k6GgEuWcDqrMr1+d8tjkOb9Y2vu3rgU7xfo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114465+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223991838350.1349927386343; Thu, 25 Jan 2024 15:06:31 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=UTzw4fj59mSOH3q/MfhoGdjNyd7e9t3kNg4ndGgMTTs=; 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=1706223991; v=1; b=crBcX4wHWWcXWOIxOGsbmtmROlKEvqaGT/yMDGc7LCbLI74YjnSoBryy9js4nig5OtjVNZer 5VkCdgWPgQ5bxJFAU79nLfH8cp20oA13TtNIPm1R7KHgeOpV/NjyPuqbiMW6HdjH6KE+PFzAkY4 OjzS+px+hCkFcNJwz5TB1jIk= X-Received: by 127.0.0.2 with SMTP id nmFxYY1788612xI2KsvIVaRT; Thu, 25 Jan 2024 15:06:31 -0800 X-Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) by mx.groups.io with SMTP id smtpd.web11.777.1706223990862575729 for ; Thu, 25 Jan 2024 15:06:30 -0800 X-Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-1d71e184695so32016955ad.3 for ; Thu, 25 Jan 2024 15:06:30 -0800 (PST) X-Gm-Message-State: wITzK0WEzmnL2yJ9Wejpja6Px1787277AA= X-Google-Smtp-Source: AGHT+IFhRM/LZFZw900yjaKK4HkAHklc2eIiXtMveBC3FjgBxmqZOe3qRed6j9Pu34zFb37IBkdv8w== X-Received: by 2002:a17:902:efc2:b0:1d7:2b80:ad84 with SMTP id ja2-20020a170902efc200b001d72b80ad84mr535910plb.50.1706223989858; Thu, 25 Jan 2024 15:06:29 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:29 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Saloni Kasbekar , Zachary Clark-williams Subject: [edk2-devel] [PATCH v2 03/15] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests Date: Thu, 25 Jan 2024 13:54:45 -0800 Message-ID: <4c33819343179a2cbdde07be55ac125c59f41f26.1706219324.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223993893100015 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4535 Confirms that reported issue... "Buffer overflow in the DHCPv6 client via a long Server ID option" ..has been corrected by the provided patch. Tests the following functions to ensure they appropriately handle untrusted data (either too long or too small) to prevent a buffer overflow: Dhcp6AppendOption Dhcp6AppendETOption Dhcp6AppendIaOption Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + .../GoogleTest/Dhcp6DxeGoogleTest.inf | 43 ++ .../GoogleTest/Dhcp6DxeGoogleTest.cpp | 20 + .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 478 ++++++++++++++++++ 4 files changed, 542 insertions(+) create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/Netwo= rkPkgHostTest.dsc index 1aeca5c5b353..20bc90b1728d 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -24,6 +24,7 @@ [Components] # # Build HOST_APPLICATION that tests NetworkPkg # + NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf =20 # Despite these library classes being listed in [LibraryClasses] below, th= ey are not needed for the host-based unit tests. [LibraryClasses] diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/Networ= kPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf new file mode 100644 index 000000000000..8e9119a37158 --- /dev/null +++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf @@ -0,0 +1,43 @@ +## @file +# Unit test suite for the Dhcp6Dxe using Google Test +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D Dhcp6DxeGoogleTest + FILE_GUID =3D 1D2A4C65-38C8-4C2F-BB60-B5FA49625AA9 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D HOST_APPLICATION +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64 +# +[Sources] + Dhcp6DxeGoogleTest.cpp + Dhcp6IoGoogleTest.cpp + ../Dhcp6Io.c + ../Dhcp6Utility.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + NetworkPkg/NetworkPkg.dec + +[LibraryClasses] + GoogleTestLib + DebugLib + NetLib + PcdLib + +[Protocols] + gEfiDhcp6ServiceBindingProtocolGuid + +[Pcd] + gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType + +[Guids] + gZeroGuid diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp b/Networ= kPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp new file mode 100644 index 000000000000..9aeced2f9156 --- /dev/null +++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp @@ -0,0 +1,20 @@ +/** @file + Acts as the main entry point for the tests for the Dhcp6Dxe module. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include + +//////////////////////////////////////////////////////////////////////////= ////// +// Run the tests +//////////////////////////////////////////////////////////////////////////= ////// +int +main ( + int argc, + char *argv[] + ) +{ + testing::InitGoogleTest (&argc, argv); + return RUN_ALL_TESTS (); +} diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/Network= Pkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp new file mode 100644 index 000000000000..7ee40e4af480 --- /dev/null +++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp @@ -0,0 +1,478 @@ +/** @file + Tests for Dhcp6Io.c. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include + +extern "C" { + #include + #include + #include + #include + #include "../Dhcp6Impl.h" + #include "../Dhcp6Utility.h" +} + +//////////////////////////////////////////////////////////////////////// +// Defines +//////////////////////////////////////////////////////////////////////// + +#define DHCP6_PACKET_MAX_LEN 1500 + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +// Symbol Definitions +// These functions are not directly under test - but required to compile +//////////////////////////////////////////////////////////////////////// + +// This definition is used by this test but is also required to compile +// by Dhcp6Io.c +EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress =3D { + { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 } +}; + +EFI_STATUS +EFIAPI +UdpIoSendDatagram ( + IN UDP_IO *UdpIo, + IN NET_BUF *Packet, + IN UDP_END_POINT *EndPoint OPTIONAL, + IN EFI_IP_ADDRESS *Gateway OPTIONAL, + IN UDP_IO_CALLBACK CallBack, + IN VOID *Context + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +UdpIoRecvDatagram ( + IN UDP_IO *UdpIo, + IN UDP_IO_CALLBACK CallBack, + IN VOID *Context, + IN UINT32 HeadLen + ) +{ + return EFI_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////// +// Dhcp6AppendOptionTest Tests +//////////////////////////////////////////////////////////////////////// + +class Dhcp6AppendOptionTest : public ::testing::Test { +public: + UINT8 *Buffer =3D NULL; + EFI_DHCP6_PACKET *Packet; + +protected: + // Add any setup code if needed + virtual void + SetUp ( + ) + { + // Initialize any resources or variables + Buffer =3D (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); + ASSERT_NE (Buffer, (UINT8 *)NULL); + + Packet =3D (EFI_DHCP6_PACKET *)Buffer; + Packet->Size =3D DHCP6_PACKET_MAX_LEN; + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + // Clean up any resources or variables + if (Buffer !=3D NULL) { + FreePool (Buffer); + } + } +}; + +// Test Description: +// Attempt to append an option to a packet that is too small by a duid tha= t is too large +TEST_F (Dhcp6AppendOptionTest, InvalidDataExpectBufferTooSmall) { + UINT8 *Cursor; + EFI_DHCP6_DUID *UntrustedDuid; + EFI_STATUS Status; + + UntrustedDuid =3D (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_= DUID)); + ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL); + + UntrustedDuid->Length =3D NTOHS (0xFFFF); + + Cursor =3D Dhcp6AppendOptionTest::Packet->Dhcp6.Option; + + Status =3D Dhcp6AppendOption ( + Dhcp6AppendOptionTest::Packet, + &Cursor, + HTONS (Dhcp6OptServerId), + UntrustedDuid->Length, + UntrustedDuid->Duid + ); + + ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); +} + +// Test Description: +// Attempt to append an option to a packet that is large enough +TEST_F (Dhcp6AppendOptionTest, ValidDataExpectSuccess) { + UINT8 *Cursor; + EFI_DHCP6_DUID *UntrustedDuid; + EFI_STATUS Status; + UINTN OriginalLength; + + UINT8 Duid[6] =3D { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); + OriginalLength =3D Packet->Length; + + UntrustedDuid =3D (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_= DUID)); + ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL); + + UntrustedDuid->Length =3D NTOHS (sizeof (Duid)); + CopyMem (UntrustedDuid->Duid, Duid, sizeof (Duid)); + + Cursor =3D Dhcp6AppendOptionTest::Packet->Dhcp6.Option; + + Status =3D Dhcp6AppendOption ( + Dhcp6AppendOptionTest::Packet, + &Cursor, + HTONS (Dhcp6OptServerId), + UntrustedDuid->Length, + UntrustedDuid->Duid + ); + + ASSERT_EQ (Status, EFI_SUCCESS); + + // verify that the pointer to cursor moved by the expected amount + ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendOptionTest::Packet->Dhcp6.Option = + sizeof (Duid) + 4); + + // verify that the length of the packet is now the expected amount + ASSERT_EQ (Dhcp6AppendOptionTest::Packet->Length, OriginalLength + sizeo= f (Duid) + 4); +} + +//////////////////////////////////////////////////////////////////////// +// Dhcp6AppendETOption Tests +//////////////////////////////////////////////////////////////////////// + +class Dhcp6AppendETOptionTest : public ::testing::Test { +public: + UINT8 *Buffer =3D NULL; + EFI_DHCP6_PACKET *Packet; + +protected: + // Add any setup code if needed + virtual void + SetUp ( + ) + { + // Initialize any resources or variables + Buffer =3D (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); + ASSERT_NE (Buffer, (UINT8 *)NULL); + + Packet =3D (EFI_DHCP6_PACKET *)Buffer; + Packet->Size =3D DHCP6_PACKET_MAX_LEN; + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + // Clean up any resources or variables + if (Buffer !=3D NULL) { + FreePool (Buffer); + } + } +}; + +// Test Description: +// Attempt to append an option to a packet that is too small by a duid tha= t is too large +TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) { + UINT8 *Cursor; + EFI_STATUS Status; + DHCP6_INSTANCE Instance; + UINT16 ElapsedTimeVal; + UINT16 *ElapsedTime; + + Cursor =3D Dhcp6AppendETOptionTest::Packet->Dhcp6.Option; + ElapsedTime =3D &ElapsedTimeVal; + + Packet->Length =3D Packet->Size - 2; + + Status =3D Dhcp6AppendETOption ( + Dhcp6AppendETOptionTest::Packet, + &Cursor, + &Instance, // Instance is not used in this function + &ElapsedTime + ); + + // verify that we error out because the packet is too small for the opti= on header + ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); + + // reset the length + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); +} + +// Test Description: +// Attempt to append an option to a packet that is large enough +TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) { + UINT8 *Cursor; + EFI_STATUS Status; + DHCP6_INSTANCE Instance; + UINT16 ElapsedTimeVal; + UINT16 *ElapsedTime; + UINTN ExpectedSize; + UINTN OriginalLength; + + Cursor =3D Dhcp6AppendETOptionTest::Packet->Dhcp6.Option; + ElapsedTime =3D &ElapsedTimeVal; + ExpectedSize =3D 6; + OriginalLength =3D Packet->Length; + + Status =3D Dhcp6AppendETOption ( + Dhcp6AppendETOptionTest::Packet, + &Cursor, + &Instance, // Instance is not used in this function + &ElapsedTime + ); + + // verify that the status is EFI_SUCCESS + ASSERT_EQ (Status, EFI_SUCCESS); + + // verify that the pointer to cursor moved by the expected amount + ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendETOptionTest::Packet->Dhcp6.Optio= n + ExpectedSize); + + // verify that the length of the packet is now the expected amount + ASSERT_EQ (Dhcp6AppendETOptionTest::Packet->Length, OriginalLength + Exp= ectedSize); +} + +//////////////////////////////////////////////////////////////////////// +// Dhcp6AppendIaOption Tests +//////////////////////////////////////////////////////////////////////// + +class Dhcp6AppendIaOptionTest : public ::testing::Test { +public: + UINT8 *Buffer =3D NULL; + EFI_DHCP6_PACKET *Packet; + EFI_DHCP6_IA *Ia; + +protected: + // Add any setup code if needed + virtual void + SetUp ( + ) + { + // Initialize any resources or variables + Buffer =3D (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN); + ASSERT_NE (Buffer, (UINT8 *)NULL); + + Packet =3D (EFI_DHCP6_PACKET *)Buffer; + Packet->Size =3D DHCP6_PACKET_MAX_LEN; + + Ia =3D (EFI_DHCP6_IA *)AllocateZeroPool (sizeof (EFI_DHCP6_IA) + sizeo= f (EFI_DHCP6_IA_ADDRESS) * 2); + ASSERT_NE (Ia, (EFI_DHCP6_IA *)NULL); + + CopyMem (Ia->IaAddress, mAllDhcpRelayAndServersAddress.Addr, sizeof (E= FI_IPv6_ADDRESS)); + CopyMem (Ia->IaAddress + 1, mAllDhcpRelayAndServersAddress.Addr, sizeo= f (EFI_IPv6_ADDRESS)); + + Ia->IaAddressCount =3D 2; + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + // Clean up any resources or variables + if (Buffer !=3D NULL) { + FreePool (Buffer); + } + + if (Ia !=3D NULL) { + FreePool (Ia); + } + } +}; + +// Test Description: +// Attempt to append an option to a packet that doesn't have enough space +// for the option header +TEST_F (Dhcp6AppendIaOptionTest, IaNaInvalidDataExpectBufferTooSmall) { + UINT8 *Cursor; + EFI_STATUS Status; + + Packet->Length =3D Packet->Size - 2; + + Ia->Descriptor.Type =3D Dhcp6OptIana; + Ia->Descriptor.IaId =3D 0x12345678; + + Cursor =3D Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; + + Status =3D Dhcp6AppendIaOption ( + Dhcp6AppendIaOptionTest::Packet, + &Cursor, + Ia, + 0x12345678, + 0x11111111, + Dhcp6OptIana + ); + + // verify that we error out because the packet is too small for the opti= on header + ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); + + // reset the length + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); +} + +// Test Description: +// Attempt to append an option to a packet that doesn't have enough space +// for the option header +TEST_F (Dhcp6AppendIaOptionTest, IaTaInvalidDataExpectBufferTooSmall) { + UINT8 *Cursor; + EFI_STATUS Status; + + // Use up nearly all the space in the packet + Packet->Length =3D Packet->Size - 2; + + Ia->Descriptor.Type =3D Dhcp6OptIata; + Ia->Descriptor.IaId =3D 0x12345678; + + Cursor =3D Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; + + Status =3D Dhcp6AppendIaOption ( + Dhcp6AppendIaOptionTest::Packet, + &Cursor, + Ia, + 0, + 0, + Dhcp6OptIata + ); + + // verify that we error out because the packet is too small for the opti= on header + ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL); + + // reset the length + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); +} + +TEST_F (Dhcp6AppendIaOptionTest, IaNaValidDataExpectSuccess) { + UINT8 *Cursor; + EFI_STATUS Status; + UINTN ExpectedSize; + UINTN OriginalLength; + + // + // 2 bytes for the option header type + // + ExpectedSize =3D 2; + // + // 2 bytes for the option header length + // + ExpectedSize +=3D 2; + // + // 4 bytes for the IAID + // + ExpectedSize +=3D 4; + // + // + 4 bytes for the T1 + // + ExpectedSize +=3D 4; + // + // + 4 bytes for the T2 + // + ExpectedSize +=3D 4; + // + // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; + // + 2 bytes for the option header type + // + 2 bytes for the option header length + // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address + // + ExpectedSize +=3D (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; + + Cursor =3D Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; + + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); + OriginalLength =3D Packet->Length; + + Ia->Descriptor.Type =3D Dhcp6OptIana; + Ia->Descriptor.IaId =3D 0x12345678; + + Status =3D Dhcp6AppendIaOption ( + Dhcp6AppendIaOptionTest::Packet, + &Cursor, + Ia, + 0x12345678, + 0x12345678, + Dhcp6OptIana + ); + + // verify that the pointer to cursor moved by the expected amount + ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Optio= n + ExpectedSize); + + // verify that the length of the packet is now the expected amount + ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + Exp= ectedSize); + + // verify that the status is EFI_SUCCESS + ASSERT_EQ (Status, EFI_SUCCESS); +} + +TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) { + UINT8 *Cursor; + EFI_STATUS Status; + UINTN ExpectedSize; + UINTN OriginalLength; + + // + // 2 bytes for the option header type + // + ExpectedSize =3D 2; + // + // 2 bytes for the option header length + // + ExpectedSize +=3D 2; + // + // 4 bytes for the IAID + // + ExpectedSize +=3D 4; + // + // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; + // + 2 bytes for the option header type + // + 2 bytes for the option header length + // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address + // + ExpectedSize +=3D (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2; + + Cursor =3D Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option; + + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); + OriginalLength =3D Packet->Length; + + Ia->Descriptor.Type =3D Dhcp6OptIata; + Ia->Descriptor.IaId =3D 0x12345678; + + Status =3D Dhcp6AppendIaOption ( + Dhcp6AppendIaOptionTest::Packet, + &Cursor, + Ia, + 0, + 0, + Dhcp6OptIata + ); + + // verify that the pointer to cursor moved by the expected amount + ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Optio= n + ExpectedSize); + + // verify that the length of the packet is now the expected amount + ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + Exp= ectedSize); + + // verify that the status is EFI_SUCCESS + ASSERT_EQ (Status, EFI_SUCCESS); +} --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114465): https://edk2.groups.io/g/devel/message/114465 Mute This Topic: https://groups.io/mt/103964978/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114466+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114466+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223992; cv=none; d=zohomail.com; s=zohoarc; b=SaQJnV7HZkSL+8otydlt8GCg/MthloN6jzevWcFQoZnY2cHHyq8xm21BQtBiHwL3NOiJO5TEIgz6Znexo1B0G/lk4vgYz1MuqzV5pif0xnfImEvy4zybdxikOVlFSfPZ9E2e6uhgL/F/8wmHo94U3iXgRrkbZ54rzGyfQTpHiDk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223992; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=PXeungwXTEghSFDMSv1InKTQSfmF0afLFAtAlf9buiA=; b=heccF1hDe6OUQQpw9T5j0FDRxGCZomfwqD5PYqEBR/2/QUn6Rw3e9WKPDUH5OF2Krk5dMgLl9wxNeqYPh2lIDvJBywjAxl/xotbvCdISJKA5PnGwV+Oemgs/CYK2bA8migofFtH2QyprVq/P4C+g/Er2plIRvr/dXMzuslsGStc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114466+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223992546390.73983632166176; Thu, 25 Jan 2024 15:06:32 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=SrENJ1JKCdl2K2YBSdzLNtSHvIMItYP4mE3hIM2cuc8=; 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=1706223992; v=1; b=IFETwOjFOUfMLgSogYsYsG+YjlM7i3O4Pa/kq3BAD9J6wcyVNeWZzXQtHA/uhrHJb5z0vpTS kFXtvwCCiaYMaXwzkjrAcYNo2m0Q90rM6QS/Zqw6fn5oYwb38YDbPZ0Pgzq2nJqaDB7EyWwavw8 MdzRakPov4dCFMWVRywW7zb8= X-Received: by 127.0.0.2 with SMTP id G1K1YY1788612x1p4qUt0ZoY; Thu, 25 Jan 2024 15:06:32 -0800 X-Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) by mx.groups.io with SMTP id smtpd.web11.778.1706223991717087101 for ; Thu, 25 Jan 2024 15:06:31 -0800 X-Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-1d7881b1843so18028985ad.3 for ; Thu, 25 Jan 2024 15:06:31 -0800 (PST) X-Gm-Message-State: gaKlc3kelUMAjXsN8xh7ytTYx1787277AA= X-Google-Smtp-Source: AGHT+IGF7X1x2TCPTw5pRef1d2Y0s7uTXkRvq63uWPRti+s/61EmTGecPVfzXLJHDax+4Aw67oKwRw== X-Received: by 2002:a17:902:d2c9:b0:1d7:2cc1:a766 with SMTP id n9-20020a170902d2c900b001d72cc1a766mr505193plc.22.1706223990771; Thu, 25 Jan 2024 15:06:30 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:30 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Saloni Kasbekar , Zachary Clark-williams Subject: [edk2-devel] [PATCH v2 04/15] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch Date: Thu, 25 Jan 2024 13:54:46 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223993906100017 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4534 Bug Details: PixieFail Bug #1 CVE-2023-45229 CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N CWE-125 Out-of-bounds Read Change Overview: Introduce Dhcp6SeekInnerOptionSafe which performs checks before seeking the Inner Option from a DHCP6 Option. > > EFI_STATUS > Dhcp6SeekInnerOptionSafe ( > IN UINT16 IaType, > IN UINT8 *Option, > IN UINT32 OptionLen, > OUT UINT8 **IaInnerOpt, > OUT UINT16 *IaInnerLen > ); > Lots of code cleanup to improve code readability. Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 138 +++++++++++++++++++--- NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 203 +++++++++++++++++++++----------- 2 files changed, 256 insertions(+), 85 deletions(-) diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Imp= l.h index f2422c2f2827..220e7c68f11b 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h @@ -45,6 +45,20 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S') #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I') =20 +#define DHCP6_PACKET_ALL 0 +#define DHCP6_PACKET_STATEFUL 1 +#define DHCP6_PACKET_STATELESS 2 + +#define DHCP6_BASE_PACKET_SIZE 1024 + +#define DHCP6_PORT_CLIENT 546 +#define DHCP6_PORT_SERVER 547 + +#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) + +#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE= , Dhcp6, DHCP6_INSTANCE_SIGNATURE) +#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, = ServiceBinding, DHCP6_SERVICE_SIGNATURE) + // // For more information on DHCP options see RFC 8415, Section 21.1 // @@ -59,12 +73,10 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; // | (option-len octets) | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // -#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16)) -#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16)) +#define DHCP6_SIZE_OF_OPT_CODE (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->O= pCode)) +#define DHCP6_SIZE_OF_OPT_LEN (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->O= pLen)) =20 -// // Combined size of Code and Length -// #define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \ DHCP6_SIZE_OF_OPT_LEN) =20 @@ -73,34 +85,122 @@ STATIC_ASSERT ( "Combined size of Code and Length must be 4 per RFC 8415" ); =20 -// // Offset to the length is just past the code -// -#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE) +#define DHCP6_OFFSET_OF_OPT_LEN(a) (a + DHCP6_SIZE_OF_OPT_CODE) STATIC_ASSERT ( - DHCP6_OPT_LEN_OFFSET (0) =3D=3D 2, + DHCP6_OFFSET_OF_OPT_LEN (0) =3D=3D 2, "Offset of length is + 2 past start of option" ); =20 -#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) +#define DHCP6_OFFSET_OF_OPT_DATA(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_= LEN) STATIC_ASSERT ( - DHCP6_OPT_DATA_OFFSET (0) =3D=3D 4, + DHCP6_OFFSET_OF_OPT_DATA (0) =3D=3D 4, "Offset to option data should be +4 from start of option" ); +// +// Identity Association options (both NA (Non-Temporary) and TA (Temporary= Association)) +// are defined in RFC 8415 and are a deriviation of a TLV stucture +// For more information on IA_NA see Section 21.4 +// For more information on IA_TA see Section 21.5 +// +// +// The format of IA_NA and IA_TA option: +// +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | OPTION_IA_NA | option-len | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | IAID (4 octets) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | T1 (only for IA_NA) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | T2 (only for IA_NA) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// . IA_NA-options/IA_TA-options . +// . . +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +#define DHCP6_SIZE_OF_IAID (sizeof(UINT32)) +#define DHCP6_SIZE_OF_TIME_INTERVAL (sizeof(UINT32)) =20 -#define DHCP6_PACKET_ALL 0 -#define DHCP6_PACKET_STATEFUL 1 -#define DHCP6_PACKET_STATELESS 2 +// Combined size of IAID, T1, and T2 +#define DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 (DHCP6_SIZE_OF_IAID + \ + DHCP6_SIZE_OF_TIME_INTERVAL + \ + DHCP6_SIZE_OF_TIME_INTERVAL) +STATIC_ASSERT ( + DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 =3D=3D 12, + "Combined size of IAID, T1, T2 must be 12 per RFC 8415" + ); =20 -#define DHCP6_BASE_PACKET_SIZE 1024 +// This is the size of IA_TA without options +#define DHCP6_MIN_SIZE_OF_IA_TA (DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ + DHCP6_SIZE_OF_IAID) +STATIC_ASSERT ( + DHCP6_MIN_SIZE_OF_IA_TA =3D=3D 8, + "Minimum combined size of IA_TA per RFC 8415" + ); =20 -#define DHCP6_PORT_CLIENT 546 -#define DHCP6_PORT_SERVER 547 +// Offset to a IA_TA inner option +#define DHCP6_OFFSET_OF_IA_TA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_TA) +STATIC_ASSERT ( + DHCP6_OFFSET_OF_IA_TA_INNER_OPT (0) =3D=3D 8, + "Offset of IA_TA Inner option is + 8 past start of option" + ); =20 -#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20) +// This is the size of IA_NA without options (16) +#define DHCP6_MIN_SIZE_OF_IA_NA DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ + DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 +STATIC_ASSERT ( + DHCP6_MIN_SIZE_OF_IA_NA =3D=3D 16, + "Minimum combined size of IA_TA per RFC 8415" + ); =20 -#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE= , Dhcp6, DHCP6_INSTANCE_SIGNATURE) -#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, = ServiceBinding, DHCP6_SERVICE_SIGNATURE) +#define DHCP6_OFFSET_OF_IA_NA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_NA) +STATIC_ASSERT ( + DHCP6_OFFSET_OF_IA_NA_INNER_OPT (0) =3D=3D 16, + "Offset of IA_NA Inner option is + 16 past start of option" + ); + +#define DHCP6_OFFSET_OF_IA_NA_T1(a) (a + \ + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \ + DHCP6_SIZE_OF_IAID) +STATIC_ASSERT ( + DHCP6_OFFSET_OF_IA_NA_T1 (0) =3D=3D 8, + "Offset of IA_NA Inner option is + 8 past start of option" + ); + +#define DHCP6_OFFSET_OF_IA_NA_T2(a) (a + \ + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN +\ + DHCP6_SIZE_OF_IAID + \ + DHCP6_SIZE_OF_TIME_INTERVAL) +STATIC_ASSERT ( + DHCP6_OFFSET_OF_IA_NA_T2 (0) =3D=3D 12, + "Offset of IA_NA Inner option is + 12 past start of option" + ); + +// +// For more information see RFC 8415 Section 21.13 +// +// The format of the Status Code Option: +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | OPTION_STATUS_CODE | option-len | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | status-code | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +// . . +// . status-message . +// . . +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +#define DHCP6_OFFSET_OF_STATUS_CODE(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_A= ND_LEN) +STATIC_ASSERT ( + DHCP6_OFFSET_OF_STATUS_CODE (0) =3D=3D 4, + "Offset of status is + 4 past start of option" + ); =20 extern EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress; extern EFI_DHCP6_PROTOCOL gDhcp6ProtocolTemplate; diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c index bf5aa7a769de..89d16484a568 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c @@ -598,8 +598,8 @@ Dhcp6UpdateIaInfo ( // The inner options still start with 2 bytes option-code and 2 bytes op= tion-len. // if (Instance->Config->IaDescriptor.Type =3D=3D Dhcp6OptIana) { - T1 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 8))); - T2 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 12))); + T1 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Op= tion)))); + T2 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Op= tion)))); // // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T= 1 greater than T2, // and both T1 and T2 are greater than 0, the client discards the IA_N= A option and processes @@ -609,13 +609,14 @@ Dhcp6UpdateIaInfo ( return EFI_DEVICE_ERROR; } =20 - IaInnerOpt =3D Option + 16; - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2)= )) - 12); + IaInnerOpt =3D DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); + IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSE= T_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); } else { - T1 =3D 0; - T2 =3D 0; - IaInnerOpt =3D Option + 8; - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2)= )) - 4); + T1 =3D 0; + T2 =3D 0; + + IaInnerOpt =3D DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); + IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSE= T_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID); } =20 // @@ -641,7 +642,7 @@ Dhcp6UpdateIaInfo ( Option =3D Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); =20 if (Option !=3D NULL) { - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4))); + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN= (Option)))); if (StsCode !=3D Dhcp6StsSuccess) { return EFI_DEVICE_ERROR; } @@ -661,6 +662,87 @@ Dhcp6UpdateIaInfo ( return Status; } =20 +/** + Seeks the Inner Options from a DHCP6 Option + + @param[in] IaType The type of the IA option. + @param[in] Option The pointer to the DHCP6 Option. + @param[in] OptionLen The length of the DHCP6 Option. + @param[out] IaInnerOpt The pointer to the IA inner option. + @param[out] IaInnerLen The length of the IA inner option. + + @retval EFI_SUCCESS Seek the inner option successfully. + @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, + the pointers are not modified +**/ +EFI_STATUS +Dhcp6SeekInnerOptionSafe ( + IN UINT16 IaType, + IN UINT8 *Option, + IN UINT32 OptionLen, + OUT UINT8 **IaInnerOpt, + OUT UINT16 *IaInnerLen + ) +{ + UINT16 IaInnerLenTmp; + UINT8 *IaInnerOptTmp; + + if (Option =3D=3D NULL) { + ASSERT (Option !=3D NULL); + return EFI_DEVICE_ERROR; + } + + if (IaInnerOpt =3D=3D NULL) { + ASSERT (IaInnerOpt !=3D NULL); + return EFI_DEVICE_ERROR; + } + + if (IaInnerLen =3D=3D NULL) { + ASSERT (IaInnerLen !=3D NULL); + return EFI_DEVICE_ERROR; + } + + if (IaType =3D=3D Dhcp6OptIana) { + // Verify we have a fully formed IA_NA + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { + return EFI_DEVICE_ERROR; + } + + // + IaInnerOptTmp =3D DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); + + // Verify the IaInnerLen is valid. + IaInnerLenTmp =3D (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFS= ET_OF_OPT_LEN (Option))); + if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { + return EFI_DEVICE_ERROR; + } + + IaInnerLenTmp -=3D DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; + } else if (IaType =3D=3D Dhcp6OptIata) { + // Verify the OptionLen is valid. + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { + return EFI_DEVICE_ERROR; + } + + IaInnerOptTmp =3D DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); + + // Verify the IaInnerLen is valid. + IaInnerLenTmp =3D (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFF= SET_OF_OPT_LEN (Option)))); + if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { + return EFI_DEVICE_ERROR; + } + + IaInnerLenTmp -=3D DHCP6_SIZE_OF_IAID; + } else { + return EFI_DEVICE_ERROR; + } + + *IaInnerOpt =3D IaInnerOptTmp; + *IaInnerLen =3D IaInnerLenTmp; + + return EFI_SUCCESS; +} + /** Seek StatusCode Option in package. A Status Code option may appear in the options field of a DHCP message and/or in the options field of another o= ption. @@ -684,6 +766,12 @@ Dhcp6SeekStsOption ( UINT8 *IaInnerOpt; UINT16 IaInnerLen; UINT16 StsCode; + UINT32 OptionLen; + + // OptionLen is the length of the Options excluding the DHCP header. + // Length of the EFI_DHCP6_PACKET from the first byte of the Header fiel= d to the last + // byte of the Option[] field. + OptionLen =3D Packet->Length - sizeof (Packet->Dhcp6.Header); =20 // // Seek StatusCode option directly in DHCP message body. That is, search= in @@ -691,12 +779,12 @@ Dhcp6SeekStsOption ( // *Option =3D Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - 4, + OptionLen, Dhcp6OptStatusCode ); =20 if (*Option !=3D NULL) { - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4))); + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_= CODE (*Option)))); if (StsCode !=3D Dhcp6StsSuccess) { return EFI_DEVICE_ERROR; } @@ -707,7 +795,7 @@ Dhcp6SeekStsOption ( // *Option =3D Dhcp6SeekIaOption ( Packet->Dhcp6.Option, - Packet->Length - sizeof (EFI_DHCP6_HEADER), + OptionLen, &Instance->Config->IaDescriptor ); if (*Option =3D=3D NULL) { @@ -715,52 +803,35 @@ Dhcp6SeekStsOption ( } =20 // - // The format of the IA_NA option is: + // Calculate the distance from Packet->Dhcp6.Option to the IA option. // - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | OPTION_IA_NA | option-len | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | IAID (4 octets) | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | T1 | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | T2 | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | | - // . IA_NA-options . - // . . - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Packet->Size and Packet->Length are both UINT32 type, and Packet->Siz= e is + // the size of the whole packet, including the DHCP header, and Packet->= Length + // is the length of the DHCP message body, excluding the DHCP header. // - // The format of the IA_TA option is: + // (*Option - Packet->Dhcp6.Option) is the number of bytes from the star= t of + // DHCP6 option area to the start of the IA option. // - // 0 1 2 3 - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | OPTION_IA_TA | option-len | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | IAID (4 octets) | - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - // | | - // . IA_TA-options . - // . . - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the + // IA option to the end of the DHCP6 option area, thus subtract the space + // up until this option // + OptionLen =3D OptionLen - (*Option - Packet->Dhcp6.Option); =20 // - // sizeof (option-code + option-len + IaId) =3D 8 - // sizeof (option-code + option-len + IaId + T1) =3D 12 - // sizeof (option-code + option-len + IaId + T1 + T2) =3D 16 + // Seek the inner option // - // The inner options still start with 2 bytes option-code and 2 bytes op= tion-len. - // - if (Instance->Config->IaDescriptor.Type =3D=3D Dhcp6OptIana) { - IaInnerOpt =3D *Option + 16; - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2= ))) - 12); - } else { - IaInnerOpt =3D *Option + 8; - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2= ))) - 4); + if (EFI_ERROR ( + Dhcp6SeekInnerOptionSafe ( + Instance->Config->IaDescriptor.Type, + *Option, + OptionLen, + &IaInnerOpt, + &IaInnerLen + ) + )) + { + return EFI_DEVICE_ERROR; } =20 // @@ -784,7 +855,7 @@ Dhcp6SeekStsOption ( // *Option =3D Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); if (*Option !=3D NULL) { - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4))); + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS= _CODE (*Option))))); if (StsCode !=3D Dhcp6StsSuccess) { return EFI_DEVICE_ERROR; } @@ -1105,7 +1176,7 @@ Dhcp6SendRequestMsg ( // Option =3D Dhcp6SeekOption ( Instance->AdSelect->Dhcp6.Option, - Instance->AdSelect->Length - 4, + Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option =3D=3D NULL) { @@ -1289,7 +1360,7 @@ Dhcp6SendDeclineMsg ( // Option =3D Dhcp6SeekOption ( LastReply->Dhcp6.Option, - LastReply->Length - 4, + LastReply->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option =3D=3D NULL) { @@ -1448,7 +1519,7 @@ Dhcp6SendReleaseMsg ( // Option =3D Dhcp6SeekOption ( LastReply->Dhcp6.Option, - LastReply->Length - 4, + LastReply->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option =3D=3D NULL) { @@ -1673,7 +1744,7 @@ Dhcp6SendRenewRebindMsg ( =20 Option =3D Dhcp6SeekOption ( LastReply->Dhcp6.Option, - LastReply->Length - 4, + LastReply->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option =3D=3D NULL) { @@ -2208,7 +2279,7 @@ Dhcp6HandleReplyMsg ( // Option =3D Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - 4, + Packet->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptRapidCommit ); =20 @@ -2354,7 +2425,7 @@ Dhcp6HandleReplyMsg ( // // Any error status code option is found. // - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4))); + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS= _CODE (Option))))); switch (StsCode) { case Dhcp6StsUnspecFail: // @@ -2487,7 +2558,7 @@ Dhcp6SelectAdvertiseMsg ( // Option =3D Dhcp6SeekOption ( AdSelect->Dhcp6.Option, - AdSelect->Length - 4, + AdSelect->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerUnicast ); =20 @@ -2498,7 +2569,7 @@ Dhcp6SelectAdvertiseMsg ( return EFI_OUT_OF_RESOURCES; } =20 - CopyMem (Instance->Unicast, Option + 4, sizeof (EFI_IPv6_ADDRESS)); + CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof = (EFI_IPv6_ADDRESS)); } =20 // @@ -2551,7 +2622,7 @@ Dhcp6HandleAdvertiseMsg ( // Option =3D Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - 4, + Packet->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptRapidCommit ); =20 @@ -2645,7 +2716,7 @@ Dhcp6HandleAdvertiseMsg ( CopyMem (Instance->AdSelect, Packet, Packet->Size); =20 if (Option !=3D NULL) { - Instance->AdPref =3D *(Option + 4); + Instance->AdPref =3D *(DHCP6_OFFSET_OF_OPT_DATA (Option)); } } else { // @@ -2714,11 +2785,11 @@ Dhcp6HandleStateful ( // Option =3D Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - 4, + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, Dhcp6OptClientId ); =20 - if ((Option =3D=3D NULL) || (CompareMem (Option + 4, ClientId->Duid, Cli= entId->Length) !=3D 0)) { + if ((Option =3D=3D NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Optio= n), ClientId->Duid, ClientId->Length) !=3D 0)) { goto ON_CONTINUE; } =20 @@ -2727,7 +2798,7 @@ Dhcp6HandleStateful ( // Option =3D Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - 4, + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, Dhcp6OptServerId ); =20 @@ -2832,7 +2903,7 @@ Dhcp6HandleStateless ( // Option =3D Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - 4, + Packet->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); =20 --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114466): https://edk2.groups.io/g/devel/message/114466 Mute This Topic: https://groups.io/mt/103964979/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114467+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114467+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223993; cv=none; d=zohomail.com; s=zohoarc; b=Tq7ZoyJm3AG9tgSOGdElouLBn5jCWmlOA9yENruO5xe1m7A0lnfcOm6+mrkl8GjZB0x1erhYOIFA+0TY1aXHRnTwkFCh0nQ4tu1jFWtB6DmTWZYjyWzywNnITLPzTug7SfSiUP4SDLbtPEaM9AbPytm5Q7IUv7hCO+etLrrXojY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223993; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=y34py/E/zp0NV1qhSPOv1LOJIhSy0jtmG5cd4NpC3Do=; b=MlLbP8XJOUGN70kLlO+CCNXV1aKpEM9p5w4q5+5nTxQglGWvicL6YkTYhWM+P1AL4Y1JMJ+KaaIovIBlr0T6/PUZUR9nhzFYxNI0ZhqCMxDCSp9Z2+06OfjbGScKd2mDCQBuCDBEBHh7fkSzfyYQaTH0yvBiRvWXaffrxiQUtlM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114467+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223993507946.4312931686314; Thu, 25 Jan 2024 15:06:33 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=ZLoJLnUtdjInkJqI7NdWKLu/xvwlO3L/1/cUfimlDNY=; 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=1706223993; v=1; b=kk0+63w8Uj7zVpO/EmnbzwiGmLYtGlVk/KaevmyettaUrFrly5MkaQNsKHvcUAxNmr8cX7uT katTFGC0H+GS/j/jE6HsexGoZP85MI4sUbH6MQQQHcH4BOY9FIaRfpTeuKOmS+Lznp1E6OfF5TW gNu+rvJVjh1YnpuIq2BZF280= X-Received: by 127.0.0.2 with SMTP id AVVmYY1788612xnJ9WMjQqwi; Thu, 25 Jan 2024 15:06:33 -0800 X-Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by mx.groups.io with SMTP id smtpd.web10.795.1706223992600460902 for ; Thu, 25 Jan 2024 15:06:32 -0800 X-Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-1d780a392fdso21689775ad.3 for ; Thu, 25 Jan 2024 15:06:32 -0800 (PST) X-Gm-Message-State: k9LK01AOjzagteT5L2wJtPxAx1787277AA= X-Google-Smtp-Source: AGHT+IEUx9DbgIfCunWpkApEYK8IMoq4crdA1Vik3r3f2uN0MES9Qs/fHkBbsDmC4/S020iCQfQJUw== X-Received: by 2002:a17:903:2d0:b0:1d4:6a34:b435 with SMTP id s16-20020a17090302d000b001d46a34b435mr476898plk.126.1706223991674; Thu, 25 Jan 2024 15:06:31 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:31 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Saloni Kasbekar , Zachary Clark-williams Subject: [edk2-devel] [PATCH v2 05/15] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests Date: Thu, 25 Jan 2024 13:54:47 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223993906100016 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4534 These tests confirm that the report bug... "Out-of-bounds read when processing IA_NA/IA_TA options in a DHCPv6 Advertise message" ..has been patched. The following functions are tested to confirm an out of bounds read is patched and that the correct statuses are returned: Dhcp6SeekInnerOptionSafe Dhcp6SeekStsOption TCBZ4534 CVE-2023-45229 CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N CWE-125 Out-of-bounds Read Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + .../GoogleTest/Dhcp6DxeGoogleTest.inf | 1 + .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h | 58 +++ NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 2 +- .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 365 +++++++++++++++++- 5 files changed, 424 insertions(+), 3 deletions(-) create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/Netwo= rkPkgHostTest.dsc index 20bc90b1728d..24dee654df2e 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -16,6 +16,7 @@ [Defines] SKUID_IDENTIFIER =3D DEFAULT =20 !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc + [Packages] MdePkg/MdePkg.dec UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/Networ= kPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf index 8e9119a37158..12532ed30cb3 100644 --- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf +++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf @@ -18,6 +18,7 @@ [Defines] [Sources] Dhcp6DxeGoogleTest.cpp Dhcp6IoGoogleTest.cpp + Dhcp6IoGoogleTest.h ../Dhcp6Io.c ../Dhcp6Utility.c =20 diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h b/NetworkPk= g/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h new file mode 100644 index 000000000000..aed3b890827b --- /dev/null +++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h @@ -0,0 +1,58 @@ +/** @file + Acts as header for private functions under test in Dhcp6Io.c + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef DHCP6_IO_GOOGLE_TEST_H_ +#define DHCP6_IO_GOOGLE_TEST_H_ + +//////////////////////////////////////////////////////////////////////////= ////// +// These are the functions that are being unit tested +//////////////////////////////////////////////////////////////////////////= ////// + +#include + +/** + Seeks the Inner Options from a DHCP6 Option + + @param[in] IaType The type of the IA option. + @param[in] Option The pointer to the DHCP6 Option. + @param[in] OptionLen The length of the DHCP6 Option. + @param[out] IaInnerOpt The pointer to the IA inner option. + @param[out] IaInnerLen The length of the IA inner option. + + @retval EFI_SUCCESS Seek the inner option successfully. + @retval EFI_DEVICE_ERROR The OptionLen is invalid. +*/ +EFI_STATUS +Dhcp6SeekInnerOptionSafe ( + UINT16 IaType, + UINT8 *Option, + UINT32 OptionLen, + UINT8 **IaInnerOpt, + UINT16 *IaInnerLen + ); + +/** + Seek StatusCode Option in package. A Status Code option may appear in the + options field of a DHCP message and/or in the options field of another o= ption. + See details in section 22.13, RFC3315. + + @param[in] Instance The pointer to the Dhcp6 instance. + @param[in] Packet The pointer to reply messages. + @param[out] Option The pointer to status code option. + + @retval EFI_SUCCESS Seek status code option successfully. + @retval EFI_DEVICE_ERROR An unexpected error. + +**/ +EFI_STATUS +Dhcp6SeekStsOption ( + IN DHCP6_INSTANCE *Instance, + IN EFI_DHCP6_PACKET *Packet, + OUT UINT8 **Option + ); + +#endif // DHCP6_IO_GOOGLE_TEST_H diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c index 89d16484a568..3b8feb4a2032 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c @@ -816,7 +816,7 @@ Dhcp6SeekStsOption ( // IA option to the end of the DHCP6 option area, thus subtract the space // up until this option // - OptionLen =3D OptionLen - (*Option - Packet->Dhcp6.Option); + OptionLen =3D OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option); =20 // // Seek the inner option diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/Network= Pkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp index 7ee40e4af480..7db253a7b87f 100644 --- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp +++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp @@ -13,6 +13,7 @@ extern "C" { #include #include "../Dhcp6Impl.h" #include "../Dhcp6Utility.h" + #include "Dhcp6IoGoogleTest.h" } =20 //////////////////////////////////////////////////////////////////////// @@ -21,7 +22,35 @@ extern "C" { =20 #define DHCP6_PACKET_MAX_LEN 1500 =20 +// This definition is used by this test but is also required to compile +// by Dhcp6Io.c +#define DHCPV6_OPTION_IA_NA 3 +#define DHCPV6_OPTION_IA_TA 4 + +#define SEARCH_PATTERN 0xDEADC0DE +#define SEARCH_PATTERN_LEN sizeof(SEARCH_PATTERN) + //////////////////////////////////////////////////////////////////////// +// Test structures for IA_NA and IA_TA options +//////////////////////////////////////////////////////////////////////// +typedef struct { + UINT16 Code; + UINT16 Len; + UINT32 IAID; +} DHCPv6_OPTION; + +typedef struct { + DHCPv6_OPTION Header; + UINT32 T1; + UINT32 T2; + UINT8 InnerOptions[0]; +} DHCPv6_OPTION_IA_NA; + +typedef struct { + DHCPv6_OPTION Header; + UINT8 InnerOptions[0]; +} DHCPv6_OPTION_IA_TA; + //////////////////////////////////////////////////////////////////////// // Symbol Definitions // These functions are not directly under test - but required to compile @@ -210,7 +239,7 @@ TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBuffe= rTooSmall) { Status =3D Dhcp6AppendETOption ( Dhcp6AppendETOptionTest::Packet, &Cursor, - &Instance, // Instance is not used in this function + &Instance, // Instance is not used in this= function &ElapsedTime ); =20 @@ -240,7 +269,7 @@ TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess= ) { Status =3D Dhcp6AppendETOption ( Dhcp6AppendETOptionTest::Packet, &Cursor, - &Instance, // Instance is not used in this function + &Instance, // Instance is not used in this= function &ElapsedTime ); =20 @@ -476,3 +505,335 @@ TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectS= uccess) { // verify that the status is EFI_SUCCESS ASSERT_EQ (Status, EFI_SUCCESS); } + +//////////////////////////////////////////////////////////////////////// +// Dhcp6SeekInnerOptionSafe Tests +//////////////////////////////////////////////////////////////////////// + +// Define a fixture for your tests if needed +class Dhcp6SeekInnerOptionSafeTest : 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: +// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS wh= en the IANA option is found. +TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAValidOptionExpectSuccess) { + EFI_STATUS Result; + UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTER= N_LEN] =3D { 0 }; + UINT32 OptionLength = =3D sizeof (Option); + DHCPv6_OPTION_IA_NA *OptionPtr = =3D (DHCPv6_OPTION_IA_NA *)Option; + UINT32 SearchPattern = =3D SEARCH_PATTERN; + + UINTN SearchPatternLength =3D SEARCH_PATTERN_LEN; + UINT8 *InnerOptionPtr =3D NULL; + UINT16 InnerOptionLength =3D 0; + + OptionPtr->Header.Code =3D Dhcp6OptIana; + OptionPtr->Header.Len =3D HTONS (4 + 12); // Valid length has to be mor= e than 12 + OptionPtr->Header.IAID =3D 0x12345678; + OptionPtr->T1 =3D 0x11111111; + OptionPtr->T2 =3D 0x22222222; + CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); + + Result =3D Dhcp6SeekInnerOptionSafe ( + Dhcp6OptIana, + Option, + OptionLength, + &InnerOptionPtr, + &InnerOptionLength + ); + ASSERT_EQ (Result, EFI_SUCCESS); + ASSERT_EQ (InnerOptionLength, 4); + ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLeng= th), 0); +} + +// Test Description: +// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_DEIVCE_ERR= OR when the IANA option size is invalid. +TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAInvalidSizeExpectFail) { + // Lets add an inner option of bytes we expect to find + EFI_STATUS Status; + UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTER= N_LEN] =3D { 0 }; + UINT32 OptionLength = =3D sizeof (Option); + DHCPv6_OPTION_IA_NA *OptionPtr = =3D (DHCPv6_OPTION_IA_NA *)Option; + UINT32 SearchPattern = =3D SEARCH_PATTERN; + + UINTN SearchPatternLength =3D SEARCH_PATTERN_LEN; + UINT8 *InnerOptionPtr =3D NULL; + UINT16 InnerOptionLength =3D 0; + + OptionPtr->Header.Code =3D Dhcp6OptIana; + OptionPtr->Header.Len =3D HTONS (4); // Set the length to lower than ex= pected (12) + OptionPtr->Header.IAID =3D 0x12345678; + OptionPtr->T1 =3D 0x11111111; + OptionPtr->T2 =3D 0x22222222; + CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); + + // Set the InnerOptionLength to be less than the size of the option + Status =3D Dhcp6SeekInnerOptionSafe ( + Dhcp6OptIana, + Option, + OptionLength, + &InnerOptionPtr, + &InnerOptionLength + ); + ASSERT_EQ (Status, EFI_DEVICE_ERROR); + + // Now set the OptionLength to be less than the size of the option + OptionLength =3D sizeof (DHCPv6_OPTION_IA_NA) - 1; + Status =3D Dhcp6SeekInnerOptionSafe ( + Dhcp6OptIana, + Option, + OptionLength, + &InnerOptionPtr, + &InnerOptionLength + ); + ASSERT_EQ (Status, EFI_DEVICE_ERROR); +} + +// Test Description: +// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS wh= en the IATA option is found +TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAValidOptionExpectSuccess) { + // Lets add an inner option of bytes we expect to find + EFI_STATUS Status; + UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTER= N_LEN] =3D { 0 }; + UINT32 OptionLength = =3D sizeof (Option); + DHCPv6_OPTION_IA_TA *OptionPtr = =3D (DHCPv6_OPTION_IA_TA *)Option; + UINT32 SearchPattern = =3D SEARCH_PATTERN; + + UINTN SearchPatternLength =3D SEARCH_PATTERN_LEN; + UINT8 *InnerOptionPtr =3D NULL; + UINT16 InnerOptionLength =3D 0; + + OptionPtr->Header.Code =3D Dhcp6OptIata; + OptionPtr->Header.Len =3D HTONS (4 + 4); // Valid length has to be more= than 4 + OptionPtr->Header.IAID =3D 0x12345678; + CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); + + Status =3D Dhcp6SeekInnerOptionSafe ( + Dhcp6OptIata, + Option, + OptionLength, + &InnerOptionPtr, + &InnerOptionLength + ); + ASSERT_EQ (Status, EFI_SUCCESS); + ASSERT_EQ (InnerOptionLength, 4); + ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLeng= th), 0); +} + +// Test Description: +// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS wh= en the IATA option size is invalid. +TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAInvalidSizeExpectFail) { + // Lets add an inner option of bytes we expect to find + EFI_STATUS Status; + UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTER= N_LEN] =3D { 0 }; + UINT32 OptionLength = =3D sizeof (Option); + DHCPv6_OPTION_IA_TA *OptionPtr = =3D (DHCPv6_OPTION_IA_TA *)Option; + UINT32 SearchPattern = =3D SEARCH_PATTERN; + + UINTN SearchPatternLength =3D SEARCH_PATTERN_LEN; + UINT8 *InnerOptionPtr =3D NULL; + UINT16 InnerOptionLength =3D 0; + + OptionPtr->Header.Code =3D Dhcp6OptIata; + OptionPtr->Header.Len =3D HTONS (2); // Set the length to lower than ex= pected (4) + OptionPtr->Header.IAID =3D 0x12345678; + CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); + + Status =3D Dhcp6SeekInnerOptionSafe ( + Dhcp6OptIata, + Option, + OptionLength, + &InnerOptionPtr, + &InnerOptionLength + ); + ASSERT_EQ (Status, EFI_DEVICE_ERROR); + + // Now lets try modifying the OptionLength to be less than the size of t= he option + OptionLength =3D sizeof (DHCPv6_OPTION_IA_TA) - 1; + Status =3D Dhcp6SeekInnerOptionSafe ( + Dhcp6OptIata, + Option, + OptionLength, + &InnerOptionPtr, + &InnerOptionLength + ); + ASSERT_EQ (Status, EFI_DEVICE_ERROR); +} + +// Test Description: +// This test verifies that any other Option Type fails +TEST_F (Dhcp6SeekInnerOptionSafeTest, InvalidOption) { + // Lets add an inner option of bytes we expect to find + EFI_STATUS Result; + UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTER= N_LEN] =3D { 0 }; + UINT32 OptionLength = =3D sizeof (Option); + DHCPv6_OPTION_IA_TA *OptionPtr = =3D (DHCPv6_OPTION_IA_TA *)Option; + UINT32 SearchPattern = =3D SEARCH_PATTERN; + + UINTN SearchPatternLength =3D SEARCH_PATTERN_LEN; + UINT8 *InnerOptionPtr =3D NULL; + UINT16 InnerOptionLength =3D 0; + + OptionPtr->Header.Code =3D 0xC0DE; + OptionPtr->Header.Len =3D HTONS (2); // Set the length to lower than ex= pected (4) + OptionPtr->Header.IAID =3D 0x12345678; + CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength); + + Result =3D Dhcp6SeekInnerOptionSafe (0xC0DE, Option, OptionLength, &Inne= rOptionPtr, &InnerOptionLength); + ASSERT_EQ (Result, EFI_DEVICE_ERROR); +} + +//////////////////////////////////////////////////////////////////////// +// Dhcp6SeekStsOption Tests +//////////////////////////////////////////////////////////////////////// + +#define PACKET_SIZE (1500) + +class Dhcp6SeekStsOptionTest : public ::testing::Test { +public: + DHCP6_INSTANCE Instance =3D { 0 }; + EFI_DHCP6_PACKET *Packet =3D NULL; + EFI_DHCP6_CONFIG_DATA Config =3D { 0 }; + +protected: + // Add any setup code if needed + virtual void + SetUp ( + ) + { + // Allocate a packet + Packet =3D (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE); + ASSERT_NE (Packet, nullptr); + + // Initialize the packet + Packet->Size =3D PACKET_SIZE; + + Instance.Config =3D &Config; + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + // Clean up any resources or variables + FreePool (Packet); + } +}; + +// Test Description: +// This test verifies that Dhcp6SeekStsOption returns EFI_DEVICE_ERROR whe= n the option is invalid +// This verifies that the calling function is working as expected +TEST_F (Dhcp6SeekStsOptionTest, SeekIATAOptionExpectFail) { + EFI_STATUS Status; + UINT8 *Option =3D NULL; + UINT32 SearchPattern =3D SEARCH_PATTERN; + UINT16 SearchPatternLength =3D SEARCH_PATTERN_LEN; + UINT16 *Len =3D NULL; + EFI_DHCP6_IA Ia =3D { 0 }; + + Ia.Descriptor.Type =3D DHCPV6_OPTION_IA_TA; + Ia.IaAddressCount =3D 1; + Ia.IaAddress[0].PreferredLifetime =3D 0xDEADBEEF; + Ia.IaAddress[0].ValidLifetime =3D 0xDEADAAAA; + Ia.IaAddress[0].IpAddress =3D mAllDhcpRelayAndServersAddress; + + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); + + Option =3D Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option; + + // Let's append the option to the packet + Status =3D Dhcp6AppendOption ( + Dhcp6SeekStsOptionTest::Packet, + &Option, + Dhcp6OptStatusCode, + SearchPatternLength, + (UINT8 *)&SearchPattern + ); + ASSERT_EQ (Status, EFI_SUCCESS); + + // Inner option length - this will be overwritten later + Len =3D (UINT16 *)(Option + 2); + + // Fill in the inner IA option + Status =3D Dhcp6AppendIaOption ( + Dhcp6SeekStsOptionTest::Packet, + &Option, + &Ia, + 0x12345678, + 0x11111111, + 0x22222222 + ); + ASSERT_EQ (Status, EFI_SUCCESS); + + // overwrite the len of inner Ia option + *Len =3D HTONS (3); + + Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type =3D DHCPV6_OP= TION_IA_TA; + + Option =3D NULL; + Status =3D Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp= 6SeekStsOptionTest::Packet, &Option); + + ASSERT_EQ (Status, EFI_DEVICE_ERROR); +} + +// Test Description: +// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS wh= en the IATA option size is invalid. +TEST_F (Dhcp6SeekStsOptionTest, SeekIANAOptionExpectSuccess) { + EFI_STATUS Status =3D EFI_NOT_FOUND; + UINT8 *Option =3D NULL; + UINT32 SearchPattern =3D SEARCH_PATTERN; + UINT16 SearchPatternLength =3D SEARCH_PATTERN_LEN; + EFI_DHCP6_IA Ia =3D { 0 }; + + Ia.Descriptor.Type =3D DHCPV6_OPTION_IA_NA; + Ia.IaAddressCount =3D 1; + Ia.IaAddress[0].PreferredLifetime =3D 0x11111111; + Ia.IaAddress[0].ValidLifetime =3D 0x22222222; + Ia.IaAddress[0].IpAddress =3D mAllDhcpRelayAndServersAddress; + Packet->Length =3D sizeof (EFI_DHCP6_HEADER); + + Option =3D Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option; + + Status =3D Dhcp6AppendOption ( + Dhcp6SeekStsOptionTest::Packet, + &Option, + Dhcp6OptStatusCode, + SearchPatternLength, + (UINT8 *)&SearchPattern + ); + ASSERT_EQ (Status, EFI_SUCCESS); + + Status =3D Dhcp6AppendIaOption ( + Dhcp6SeekStsOptionTest::Packet, + &Option, + &Ia, + 0x12345678, + 0x11111111, + 0x22222222 + ); + ASSERT_EQ (Status, EFI_SUCCESS); + + Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type =3D DHCPV6_OP= TION_IA_NA; + + Option =3D NULL; + Status =3D Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp= 6SeekStsOptionTest::Packet, &Option); + + ASSERT_EQ (Status, EFI_SUCCESS); +} --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114467): https://edk2.groups.io/g/devel/message/114467 Mute This Topic: https://groups.io/mt/103964980/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114468+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114468+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223994; cv=none; d=zohomail.com; s=zohoarc; b=gVoqUPhk+kCCOJkVCSP+l8hu0dJAiZinzMTNWRuNTfE3TjRZS8lNwka3O33n5aGcLFLLqLIkqBqRf7foT6GMxQB7r0AfJ5vhR/NaKTn6LewDMCfaTsnqwFq2eMvslyq3wCpL7J3Bnfb8KSnfeuGWQrPRIsAXtJhdIuvDjNfiCEA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223994; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=KO2O7RjULUgHlQxtzGr6EHVECcLVnze3ZreFzTW+5po=; b=CRbO6bA4xmhLH0Tdzajyx/pFcfyIzWg2iVUDdor60eh34raoGYq/h7s1jqY0UpK+mJnq6VSlG1Gsz7/21NfF8YneM3zgg3r47kgQoTwHzgln0aOhhms8PGE5bzA9L1jOpZMYrDKTD6p75M+k86zBdm8lteKuXG2nyLVF0GXEWqY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114468+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223994168889.7626458579722; Thu, 25 Jan 2024 15:06:34 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=IskHYVtQeLIYtPWMT4O9yalJ/3tKdfNwkAbVk/jwPpE=; 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=1706223993; v=1; b=IzZRJPuDak2EfADdwPjgEBk7Gow8z6NzwYnqhaSoHlI0zHwAKQRzmBy38dNuth+6z1zKIl6w 1bkno/vmfl/1qF3Y5dIahrO3+53hOsi754Jmouumq0uUjzqTY4hUJbTLcHwS0To6hlokqN8Sidv vtml4ZtBS12goNalbekUMEVM= X-Received: by 127.0.0.2 with SMTP id 26CAYY1788612xdahMnJ9ODk; Thu, 25 Jan 2024 15:06:33 -0800 X-Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) by mx.groups.io with SMTP id smtpd.web11.781.1706223993293539648 for ; Thu, 25 Jan 2024 15:06:33 -0800 X-Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1d746856d85so303125ad.0 for ; Thu, 25 Jan 2024 15:06:33 -0800 (PST) X-Gm-Message-State: B3hzjsqxMRbfvt88Aqjfl1UYx1787277AA= X-Google-Smtp-Source: AGHT+IEa6RmuLqeIMB14GcwS5L55e3K5KuiGsTz0cTEu9IL42rk+gJT8gQSPLxeaFcDIylvCpQvnqg== X-Received: by 2002:a17:902:c94d:b0:1d4:8be0:4494 with SMTP id i13-20020a170902c94d00b001d48be04494mr476254pla.125.1706223992539; Thu, 25 Jan 2024 15:06:32 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:32 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 06/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Patch Date: Thu, 25 Jan 2024 13:54:48 -0800 Message-ID: <03b422eb7b3f88136810da4ed290d2e2374483fe.1706219324.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223995842100027 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4536 Bug Overview: PixieFail Bug #3 CVE-2023-45231 CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N CWE-125 Out-of-bounds Read Out-of-bounds read when handling a ND Redirect message with truncated options Change Overview: Adds a check to prevent truncated options from being parsed + // + // Cannot process truncated options. + // Cannot process options with a length of 0 as there is no Type field. + // + if (OptionLen < sizeof (IP6_OPTION_HEADER)) { + return FALSE; + } Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Ip6Dxe/Ip6Option.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c index 199eea124dfe..8718d5d8756a 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Option.c +++ b/NetworkPkg/Ip6Dxe/Ip6Option.c @@ -137,6 +137,14 @@ Ip6IsNDOptionValid ( return FALSE; } =20 + // + // Cannot process truncated options. + // Cannot process options with a length of 0 as there is no Type field. + // + if (OptionLen < sizeof (IP6_OPTION_HEADER)) { + return FALSE; + } + Offset =3D 0; =20 // --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114468): https://edk2.groups.io/g/devel/message/114468 Mute This Topic: https://groups.io/mt/103964981/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114469+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114469+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223995; cv=none; d=zohomail.com; s=zohoarc; b=R5gwm83b9jm+uqY6mvFSTAScMvvDt9vGntSQYwReAXNQVr7D80X5TvUf6cDvwvgwTJL9zaZTP1E5O6ztMZM+pkouMRHS0QB6vPIsIyrommHWc3yg0KGxiHQbWbSafaAfUed6Alw84SH/vfDuVyfpW8rimJaoUjLufn5jzVa9gpQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223995; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=uUOIe3jJE1iaImEaMI93mnCYuoCr2B8WiCVNOVcU14A=; b=BeZ7tdXrzSfCFbOQlvSlWFviRck2pFRaDGsyJmb+zyKSBT50UP0Hmz0mDwCb2OSIsDDe/Q2fXSpYfRfTs8hekUWTtp+kjVRZS8+5H67K5K55AoN29RXOuqf/NdWmABX2jK0itaxKkBHwKbtJ/mc44eQirmphHonLW+ltzrMKVxU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114469+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223995067423.0427903769753; Thu, 25 Jan 2024 15:06:35 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=bilDKZ60ecaqOrUCblZxGlA7rZr1HoUrDYX5Xz72YBg=; 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=1706223994; v=1; b=vH7k1qE1idcXZaZYa4j6Oimkz2A6qA0zEM7pzqIilxeIkKNSRKpSmS9qoQwy6tZ1pmoyIOD2 QLxqBke1BtT8xLuHO9HVYotkSbBSVuuAJNlEsUsBTw0ERImR+vMMSQXlUUkpmd9fQIlRn6Z0U7J 8zxrpYInp42zfcaTgsx2wyEs= X-Received: by 127.0.0.2 with SMTP id vCXuYY1788612xQdf0DKGZSB; Thu, 25 Jan 2024 15:06:34 -0800 X-Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) by mx.groups.io with SMTP id smtpd.web11.783.1706223994172159769 for ; Thu, 25 Jan 2024 15:06:34 -0800 X-Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-1d7859efea5so2165295ad.0 for ; Thu, 25 Jan 2024 15:06:34 -0800 (PST) X-Gm-Message-State: CXorY7vLrMaEA4bwVFQFjVhwx1787277AA= X-Google-Smtp-Source: AGHT+IGMW6+4JH3JRCvSFUWvuxLomPXcFebJAk1X2fcMzJAax+TEtM3ALF0TuFNOVzUatA1z8WqDFQ== X-Received: by 2002:a17:903:1c3:b0:1d7:2817:a63a with SMTP id e3-20020a17090301c300b001d72817a63amr476150plh.19.1706223993220; Thu, 25 Jan 2024 15:06:33 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:32 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 07/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Unit Tests Date: Thu, 25 Jan 2024 13:54:49 -0800 Message-ID: <0e584109537f3cea0b6393d598a69c61dc6912a5.1706219324.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223995874100028 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4536 Validates that the patch for... Out-of-bounds read when handling a ND Redirect message with truncated options .. has been fixed Tests the following function to ensure that an out of bounds read does not occur Ip6OptionValidation Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 42 ++++++ .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp | 20 +++ .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 129 ++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/Netwo= rkPkgHostTest.dsc index 24dee654df2e..7fa7b0f9d5be 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -26,6 +26,7 @@ [Components] # Build HOST_APPLICATION that tests NetworkPkg # NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf + NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf =20 # Despite these library classes being listed in [LibraryClasses] below, th= ey are not needed for the host-based unit tests. [LibraryClasses] diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg= /Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf new file mode 100644 index 000000000000..6e4de0745fb5 --- /dev/null +++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf @@ -0,0 +1,42 @@ +## @file +# Unit test suite for the Ip6Dxe using Google Test +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D Ip6DxeUnitTest + FILE_GUID =3D 4F05D17D-D3E7-4AAE-820C-576D46D2D34A + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D HOST_APPLICATION +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64 +# +[Sources] + Ip6DxeGoogleTest.cpp + Ip6OptionGoogleTest.cpp + ../Ip6Option.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + NetworkPkg/NetworkPkg.dec + +[LibraryClasses] + GoogleTestLib + DebugLib + NetLib + PcdLib + +[Protocols] + gEfiDhcp6ServiceBindingProtocolGuid + +[Pcd] + gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType + +[Guids] + gZeroGuid diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp b/NetworkPkg= /Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp new file mode 100644 index 000000000000..6ebfd5fdfb70 --- /dev/null +++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp @@ -0,0 +1,20 @@ +/** @file + Acts as the main entry point for the tests for the Ip6Dxe module. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include + +//////////////////////////////////////////////////////////////////////////= ////// +// Run the tests +//////////////////////////////////////////////////////////////////////////= ////// +int +main ( + int argc, + char *argv[] + ) +{ + testing::InitGoogleTest (&argc, argv); + return RUN_ALL_TESTS (); +} diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/Network= Pkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp new file mode 100644 index 000000000000..f2cd90e1a952 --- /dev/null +++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp @@ -0,0 +1,129 @@ +/** @file + Tests for Ip6Option.c. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include + +extern "C" { + #include + #include + #include + #include "../Ip6Impl.h" + #include "../Ip6Option.h" +} + +///////////////////////////////////////////////////////////////////////// +// Defines +/////////////////////////////////////////////////////////////////////// + +#define IP6_PREFIX_INFO_OPTION_DATA_LEN 32 +#define OPTION_HEADER_IP6_PREFIX_DATA_LEN (sizeof (IP6_OPTION_HEADER) + I= P6_PREFIX_INFO_OPTION_DATA_LEN) + +//////////////////////////////////////////////////////////////////////// +// Symbol Definitions +// These functions are not directly under test - but required to compile +//////////////////////////////////////////////////////////////////////// +UINT32 mIp6Id; + +EFI_STATUS +Ip6SendIcmpError ( + IN IP6_SERVICE *IpSb, + IN NET_BUF *Packet, + IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, + IN EFI_IPv6_ADDRESS *DestinationAddress, + IN UINT8 Type, + IN UINT8 Code, + IN UINT32 *Pointer OPTIONAL + ) +{ + // .. + return EFI_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////// +// Ip6OptionValidation Tests +//////////////////////////////////////////////////////////////////////// + +// Define a fixture for your tests if needed +class Ip6OptionValidationTest : 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: +// Null option should return false +TEST_F (Ip6OptionValidationTest, NullOptionShouldReturnFalse) { + UINT8 *option =3D nullptr; + UINT16 optionLen =3D 10; // Provide a suitable length + + EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); +} + +// Test Description: +// Truncated option should return false +TEST_F (Ip6OptionValidationTest, TruncatedOptionShouldReturnFalse) { + UINT8 option[] =3D { 0x01 }; // Provide a truncated option + UINT16 optionLen =3D 1; + + EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); +} + +// Test Description: +// Ip6OptionPrefixInfo Option with zero length should return false +TEST_F (Ip6OptionValidationTest, OptionWithZeroLengthShouldReturnFalse) { + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D Ip6OptionPrefixInfo; + optionHeader.Length =3D 0; + UINT8 option[sizeof (IP6_OPTION_HEADER)]; + + CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); + UINT16 optionLen =3D sizeof (IP6_OPTION_HEADER); + + EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); +} + +// Test Description: +// Ip6OptionPrefixInfo Option with valid length should return true +TEST_F (Ip6OptionValidationTest, ValidPrefixInfoOptionShouldReturnTrue) { + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D Ip6OptionPrefixInfo; + optionHeader.Length =3D 4; // Length 4 * 8 =3D 32 + UINT8 option[OPTION_HEADER_IP6_PREFIX_DATA_LEN]; + + CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); + + EXPECT_TRUE (Ip6IsNDOptionValid (option, IP6_PREFIX_INFO_OPTION_DATA_LEN= )); +} + +// Test Description: +// Ip6OptionPrefixInfo Option with invalid length should return false +TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturn= False) { + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D Ip6OptionPrefixInfo; + optionHeader.Length =3D 3; // Length 3 * 8 =3D 24 (Invalid) + UINT8 option[sizeof (IP6_OPTION_HEADER)]; + + CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER)); + UINT16 optionLen =3D sizeof (IP6_OPTION_HEADER); + + EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen)); +} --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114469): https://edk2.groups.io/g/devel/message/114469 Mute This Topic: https://groups.io/mt/103964982/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114470+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114470+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223995; cv=none; d=zohomail.com; s=zohoarc; b=XZy3AreWrBsKjvSvD4LLmfq8VBltn3/x5EkG5H/tFUGwE2eryr2gd8Wxzw6GuOx6IsXN/+wb4T1kM1fABti/TuR/ErnEFg1bQvWpQuMgDCw7nRyVfXNi36kqysJtsinCb++HJX78zhUyP1KYfanYU3waFu9oN//ewc5YzUogC58= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223995; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=TzDC+rHAP88ebUhVroSn/OlI57S3JT7pIGRf13aOdIk=; b=BLxTtmCyO9+3Da3T59sssAGsLIGWaBMQPHpp15slLTMVtAzVe0aZTHlZbvfXklQL5rX3hGVBgcgU/zJyXZs+AABmPY1u7OQjryRpyPm/2RmeeRkRh/ixHrleY0G2jfQ61T90yi7beTblKzeBl3A7nHcJVQVjavsCcHQZrm5sVIc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114470+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223995948974.9866399849867; Thu, 25 Jan 2024 15:06:35 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=9jqkdejpnLO8ss9i18hlCM8Rjl0yGWEw5xQxFC8DDbE=; 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=1706223995; v=1; b=xaPwCQ8Kbt2nC++niHH5edISmSuLKZJ6YLNd8M0wVY5LhlTY69IZsyt1dJaqZr/teLi8I9Gx 8BeiOkkmRr1R5WxCOZKkhQ3+J7zdfwxfCAqCVnMtr/aHhPtWxBfg3EfSdB1hde3n4J+3phJG2Ua v86poUB99euwCcvP3qt7raCA= X-Received: by 127.0.0.2 with SMTP id rf56YY1788612xOxWBKOpR3o; Thu, 25 Jan 2024 15:06:35 -0800 X-Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) by mx.groups.io with SMTP id smtpd.web11.784.1706223995043224946 for ; Thu, 25 Jan 2024 15:06:35 -0800 X-Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-1d7858a469aso16590785ad.2 for ; Thu, 25 Jan 2024 15:06:34 -0800 (PST) X-Gm-Message-State: D9TjBTpRfMw2f9qSnWQcqaGEx1787277AA= X-Google-Smtp-Source: AGHT+IH3AZr5ObGDzXf7erG3nRJWroCFKITX8k9wXN+QGSmhF/xQZc4ZlTMul+qKIgchIbL0BboKZg== X-Received: by 2002:a17:902:d34c:b0:1d5:7690:3ae6 with SMTP id l12-20020a170902d34c00b001d576903ae6mr414898plk.17.1706223994126; Thu, 25 Jan 2024 15:06:34 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:33 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 08/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch Date: Thu, 25 Jan 2024 13:54:50 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223997863100036 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4537 REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4538 Bug Details: PixieFail Bug #4 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') Infinite loop when parsing unknown options in the Destination Options header PixieFail Bug #5 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') Infinite loop when parsing a PadN option in the Destination Options header Change Overview: Most importantly this change corrects the following incorrect math and cleans up the code. > // It is a PadN option > // > - Offset =3D (UINT8)(Offset + *(Option + Offset + 1) + 2); > + OptDataLen =3D ((EFI_IP6_OPTION *)(Option + Offset))->Length; > + Offset =3D IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); > case Ip6OptionSkip: > - Offset =3D (UINT8)(Offset + *(Option + Offset + 1)); > OptDataLen =3D ((EFI_IP6_OPTION *)(Option + Offset))->Length; > Offset =3D IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); Additionally, this change also corrects incorrect math where the calling function was calculating the HDR EXT optionLen as a uint8 instead of a uint16 > - OptionLen =3D (UINT8)((*Option + 1) * 8 - 2); > + OptionLen =3D IP6_HDR_EXT_LEN (*Option) - IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN; Additionally this check adds additional logic to santize the incoming data Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Ip6Dxe/Ip6Nd.h | 35 ++++++++++++++++ NetworkPkg/Ip6Dxe/Ip6Option.h | 71 ++++++++++++++++++++++++++++++++ NetworkPkg/Ip6Dxe/Ip6Option.c | 76 ++++++++++++++++++++++++++++++----- 3 files changed, 171 insertions(+), 11 deletions(-) diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h index 860934a167eb..bf64e9114e13 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Nd.h +++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h @@ -56,13 +56,48 @@ VOID VOID *Context ); =20 +// +// Per RFC8200 Section 4.2 +// +// Two of the currently-defined extension headers -- the Hop-by-Hop +// Options header and the Destination Options header -- carry a variable +// number of type-length-value (TLV) encoded "options", of the following +// format: +// +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - +// | Option Type | Opt Data Len | Option Data +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - +// +// Option Type 8-bit identifier of the type of option. +// +// Opt Data Len 8-bit unsigned integer. Length of the Option +// Data field of this option, in octets. +// +// Option Data Variable-length field. Option-Type-specific +// data. +// typedef struct _IP6_OPTION_HEADER { + /// + /// identifier of the type of option. + /// UINT8 Type; + /// + /// Length of the Option Data field of this option, in octets. + /// UINT8 Length; + /// + /// Option-Type-specific data. + /// } IP6_OPTION_HEADER; =20 STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) =3D=3D 2, "IP6_OPTION_HEADER is = expected to be exactly 2 bytes long."); =20 +#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + sizeof(IP6_OPTIO= N_HEADER) + length) +STATIC_ASSERT ( + IP6_NEXT_OPTION_OFFSET (0, 0) =3D=3D 2, + "The next option is minimally the combined size of the option tag and le= ngth" + ); + typedef struct _IP6_ETHE_ADDR_OPTION { UINT8 Type; UINT8 Length; diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h index bd8e223c8a67..fb07c28f5ad7 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Option.h +++ b/NetworkPkg/Ip6Dxe/Ip6Option.h @@ -12,6 +12,77 @@ =20 #define IP6_FRAGMENT_OFFSET_MASK (~0x3) =20 +// +// For more information see RFC 8200, Section 4.3, 4.4, and 4.6 +// +// This example format is from section 4.6 +// This does not apply to fragment headers +// +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Next Header | Hdr Ext Len | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +// | | +// . . +// . Header-Specific Data . +// . . +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Next Header 8-bit selector. Identifies the type of +// header immediately following the extension +// header. Uses the same values as the IPv4 +// Protocol field [IANA-PN]. +// +// Hdr Ext Len 8-bit unsigned integer. Length of the +// Destination Options header in 8-octet units, +// not including the first 8 octets. + +// +// These defines apply to the following: +// 1. Hop by Hop +// 2. Routing +// 3. Destination +// +typedef struct _IP6_EXT_HDR { + /// + /// The Next Header field identifies the type of header immediately + /// + UINT8 NextHeader; + /// + /// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options + /// + UINT8 HdrExtLen; + /// + /// Header-Specific Data + /// +} IP6_EXT_HDR; + +STATIC_ASSERT ( + sizeof (IP6_EXT_HDR) =3D=3D 2, + "The combined size of Next Header and Len is two 8 bit fields" + ); + +// +// IPv6 extension headers contain an 8-bit length field which describes th= e size of +// the header. However, the length field only includes the size of the ext= ension +// header options, not the size of the first 8 bytes of the header. Theref= ore, in +// order to calculate the full size of the extension header, we add 1 (to = account +// for the first 8 bytes omitted by the length field reporting) and then m= ultiply +// by 8 (since the size is represented in 8-byte units). +// +// a is the length field of the extension header (UINT8) +// The result may be up to 2046 octets (UINT16) +// +#define IP6_HDR_EXT_LEN(a) (((UINT16)((UINT8)(a)) + 1) * 8) + +// This is the maxmimum length permissible by a extension header +// Length is UINT8 of 8 octets not including the first 8 octets +#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - sizeof(IP6= _EXT_HDR)) +STATIC_ASSERT ( + IP6_MAX_EXT_DATA_LENGTH =3D=3D 2046, + "Maximum data length is ((MAX_UINT8 + 1) * 8) - 2" + ); + typedef struct _IP6_FRAGMENT_HEADER { UINT8 NextHeader; UINT8 Reserved; diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c index 8718d5d8756a..fd97ce116f98 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Option.c +++ b/NetworkPkg/Ip6Dxe/Ip6Option.c @@ -17,7 +17,8 @@ @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] OptionLen The length of all options, expressed in by= te length of octets. + Maximum length is 2046 bytes or ((n + 1) *= 8) - 2 where n is 255. @param[in] Pointer Identifies the octet offset within the invoking packet where the error was de= tected. =20 @@ -31,12 +32,33 @@ Ip6IsOptionValid ( IN IP6_SERVICE *IpSb, IN NET_BUF *Packet, IN UINT8 *Option, - IN UINT8 OptionLen, + IN UINT16 OptionLen, IN UINT32 Pointer ) { - UINT8 Offset; - UINT8 OptionType; + UINT16 Offset; + UINT8 OptionType; + UINT8 OptDataLen; + + if (Option =3D=3D NULL) { + ASSERT (Option !=3D NULL); + return FALSE; + } + + if ((OptionLen <=3D 0) || (OptionLen > IP6_MAX_EXT_DATA_LENGTH)) { + ASSERT (OptionLen > 0 && OptionLen <=3D IP6_MAX_EXT_DATA_LENGTH); + return FALSE; + } + + if (Packet =3D=3D NULL) { + ASSERT (Packet !=3D NULL); + return FALSE; + } + + if (IpSb =3D=3D NULL) { + ASSERT (IpSb !=3D NULL); + return FALSE; + } =20 Offset =3D 0; =20 @@ -54,7 +76,8 @@ Ip6IsOptionValid ( // // It is a PadN option // - Offset =3D (UINT8)(Offset + *(Option + Offset + 1) + 2); + OptDataLen =3D ((IP6_OPTION_HEADER *)(Option + Offset))->Length; + Offset =3D IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); break; case Ip6OptionRouterAlert: // @@ -69,7 +92,8 @@ Ip6IsOptionValid ( // switch (OptionType & Ip6OptionMask) { case Ip6OptionSkip: - Offset =3D (UINT8)(Offset + *(Option + Offset + 1)); + OptDataLen =3D ((IP6_OPTION_HEADER *)(Option + Offset))->Lengt= h; + Offset =3D IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); break; case Ip6OptionDiscard: return FALSE; @@ -308,7 +332,7 @@ Ip6IsExtsValid ( UINT32 Pointer; UINT32 Offset; UINT8 *Option; - UINT8 OptionLen; + UINT16 OptionLen; BOOLEAN Flag; UINT8 CountD; UINT8 CountA; @@ -385,6 +409,36 @@ Ip6IsExtsValid ( // Fall through // case IP6_DESTINATION: + // + // See https://www.rfc-editor.org/rfc/rfc2460#section-4.2 page 23 + // + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= -+ + // | Next Header | Hdr Ext Len | = | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ = + + // | = | + // . = . + // . Options = . + // . = . + // | = | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= -+ + // + // + // Next Header 8-bit selector. Identifies the type of header + // immediately following the Destination Options + // header. Uses the same values as the IPv4 + // Protocol field [RFC-1700 et seq.]. + // + // Hdr Ext Len 8-bit unsigned integer. Length of the + // Destination Options header in 8-octet units, n= ot + // including the first 8 octets. + // + // Options Variable-length field, of length such that the + // complete Destination Options header is an + // integer multiple of 8 octets long. Contains o= ne + // or more TLV-encoded options, as described in + // section 4.2. + // + if (*NextHeader =3D=3D IP6_DESTINATION) { CountD++; } @@ -398,7 +452,7 @@ Ip6IsExtsValid ( =20 Offset++; Option =3D ExtHdrs + Offset; - OptionLen =3D (UINT8)((*Option + 1) * 8 - 2); + OptionLen =3D IP6_HDR_EXT_LEN (*Option) - sizeof (IP6_EXT_HDR); Option++; Offset++; =20 @@ -430,7 +484,7 @@ Ip6IsExtsValid ( // // Ignore the routing header and proceed to process the next hea= der. // - Offset =3D Offset + (RoutingHead->HeaderLen + 1) * 8; + Offset =3D Offset + IP6_HDR_EXT_LEN (RoutingHead->HeaderLen); =20 if (UnFragmentLen !=3D NULL) { *UnFragmentLen =3D Offset; @@ -441,7 +495,7 @@ Ip6IsExtsValid ( // to the packet's source address, pointing to the unrecognized = routing // type. // - Pointer =3D Offset + 2 + sizeof (EFI_IP6_HEADER); + Pointer =3D Offset + sizeof (IP6_EXT_HDR) + sizeof (EFI_IP6_HEAD= ER); if ((IpSb !=3D NULL) && (Packet !=3D NULL) && !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { @@ -527,7 +581,7 @@ Ip6IsExtsValid ( // // RFC2402, Payload length is specified in 32-bit words, minus "2". // - OptionLen =3D (UINT8)((*Option + 2) * 4); + OptionLen =3D ((UINT16)(*Option + 2) * 4); Offset =3D Offset + OptionLen; break; =20 --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114470): https://edk2.groups.io/g/devel/message/114470 Mute This Topic: https://groups.io/mt/103964983/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114471+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114471+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223996; cv=none; d=zohomail.com; s=zohoarc; b=iGA2aYbzMY9KuTTcu9Q7BDPmSZl+3S3Cfmw2dMZzof1kZX8SDxY/MKZJv8aM9eXnkaPGpA71y8i6DA5R3mQWbLEEtLGdlyjsT3JHVYAEwCJQTBUu7awDX4yCYw2DHVCu1rr8IhMwOhy7NRfz0NYxwW5fMJUjSlY8j6PMtzbweT4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223996; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=oMd1P502+jelSGgIIK+hs1zrHnrD3zGQf3j0O9MtJBY=; b=j4atzEy+VK/eYTptmIVvZlsImte+M4RZIADp+M+n70gQLK2x96WnjkhsmWPVLaRaQ6admo+5/GMJGGCL8aU5L5taWDkeYKd00IRo9t2wBGCX7GDtTzzaDmeePG10QggyaMwPl+yz2TMinOEl6d24JoLZAFqnG037eH5ni0HYGF8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114471+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223996635964.2988227490674; Thu, 25 Jan 2024 15:06:36 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=IKAXZPKocGBUZfZS15Cub1rhj3/IKeiiKmETADEvJ6g=; 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=1706223996; v=1; b=ppiLscp6BPnssBu29s2lQFYq4mIBBpm57ne6eHYcymahIo0i14ZqpqYOo7SxZ2qhu6x9KvfT Z8JmZqPw2qUe/gpN6NBrMUjuU0Oav8K9NPQi6DgHiQrWN3f/Aj/BvTlk+CZk3eZ07CbhVSXUmEu CfAoBPgYPVX7wz5hHy9OJpcs= X-Received: by 127.0.0.2 with SMTP id oYYnYY1788612x71iXJpocHJ; Thu, 25 Jan 2024 15:06:36 -0800 X-Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) by mx.groups.io with SMTP id smtpd.web11.785.1706223995731365733 for ; Thu, 25 Jan 2024 15:06:35 -0800 X-Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-1d780a392fdso21690075ad.3 for ; Thu, 25 Jan 2024 15:06:35 -0800 (PST) X-Gm-Message-State: oftbCPF26esz6qLSp0lWR2vUx1787277AA= X-Google-Smtp-Source: AGHT+IFpAcrgSWzGKh2gC8EsplFp9vaVH7X1zvr2wW1f/0BaHm8kM4iJMMBQ2Amd6uOtwSMNgN/D1Q== X-Received: by 2002:a17:903:1205:b0:1d8:4a55:6f21 with SMTP id l5-20020a170903120500b001d84a556f21mr468918plh.109.1706223994891; Thu, 25 Jan 2024 15:06:34 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:34 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 09/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests Date: Thu, 25 Jan 2024 13:54:51 -0800 Message-ID: <79694c13f6babf55e33e298eee6e60de44691c0f.1706219324.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223997877100037 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4537 REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4538 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 Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 10 +- .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h | 40 +++ .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 278 ++++++++++++++++++ 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 6e4de0745fb5..ba29dbabadb9 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.
# SPDX-License-Identifier: BSD-2-Clause-Patent ## [Defines] INF_VERSION =3D 0x00010017 - BASE_NAME =3D Ip6DxeUnitTest - FILE_GUID =3D 4F05D17D-D3E7-4AAE-820C-576D46D2D34A + BASE_NAME =3D Ip6DxeGoogleTest + FILE_GUID =3D AE39981C-B7FE-41A8-A9C2-F41910477CA3 VERSION_STRING =3D 1.0 MODULE_TYPE =3D HOST_APPLICATION # @@ -16,9 +16,11 @@ [Defines] # VALID_ARCHITECTURES =3D IA32 X64 AARCH64 # [Sources] + ../Ip6Option.c + Ip6OptionGoogleTest.h Ip6DxeGoogleTest.cpp Ip6OptionGoogleTest.cpp - ../Ip6Option.c + Ip6OptionGoogleTest.h =20 [Packages] MdePkg/MdePkg.dec diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h b/NetworkPk= g/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h new file mode 100644 index 000000000000..0509b6ae30d2 --- /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 +#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 fiel= ds + 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 de= tected. + + + @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__ diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/Network= Pkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp index f2cd90e1a952..29f8a4a96e4c 100644 --- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp @@ -12,6 +12,7 @@ extern "C" { #include #include "../Ip6Impl.h" #include "../Ip6Option.h" + #include "Ip6OptionGoogleTest.h" } =20 ///////////////////////////////////////////////////////////////////////// @@ -127,3 +128,280 @@ TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOpt= ionLengthShouldReturnFalse) =20 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 =3D { 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 =3D NULL; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + EXPECT_FALSE (Ip6IsOptionValid (IpSb, &Packet, NULL, 0, 0)); +} + +// Test Description +// Verify that an unknown option with a length of 0 and type of = does not cause an infinite loop +TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength0) { + NET_BUF Packet =3D { 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 =3D 0xDeadC0de; + // Don't actually use this pointer, just pass it to the function, nothin= g will be done with it + IP6_SERVICE *IpSb =3D (IP6_SERVICE *)&DeadCode; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D 23; // Unknown Option + optionHeader.Length =3D 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, si= zeof (optionHeader), 0)); +} + +// Test Description +// Verify that an unknown option with a length of 1 and type of = does not cause an infinite loop +TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength1) { + NET_BUF Packet =3D { 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 =3D 0xDeadC0de; + // Don't actually use this pointer, just pass it to the function, nothin= g will be done with it + IP6_SERVICE *IpSb =3D (IP6_SERVICE *)&DeadCode; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D 23; // Unknown Option + optionHeader.Length =3D 1; // This will cause an infinite loop if the= function is not working correctly + + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); +} + +// Test Description +// Verify that an unknown option with a length of 2 and type of = does not cause an infinite loop +TEST_F (Ip6IsOptionValidTest, VerifyIpSkipUnknownOption) { + NET_BUF Packet =3D { 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 =3D 0xDeadC0de; + // Don't actually use this pointer, just pass it to the function, nothin= g will be done with it + IP6_SERVICE *IpSb =3D (IP6_SERVICE *)&DeadCode; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D 23; // Unknown Option + optionHeader.Length =3D 2; // Valid length for an unknown option + + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); +} + +// Test Description +// Verify that Ip6OptionPad1 is valid with a length of 0 +TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPad1) { + NET_BUF Packet =3D { 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 =3D 0xDeadC0de; + // Don't actually use this pointer, just pass it to the function, nothin= g will be done with it + IP6_SERVICE *IpSb =3D (IP6_SERVICE *)&DeadCode; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D Ip6OptionPad1; + optionHeader.Length =3D 0; + + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); +} + +// Test Description +// Verify that Ip6OptionPadN doesn't overflow with various lengths +TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPadN) { + NET_BUF Packet =3D { 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 =3D 0xDeadC0de; + // Don't actually use this pointer, just pass it to the function, nothin= g will be done with it + IP6_SERVICE *IpSb =3D (IP6_SERVICE *)&DeadCode; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D Ip6OptionPadN; + optionHeader.Length =3D 0xFF; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); + + optionHeader.Length =3D 0xFE; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); + + optionHeader.Length =3D 0xFD; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); + + optionHeader.Length =3D 0xFC; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); +} + +// Test Description +// Verify an unknown option doesn't cause an infinite loop with various le= ngths +TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLengthAtt= emptOverflow) { + NET_BUF Packet =3D { 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 =3D 0xDeadC0de; + // Don't actually use this pointer, just pass it to the function, nothin= g will be done with it + IP6_SERVICE *IpSb =3D (IP6_SERVICE *)&DeadCode; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + IP6_OPTION_HEADER optionHeader; + + optionHeader.Type =3D 23; // Unknown Option + optionHeader.Length =3D 0xFF; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); + + optionHeader.Length =3D 0xFE; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); + + optionHeader.Length =3D 0xFD; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); + + optionHeader.Length =3D 0xFC; + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, si= zeof (optionHeader), 0)); +} + +// Test Description +// Verify that the function supports multiple options +TEST_F (Ip6IsOptionValidTest, MultiOptionSupport) { + UINT16 HdrLen; + NET_BUF Packet =3D { 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 =3D 0xDeadC0de; + // Don't actually use this pointer, just pass it to the function, nothin= g will be done with it + IP6_SERVICE *IpSb =3D (IP6_SERVICE *)&DeadCode; + + EFI_IPv6_ADDRESS SourceAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IPv6_ADDRESS DestinationAddress =3D { 0x20, 0x01, 0x0d, 0xb8, 0x00,= 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 }; + EFI_IP6_HEADER Ip6Header =3D { 0 }; + + Ip6Header.SourceAddress =3D SourceAddress; + Ip6Header.DestinationAddress =3D DestinationAddress; + Packet.Ip.Ip6 =3D &Ip6Header; + + UINT8 ExtHdr[1024] =3D { 0 }; + UINT8 *Cursor =3D ExtHdr; + IP6_OPTION_HEADER *Option =3D (IP6_OPTION_HEADER *)ExtHdr; + + // Let's start chaining options + + Option->Type =3D 23; // Unknown Option + Option->Length =3D 0xFC; + + Cursor +=3D sizeof (IP6_OPTION_HEADER) + 0xFC; + + Option =3D (IP6_OPTION_HEADER *)Cursor; + Option->Type =3D Ip6OptionPad1; + + Cursor +=3D sizeof (1); + + // Type and length aren't processed, instead it just moves the pointer f= orward by 4 bytes + Option =3D (IP6_OPTION_HEADER *)Cursor; + Option->Type =3D Ip6OptionRouterAlert; + Option->Length =3D 4; + + Cursor +=3D sizeof (IP6_OPTION_HEADER) + 4; + + Option =3D (IP6_OPTION_HEADER *)Cursor; + Option->Type =3D Ip6OptionPadN; + Option->Length =3D 0xFC; + + Cursor +=3D sizeof (IP6_OPTION_HEADER) + 0xFC; + + Option =3D (IP6_OPTION_HEADER *)Cursor; + Option->Type =3D Ip6OptionRouterAlert; + Option->Length =3D 4; + + Cursor +=3D sizeof (IP6_OPTION_HEADER) + 4; + + // Total 524 + + HdrLen =3D (UINT16)(Cursor - ExtHdr); + + EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, ExtHdr, HdrLen, 0)); +} --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114471): https://edk2.groups.io/g/devel/message/114471 Mute This Topic: https://groups.io/mt/103964985/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114472+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114472+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223997; cv=none; d=zohomail.com; s=zohoarc; b=jEfhmAZr3ihBKBczqL8MQw0JzNtj9vIJ1va2PAgtsy5FFL72VAzoYag7KE+Vjll+BmaqpVrV/jJAiQNYc7zsUW08gBK9fx+9xuQeGg4sLd9Dl6lZNfARqiXpn1ne61cDsVIagLN2R8gkI/JOUybyn2x1TTKR7C1IQnPf9sNvs9k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223997; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=KYl2wIxMXi33G0O/QBzKMTlDRYL9+3WTFVOBzzXVQNo=; b=RofEMBUJJI20gHcgTRAD1Z6G75faMkaAIIjOjqcCJkHcElyA1OPGLsr167AZUZPyU9DSuIvH8kO3hexruHqgw9iedAkBRxkkg9MRNtPE12WjbzCb3f2Pl9gqq3yJrztpuNAi2WGTndLos0vySjOP0QUecn2yOXE6e/YqTlKe0s8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114472+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223997310408.4978646905157; Thu, 25 Jan 2024 15:06:37 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=kvub1716bQhICORSbRBqdPO0Oj0Wp8XivH8hBqulNVE=; 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=1706223996; v=1; b=scnFmj1bt+7rtpVBVlyC4JG6bHg6udm68i+3g2CSPnnXPwiI6Oe3R2RXAyorzu1oyYocPjD9 kCl4Gt4RdtTn2qmMzgYtrylNHlM2EdtUbgDH51T6wrTS1LGMS2X2/peDN6az9x2VfMtlAnJpXML gm2oHnNPMRd+Nde6RGjYRXsM= X-Received: by 127.0.0.2 with SMTP id aAbCYY1788612x9991NGwJrX; Thu, 25 Jan 2024 15:06:36 -0800 X-Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) by mx.groups.io with SMTP id smtpd.web11.786.1706223996373798365 for ; Thu, 25 Jan 2024 15:06:36 -0800 X-Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-1d71cb97937so47980985ad.3 for ; Thu, 25 Jan 2024 15:06:36 -0800 (PST) X-Gm-Message-State: B05Ur2RWwSzPYeX4e2imtIRdx1787277AA= X-Google-Smtp-Source: AGHT+IHP1IaE4mLqHVeJfC3WyOCkK9zTohFQGfXbOoq+gQIrUfiTBPXIE+8oVElNM7cJstUml7PUuw== X-Received: by 2002:a17:902:7688:b0:1d4:4621:fe8c with SMTP id m8-20020a170902768800b001d44621fe8cmr386937pll.64.1706223995664; Thu, 25 Jan 2024 15:06:35 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:35 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 10/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch Date: Thu, 25 Jan 2024 13:54:52 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223997853100035 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4539 Bug Details: PixieFail Bug #6 CVE-2023-45234 CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message Change Overview: Introduces a function to cache the Dns Server and perform sanitizing on the incoming DnsServerLen to ensure that the length is valid > + EFI_STATUS > + PxeBcCacheDnsServerAddresses ( > + IN PXEBC_PRIVATE_DATA *Private, > + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 > + ) Additional code cleanup Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 71 +++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe= /PxeBcDhcp6.c index 425e0cf8061d..2b2d372889a3 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c @@ -3,6 +3,7 @@ =20 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -1312,6 +1313,65 @@ PxeBcSelectDhcp6Offer ( } } =20 +/** + Cache the DHCPv6 DNS Server addresses + + @param[in] Private The pointer to PXEBC_PRIVATE_DATA. + @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE. + + @retval EFI_SUCCESS Cache the DHCPv6 DNS Server address suc= cessfully. + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_DEVICE_ERROR The DNS Server Address Length provided = by a untrusted + option is not a multiple of 16 bytes (s= izeof (EFI_IPv6_ADDRESS)). +**/ +EFI_STATUS +PxeBcCacheDnsServerAddresses ( + IN PXEBC_PRIVATE_DATA *Private, + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 + ) +{ + UINT16 DnsServerLen; + + DnsServerLen =3D NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpL= en); + // + // Make sure that the number is nonzero + // + if (DnsServerLen =3D=3D 0) { + return EFI_DEVICE_ERROR; + } + + // + // Make sure the DnsServerlen is a multiple of EFI_IPv6_ADDRESS (16) + // + if (DnsServerLen % sizeof (EFI_IPv6_ADDRESS) !=3D 0) { + return EFI_DEVICE_ERROR; + } + + // + // This code is currently written to only support a single DNS Server in= stead + // of multiple such as is spec defined (RFC3646, Section 3). The proper = behavior + // would be to allocate the full space requested, CopyMem all of the dat= a, + // and then add a DnsServerCount field to Private and update additional = code + // that depends on this. + // + // To support multiple DNS servers the `AllocationSize` would need to be= changed to DnsServerLen + // + // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=3D1= 886 + // + Private->DnsServer =3D AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS)); + if (Private->DnsServer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Intentionally only copy over the first server address. + // To support multiple DNS servers, the `Length` would need to be change= d to DnsServerLen + // + CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]= ->Data, sizeof (EFI_IPv6_ADDRESS)); + + return EFI_SUCCESS; +} + /** Handle the DHCPv6 offer packet. =20 @@ -1335,6 +1395,7 @@ PxeBcHandleDhcp6Offer ( UINT32 SelectIndex; UINT32 Index; =20 + ASSERT (Private !=3D NULL); ASSERT (Private->SelectIndex > 0); SelectIndex =3D (UINT32)(Private->SelectIndex - 1); ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM); @@ -1342,15 +1403,13 @@ PxeBcHandleDhcp6Offer ( Status =3D EFI_SUCCESS; =20 // - // First try to cache DNS server address if DHCP6 offer provides. + // First try to cache DNS server addresses if DHCP6 offer provides. // if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] !=3D NULL) { - Private->DnsServer =3D AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_= DHCP6_IDX_DNS_SERVER]->OpLen)); - if (Private->DnsServer =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; + Status =3D PxeBcCacheDnsServerAddresses (Private, Cache6); + if (EFI_ERROR (Status)) { + return Status; } - - CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVE= R]->Data, sizeof (EFI_IPv6_ADDRESS)); } =20 if (Cache6->OfferType =3D=3D PxeOfferTypeDhcpBinl) { --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114472): https://edk2.groups.io/g/devel/message/114472 Mute This Topic: https://groups.io/mt/103964986/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114473+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114473+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223998; cv=none; d=zohomail.com; s=zohoarc; b=nh0pgDJrw0WR2IbbhccFG4TYULYap7Ab0o1y3M1R5+f35GQ6yKAlvOZsDiv6OQbY9wTnbBl9ALJKsbPR5evXnz4mABOfixVXp6zUiIQS0r9upcqJxx3J+EagFcXPr3vHRJyhYHMLONwuvIaj2NzC9Qawrjo3mYfhU5lJh1UoMHM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223998; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=y+LmWtuww7rkzXW02ypf+ZOvzqI/L9hzEpaFf3kOFs8=; b=Zknq+fF9ml7tT9vWaxEp+YNxIvqus00JdrkeMA9W4SfZ0zXxt3JwaBJEygxNLDIplYpzsNwpJaDPGif0TU1c6FfvFnAE9EZp+GeRZYKwMbVnsdpIpWmByQDWL2D7nIH8/TESm0ubUjurnbdEeMssMtuV0K1B3l0pXT0iZBMQuwI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114473+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223998326319.14388045920384; Thu, 25 Jan 2024 15:06:38 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=vm7PI4vmVhlkW3ETMbQn9lFAGgrGgwxckGQw4/g6T8Q=; 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=1706223998; v=1; b=PSiALhsKNwyeFmG11MkYejO1Dhri/rO4ym0SzCG4QzoR5WHGJsH+H0PGgu2pP+N3fUls/X1i LbibyVUjTGr2R/H+wfVGlHAIVb9AyAVVXp+Ol6GN9w7320Ocldue0f2sfTFGW2IKvYKhXi3MEHv W0Yv/gJ8mFXtyPeLMLwUQ8H8= X-Received: by 127.0.0.2 with SMTP id E31sYY1788612x85ayBs1jac; Thu, 25 Jan 2024 15:06:38 -0800 X-Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) by mx.groups.io with SMTP id smtpd.web10.799.1706223997401490863 for ; Thu, 25 Jan 2024 15:06:37 -0800 X-Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-1d70b0e521eso53148745ad.1 for ; Thu, 25 Jan 2024 15:06:37 -0800 (PST) X-Gm-Message-State: KWv7VDHNZHkmT84DJVL2gOiWx1787277AA= X-Google-Smtp-Source: AGHT+IF9Fm3sSdpSUAquJicWj/lB+ZhlsOS7E2IlrvUsQ7uCVkMTD2ulAeG7EWVMpvjQj9fzopz+FA== X-Received: by 2002:a17:902:ea08:b0:1d6:fbab:d40b with SMTP id s8-20020a170902ea0800b001d6fbabd40bmr426026plg.85.1706223996451; Thu, 25 Jan 2024 15:06:36 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:36 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 11/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Unit Tests Date: Thu, 25 Jan 2024 13:54:53 -0800 Message-ID: <87dd1ac4223e2dc4e7f059db206b2954a0340234.1706219324.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223999896100050 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4539 Unit tests to that the bug.. Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message ..has been patched This contains tests for the following functions: PxeBcHandleDhcp6Offer PxeBcCacheDnsServerAddresses Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + .../GoogleTest/UefiPxeBcDxeGoogleTest.inf | 48 +++ .../GoogleTest/PxeBcDhcp6GoogleTest.h | 50 +++ .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 300 ++++++++++++++++++ .../GoogleTest/UefiPxeBcDxeGoogleTest.cpp | 19 ++ 5 files changed, 418 insertions(+) create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTe= st.inf create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest= .h create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest= .cpp create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTe= st.cpp diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/Netwo= rkPkgHostTest.dsc index 7fa7b0f9d5be..a0273c431025 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -27,6 +27,7 @@ [Components] # NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf + NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf =20 # Despite these library classes being listed in [LibraryClasses] below, th= ey are not needed for the host-based unit tests. [LibraryClasses] diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf = b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf new file mode 100644 index 000000000000..301dcdf61109 --- /dev/null +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf @@ -0,0 +1,48 @@ +## @file +# Unit test suite for the UefiPxeBcDxe using Google Test +# +# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## +[Defines] +INF_VERSION =3D 0x00010005 +BASE_NAME =3D UefiPxeBcDxeGoogleTest +FILE_GUID =3D 77D45C64-EC1E-4174-887B-886E89FD1EDF +MODULE_TYPE =3D HOST_APPLICATION +VERSION_STRING =3D 1.0 + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + UefiPxeBcDxeGoogleTest.cpp + PxeBcDhcp6GoogleTest.cpp + PxeBcDhcp6GoogleTest.h + ../PxeBcDhcp6.c + ../PxeBcSupport.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + NetworkPkg/NetworkPkg.dec + +[LibraryClasses] + GoogleTestLib + DebugLib + NetLib + PcdLib + +[Protocols] + gEfiDhcp6ServiceBindingProtocolGuid + gEfiDns6ServiceBindingProtocolGuid + gEfiDns6ProtocolGuid + +[Pcd] + gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType + +[Guids] + gZeroGuid diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/Ne= tworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h new file mode 100644 index 000000000000..b17c314791c8 --- /dev/null +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h @@ -0,0 +1,50 @@ +/** @file + This file exposes the internal interfaces which may be unit tested + for the PxeBcDhcp6Dxe driver. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef PXE_BC_DHCP6_GOOGLE_TEST_H_ +#define PXE_BC_DHCP6_GOOGLE_TEST_H_ + +// +// Minimal includes needed to compile +// +#include +#include "../PxeBcImpl.h" + +/** + Handle the DHCPv6 offer packet. + + @param[in] Private The pointer to PXEBC_PRIVATE_DATA. + + @retval EFI_SUCCESS Handled the DHCPv6 offer packet succes= sfully. + @retval EFI_NO_RESPONSE No response to the following request p= acket. + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_BUFFER_TOO_SMALL Can't cache the offer pacet. + +**/ +EFI_STATUS +PxeBcHandleDhcp6Offer ( + IN PXEBC_PRIVATE_DATA *Private + ); + +/** + Cache the DHCPv6 Server address + + @param[in] Private The pointer to PXEBC_PRIVATE_DATA. + @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE. + + @retval EFI_SUCCESS Cache the DHCPv6 Server address success= fully. + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_DEVICE_ERROR Failed to cache the DHCPv6 Server addre= ss. +**/ +EFI_STATUS +PxeBcCacheDnsServerAddresses ( + IN PXEBC_PRIVATE_DATA *Private, + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 + ); + +#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_ diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/= NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp new file mode 100644 index 000000000000..8260eeee50dc --- /dev/null +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp @@ -0,0 +1,300 @@ +/** @file + Host based unit test for PxeBcDhcp6.c. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include + +extern "C" { + #include + #include + #include + #include "../PxeBcImpl.h" + #include "../PxeBcDhcp6.h" + #include "PxeBcDhcp6GoogleTest.h" +} + +//////////////////////////////////////////////////////////////////////////= ///// +// Definitions +//////////////////////////////////////////////////////////////////////////= ///// + +#define PACKET_SIZE (1500) + +typedef struct { + UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g.= , 0x03) + UINT16 OptionLen; // The length of the option (e.g., 16 bytes) + UINT8 ServerId[16]; // The 16-byte DHCPv6 Server Identifier +} DHCP6_OPTION_SERVER_ID; + +//////////////////////////////////////////////////////////////////////////= ///// +/// Symbol Definitions +//////////////////////////////////////////////////////////////////////////= ///// + +EFI_STATUS +MockUdpWrite ( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 OpFlags, + IN EFI_IP_ADDRESS *DestIp, + IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, + IN EFI_IP_ADDRESS *GatewayIp OPTIONAL, + IN EFI_IP_ADDRESS *SrcIp OPTIONAL, + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, + IN UINTN *HeaderSize OPTIONAL, + IN VOID *HeaderPtr OPTIONAL, + IN UINTN *BufferSize, + IN VOID *BufferPtr + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +MockUdpRead ( + IN EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 OpFlags, + IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL, + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL, + IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL, + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL, + IN UINTN *HeaderSize OPTIONAL, + IN VOID *HeaderPtr OPTIONAL, + IN OUT UINTN *BufferSize, + IN VOID *BufferPtr + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +MockConfigure ( + IN EFI_UDP6_PROTOCOL *This, + IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +// Needed by PxeBcSupport +EFI_STATUS +EFIAPI +QueueDpc ( + IN EFI_TPL DpcTpl, + IN EFI_DPC_PROCEDURE DpcProcedure, + IN VOID *DpcContext OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////////= ///// +// PxeBcHandleDhcp6OfferTest Tests +//////////////////////////////////////////////////////////////////////////= ///// + +class PxeBcHandleDhcp6OfferTest : public ::testing::Test { +public: + PXEBC_PRIVATE_DATA Private =3D { 0 }; + EFI_UDP6_PROTOCOL Udp6Read; + EFI_PXE_BASE_CODE_MODE Mode =3D { 0 }; + +protected: + // Add any setup code if needed + virtual void + SetUp ( + ) + { + Private.Dhcp6Request =3D (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_= SIZE); + + // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL + // The function under test really only needs the following: + // UdpWrite + // UdpRead + + Private.PxeBc.UdpWrite =3D (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; + Private.PxeBc.UdpRead =3D (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; + + // Need to setup EFI_UDP6_PROTOCOL + // The function under test really only needs the following: + // Configure + + Udp6Read.Configure =3D (EFI_UDP6_CONFIGURE)MockConfigure; + Private.Udp6Read =3D &Udp6Read; + + // Need to setup the EFI_PXE_BASE_CODE_MODE + Private.PxeBc.Mode =3D &Mode; + + // for this test it doesn't really matter what the Dhcpv6 ack is set to + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + if (Private.Dhcp6Request !=3D NULL) { + FreePool (Private.Dhcp6Request); + } + + // Clean up any resources or variables + } +}; + +// Note: +// Testing PxeBcHandleDhcp6Offer() is difficult because it depends on a +// properly setup Private structure. Attempting to properly test this func= tion +// without a signficant refactor is a fools errand. Instead, we will test +// that we can prevent an overflow in the function. +TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) { + PXEBC_DHCP6_PACKET_CACHE *Cache6 =3D NULL; + EFI_DHCP6_PACKET_OPTION Option =3D { 0 }; + + Private.SelectIndex =3D 1; // SelectIndex is 1-based + Cache6 =3D &Private.OfferBuffer[Private.SelectIndex - 1].Dh= cp6; + + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] =3D &Option; + // Setup the DHCPv6 offer packet + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode =3D DHCP6_OPT_SERVER= _ID; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen =3D NTOHS (1337); + + ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private))= , EFI_DEVICE_ERROR); +} + +class PxeBcCacheDnsServerAddressesTest : public ::testing::Test { +public: + PXEBC_PRIVATE_DATA Private =3D { 0 }; + +protected: + // Add any setup code if needed + virtual void + SetUp ( + ) + { + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + } +}; + +// Test Description +// Test that we cache the DNS server address from the DHCPv6 offer packet +TEST_F (PxeBcCacheDnsServerAddressesTest, BasicUsageTest) { + UINT8 SearchPattern[16] =3D { 0xDE, 0xAD, 0xBE, 0xEF= , 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF }; + EFI_DHCP6_PACKET_OPTION *Option; + PXEBC_DHCP6_PACKET_CACHE *Cache6 =3D NULL; + + Option =3D (EFI_DHCP6_PACKET_OPTION *)AllocateZeroPool (sizeof (EFI_DHCP= 6_PACKET_OPTION) + sizeof (SearchPattern)); + ASSERT_NE (Option, nullptr); + + Option->OpCode =3D DHCP6_OPT_SERVER_ID; + Option->OpLen =3D NTOHS (sizeof (SearchPattern)); + CopyMem (Option->Data, SearchPattern, sizeof (SearchPattern)); + + Private.SelectIndex =3D 1; // SelectIndex is 1-b= ased + Cache6 =3D &Private.OfferBuffer[Pri= vate.SelectIndex - 1].Dhcp6; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] =3D Option; + + Private.DnsServer =3D nullptr; + + ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesT= est::Private), Cache6), EFI_SUCCESS); + ASSERT_NE (Private.DnsServer, nullptr); + ASSERT_EQ (CompareMem (Private.DnsServer, SearchPattern, sizeof (SearchP= attern)), 0); + + if (Private.DnsServer) { + FreePool (Private.DnsServer); + } + + if (Option) { + FreePool (Option); + } +} +// Test Description +// Test that we can prevent an overflow in the function +TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptOverflowTest) { + EFI_DHCP6_PACKET_OPTION Option =3D { 0 }; + PXEBC_DHCP6_PACKET_CACHE *Cache6 =3D NULL; + + Private.SelectIndex =3D 1; // SelectIndex is 1-b= ased + Cache6 =3D &Private.OfferBuffer[Pri= vate.SelectIndex - 1].Dhcp6; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] =3D &Option; + // Setup the DHCPv6 offer packet + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode =3D DHCP6_OPT_SERVER= _ID; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen =3D NTOHS (1337); + + Private.DnsServer =3D NULL; + + ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesT= est::Private), Cache6), EFI_DEVICE_ERROR); + ASSERT_EQ (Private.DnsServer, nullptr); + + if (Private.DnsServer) { + FreePool (Private.DnsServer); + } +} + +// Test Description +// Test that we can prevent an underflow in the function +TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) { + EFI_DHCP6_PACKET_OPTION Option =3D { 0 }; + PXEBC_DHCP6_PACKET_CACHE *Cache6 =3D NULL; + + Private.SelectIndex =3D 1; // SelectIndex is 1-b= ased + Cache6 =3D &Private.OfferBuffer[Pri= vate.SelectIndex - 1].Dhcp6; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] =3D &Option; + // Setup the DHCPv6 offer packet + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode =3D DHCP6_OPT_SERVER= _ID; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen =3D NTOHS (2); + + Private.DnsServer =3D NULL; + + ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesT= est::Private), Cache6), EFI_DEVICE_ERROR); + ASSERT_EQ (Private.DnsServer, nullptr); + + if (Private.DnsServer) { + FreePool (Private.DnsServer); + } +} + +// Test Description +// Test that we can handle recursive dns (multiple dns entries) +TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) { + EFI_DHCP6_PACKET_OPTION Option =3D { 0 }; + PXEBC_DHCP6_PACKET_CACHE *Cache6 =3D NULL; + + Private.SelectIndex =3D 1; // SelectIndex is 1-b= ased + Cache6 =3D &Private.OfferBuffer[Pri= vate.SelectIndex - 1].Dhcp6; + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] =3D &Option; + // Setup the DHCPv6 offer packet + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode =3D DHCP6_OPT_SERVER= _ID; + + EFI_IPv6_ADDRESS addresses[2] =3D { + // 2001:db8:85a3::8a2e:370:7334 + { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x= 2e, 0x03, 0x70, 0x73, 0x34 }, + // fe80::d478:91c3:ecd7:4ff9 + { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0x= c3, 0xec, 0xd7, 0x4f, 0xf9 } + }; + + CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, = sizeof (addresses)); + + Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen =3D NTOHS (sizeof (ad= dresses)); + + Private.DnsServer =3D NULL; + + ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesT= est::Private), Cache6), EFI_SUCCESS); + + ASSERT_NE (Private.DnsServer, nullptr); + + // + // This is expected to fail until DnsServer supports multiple DNS servers + // + // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=3D1= 886 + // + // Disabling: + // ASSERT_EQ (CompareMem(Private.DnsServer, &addresses, sizeof(addresses= )), 0); + + if (Private.DnsServer) { + FreePool (Private.DnsServer); + } +} diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp = b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp new file mode 100644 index 000000000000..cc4fdf525b62 --- /dev/null +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp @@ -0,0 +1,19 @@ +/** @file + Acts as the main entry point for the tests for the UefiPxeBcDxe module. + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include + +//////////////////////////////////////////////////////////////////////////= ////// +// Run the tests +//////////////////////////////////////////////////////////////////////////= ////// +int +main ( + int argc, + char *argv[] + ) +{ + testing::InitGoogleTest (&argc, argv); + return RUN_ALL_TESTS (); +} --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114473): https://edk2.groups.io/g/devel/message/114473 Mute This Topic: https://groups.io/mt/103964987/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114474+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114474+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223998; cv=none; d=zohomail.com; s=zohoarc; b=h1sVG/RJHZYEUe/rObxUXFQ+KNQOfltyX/LT4ZkiaU9UBa1Mz4V+bFsbMeDvUngTkLfTviKBstdJpjAl9VKuwNyzKsgRiGP2Xjjo7+x5/Y2mc/Qkpob9Jbg/sINTzeLgAT53MWEkWAniCrattFGx1ancpJTdZPgQTWOz0nESM6g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223998; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=e6CCxBHEHJQeZP3a31MObxkrQvRXand3JMf9GA096/Q=; b=Sz61kIDZM6oJ6b016Za0msYB4wpcw5JyAuZJ8HorKzdc92tI9PxgCv8fNmIkH40BcF2r/fWgThVEvGX85sHRS9FeB1V0Dc+wUiEpFeI4g+mWNQqvMWUVH363GyTSL6uf1IcHpQROnapB//bigctBXa3+mHwDqt4Dd4hrRyHOxgU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114474+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223998663972.4677059041492; Thu, 25 Jan 2024 15:06:38 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=vKmHyO84ID3BsAz5GAOIwM/iYsZy4Y8gYcrFeQ9J1dg=; 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=1706223998; v=1; b=k/DIMO9JBT4eSbr3h6DrKkRzHieTHGFLgbzX8ds1neYWLNaZTrOUZWm6PQHMgnvGgGAfCbVp hkBi6hfeHuxOOHnTUgMDMlJFfXOFCiOQbjgZxi56TL7cuu6ecDkVJo02hMXHs5Vx5Y+YWwDoNzJ khg2FQDJz2MIXOoQXMQInGho= X-Received: by 127.0.0.2 with SMTP id umYeYY1788612x4G7KHMFW3i; Thu, 25 Jan 2024 15:06:38 -0800 X-Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) by mx.groups.io with SMTP id smtpd.web11.788.1706223997749321651 for ; Thu, 25 Jan 2024 15:06:37 -0800 X-Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-1d75ea3a9b6so40725515ad.2 for ; Thu, 25 Jan 2024 15:06:37 -0800 (PST) X-Gm-Message-State: Lt9hp2FS1i2USRermm3yZysgx1787277AA= X-Google-Smtp-Source: AGHT+IFugyihaW5RSXBBuG8L2nF+Htb57GTLysySIP4PylNPA89nvNd1kynpmJdo5qITx0jjvSWYPw== X-Received: by 2002:a17:902:b418:b0:1d4:5a7d:21ce with SMTP id x24-20020a170902b41800b001d45a7d21cemr418645plr.40.1706223997119; Thu, 25 Jan 2024 15:06:37 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:36 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Michael D Kinney , Liming Gao , Zhiguang Liu Subject: [edk2-devel] [PATCH v2 12/15] MdePkg: Test: Add gRT_GetTime Google Test Mock Date: Thu, 25 Jan 2024 13:54:54 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223999826100047 Content-Type: text/plain; charset="utf-8" This adds support for GetTime Google Test Mock Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Signed-off-by: Doug Flick [MSFT] Reviewed-by: Michael D Kinney --- .../GoogleTest/Library/MockUefiRuntimeServicesTableLib.h | 7 +++++++ .../MockUefiRuntimeServicesTableLib.cpp | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeSer= vicesTableLib.h b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRunti= meServicesTableLib.h index 241abc55c079..bcc902cb93c2 100644 --- a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTa= bleLib.h +++ b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTa= bleLib.h @@ -37,6 +37,13 @@ struct MockUefiRuntimeServicesTableLib { IN UINTN DataSize, IN VOID *Data) ); + + MOCK_FUNCTION_DECLARATION ( + EFI_STATUS, + gRT_GetTime, + (OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL) + ); }; =20 #endif diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTab= leLib/MockUefiRuntimeServicesTableLib.cpp b/MdePkg/Test/Mock/Library/Google= Test/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp index 14296b0ccb88..8d2afd5dd63a 100644 --- a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/M= ockUefiRuntimeServicesTableLib.cpp +++ b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/M= ockUefiRuntimeServicesTableLib.cpp @@ -10,11 +10,12 @@ MOCK_INTERFACE_DEFINITION (MockUefiRuntimeServicesTable= Lib); =20 MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_GetVariable= , 5, EFIAPI); MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_SetVariable= , 5, EFIAPI); +MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_GetTime, 2,= EFIAPI); =20 static EFI_RUNTIME_SERVICES localRt =3D { - { 0 }, // EFI_TABLE_HEADER + { 0 }, // EFI_TABLE_HEADER =20 - NULL, // EFI_GET_TIME + gRT_GetTime, // EFI_GET_TIME NULL, // EFI_SET_TIME NULL, // EFI_GET_WAKEUP_TIME NULL, // EFI_SET_WAKEUP_TIME --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114474): https://edk2.groups.io/g/devel/message/114474 Mute This Topic: https://groups.io/mt/103964988/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114475+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114475+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706223999; cv=none; d=zohomail.com; s=zohoarc; b=R9fC7ShNHgoXWYcsnGgbiFs/G3BjmPZ8kSYtAcDwCXfLmJLEE7QEmMmgMsLeTnOTilv/qf4Iczx1jZw2fHOb8LolNCtCpitaWadp9u9c4wsTHmbpGMstP2NCLjpJv3h8HW3Lm7Sl9ojC9Zvgxorti7VjO/NdTS0Vx2xvzpjKZNM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706223999; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=FuUNwzzx/0i6WNbSu+MnXPxzxeF6Ion8qcnT00pHsYI=; b=iSNCOd2Of9MoJkHz6tP9aYqNMy2+oQdcp4idULWUn/paYF8vvXZb1YyutJXLQE9sg2d23pg41xxCpc9v47wYeeK4qj7KnMHeBHpPtGeT2oymCvYw1DHa629zPNXl8GsikyERCWFew5Mu/tlXbSz20I2iDtrB6IBdzhqN3ZLVtvc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114475+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706223999326362.45181124899125; Thu, 25 Jan 2024 15:06:39 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=uJ78W4dqEFwAEIfRoQX6S2Nde0Nb0WjpAaiBM6dzqao=; 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=1706223999; v=1; b=LpASl4QJdiEh7bP6PlThXuBkintKc+bmHHz8CeKgmcYvhexvx04KumG8XPMWkX+BMDip0MOG KgLg43p5DPIyMzdGq5N3vQQ6adOM4mW40w5DUCpUu53FImeZNxb6ptZzLM1enT16MmXlwXFZf1m f02S1X/GxnM/lZz1ZquEwwv4= X-Received: by 127.0.0.2 with SMTP id 8ArdYY1788612xUVDP5Ylilh; Thu, 25 Jan 2024 15:06:39 -0800 X-Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by mx.groups.io with SMTP id smtpd.web11.791.1706223998545916722 for ; Thu, 25 Jan 2024 15:06:38 -0800 X-Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-1d73066880eso49439855ad.3 for ; Thu, 25 Jan 2024 15:06:38 -0800 (PST) X-Gm-Message-State: rDcqnhRNI5pnzh3wLMEXzOk8x1787277AA= X-Google-Smtp-Source: AGHT+IHXT0Z2ylqWpXUTSI80Ih1jWyMD08TJTIwlxFpZXvq9CTrEGXNmXv3Qd2EFnmk12VNmr50x1g== X-Received: by 2002:a17:903:24d:b0:1d4:e0e:fa1b with SMTP id j13-20020a170903024d00b001d40e0efa1bmr571117plh.57.1706223997744; Thu, 25 Jan 2024 15:06:37 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:37 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 13/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch Date: Thu, 25 Jan 2024 13:54:55 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706223999875100048 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4540 Bug Details: PixieFail Bug #7 CVE-2023-45235 CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message Change Overview: Performs two checks 1. Checks that the length of the duid is accurate > + // > + // Check that the minimum and maximum requirements are met > + // > + if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ON_ERROR; > + } 2. Ensures that the amount of data written to the buffer is tracked and never exceeds that > + // > + // Check that the option length is valid. > + // > + if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_ERROR; > + } Additional code clean up and fix for memory leak in case Option was NULL Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 ++++++ NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 77 ++++++++++++++++++++++------ 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe= /PxeBcDhcp6.h index c86f6d391b80..6357d27faefd 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h @@ -34,6 +34,23 @@ #define PXEBC_ADDR_START_DELIMITER '[' #define PXEBC_ADDR_END_DELIMITER ']' =20 +// +// A DUID consists of a 2-octet type code represented in network byte +// order, followed by a variable number of octets that make up the +// actual identifier. The length of the DUID (not including the type +// code) is at least 1 octet and at most 128 octets. +// +#define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1) +#define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128) + +// +// This define represents the combineds code and length field from +// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1 +// +#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \ + (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \ + sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen)) + #define GET_NEXT_DHCP6_OPTION(Opt) \ (EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \ sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1) diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe= /PxeBcDhcp6.c index 2b2d372889a3..7fd1281c1184 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c @@ -887,6 +887,7 @@ PxeBcRequestBootService ( EFI_STATUS Status; EFI_DHCP6_PACKET *IndexOffer; UINT8 *Option; + UINTN DiscoverLenNeeded; =20 PxeBc =3D &Private->PxeBc; Request =3D Private->Dhcp6Request; @@ -899,7 +900,8 @@ PxeBcRequestBootService ( return EFI_DEVICE_ERROR; } =20 - Discover =3D AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); + DiscoverLenNeeded =3D sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); + Discover =3D AllocateZeroPool (DiscoverLenNeeded); if (Discover =3D=3D NULL) { return EFI_OUT_OF_RESOURCES; } @@ -924,16 +926,34 @@ PxeBcRequestBootService ( DHCP6_OPT_SERVER_ID ); if (Option =3D=3D NULL) { - return EFI_NOT_FOUND; + Status =3D EFI_NOT_FOUND; + goto ON_ERROR; } =20 // // Add Server ID Option. // OpLen =3D NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen); - CopyMem (DiscoverOpt, Option, OpLen + 4); - DiscoverOpt +=3D (OpLen + 4); - DiscoverLen +=3D (OpLen + 4); + + // + // Check that the minimum and maximum requirements are met + // + if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUI= D)) { + Status =3D EFI_INVALID_PARAMETER; + goto ON_ERROR; + } + + // + // Check that the option length is valid. + // + if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > = DiscoverLenNeeded) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; + } + + CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_= AND_LEN); + DiscoverOpt +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + DiscoverLen +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); } =20 while (RequestLen < Request->Length) { @@ -944,16 +964,24 @@ PxeBcRequestBootService ( (OpCode !=3D DHCP6_OPT_SERVER_ID) ) { + // + // Check that the option length is valid. + // + if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > = DiscoverLenNeeded) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; + } + // // Copy all the options except IA option and Server ID // - CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); - DiscoverOpt +=3D (OpLen + 4); - DiscoverLen +=3D (OpLen + 4); + CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT= _CODE_AND_LEN); + DiscoverOpt +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + DiscoverLen +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); } =20 - RequestOpt +=3D (OpLen + 4); - RequestLen +=3D (OpLen + 4); + RequestOpt +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + RequestLen +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); } =20 // @@ -2154,6 +2182,7 @@ PxeBcDhcp6Discover ( UINT16 OpLen; UINT32 Xid; EFI_STATUS Status; + UINTN DiscoverLenNeeded; =20 PxeBc =3D &Private->PxeBc; Mode =3D PxeBc->Mode; @@ -2169,7 +2198,8 @@ PxeBcDhcp6Discover ( return EFI_DEVICE_ERROR; } =20 - Discover =3D AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET)); + DiscoverLenNeeded =3D sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET); + Discover =3D AllocateZeroPool (DiscoverLenNeeded); if (Discover =3D=3D NULL) { return EFI_OUT_OF_RESOURCES; } @@ -2185,22 +2215,37 @@ PxeBcDhcp6Discover ( DiscoverLen =3D sizeof (EFI_DHCP6_HEADER); RequestLen =3D DiscoverLen; =20 + // + // The request packet is generated by the UEFI network stack. In the DHC= P4 DORA and DHCP6 SARR sequence, + // the first (discover in DHCP4 and solicit in DHCP6) and third (request= in both DHCP4 and DHCP6) are + // generated by the DHCP client (the UEFI network stack in this case). B= y the time this function executes, + // the DHCP sequence already has been executed once (see UEFI Specificat= ion Figures 24.2 and 24.3), with + // Private->Dhcp6Request being a cached copy of the DHCP6 request packet= that UEFI network stack previously + // generated and sent. + // + // Therefore while this code looks like it could overflow, in practice i= t's not possible. + // while (RequestLen < Request->Length) { OpCode =3D NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpCode); OpLen =3D NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpLen); if ((OpCode !=3D EFI_DHCP6_IA_TYPE_NA) && (OpCode !=3D EFI_DHCP6_IA_TYPE_TA)) { + if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > = DiscoverLenNeeded) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ON_ERROR; + } + // // Copy all the options except IA option. // - CopyMem (DiscoverOpt, RequestOpt, OpLen + 4); - DiscoverOpt +=3D (OpLen + 4); - DiscoverLen +=3D (OpLen + 4); + CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT= _CODE_AND_LEN); + DiscoverOpt +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + DiscoverLen +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); } =20 - RequestOpt +=3D (OpLen + 4); - RequestLen +=3D (OpLen + 4); + RequestOpt +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); + RequestLen +=3D (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN); } =20 Status =3D PxeBc->UdpWrite ( --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114475): https://edk2.groups.io/g/devel/message/114475 Mute This Topic: https://groups.io/mt/103964991/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114476+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114476+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706224000; cv=none; d=zohomail.com; s=zohoarc; b=EQ1/EHolYsnbNIbgmajMGWcpGgfJ+3pSWdc/uGF7jwXxp8dQICbLzDcnLWcFquSiOCik3NiZc20xCqBT8KNPaeaoy5zvUyDyzQWS88NUoTtaTSQIBLXTC3xdFYkF6bqWTIF5i2ZxyM+uF323KGO9RIl+Yr3Qs8RzufiPkMdW12s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706224000; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=XK3+fIcCTfRRlyQb4e9xHZLbd3OYpXU57C+zhwdvnvY=; b=l4vOZ0GRRt3rKfUGj/EXRp/omxJz0BCT3M45T2HvEKMH5Oh9pA9tBOXCWgXY3sEAm9IwhIKdaPRQd/8KYsC1qmD7mHE1rTs1BOnlaZYKm8PiWanMMJc3M+yLtRpISeXxRebMnAvd0fIx87ukHwpNAJOqvKVznuOmdYZRBGpSYts= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114476+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706224000489630.8724610995453; Thu, 25 Jan 2024 15:06:40 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=bRvUW/yThb/8UKWrVA3cAnbfprCxQUcI3X7UroMdvII=; 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=1706224000; v=1; b=bR5PV7ahHuVCXxB4cqi3ESk833hxSfQQliIGoxVpch7P13/rZhi2hYm1my4xKIYZiq0LTsAb NQ9vWmJNJyvILWAIl8MF8P43ZFl3YY7LNL5C7WQe1Zhhk5RLQygat87uq/skyUw/YBRyuoCpeiG RGIEMzKkN3C1JtzVXmO8Z/UU= X-Received: by 127.0.0.2 with SMTP id r6AKYY1788612xkj6NmscqL2; Thu, 25 Jan 2024 15:06:40 -0800 X-Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) by mx.groups.io with SMTP id smtpd.web11.793.1706223999630067004 for ; Thu, 25 Jan 2024 15:06:39 -0800 X-Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-1d746ce7d13so42513425ad.0 for ; Thu, 25 Jan 2024 15:06:39 -0800 (PST) X-Gm-Message-State: A9FJy7JlnKFLZ70wW88loYI4x1787277AA= X-Google-Smtp-Source: AGHT+IHutbe8UoR/pcXXVliQg7WwATFGArWLpz18RsqpxZ/GXTGOABX0uhHP1O4DRM/b0VIQgV+s0g== X-Received: by 2002:a17:902:e80d:b0:1d7:6e2d:db62 with SMTP id u13-20020a170902e80d00b001d76e2ddb62mr504566plg.47.1706223998782; Thu, 25 Jan 2024 15:06:38 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:38 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: Doug Flick , Saloni Kasbekar , Zachary Clark-williams , "Doug Flick [MSFT]" Subject: [edk2-devel] [PATCH v2 14/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit Tests Date: Thu, 25 Jan 2024 13:54:56 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706224001896100059 Content-Type: text/plain; charset="utf-8" From: Doug Flick REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4540 Unit tests to confirm that the bug.. Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message ..has been patched. This patch contains unit tests for the following functions: PxeBcRequestBootService PxeBcDhcp6Discover Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Test/NetworkPkgHostTest.dsc | 5 +- .../GoogleTest/PxeBcDhcp6GoogleTest.h | 18 ++ .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 278 +++++++++++++++++- 3 files changed, 298 insertions(+), 3 deletions(-) diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/Netwo= rkPkgHostTest.dsc index a0273c431025..fa301a7a52ab 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -27,7 +27,10 @@ [Components] # NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf - NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf + NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf { + + UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/Mock= UefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf + } =20 # Despite these library classes being listed in [LibraryClasses] below, th= ey are not needed for the host-based unit tests. [LibraryClasses] diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/Ne= tworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h index b17c314791c8..0d825e44250a 100644 --- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h @@ -47,4 +47,22 @@ PxeBcCacheDnsServerAddresses ( IN PXEBC_DHCP6_PACKET_CACHE *Cache6 ); =20 +/** + Build and send out the request packet for the bootfile, and parse the re= ply. + + @param[in] Private The pointer to PxeBc private data. + @param[in] Index PxeBc option boot item type. + + @retval EFI_SUCCESS Successfully discovered the boot file. + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_NOT_FOUND Can't get the PXE reply packet. + @retval Others Failed to discover the boot file. + +**/ +EFI_STATUS +PxeBcRequestBootService ( + IN PXEBC_PRIVATE_DATA *Private, + IN UINT32 Index + ); + #endif // PXE_BC_DHCP6_GOOGLE_TEST_H_ diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/= NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp index 8260eeee50dc..bd423ebadfce 100644 --- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp @@ -4,7 +4,9 @@ Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include +#include +#include +#include =20 extern "C" { #include @@ -19,7 +21,8 @@ extern "C" { // Definitions //////////////////////////////////////////////////////////////////////////= ///// =20 -#define PACKET_SIZE (1500) +#define PACKET_SIZE (1500) +#define REQUEST_OPTION_LENGTH (120) =20 typedef struct { UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g.= , 0x03) @@ -76,6 +79,26 @@ MockConfigure ( } =20 // Needed by PxeBcSupport +EFI_STATUS +PxeBcDns6 ( + IN PXEBC_PRIVATE_DATA *Private, + IN CHAR16 *HostName, + OUT EFI_IPv6_ADDRESS *IpAddress + ) +{ + return EFI_SUCCESS; +} + +UINT32 +PxeBcBuildDhcp6Options ( + IN PXEBC_PRIVATE_DATA *Private, + OUT EFI_DHCP6_PACKET_OPTION **OptList, + IN UINT8 *Buffer + ) +{ + return EFI_SUCCESS; +} + EFI_STATUS EFIAPI QueueDpc ( @@ -159,6 +182,10 @@ TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) { ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private))= , EFI_DEVICE_ERROR); } =20 +//////////////////////////////////////////////////////////////////////////= ///// +// PxeBcCacheDnsServerAddresses Tests +//////////////////////////////////////////////////////////////////////////= ///// + class PxeBcCacheDnsServerAddressesTest : public ::testing::Test { public: PXEBC_PRIVATE_DATA Private =3D { 0 }; @@ -298,3 +325,250 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDns= Entries) { FreePool (Private.DnsServer); } } + +//////////////////////////////////////////////////////////////////////////= ///// +// PxeBcRequestBootServiceTest Test Cases +//////////////////////////////////////////////////////////////////////////= ///// + +class PxeBcRequestBootServiceTest : public ::testing::Test { +public: + PXEBC_PRIVATE_DATA Private =3D { 0 }; + EFI_UDP6_PROTOCOL Udp6Read; + +protected: + // Add any setup code if needed + virtual void + SetUp ( + ) + { + Private.Dhcp6Request =3D (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_= SIZE); + + // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL + // The function under test really only needs the following: + // UdpWrite + // UdpRead + + Private.PxeBc.UdpWrite =3D (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; + Private.PxeBc.UdpRead =3D (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; + + // Need to setup EFI_UDP6_PROTOCOL + // The function under test really only needs the following: + // Configure + + Udp6Read.Configure =3D (EFI_UDP6_CONFIGURE)MockConfigure; + Private.Udp6Read =3D &Udp6Read; + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + if (Private.Dhcp6Request !=3D NULL) { + FreePool (Private.Dhcp6Request); + } + + // Clean up any resources or variables + } +}; + +TEST_F (PxeBcRequestBootServiceTest, ServerDiscoverBasicUsageTest) { + PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType =3D = PxeOfferTypeProxyBinl; + + DHCP6_OPTION_SERVER_ID Server =3D { 0 }; + + Server.OptionCode =3D HTONS (DHCP6_OPT_SERVER_ID); + Server.OptionLen =3D HTONS (16); // valid length + UINT8 Index =3D 0; + + EFI_DHCP6_PACKET *Packet =3D (EFI_DHCP6_PACKET *)&Private.OfferBuffer[I= ndex].Dhcp6.Packet.Offer; + + UINT8 *Cursor =3D (UINT8 *)(Packet->Dhcp6.Option); + + CopyMem (Cursor, &Server, sizeof (Server)); + Cursor +=3D sizeof (Server); + + // Update the packet length + Packet->Length =3D (UINT16)(Cursor - (UINT8 *)Packet); + Packet->Size =3D PACKET_SIZE; + + ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Priva= te), Index), EFI_SUCCESS); +} + +TEST_F (PxeBcRequestBootServiceTest, AttemptDiscoverOverFlowExpectFailure)= { + PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType =3D = PxeOfferTypeProxyBinl; + + DHCP6_OPTION_SERVER_ID Server =3D { 0 }; + + Server.OptionCode =3D HTONS (DHCP6_OPT_SERVER_ID); + Server.OptionLen =3D HTONS (1500); // This length would overflow withou= t a check + UINT8 Index =3D 0; + + EFI_DHCP6_PACKET *Packet =3D (EFI_DHCP6_PACKET *)&Private.OfferBuffer[I= ndex].Dhcp6.Packet.Offer; + + UINT8 *Cursor =3D (UINT8 *)(Packet->Dhcp6.Option); + + CopyMem (Cursor, &Server, sizeof (Server)); + Cursor +=3D sizeof (Server); + + // Update the packet length + Packet->Length =3D (UINT16)(Cursor - (UINT8 *)Packet); + Packet->Size =3D PACKET_SIZE; + + // This is going to be stopped by the duid overflow check + ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Priva= te), Index), EFI_INVALID_PARAMETER); +} + +TEST_F (PxeBcRequestBootServiceTest, RequestBasicUsageTest) { + EFI_DHCP6_PACKET_OPTION RequestOpt =3D { 0 }; // the data section doesn= 't really matter + + RequestOpt.OpCode =3D HTONS (0x1337); + RequestOpt.OpLen =3D 0; // valid length + + UINT8 Index =3D 0; + + EFI_DHCP6_PACKET *Packet =3D (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[= Index]; + + UINT8 *Cursor =3D (UINT8 *)(Packet->Dhcp6.Option); + + CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); + Cursor +=3D sizeof (RequestOpt); + + // Update the packet length + Packet->Length =3D (UINT16)(Cursor - (UINT8 *)Packet); + Packet->Size =3D PACKET_SIZE; + + ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Priva= te), Index), EFI_SUCCESS); +} + +TEST_F (PxeBcRequestBootServiceTest, AttemptRequestOverFlowExpectFailure) { + EFI_DHCP6_PACKET_OPTION RequestOpt =3D { 0 }; // the data section doesn= 't really matter + + RequestOpt.OpCode =3D HTONS (0x1337); + RequestOpt.OpLen =3D 1500; // this length would overflow without a check + + UINT8 Index =3D 0; + + EFI_DHCP6_PACKET *Packet =3D (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[= Index]; + + UINT8 *Cursor =3D (UINT8 *)(Packet->Dhcp6.Option); + + CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); + Cursor +=3D sizeof (RequestOpt); + + // Update the packet length + Packet->Length =3D (UINT16)(Cursor - (UINT8 *)Packet); + Packet->Size =3D PACKET_SIZE; + + ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Priva= te), Index), EFI_OUT_OF_RESOURCES); +} + +//////////////////////////////////////////////////////////////////////////= ///// +// PxeBcDhcp6Discover Test +//////////////////////////////////////////////////////////////////////////= ///// + +class PxeBcDhcp6DiscoverTest : public ::testing::Test { +public: + PXEBC_PRIVATE_DATA Private =3D { 0 }; + EFI_UDP6_PROTOCOL Udp6Read; + +protected: + MockUefiRuntimeServicesTableLib RtServicesMock; + + // Add any setup code if needed + virtual void + SetUp ( + ) + { + Private.Dhcp6Request =3D (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_= SIZE); + + // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL + // The function under test really only needs the following: + // UdpWrite + // UdpRead + + Private.PxeBc.UdpWrite =3D (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite; + Private.PxeBc.UdpRead =3D (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead; + + // Need to setup EFI_UDP6_PROTOCOL + // The function under test really only needs the following: + // Configure + + Udp6Read.Configure =3D (EFI_UDP6_CONFIGURE)MockConfigure; + Private.Udp6Read =3D &Udp6Read; + } + + // Add any cleanup code if needed + virtual void + TearDown ( + ) + { + if (Private.Dhcp6Request !=3D NULL) { + FreePool (Private.Dhcp6Request); + } + + // Clean up any resources or variables + } +}; + +// Test Description +// This will cause an overflow by an untrusted packet during the option pa= rsing +TEST_F (PxeBcDhcp6DiscoverTest, BasicOverflowTest) { + EFI_IPv6_ADDRESS DestIp =3D { 0 }; + EFI_DHCP6_PACKET_OPTION RequestOpt =3D { 0 }; // the data section doesn= 't really matter + + RequestOpt.OpCode =3D HTONS (0x1337); + RequestOpt.OpLen =3D HTONS (0xFFFF); // overflow + + UINT8 *Cursor =3D (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option); + + CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); + Cursor +=3D sizeof (RequestOpt); + + Private.Dhcp6Request->Length =3D (UINT16)(Cursor - (UINT8 *)Private.Dhcp= 6Request); + + EXPECT_CALL (RtServicesMock, gRT_GetTime) + .WillOnce (::testing::Return (0)); + + ASSERT_EQ ( + PxeBcDhcp6Discover ( + &(PxeBcDhcp6DiscoverTest::Private), + 0, + NULL, + FALSE, + (EFI_IP_ADDRESS *)&DestIp + ), + EFI_OUT_OF_RESOURCES + ); +} + +// Test Description +// This will test that we can handle a packet with a valid option length +TEST_F (PxeBcDhcp6DiscoverTest, BasicUsageTest) { + EFI_IPv6_ADDRESS DestIp =3D { 0 }; + EFI_DHCP6_PACKET_OPTION RequestOpt =3D { 0 }; // the data section doesn= 't really matter + + RequestOpt.OpCode =3D HTONS (0x1337); + RequestOpt.OpLen =3D HTONS (0x30); + + UINT8 *Cursor =3D (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option); + + CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt)); + Cursor +=3D sizeof (RequestOpt); + + Private.Dhcp6Request->Length =3D (UINT16)(Cursor - (UINT8 *)Private.Dhcp= 6Request); + + EXPECT_CALL (RtServicesMock, gRT_GetTime) + .WillOnce (::testing::Return (0)); + + ASSERT_EQ ( + PxeBcDhcp6Discover ( + &(PxeBcDhcp6DiscoverTest::Private), + 0, + NULL, + FALSE, + (EFI_IP_ADDRESS *)&DestIp + ), + EFI_SUCCESS + ); +} --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114476): https://edk2.groups.io/g/devel/message/114476 Mute This Topic: https://groups.io/mt/103964992/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun May 12 05:40:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114477+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114477+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1706224001; cv=none; d=zohomail.com; s=zohoarc; b=SF7FmiX8HmX2KHbzxtVx2OptlLHtedqc6NjOY0fZSg1WUiIDeowkbbQsnjyGqbEYRSZM5Sl2t0hN66m5m7ws1p10hiqHTaEFjHyr/bvlZbBo+ii90j8OZZgo6BFZltQf4Yvuhc1REE9PMwSHfNIEckT8ocBYfDn7oKUh/SX5QnU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1706224001; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=jGsTpf1W2PVOkQqoQYE5GxP3xAJSc39E/Tzc2tTsDwc=; b=gSfBe1Ot4CcXxFDSRnVVLZbdrix5U4f+RErXGB75IcvztIE82CgP6PHTyf8lnsub77JM57Nz5sqwck7mkDkaex9cStUJ5CCrRTUJZpyArQC4xOiqXzLBT7NEH9BZSgdSmRtZMWAs35OFNOvuwwERbENlchgdZdvqDS6HA/6F8p8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114477+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 170622400113047.42249432549659; Thu, 25 Jan 2024 15:06:41 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=PgCztqBcsK2Sfzu6cb/jI3B6zt9mvxui313CGPCn64w=; 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=1706224000; v=1; b=AD7rJVS1uyC7hLB8Jh2jFYSJGYI00PbHxv0qGSMnLm7spZnYamoQz8cDywbqEH+cK55jarD3 lq3F0UfyaMpTfNeK6Bdv5Vsrl3Eio6fofIo4qYt0eoSM87pHs1f3of1j2N73/UqC8k2NEMC1Rhr 7FgD/ZKm7kg9a+MK12j1t2nc= X-Received: by 127.0.0.2 with SMTP id CzxOYY1788612xJWWnovhroL; Thu, 25 Jan 2024 15:06:40 -0800 X-Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) by mx.groups.io with SMTP id smtpd.web11.794.1706224000316895407 for ; Thu, 25 Jan 2024 15:06:40 -0800 X-Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-1d71cb97937so47981405ad.3 for ; Thu, 25 Jan 2024 15:06:40 -0800 (PST) X-Gm-Message-State: U5hPEHnlUxnbgYLkoKJTMEnUx1787277AA= X-Google-Smtp-Source: AGHT+IE1D6aZtSfrXQbna9pyjvA9qBubdAx1AxQR2a3GCRlvsoSZF+pF8FNK74QzHu5dRKtAGcuXJA== X-Received: by 2002:a17:902:d507:b0:1d5:6648:5f1 with SMTP id b7-20020a170902d50700b001d5664805f1mr560882plg.36.1706223999579; Thu, 25 Jan 2024 15:06:39 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:39 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Saloni Kasbekar , Zachary Clark-williams Subject: [edk2-devel] [PATCH v2 15/15] NetworkPkg: : Adds a SecurityFix.yaml file Date: Thu, 25 Jan 2024 13:54:57 -0800 Message-ID: <7cff1e0c867f716759a3aea9a67e3ded0ac59620.1706219324.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: 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: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706224002091100061 Content-Type: text/plain; charset="utf-8" This creates / adds a security file that tracks the security fixes found in this package and can be used to find the fixes that were applied. Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/SecurityFixes.yaml | 123 ++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 NetworkPkg/SecurityFixes.yaml diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml new file mode 100644 index 000000000000..7e900483fec5 --- /dev/null +++ b/NetworkPkg/SecurityFixes.yaml @@ -0,0 +1,123 @@ +## @file +# Security Fixes for SecurityPkg +# +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +CVE_2023_45229: + commit_titles: + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch" + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests" + cve: CVE-2023-45229 + date_reported: 2023-08-28 13:56 UTC + description: "Bug 01 - edk2/NetworkPkg: Out-of-bounds read when processi= ng IA_NA/IA_TA options in a DHCPv6 Advertise message" + note: + files_impacted: + - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c + - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4534 + - https://nvd.nist.gov/vuln/detail/CVE-2023-45229 + - http://www.openwall.com/lists/oss-security/2024/01/16/2 + - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Conce= pts.html + - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianoco= res-edk-ii-ipv6-network-stack.html +CVE_2023_45230: + commit_titles: + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch" + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests" + cve: CVE-2023-45230 + date_reported: 2023-08-28 13:56 UTC + description: "Bug 02 - edk2/NetworkPkg: Buffer overflow in the DHCPv6 cl= ient via a long Server ID option" + note: + files_impacted: + - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c + - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4535 + - https://nvd.nist.gov/vuln/detail/CVE-2023-45230 + - http://www.openwall.com/lists/oss-security/2024/01/16/2 + - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Conce= pts.html + - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianoco= res-edk-ii-ipv6-network-stack.html +CVE_2023_45231: + commit_titles: + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Patch" + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Unit Tests" + cve: CVE-2023-45231 + date_reported: 2023-08-28 13:56 UTC + description: "Bug 03 - edk2/NetworkPkg: Out-of-bounds read when handling= a ND Redirect message with truncated options" + note: + files_impacted: + - NetworkPkg/Ip6Dxe/Ip6Option.c + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4536 + - https://nvd.nist.gov/vuln/detail/CVE-2023-45231 + - http://www.openwall.com/lists/oss-security/2024/01/16/2 + - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Conce= pts.html + - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianoco= res-edk-ii-ipv6-network-stack.html +CVE_2023_45232: + commit_titles: + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch" + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests" + cve: CVE-2023-45232 + date_reported: 2023-08-28 13:56 UTC + description: "Bug 04 - edk2/NetworkPkg: Infinite loop when parsing unkno= wn options in the Destination Options header" + note: + files_impacted: + - NetworkPkg/Ip6Dxe/Ip6Option.c + - NetworkPkg/Ip6Dxe/Ip6Option.h + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4537 + - https://nvd.nist.gov/vuln/detail/CVE-2023-45232 + - http://www.openwall.com/lists/oss-security/2024/01/16/2 + - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Conce= pts.html + - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianoco= res-edk-ii-ipv6-network-stack.html +CVE_2023_45233: + commit_titles: + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch" + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests" + cve: CVE-2023-45233 + date_reported: 2023-08-28 13:56 UTC + description: "Bug 05 - edk2/NetworkPkg: Infinite loop when parsing a Pad= N option in the Destination Options header " + note: This was fixed along with CVE-2023-45233 + files_impacted: + - NetworkPkg/Ip6Dxe/Ip6Option.c + - NetworkPkg/Ip6Dxe/Ip6Option.h + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4538 + - https://nvd.nist.gov/vuln/detail/CVE-2023-45233 + - http://www.openwall.com/lists/oss-security/2024/01/16/2 + - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Conce= pts.html + - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianoco= res-edk-ii-ipv6-network-stack.html +CVE_2023_45234: + commit_titles: + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Patch" + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Unit Tests" + cve: CVE-2023-45234 + date_reported: 2023-08-28 13:56 UTC + description: "Bug 06 - edk2/NetworkPkg: Buffer overflow when processing = DNS Servers option in a DHCPv6 Advertise message" + note: + files_impacted: + - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4539 + - https://nvd.nist.gov/vuln/detail/CVE-2023-45234 + - http://www.openwall.com/lists/oss-security/2024/01/16/2 + - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Conce= pts.html + - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianoco= res-edk-ii-ipv6-network-stack.html +CVE_2023_45235: + commit_titles: + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Patch" + - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Unit Tests" + cve: CVE-2023-45235 + date_reported: 2023-08-28 13:56 UTC + description: "Bug 07 - edk2/NetworkPkg: Buffer overflow when handling Se= rver ID option from a DHCPv6 proxy Advertise message" + note: + files_impacted: + - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c + - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4540 + - https://nvd.nist.gov/vuln/detail/CVE-2023-45235 + - http://www.openwall.com/lists/oss-security/2024/01/16/2 + - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Conce= pts.html + - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianoco= res-edk-ii-ipv6-network-stack.html --=20 2.43.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114477): https://edk2.groups.io/g/devel/message/114477 Mute This Topic: https://groups.io/mt/103964993/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-