From 79b32f0276708a906ced8ce54b307bc42dc6effd Mon Sep 17 00:00:00 2001 From: Doug Flick Date: Tue, 13 Feb 2024 10:46:00 -0800 Subject: [PATCH 1/3] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Related Patch REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4673 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534 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 = NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); > + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) DHCP6_OFFSET_OF_STATUS_CODE (Option)); Cc: Saloni Kasbekar Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] Reviewed-by: Saloni Kasbekar Reviewed-by: Leif Lindholm reference: https://github.com/tianocore/edk2/pull/5372 Signed-off-by: yexiao --- NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 877 ++++++++++++++++++---------------- NetworkPkg/Dhcp6Dxe/Dhcp6Io.h | 22 + 2 files changed, 479 insertions(+), 420 deletions(-) diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c index 9a31c118..5b337a09 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c @@ -3,7 +3,7 @@ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- Copyright (c) Microsoft Corporation + Copyright (c) Microsoft Corporation SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -541,13 +541,23 @@ Dhcp6UpdateIaInfo ( { EFI_STATUS Status; UINT8 *Option; + UINT32 OptionLen; UINT8 *IaInnerOpt; UINT16 IaInnerLen; UINT16 StsCode; UINT32 T1; UINT32 T2; + T1 = 0; + T2 = 0; + ASSERT (Instance->Config != NULL); + + // OptionLen is the length of the Options excluding the DHCP header. + // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last + // byte of the Option[] field. + OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); + // // If the reply was received in response to a solicit with rapid commit option, // request, renew or rebind message, the client updates the information it has @@ -562,13 +572,29 @@ Dhcp6UpdateIaInfo ( // Option = Dhcp6SeekIaOption ( Packet->Dhcp6.Option, - Packet->Length - sizeof (EFI_DHCP6_HEADER), + OptionLen, &Instance->Config->IaDescriptor ); if (Option == NULL) { return EFI_DEVICE_ERROR; } + // + // Calculate the distance from Packet->Dhcp6.Option to the IA option. + // + // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size 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. + // + // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of + // DHCP6 option area to the start of the IA option. + // + // 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 = OptionLen - (UINT32)(Option - Packet->Dhcp6.Option); + // // The format of the IA_NA option is: // @@ -604,31 +630,32 @@ Dhcp6UpdateIaInfo ( // // - // sizeof (option-code + option-len + IaId) = 8 - // sizeof (option-code + option-len + IaId + T1) = 12 - // sizeof (option-code + option-len + IaId + T1 + T2) = 16 - // - // The inner options still start with 2 bytes option-code and 2 bytes option-len. + // Seek the inner option // + if (EFI_ERROR ( + Dhcp6SeekInnerOptionSafe ( + Instance->Config->IaDescriptor.Type, + Option, + OptionLen, + &IaInnerOpt, + &IaInnerLen + ) + )) + { + return EFI_DEVICE_ERROR; + } + if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { - T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); - T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); + T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); + T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); // // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2, // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes - // the remainder of the message as though the server had not included the invalid IA_NA option. + // the remainder of the message as though the server had not included the invalid IA_NA option. // if (T1 > T2 && T2 > 0) { return EFI_DEVICE_ERROR; } - IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); - IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); - } else { - T1 = 0; - T2 = 0; - - IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); - IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID); } // @@ -654,7 +681,7 @@ Dhcp6UpdateIaInfo ( Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); if (Option != NULL) { - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (Option)))); if (StsCode != Dhcp6StsSuccess) { return EFI_DEVICE_ERROR; } @@ -674,86 +701,96 @@ Dhcp6UpdateIaInfo ( return Status; } -/** - 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 == NULL) { - ASSERT (Option != NULL); - return EFI_DEVICE_ERROR; - } - - if (IaInnerOpt == NULL) { - ASSERT (IaInnerOpt != NULL); - return EFI_DEVICE_ERROR; - } - - if (IaInnerLen == NULL) { - ASSERT (IaInnerLen != NULL); - return EFI_DEVICE_ERROR; - } - - if (IaType == Dhcp6OptIana) { - // Verify we have a fully formed IA_NA - if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { - return EFI_DEVICE_ERROR; - } - - // - IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); - - // Verify the IaInnerLen is valid. - IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); - if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { - return EFI_DEVICE_ERROR; - } - - IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; - } else if (IaType == Dhcp6OptIata) { - // Verify the OptionLen is valid. - if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { - return EFI_DEVICE_ERROR; - } - - IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); - - // Verify the IaInnerLen is valid. - IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); - if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { - return EFI_DEVICE_ERROR; - } - - IaInnerLenTmp -= DHCP6_SIZE_OF_IAID; - } else { - return EFI_DEVICE_ERROR; - } - - *IaInnerOpt = IaInnerOptTmp; - *IaInnerLen = IaInnerLenTmp; - - return EFI_SUCCESS; -} +/** + 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 == NULL) { + ASSERT (Option != NULL); + return EFI_DEVICE_ERROR; + } + + if (IaInnerOpt == NULL) { + ASSERT (IaInnerOpt != NULL); + return EFI_DEVICE_ERROR; + } + + if (IaInnerLen == NULL) { + ASSERT (IaInnerLen != NULL); + return EFI_DEVICE_ERROR; + } + + if (IaType == Dhcp6OptIana) { + // + // Verify we have a fully formed IA_NA + // + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { + return EFI_DEVICE_ERROR; + } + + // + // Get the IA Inner Option and Length + // + IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); + + // + // Verify the IaInnerLen is valid. + // + IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); + if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { + return EFI_DEVICE_ERROR; + } + + IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2; + } else if (IaType == Dhcp6OptIata) { + // + // Verify the OptionLen is valid. + // + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) { + return EFI_DEVICE_ERROR; + } + + IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); + + // + // Verify the IaInnerLen is valid. + // + IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); + if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) { + return EFI_DEVICE_ERROR; + } + + IaInnerLenTmp -= DHCP6_SIZE_OF_IAID; + } else { + return EFI_DEVICE_ERROR; + } + + *IaInnerOpt = IaInnerOptTmp; + *IaInnerLen = IaInnerLenTmp; + + return EFI_SUCCESS; +} /** Seek StatusCode Option in package. A Status Code option may appear in the @@ -778,12 +815,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 field to the last - // byte of the Option[] field. - OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); + 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 field to the last + // byte of the Option[] field. + OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); // // Seek StatusCode option directly in DHCP message body. That is, search in @@ -791,12 +828,12 @@ Dhcp6SeekStsOption ( // *Option = Dhcp6SeekOption ( Packet->Dhcp6.Option, - OptionLen, + OptionLen, Dhcp6OptStatusCode ); if (*Option != NULL) { - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option)))); + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option)))); if (StsCode != Dhcp6StsSuccess) { return EFI_DEVICE_ERROR; } @@ -807,7 +844,7 @@ Dhcp6SeekStsOption ( // *Option = Dhcp6SeekIaOption ( Packet->Dhcp6.Option, - OptionLen, + OptionLen, &Instance->Config->IaDescriptor ); if (*Option == NULL) { @@ -815,34 +852,34 @@ Dhcp6SeekStsOption ( } // - // Calculate the distance from Packet->Dhcp6.Option to the IA option. + // Calculate the distance from Packet->Dhcp6.Option to the IA option. // - // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size 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. + // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size 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. // - // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of - // DHCP6 option area to the start of the IA option. + // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of + // DHCP6 option area to the start of the IA option. // - // 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 + // 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 = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option); + OptionLen = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option); // - // Seek the inner option + // Seek the inner option // - if (EFI_ERROR ( - Dhcp6SeekInnerOptionSafe ( - Instance->Config->IaDescriptor.Type, - *Option, - OptionLen, - &IaInnerOpt, - &IaInnerLen - ) - )) - { - return EFI_DEVICE_ERROR; + if (EFI_ERROR ( + Dhcp6SeekInnerOptionSafe ( + Instance->Config->IaDescriptor.Type, + *Option, + OptionLen, + &IaInnerOpt, + &IaInnerLen + ) + )) + { + return EFI_DEVICE_ERROR; } // @@ -866,7 +903,7 @@ Dhcp6SeekStsOption ( // *Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); if (*Option != NULL) { - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option))))); + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option))))); if (StsCode != Dhcp6StsSuccess) { return EFI_DEVICE_ERROR; } @@ -1014,8 +1051,8 @@ Dhcp6SendSolicitMsg ( // Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; @@ -1029,38 +1066,38 @@ Dhcp6SendSolicitMsg ( Cursor = Packet->Dhcp6.Option; Length = HTONS (ClientId->Length); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendETOption ( - Packet, - &Cursor, + Status = Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendIaOption ( - Packet, - &Cursor, + Status = Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } // // Append user-defined when configurate Dhcp6 service. @@ -1068,16 +1105,16 @@ Dhcp6SendSolicitMsg ( for (Index = 0; Index < Instance->Config->OptionCount; Index++) { UserOpt = Instance->Config->OptionList[Index]; - Status = Dhcp6AppendOption( - Packet, - &Cursor, + Status = Dhcp6AppendOption( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } ASSERT (Packet->Size > Packet->Length + 8); @@ -1088,7 +1125,7 @@ Dhcp6SendSolicitMsg ( Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // @@ -1103,7 +1140,7 @@ Dhcp6SendSolicitMsg ( Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // @@ -1115,14 +1152,14 @@ Dhcp6SendSolicitMsg ( Elapsed, Instance->Config->SolicitRetransmission ); - -ON_ERROR: - - if (Packet) { - FreePool (Packet); - } - - return Status; + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } /** @@ -1192,7 +1229,7 @@ Dhcp6SendRequestMsg ( // Option = Dhcp6SeekOption ( Instance->AdSelect->Dhcp6.Option, - Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER), + Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option == NULL) { @@ -1214,8 +1251,8 @@ Dhcp6SendRequestMsg ( // Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; @@ -1229,49 +1266,49 @@ Dhcp6SendRequestMsg ( Cursor = Packet->Dhcp6.Option; Length = HTONS (ClientId->Length); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendETOption ( - Packet, - &Cursor, + Status = Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendIaOption ( - Packet, - &Cursor, + Status = Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } // // Append user-defined when configurate Dhcp6 service. @@ -1279,16 +1316,16 @@ Dhcp6SendRequestMsg ( for (Index = 0; Index < Instance->Config->OptionCount; Index++) { UserOpt = Instance->Config->OptionList[Index]; - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } ASSERT (Packet->Size > Packet->Length + 8); @@ -1299,7 +1336,7 @@ Dhcp6SendRequestMsg ( Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // @@ -1315,21 +1352,21 @@ Dhcp6SendRequestMsg ( Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // // 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; + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } @@ -1378,7 +1415,7 @@ Dhcp6SendDeclineMsg ( // Option = Dhcp6SeekOption ( LastReply->Dhcp6.Option, - LastReply->Length - sizeof (EFI_DHCP6_HEADER), + LastReply->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option == NULL) { @@ -1395,8 +1432,8 @@ Dhcp6SendDeclineMsg ( // Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); if (Packet == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } Packet->Size = DHCP6_BASE_PACKET_SIZE; @@ -1410,49 +1447,49 @@ Dhcp6SendDeclineMsg ( Cursor = Packet->Dhcp6.Option; Length = HTONS (ClientId->Length); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendETOption ( - Packet, - &Cursor, + Status = Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = Dhcp6AppendIaOption ( - Packet, - &Cursor, - DecIa, - 0, - 0, - Packet->Dhcp6.Header.MessageType - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + Status = Dhcp6AppendIaOption ( + Packet, + &Cursor, + DecIa, + 0, + 0, + Packet->Dhcp6.Header.MessageType + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } ASSERT (Packet->Size > Packet->Length + 8); @@ -1462,7 +1499,7 @@ Dhcp6SendDeclineMsg ( Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // @@ -1478,21 +1515,21 @@ Dhcp6SendDeclineMsg ( Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // // 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; + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } @@ -1540,7 +1577,7 @@ Dhcp6SendReleaseMsg ( // Option = Dhcp6SeekOption ( LastReply->Dhcp6.Option, - LastReply->Length - sizeof (EFI_DHCP6_HEADER), + LastReply->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option == NULL) { @@ -1554,8 +1591,8 @@ Dhcp6SendReleaseMsg ( // Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); if (Packet == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } Packet->Size = DHCP6_BASE_PACKET_SIZE; @@ -1569,52 +1606,52 @@ Dhcp6SendReleaseMsg ( Cursor = Packet->Dhcp6.Option; Length = HTONS (ClientId->Length); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } // // ServerId is extracted from packet, it's network order. // - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendETOption ( - Packet, - &Cursor, + Status = Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = Dhcp6AppendIaOption ( - Packet, - &Cursor, - RelIa, - 0, - 0, - Packet->Dhcp6.Header.MessageType - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + Status = Dhcp6AppendIaOption ( + Packet, + &Cursor, + RelIa, + 0, + 0, + Packet->Dhcp6.Header.MessageType + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } ASSERT (Packet->Size > Packet->Length + 8); @@ -1624,7 +1661,7 @@ Dhcp6SendReleaseMsg ( Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // @@ -1636,21 +1673,21 @@ Dhcp6SendReleaseMsg ( Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // // 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; + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } @@ -1710,8 +1747,8 @@ Dhcp6SendRenewRebindMsg ( // Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; @@ -1725,38 +1762,38 @@ Dhcp6SendRenewRebindMsg ( Cursor = Packet->Dhcp6.Option; Length = HTONS (ClientId->Length); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendETOption ( - Packet, - &Cursor, + Status = Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendIaOption ( - Packet, - &Cursor, + Status = Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } if (!RebindRequest) { // @@ -1768,7 +1805,7 @@ Dhcp6SendRenewRebindMsg ( Option = Dhcp6SeekOption ( LastReply->Dhcp6.Option, - LastReply->Length - sizeof (EFI_DHCP6_HEADER), + LastReply->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); if (Option == NULL) { @@ -1778,16 +1815,16 @@ Dhcp6SendRenewRebindMsg ( ServerId = (EFI_DHCP6_DUID *) (Option + 2); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptServerId), ServerId->Length, ServerId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } // @@ -1796,16 +1833,16 @@ Dhcp6SendRenewRebindMsg ( for (Index = 0; Index < Instance->Config->OptionCount; Index++) { UserOpt = Instance->Config->OptionList[Index]; - Status = Dhcp6AppendOption( - Packet, - &Cursor, + Status = Dhcp6AppendOption( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } ASSERT (Packet->Size > Packet->Length + 8); @@ -1819,7 +1856,7 @@ Dhcp6SendRenewRebindMsg ( Status = Dhcp6CallbackUser (Instance, Event, &Packet); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // @@ -1838,21 +1875,21 @@ Dhcp6SendRenewRebindMsg ( Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // // 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; + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } /** @@ -2016,8 +2053,8 @@ Dhcp6SendInfoRequestMsg ( // Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; @@ -2034,38 +2071,38 @@ Dhcp6SendInfoRequestMsg ( if (SendClientId) { Length = HTONS (ClientId->Length); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } - Status = Dhcp6AppendETOption ( - Packet, - &Cursor, + Status = Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, OptionRequest->OpCode, OptionRequest->OpLen, OptionRequest->Data ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } // // Append user-defined when configurate Dhcp6 service. @@ -2073,16 +2110,16 @@ Dhcp6SendInfoRequestMsg ( for (Index = 0; Index < OptionCount; Index++) { UserOpt = OptionList[Index]; - Status = Dhcp6AppendOption( - Packet, - &Cursor, + Status = Dhcp6AppendOption( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } ASSERT (Packet->Size > Packet->Length + 8); @@ -2098,21 +2135,21 @@ Dhcp6SendInfoRequestMsg ( Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // // 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; + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } @@ -2164,8 +2201,8 @@ Dhcp6SendConfirmMsg ( // Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); if (Packet == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; } Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen; @@ -2179,54 +2216,54 @@ Dhcp6SendConfirmMsg ( Cursor = Packet->Dhcp6.Option; Length = HTONS (ClientId->Length); - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, HTONS (Dhcp6OptClientId), Length, ClientId->Duid ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendETOption ( - Packet, - &Cursor, + Status = Dhcp6AppendETOption ( + Packet, + &Cursor, Instance, &Elapsed ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } - Status = Dhcp6AppendIaOption ( - Packet, - &Cursor, + Status = Dhcp6AppendIaOption ( + Packet, + &Cursor, Instance->IaCb.Ia, Instance->IaCb.T1, Instance->IaCb.T2, Packet->Dhcp6.Header.MessageType ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } // // Append user-defined when configurate Dhcp6 service. // for (Index = 0; Index < Instance->Config->OptionCount; Index++) { UserOpt = Instance->Config->OptionList[Index]; - Status = Dhcp6AppendOption ( - Packet, - &Cursor, + Status = Dhcp6AppendOption ( + Packet, + &Cursor, UserOpt->OpCode, UserOpt->OpLen, UserOpt->Data ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } } ASSERT (Packet->Size > Packet->Length + 8); @@ -2237,7 +2274,7 @@ Dhcp6SendConfirmMsg ( Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // @@ -2253,21 +2290,21 @@ Dhcp6SendConfirmMsg ( Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); if (EFI_ERROR (Status)) { - goto ON_ERROR; + goto ON_ERROR; } // // 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; + +ON_ERROR: + + if (Packet) { + FreePool (Packet); + } + + return Status; } @@ -2313,7 +2350,7 @@ Dhcp6HandleReplyMsg ( // Option = Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - sizeof (EFI_DHCP6_HEADER), + Packet->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptRapidCommit ); @@ -2461,7 +2498,7 @@ Dhcp6HandleReplyMsg ( // // Any error status code option is found. // - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option))))); + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option))))); switch (StsCode) { case Dhcp6StsUnspecFail: // @@ -2592,7 +2629,7 @@ Dhcp6SelectAdvertiseMsg ( // Option = Dhcp6SeekOption( AdSelect->Dhcp6.Option, - AdSelect->Length - sizeof (EFI_DHCP6_HEADER), + AdSelect->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerUnicast ); @@ -2604,7 +2641,7 @@ Dhcp6SelectAdvertiseMsg ( return EFI_OUT_OF_RESOURCES; } - CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS)); + CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS)); } // @@ -2658,7 +2695,7 @@ Dhcp6HandleAdvertiseMsg ( // Option = Dhcp6SeekOption( Packet->Dhcp6.Option, - Packet->Length - sizeof (EFI_DHCP6_HEADER), + Packet->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptRapidCommit ); @@ -2754,7 +2791,7 @@ Dhcp6HandleAdvertiseMsg ( CopyMem (Instance->AdSelect, Packet, Packet->Size); if (Option != NULL) { - Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option)); + Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option)); } } else { // @@ -2825,11 +2862,11 @@ Dhcp6HandleStateful ( // Option = Dhcp6SeekOption( Packet->Dhcp6.Option, - Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, Dhcp6OptClientId ); - if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) { + if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) { goto ON_CONTINUE; } @@ -2838,7 +2875,7 @@ Dhcp6HandleStateful ( // Option = Dhcp6SeekOption( Packet->Dhcp6.Option, - Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, Dhcp6OptServerId ); @@ -2943,7 +2980,7 @@ Dhcp6HandleStateless ( // Option = Dhcp6SeekOption ( Packet->Dhcp6.Option, - Packet->Length - sizeof (EFI_DHCP6_HEADER), + Packet->Length - sizeof (EFI_DHCP6_HEADER), Dhcp6OptServerId ); diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h index 554f0f5e..3243f05b 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h @@ -218,4 +218,26 @@ Dhcp6OnTimerTick ( IN VOID *Context ); +/** + 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 + ); + #endif -- 2.33.0