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 792E97803CD for ; Thu, 8 Feb 2024 23:45:36 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=mmvwYD0NMfs76Vz9cTJKuZV8FA2jqpJXhgdUG6lAnUs=; 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=1707435935; v=1; b=hJT7xXNJ8ocnhcpEeZ+sEJGE07jsph7DRFVqLQy07A6m1TYsUdSafcMs1XeliW8Qll+ncw6x +DwSgsw6HsSMMuLQ8krLwtxci16y8NTiOmv9Se4OsEh67PJXBeYJl0YPf1tsmlqETECzRiSDLbr 2+IbbaATtAThEtLz4YgzvGOI= X-Received: by 127.0.0.2 with SMTP id ojPnYY7687511x8FWE8S2QhX; Thu, 08 Feb 2024 15:45: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.web10.4853.1707435934650182538 for ; Thu, 08 Feb 2024 15:45:34 -0800 X-Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-1d8da50bffaso2129195ad.2 for ; Thu, 08 Feb 2024 15:45:34 -0800 (PST) X-Gm-Message-State: I1OyZDZ8JoDkomHqaakZ2KOnx7686176AA= X-Google-Smtp-Source: AGHT+IG9ugZM0meAWb2fiRuaZRLX/P//q5i8WksEX2UL4iY6nl26dz0THw65Ie2TXs51BbrpKIXVhA== X-Received: by 2002:a17:902:d48b:b0:1d9:ee5f:a980 with SMTP id c11-20020a170902d48b00b001d9ee5fa980mr1129230plg.26.1707435933778; Thu, 08 Feb 2024 15:45:33 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCUwEjyhTGMWoyuB6IB/88Rtp4eS1DZf9nwXaEFKgGPY7dZ2tgMdKy0/3313nRPdXar6WltIma6ZCWGZD1XJaaibRWWhsjO3cXceOsLZ4A4tOArm1I1bYhTAQ5v6DdAvYDRehMrjYbogMJDOrIOEkp27mOd2EW67ifiTY10uZEvCXw== X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id a12-20020a170902ee8c00b001d7492d9890sm319639pld.146.2024.02.08.15.45.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Feb 2024 15:45: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 v1 1/3] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Related Patch Date: Thu, 8 Feb 2024 16:24:00 -0800 Message-ID: <20240209002403.11352-2-doug.edk2@gmail.com> In-Reply-To: <20240209002403.11352-1-doug.edk2@gmail.com> References: <20240209002403.11352-1-doug.edk2@gmail.com> 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=hJT7xXNJ; dmarc=pass (policy=none) header.from=groups.io; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io From: Doug Flick REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4673 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4534 This was not part of the Quarkslab bugs however the same pattern as CVE-2023-45229 exists in Dhcp6UpdateIaInfo. This patch replaces the code in question with the safe function created to patch CVE-2023-45229 > > if (EFI_ERROR ( > Dhcp6SeekInnerOptionSafe ( > Instance->Config->IaDescriptor.Type, > Option, > OptionLen, > &IaInnerOpt, > &IaInnerLen > ) > )) > { > return EFI_DEVICE_ERROR; > } > Additionally corrects incorrect usage of macro to read the status > - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); > + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *) DHCP6_OFFSET_OF_STATUS_CODE (Option)); Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 232 +++++++++++--------- 1 file changed, 134 insertions(+), 98 deletions(-) diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c index 3b8feb4a2032..6000e885afaf 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c @@ -510,6 +510,97 @@ Dhcp6CallbackUser ( 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 + //=0D + // Verify we have a fully formed IA_NA=0D + //=0D + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // Get the IA Inner Option and Length=0D + //=0D + IaInnerOptTmp =3D DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);=0D +=0D + //=0D + // Verify the IaInnerLen is valid.=0D + //=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 + //=0D + // Verify the OptionLen is valid.=0D + //=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 + //=0D + // Verify the IaInnerLen is valid.=0D + //=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 Update Ia according to the new reply message.=0D =0D @@ -528,13 +619,23 @@ Dhcp6UpdateIaInfo ( {=0D EFI_STATUS Status;=0D UINT8 *Option;=0D + UINT32 OptionLen;=0D UINT8 *IaInnerOpt;=0D UINT16 IaInnerLen;=0D UINT16 StsCode;=0D UINT32 T1;=0D UINT32 T2;=0D =0D + T1 =3D 0;=0D + T2 =3D 0;=0D +=0D ASSERT (Instance->Config !=3D NULL);=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 // If the reply was received in response to a solicit with rapid commit = option,=0D // request, renew or rebind message, the client updates the information = it has=0D @@ -549,13 +650,29 @@ Dhcp6UpdateIaInfo ( //=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 return EFI_DEVICE_ERROR;=0D }=0D =0D + //=0D + // Calculate the distance from Packet->Dhcp6.Option to the IA option.=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 + // (*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 + // 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 - (UINT32)(Option - Packet->Dhcp6.Option);=0D +=0D //=0D // The format of the IA_NA option is:=0D //=0D @@ -591,32 +708,32 @@ Dhcp6UpdateIaInfo ( //=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 - //=0D - // The inner options still start with 2 bytes option-code and 2 bytes op= tion-len.=0D + // Seek the inner option=0D //=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 if (Instance->Config->IaDescriptor.Type =3D=3D Dhcp6OptIana) {=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 - // the remainder of the message as though the server had not included= the invalid IA_NA option.=0D + // the remainder of the message as though the server had not included = the invalid IA_NA option.=0D //=0D if ((T1 > T2) && (T2 > 0)) {=0D return EFI_DEVICE_ERROR;=0D }=0D -=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 -=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 @@ -642,7 +759,7 @@ Dhcp6UpdateIaInfo ( Option =3D Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode)= ;=0D =0D if (Option !=3D NULL) {=0D - StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN= (Option))));=0D + StsCode =3D NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_= CODE (Option))));=0D if (StsCode !=3D Dhcp6StsSuccess) {=0D return EFI_DEVICE_ERROR;=0D }=0D @@ -662,87 +779,6 @@ 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 --=20 2.43.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#115281): https://edk2.groups.io/g/devel/message/115281 Mute This Topic: https://groups.io/mt/104250123/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-