mirror of https://github.com/acidanthera/audk.git
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 <saloni.kasbekar@intel.com> Cc: Zachary Clark-williams <zachary.clark-williams@intel.com> Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com> Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com> Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
This commit is contained in:
parent
a1c426e844
commit
1c440a5ece
|
@ -528,13 +528,23 @@ Dhcp6UpdateIaInfo (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT8 *Option;
|
UINT8 *Option;
|
||||||
|
UINT32 OptionLen;
|
||||||
UINT8 *IaInnerOpt;
|
UINT8 *IaInnerOpt;
|
||||||
UINT16 IaInnerLen;
|
UINT16 IaInnerLen;
|
||||||
UINT16 StsCode;
|
UINT16 StsCode;
|
||||||
UINT32 T1;
|
UINT32 T1;
|
||||||
UINT32 T2;
|
UINT32 T2;
|
||||||
|
|
||||||
|
T1 = 0;
|
||||||
|
T2 = 0;
|
||||||
|
|
||||||
ASSERT (Instance->Config != NULL);
|
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,
|
// 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
|
// request, renew or rebind message, the client updates the information it has
|
||||||
|
@ -549,13 +559,29 @@ Dhcp6UpdateIaInfo (
|
||||||
//
|
//
|
||||||
Option = Dhcp6SeekIaOption (
|
Option = Dhcp6SeekIaOption (
|
||||||
Packet->Dhcp6.Option,
|
Packet->Dhcp6.Option,
|
||||||
Packet->Length - sizeof (EFI_DHCP6_HEADER),
|
OptionLen,
|
||||||
&Instance->Config->IaDescriptor
|
&Instance->Config->IaDescriptor
|
||||||
);
|
);
|
||||||
if (Option == NULL) {
|
if (Option == NULL) {
|
||||||
return EFI_DEVICE_ERROR;
|
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:
|
// The format of the IA_NA option is:
|
||||||
//
|
//
|
||||||
|
@ -591,12 +617,21 @@ Dhcp6UpdateIaInfo (
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// sizeof (option-code + option-len + IaId) = 8
|
// Seek the inner option
|
||||||
// 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.
|
|
||||||
//
|
//
|
||||||
|
if (EFI_ERROR (
|
||||||
|
Dhcp6SeekInnerOptionSafe (
|
||||||
|
Instance->Config->IaDescriptor.Type,
|
||||||
|
Option,
|
||||||
|
OptionLen,
|
||||||
|
&IaInnerOpt,
|
||||||
|
&IaInnerLen
|
||||||
|
)
|
||||||
|
))
|
||||||
|
{
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {
|
if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {
|
||||||
T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option))));
|
T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option))));
|
||||||
T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option))));
|
T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option))));
|
||||||
|
@ -608,15 +643,6 @@ Dhcp6UpdateIaInfo (
|
||||||
if ((T1 > T2) && (T2 > 0)) {
|
if ((T1 > T2) && (T2 > 0)) {
|
||||||
return EFI_DEVICE_ERROR;
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -642,7 +668,7 @@ Dhcp6UpdateIaInfo (
|
||||||
Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);
|
Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);
|
||||||
|
|
||||||
if (Option != NULL) {
|
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) {
|
if (StsCode != Dhcp6StsSuccess) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -703,15 +729,21 @@ Dhcp6SeekInnerOptionSafe (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IaType == Dhcp6OptIana) {
|
if (IaType == Dhcp6OptIana) {
|
||||||
|
//
|
||||||
// Verify we have a fully formed IA_NA
|
// Verify we have a fully formed IA_NA
|
||||||
|
//
|
||||||
if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) {
|
if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the IA Inner Option and Length
|
||||||
//
|
//
|
||||||
IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);
|
IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);
|
||||||
|
|
||||||
|
//
|
||||||
// Verify the IaInnerLen is valid.
|
// Verify the IaInnerLen is valid.
|
||||||
|
//
|
||||||
IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option)));
|
IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option)));
|
||||||
if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) {
|
if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
|
@ -719,14 +751,18 @@ Dhcp6SeekInnerOptionSafe (
|
||||||
|
|
||||||
IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2;
|
IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2;
|
||||||
} else if (IaType == Dhcp6OptIata) {
|
} else if (IaType == Dhcp6OptIata) {
|
||||||
|
//
|
||||||
// Verify the OptionLen is valid.
|
// Verify the OptionLen is valid.
|
||||||
|
//
|
||||||
if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) {
|
if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);
|
IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);
|
||||||
|
|
||||||
|
//
|
||||||
// Verify the IaInnerLen is valid.
|
// Verify the IaInnerLen is valid.
|
||||||
|
//
|
||||||
IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option))));
|
IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option))));
|
||||||
if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) {
|
if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) {
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
|
|
|
@ -217,4 +217,26 @@ Dhcp6OnTimerTick (
|
||||||
IN VOID *Context
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue