From nobody Fri Oct 18 05:19:24 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-