From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 1BA3E780091 for ; Thu, 25 Jan 2024 23:06:33 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=ziwLAd6XLFZyHn/57pR12w+JjieGXuoQ5qjEMJKsCN8=; 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=Qt0QRGMbMd7ylWvzF43NPDyHAfe2D4yeYCrR215hBbIOjlVsjPNEssNQ9vDzT8bMZpr6P2Tx 9J9Zs+xZNYcrB32BpfkUfN4j+ywrR1OR5wRUAFdjYJjAALZ6b9+vtmwmHsIBudvbQc2CWHK1lKh 6bohz+2U3m0D6inKn9PHE3t8= X-Received: by 127.0.0.2 with SMTP id e0STYY7687511xZmxSXi3fr2; 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: Y0yqGVRbAcWP9Q3grK0ziUvbx7686176AA= 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-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=Qt0QRGMb; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io 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')=0D #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I')=0D =0D +#define DHCP6_PACKET_ALL 0=0D +#define DHCP6_PACKET_STATEFUL 1=0D +#define DHCP6_PACKET_STATELESS 2=0D +=0D +#define DHCP6_BASE_PACKET_SIZE 1024=0D +=0D +#define DHCP6_PORT_CLIENT 546=0D +#define DHCP6_PORT_SERVER 547=0D +=0D +#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)=0D +=0D +#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE= , Dhcp6, DHCP6_INSTANCE_SIGNATURE)=0D +#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, = ServiceBinding, DHCP6_SERVICE_SIGNATURE)=0D +=0D //=0D // For more information on DHCP options see RFC 8415, Section 21.1=0D //=0D @@ -59,12 +73,10 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; // | (option-len octets) |=0D // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D //=0D -#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16))=0D -#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16))=0D +#define DHCP6_SIZE_OF_OPT_CODE (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->O= pCode))=0D +#define DHCP6_SIZE_OF_OPT_LEN (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->O= pLen))=0D =0D -//=0D // Combined size of Code and Length=0D -//=0D #define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \=0D DHCP6_SIZE_OF_OPT_LEN)=0D =0D @@ -73,34 +85,122 @@ STATIC_ASSERT ( "Combined size of Code and Length must be 4 per RFC 8415"=0D );=0D =0D -//=0D // Offset to the length is just past the code=0D -//=0D -#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE)=0D +#define DHCP6_OFFSET_OF_OPT_LEN(a) (a + DHCP6_SIZE_OF_OPT_CODE)=0D STATIC_ASSERT (=0D - DHCP6_OPT_LEN_OFFSET (0) =3D=3D 2,=0D + DHCP6_OFFSET_OF_OPT_LEN (0) =3D=3D 2,=0D "Offset of length is + 2 past start of option"=0D );=0D =0D -#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN= )=0D +#define DHCP6_OFFSET_OF_OPT_DATA(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_= LEN)=0D STATIC_ASSERT (=0D - DHCP6_OPT_DATA_OFFSET (0) =3D=3D 4,=0D + DHCP6_OFFSET_OF_OPT_DATA (0) =3D=3D 4,=0D "Offset to option data should be +4 from start of option"=0D );=0D +//=0D +// Identity Association options (both NA (Non-Temporary) and TA (Temporary= Association))=0D +// are defined in RFC 8415 and are a deriviation of a TLV stucture=0D +// For more information on IA_NA see Section 21.4=0D +// For more information on IA_TA see Section 21.5=0D +//=0D +//=0D +// The format of IA_NA and IA_TA option:=0D +//=0D +// 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=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | OPTION_IA_NA | option-len |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | IAID (4 octets) |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | T1 (only for IA_NA) |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | T2 (only for IA_NA) |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | |=0D +// . IA_NA-options/IA_TA-options .=0D +// . .=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +//=0D +#define DHCP6_SIZE_OF_IAID (sizeof(UINT32))=0D +#define DHCP6_SIZE_OF_TIME_INTERVAL (sizeof(UINT32))=0D =0D -#define DHCP6_PACKET_ALL 0=0D -#define DHCP6_PACKET_STATEFUL 1=0D -#define DHCP6_PACKET_STATELESS 2=0D +// Combined size of IAID, T1, and T2=0D +#define DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 (DHCP6_SIZE_OF_IAID + \=0D + DHCP6_SIZE_OF_TIME_INTERVAL + = \=0D + DHCP6_SIZE_OF_TIME_INTERVAL)=0D +STATIC_ASSERT (=0D + DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 =3D=3D 12,=0D + "Combined size of IAID, T1, T2 must be 12 per RFC 8415"=0D + );=0D =0D -#define DHCP6_BASE_PACKET_SIZE 1024=0D +// This is the size of IA_TA without options=0D +#define DHCP6_MIN_SIZE_OF_IA_TA (DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \= =0D + DHCP6_SIZE_OF_IAID)=0D +STATIC_ASSERT (=0D + DHCP6_MIN_SIZE_OF_IA_TA =3D=3D 8,=0D + "Minimum combined size of IA_TA per RFC 8415"=0D + );=0D =0D -#define DHCP6_PORT_CLIENT 546=0D -#define DHCP6_PORT_SERVER 547=0D +// Offset to a IA_TA inner option=0D +#define DHCP6_OFFSET_OF_IA_TA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_TA)= =0D +STATIC_ASSERT (=0D + DHCP6_OFFSET_OF_IA_TA_INNER_OPT (0) =3D=3D 8,=0D + "Offset of IA_TA Inner option is + 8 past start of option"=0D + );=0D =0D -#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)=0D +// This is the size of IA_NA without options (16)=0D +#define DHCP6_MIN_SIZE_OF_IA_NA DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \=0D + DHCP6_SIZE_OF_COMBINED_IAID_T1_T2=0D +STATIC_ASSERT (=0D + DHCP6_MIN_SIZE_OF_IA_NA =3D=3D 16,=0D + "Minimum combined size of IA_TA per RFC 8415"=0D + );=0D =0D -#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE= , Dhcp6, DHCP6_INSTANCE_SIGNATURE)=0D -#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, = ServiceBinding, DHCP6_SERVICE_SIGNATURE)=0D +#define DHCP6_OFFSET_OF_IA_NA_INNER_OPT(a) (a + DHCP6_MIN_SIZE_OF_IA_NA)= =0D +STATIC_ASSERT (=0D + DHCP6_OFFSET_OF_IA_NA_INNER_OPT (0) =3D=3D 16,=0D + "Offset of IA_NA Inner option is + 16 past start of option"=0D + );=0D +=0D +#define DHCP6_OFFSET_OF_IA_NA_T1(a) (a + \=0D + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \= =0D + DHCP6_SIZE_OF_IAID)=0D +STATIC_ASSERT (=0D + DHCP6_OFFSET_OF_IA_NA_T1 (0) =3D=3D 8,=0D + "Offset of IA_NA Inner option is + 8 past start of option"=0D + );=0D +=0D +#define DHCP6_OFFSET_OF_IA_NA_T2(a) (a + \=0D + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN +\= =0D + DHCP6_SIZE_OF_IAID + \=0D + DHCP6_SIZE_OF_TIME_INTERVAL)=0D +STATIC_ASSERT (=0D + DHCP6_OFFSET_OF_IA_NA_T2 (0) =3D=3D 12,=0D + "Offset of IA_NA Inner option is + 12 past start of option"=0D + );=0D +=0D +//=0D +// For more information see RFC 8415 Section 21.13=0D +//=0D +// The format of the Status Code Option:=0D +//=0D +// 0 1 2 3=0D +// 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=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | OPTION_STATUS_CODE | option-len |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | status-code | |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |=0D +// . .=0D +// . status-message .=0D +// . .=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +//=0D +#define DHCP6_OFFSET_OF_STATUS_CODE(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_A= ND_LEN)=0D +STATIC_ASSERT (=0D + DHCP6_OFFSET_OF_STATUS_CODE (0) =3D=3D 4,=0D + "Offset of status is + 4 past start of option"=0D + );=0D =0D extern EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress;=0D extern EFI_DHCP6_PROTOCOL gDhcp6ProtocolTemplate;=0D 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.=0D //=0D if (Instance->Config->IaDescriptor.Type =3D=3D Dhcp6OptIana) {=0D - T1 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 8)));=0D - T2 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 12)));=0D + T1 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Op= tion))));=0D + T2 =3D NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Op= tion))));=0D //=0D // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T= 1 greater than T2,=0D // and both T1 and T2 are greater than 0, the client discards the IA_N= A option and processes=0D @@ -609,13 +609,14 @@ Dhcp6UpdateIaInfo ( return EFI_DEVICE_ERROR;=0D }=0D =0D - IaInnerOpt =3D Option + 16;=0D - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2)= )) - 12);=0D + IaInnerOpt =3D DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);=0D + IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSE= T_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2);=0D } else {=0D - T1 =3D 0;=0D - T2 =3D 0;=0D - IaInnerOpt =3D Option + 8;=0D - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2)= )) - 4);=0D + T1 =3D 0;=0D + T2 =3D 0;=0D +=0D + IaInnerOpt =3D DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);=0D + IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSE= T_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID);=0D }=0D =0D //=0D @@ -641,7 +642,7 @@ Dhcp6UpdateIaInfo ( Option =3D Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode)= ;=0D =0D if (Option !=3D NULL) {=0D - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4)));=0D + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN= (Option))));=0D if (StsCode !=3D Dhcp6StsSuccess) {=0D return EFI_DEVICE_ERROR;=0D }=0D @@ -661,6 +662,87 @@ Dhcp6UpdateIaInfo ( return Status;=0D }=0D =0D +/**=0D + Seeks the Inner Options from a DHCP6 Option=0D +=0D + @param[in] IaType The type of the IA option.=0D + @param[in] Option The pointer to the DHCP6 Option.=0D + @param[in] OptionLen The length of the DHCP6 Option.=0D + @param[out] IaInnerOpt The pointer to the IA inner option.=0D + @param[out] IaInnerLen The length of the IA inner option.=0D +=0D + @retval EFI_SUCCESS Seek the inner option successfully.=0D + @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error,=0D + the pointers are not modified=0D +**/=0D +EFI_STATUS=0D +Dhcp6SeekInnerOptionSafe (=0D + IN UINT16 IaType,=0D + IN UINT8 *Option,=0D + IN UINT32 OptionLen,=0D + OUT UINT8 **IaInnerOpt,=0D + OUT UINT16 *IaInnerLen=0D + )=0D +{=0D + UINT16 IaInnerLenTmp;=0D + UINT8 *IaInnerOptTmp;=0D +=0D + if (Option =3D=3D NULL) {=0D + ASSERT (Option !=3D NULL);=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + if (IaInnerOpt =3D=3D NULL) {=0D + ASSERT (IaInnerOpt !=3D NULL);=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + if (IaInnerLen =3D=3D NULL) {=0D + ASSERT (IaInnerLen !=3D NULL);=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + if (IaType =3D=3D Dhcp6OptIana) {=0D + // Verify we have a fully formed IA_NA=0D + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + IaInnerOptTmp =3D DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);=0D +=0D + // Verify the IaInnerLen is valid.=0D + IaInnerLenTmp =3D (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFS= ET_OF_OPT_LEN (Option)));=0D + if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + IaInnerLenTmp -=3D DHCP6_SIZE_OF_COMBINED_IAID_T1_T2;=0D + } else if (IaType =3D=3D Dhcp6OptIata) {=0D + // Verify the OptionLen is valid.=0D + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + IaInnerOptTmp =3D DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);=0D +=0D + // Verify the IaInnerLen is valid.=0D + IaInnerLenTmp =3D (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFF= SET_OF_OPT_LEN (Option))));=0D + if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + IaInnerLenTmp -=3D DHCP6_SIZE_OF_IAID;=0D + } else {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + *IaInnerOpt =3D IaInnerOptTmp;=0D + *IaInnerLen =3D IaInnerLenTmp;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D /**=0D Seek StatusCode Option in package. A Status Code option may appear in th= e=0D options field of a DHCP message and/or in the options field of another o= ption.=0D @@ -684,6 +766,12 @@ Dhcp6SeekStsOption ( UINT8 *IaInnerOpt;=0D UINT16 IaInnerLen;=0D UINT16 StsCode;=0D + UINT32 OptionLen;=0D +=0D + // OptionLen is the length of the Options excluding the DHCP header.=0D + // Length of the EFI_DHCP6_PACKET from the first byte of the Header fiel= d to the last=0D + // byte of the Option[] field.=0D + OptionLen =3D Packet->Length - sizeof (Packet->Dhcp6.Header);=0D =0D //=0D // Seek StatusCode option directly in DHCP message body. That is, search= in=0D @@ -691,12 +779,12 @@ Dhcp6SeekStsOption ( //=0D *Option =3D Dhcp6SeekOption (=0D Packet->Dhcp6.Option,=0D - Packet->Length - 4,=0D + OptionLen,=0D Dhcp6OptStatusCode=0D );=0D =0D if (*Option !=3D NULL) {=0D - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4)));=0D + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_= CODE (*Option))));=0D if (StsCode !=3D Dhcp6StsSuccess) {=0D return EFI_DEVICE_ERROR;=0D }=0D @@ -707,7 +795,7 @@ Dhcp6SeekStsOption ( //=0D *Option =3D Dhcp6SeekIaOption (=0D Packet->Dhcp6.Option,=0D - Packet->Length - sizeof (EFI_DHCP6_HEADER),=0D + OptionLen,=0D &Instance->Config->IaDescriptor=0D );=0D if (*Option =3D=3D NULL) {=0D @@ -715,52 +803,35 @@ Dhcp6SeekStsOption ( }=0D =0D //=0D - // The format of the IA_NA option is:=0D + // Calculate the distance from Packet->Dhcp6.Option to the IA option.=0D //=0D - // 0 1 2 3=0D - // 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=0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | OPTION_IA_NA | option-len |= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | IAID (4 octets) |= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | T1 |= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | T2 |= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | |= =0D - // . IA_NA-options .= =0D - // . .= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D + // Packet->Size and Packet->Length are both UINT32 type, and Packet->Siz= e is=0D + // the size of the whole packet, including the DHCP header, and Packet->= Length=0D + // is the length of the DHCP message body, excluding the DHCP header.=0D //=0D - // The format of the IA_TA option is:=0D + // (*Option - Packet->Dhcp6.Option) is the number of bytes from the star= t of=0D + // DHCP6 option area to the start of the IA option.=0D //=0D - // 0 1 2 3=0D - // 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=0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | OPTION_IA_TA | option-len |= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | IAID (4 octets) |= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D - // | |= =0D - // . IA_TA-options .= =0D - // . .= =0D - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D + // Dhcp6SeekInnerOptionSafe() is searching starting from the start of th= e=0D + // IA option to the end of the DHCP6 option area, thus subtract the spac= e=0D + // up until this option=0D //=0D + OptionLen =3D OptionLen - (*Option - Packet->Dhcp6.Option);=0D =0D //=0D - // sizeof (option-code + option-len + IaId) =3D 8=0D - // sizeof (option-code + option-len + IaId + T1) =3D 12=0D - // sizeof (option-code + option-len + IaId + T1 + T2) =3D 16=0D + // Seek the inner option=0D //=0D - // The inner options still start with 2 bytes option-code and 2 bytes op= tion-len.=0D - //=0D - if (Instance->Config->IaDescriptor.Type =3D=3D Dhcp6OptIana) {=0D - IaInnerOpt =3D *Option + 16;=0D - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2= ))) - 12);=0D - } else {=0D - IaInnerOpt =3D *Option + 8;=0D - IaInnerLen =3D (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2= ))) - 4);=0D + if (EFI_ERROR (=0D + Dhcp6SeekInnerOptionSafe (=0D + Instance->Config->IaDescriptor.Type,=0D + *Option,=0D + OptionLen,=0D + &IaInnerOpt,=0D + &IaInnerLen=0D + )=0D + ))=0D + {=0D + return EFI_DEVICE_ERROR;=0D }=0D =0D //=0D @@ -784,7 +855,7 @@ Dhcp6SeekStsOption ( //=0D *Option =3D Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode)= ;=0D if (*Option !=3D NULL) {=0D - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4)));=0D + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS= _CODE (*Option)))));=0D if (StsCode !=3D Dhcp6StsSuccess) {=0D return EFI_DEVICE_ERROR;=0D }=0D @@ -1105,7 +1176,7 @@ Dhcp6SendRequestMsg ( //=0D Option =3D Dhcp6SeekOption (=0D Instance->AdSelect->Dhcp6.Option,=0D - Instance->AdSelect->Length - 4,=0D + Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptServerId=0D );=0D if (Option =3D=3D NULL) {=0D @@ -1289,7 +1360,7 @@ Dhcp6SendDeclineMsg ( //=0D Option =3D Dhcp6SeekOption (=0D LastReply->Dhcp6.Option,=0D - LastReply->Length - 4,=0D + LastReply->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptServerId=0D );=0D if (Option =3D=3D NULL) {=0D @@ -1448,7 +1519,7 @@ Dhcp6SendReleaseMsg ( //=0D Option =3D Dhcp6SeekOption (=0D LastReply->Dhcp6.Option,=0D - LastReply->Length - 4,=0D + LastReply->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptServerId=0D );=0D if (Option =3D=3D NULL) {=0D @@ -1673,7 +1744,7 @@ Dhcp6SendRenewRebindMsg ( =0D Option =3D Dhcp6SeekOption (=0D LastReply->Dhcp6.Option,=0D - LastReply->Length - 4,=0D + LastReply->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptServerId=0D );=0D if (Option =3D=3D NULL) {=0D @@ -2208,7 +2279,7 @@ Dhcp6HandleReplyMsg ( //=0D Option =3D Dhcp6SeekOption (=0D Packet->Dhcp6.Option,=0D - Packet->Length - 4,=0D + Packet->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptRapidCommit=0D );=0D =0D @@ -2354,7 +2425,7 @@ Dhcp6HandleReplyMsg ( //=0D // Any error status code option is found.=0D //=0D - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4)));=0D + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS= _CODE (Option)))));=0D switch (StsCode) {=0D case Dhcp6StsUnspecFail:=0D //=0D @@ -2487,7 +2558,7 @@ Dhcp6SelectAdvertiseMsg ( //=0D Option =3D Dhcp6SeekOption (=0D AdSelect->Dhcp6.Option,=0D - AdSelect->Length - 4,=0D + AdSelect->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptServerUnicast=0D );=0D =0D @@ -2498,7 +2569,7 @@ Dhcp6SelectAdvertiseMsg ( return EFI_OUT_OF_RESOURCES;=0D }=0D =0D - CopyMem (Instance->Unicast, Option + 4, sizeof (EFI_IPv6_ADDRESS));=0D + CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof = (EFI_IPv6_ADDRESS));=0D }=0D =0D //=0D @@ -2551,7 +2622,7 @@ Dhcp6HandleAdvertiseMsg ( //=0D Option =3D Dhcp6SeekOption (=0D Packet->Dhcp6.Option,=0D - Packet->Length - 4,=0D + Packet->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptRapidCommit=0D );=0D =0D @@ -2645,7 +2716,7 @@ Dhcp6HandleAdvertiseMsg ( CopyMem (Instance->AdSelect, Packet, Packet->Size);=0D =0D if (Option !=3D NULL) {=0D - Instance->AdPref =3D *(Option + 4);=0D + Instance->AdPref =3D *(DHCP6_OFFSET_OF_OPT_DATA (Option));=0D }=0D } else {=0D //=0D @@ -2714,11 +2785,11 @@ Dhcp6HandleStateful ( //=0D Option =3D Dhcp6SeekOption (=0D Packet->Dhcp6.Option,=0D - Packet->Length - 4,=0D + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN,=0D Dhcp6OptClientId=0D );=0D =0D - if ((Option =3D=3D NULL) || (CompareMem (Option + 4, ClientId->Duid, Cli= entId->Length) !=3D 0)) {=0D + if ((Option =3D=3D NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Optio= n), ClientId->Duid, ClientId->Length) !=3D 0)) {=0D goto ON_CONTINUE;=0D }=0D =0D @@ -2727,7 +2798,7 @@ Dhcp6HandleStateful ( //=0D Option =3D Dhcp6SeekOption (=0D Packet->Dhcp6.Option,=0D - Packet->Length - 4,=0D + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN,=0D Dhcp6OptServerId=0D );=0D =0D @@ -2832,7 +2903,7 @@ Dhcp6HandleStateless ( //=0D Option =3D Dhcp6SeekOption (=0D Packet->Dhcp6.Option,=0D - Packet->Length - 4,=0D + Packet->Length - sizeof (EFI_DHCP6_HEADER),=0D Dhcp6OptServerId=0D );=0D =0D --=20 2.43.0 -=-=-=-=-=-=-=-=-=-=-=- 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/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-