* [edk2-devel] [PATCH 01/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 11:30 ` Gerd Hoffmann
2024-01-24 3:33 ` [edk2-devel] [PATCH 02/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests Doug Flick via groups.io
` (13 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel; +Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535
SECURITY PATCH - Patch
TCBZ4535
CVE-2023-45230
CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
CWE-119 Improper Restriction of Operations within the Bounds
of a Memory Buffer
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>
---
NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 43 +++
NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h | 78 +++---
NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 409 +++++++++++++++++++----------
NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 373 +++++++++++++++++++++-----
4 files changed, 666 insertions(+), 237 deletions(-)
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
index 0eb9c669b5a1..f2422c2f2827 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
@@ -45,6 +45,49 @@ 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')
+//
+// For more information on DHCP options see RFC 8415, Section 21.1
+//
+// The format of DHCP options is:
+//
+// 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-code | option-len |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | option-data |
+// | (option-len octets) |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16))
+#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16))
+
+//
+// Combined size of Code and Length
+//
+#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \
+ DHCP6_SIZE_OF_OPT_LEN)
+
+STATIC_ASSERT (
+ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN == 4,
+ "Combined size of Code and Length must be 4 per RFC 8415"
+ );
+
+//
+// Offset to the length is just past the code
+//
+#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE)
+STATIC_ASSERT (
+ DHCP6_OPT_LEN_OFFSET (0) == 2,
+ "Offset of length is + 2 past start of option"
+ );
+
+#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN)
+STATIC_ASSERT (
+ DHCP6_OPT_DATA_OFFSET (0) == 4,
+ "Offset to option data should be +4 from start of option"
+ );
+
#define DHCP6_PACKET_ALL 0
#define DHCP6_PACKET_STATEFUL 1
#define DHCP6_PACKET_STATELESS 2
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
index 046454ff4ac2..06947f6c1fcf 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
@@ -160,69 +160,85 @@ Dhcp6OnTransmitted (
);
/**
- Append the appointed option to the buf, and move the buf to the end.
+ Append the option to Buf, update the length of packet, and move Buf to the end.
- @param[in, out] Buf The pointer to buffer.
- @param[in] OptType The option type.
- @param[in] OptLen The length of option content.s
- @param[in] Data The pointer to the option content.
-
- @return Buf The position to append the next option.
+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
+ will be updated.
+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
+ will be moved to the end of the option.
+ @param[in] OptType The option type.
+ @param[in] OptLen The length of option contents.
+ @param[in] Data The pointer to the option content.
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
-UINT8 *
+EFI_STATUS
Dhcp6AppendOption (
- IN OUT UINT8 *Buf,
- IN UINT16 OptType,
- IN UINT16 OptLen,
- IN UINT8 *Data
+ IN OUT EFI_DHCP6_PACKET *Packet,
+ IN OUT UINT8 **PacketCursor,
+ IN UINT16 OptType,
+ IN UINT16 OptLen,
+ IN UINT8 *Data
);
/**
- Append the Ia option to Buf, and move Buf to the end.
-
- @param[in, out] Buf The pointer to the position to append.
+ Append the appointed Ia option to Buf, update the Ia option length, and move Buf
+ to the end of the option.
+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
+ will be updated.
+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
+ will be moved to the end of the option.
@param[in] Ia The pointer to the Ia.
@param[in] T1 The time of T1.
@param[in] T2 The time of T2.
@param[in] MessageType Message type of DHCP6 package.
- @return Buf The position to append the next Ia option.
-
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
-UINT8 *
+EFI_STATUS
Dhcp6AppendIaOption (
- IN OUT UINT8 *Buf,
- IN EFI_DHCP6_IA *Ia,
- IN UINT32 T1,
- IN UINT32 T2,
- IN UINT32 MessageType
+ IN OUT EFI_DHCP6_PACKET *Packet,
+ IN OUT UINT8 **PacketCursor,
+ IN EFI_DHCP6_IA *Ia,
+ IN UINT32 T1,
+ IN UINT32 T2,
+ IN UINT32 MessageType
);
/**
Append the appointed Elapsed time option to Buf, and move Buf to the end.
- @param[in, out] Buf The pointer to the position to append.
+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
+ will be moved to the end of the option.
@param[in] Instance The pointer to the Dhcp6 instance.
@param[out] Elapsed The pointer to the elapsed time value in
the generated packet.
- @return Buf The position to append the next Ia option.
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
-UINT8 *
+EFI_STATUS
Dhcp6AppendETOption (
- IN OUT UINT8 *Buf,
- IN DHCP6_INSTANCE *Instance,
- OUT UINT16 **Elapsed
+ IN OUT EFI_DHCP6_PACKET *Packet,
+ IN OUT UINT8 **PacketCursor,
+ IN DHCP6_INSTANCE *Instance,
+ OUT UINT16 **Elapsed
);
/**
Set the elapsed time based on the given instance and the pointer to the
elapsed time option.
- @param[in] Elapsed The pointer to the position to append.
- @param[in] Instance The pointer to the Dhcp6 instance.
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
VOID
SetElapsedTime (
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
index dcd01e6268b1..bf5aa7a769de 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
@@ -3,9 +3,9 @@
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
-
**/
#include "Dhcp6Impl.h"
@@ -930,7 +930,8 @@ Dhcp6SendSolicitMsg (
//
Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
if (Packet == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
}
Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
@@ -944,54 +945,64 @@ Dhcp6SendSolicitMsg (
Cursor = Packet->Dhcp6.Option;
Length = HTONS (ClientId->Length);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptClientId),
Length,
ClientId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendETOption (
- Cursor,
+ Status = Dhcp6AppendETOption (
+ Packet,
+ &Cursor,
Instance,
&Elapsed
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendIaOption (
- 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;
+ }
//
// Append user-defined when configurate Dhcp6 service.
//
for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
UserOpt = Instance->Config->OptionList[Index];
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
UserOpt->OpCode,
UserOpt->OpLen,
UserOpt->Data
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
}
- //
- // Determine the size/length of packet.
- //
- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
ASSERT (Packet->Size > Packet->Length + 8);
//
// Callback to user with the packet to be sent and check the user's feedback.
//
Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ goto ON_ERROR;
}
//
@@ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg (
Instance->StartTime = 0;
Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ goto ON_ERROR;
}
//
@@ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg (
Elapsed,
Instance->Config->SolicitRetransmission
);
+
+ON_ERROR:
+
+ if (Packet) {
+ FreePool (Packet);
+ }
+
+ return Status;
}
/**
@@ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg (
//
Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
if (Packet == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
}
Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
@@ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg (
Cursor = Packet->Dhcp6.Option;
Length = HTONS (ClientId->Length);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptClientId),
Length,
ClientId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendETOption (
- Cursor,
+ Status = Dhcp6AppendETOption (
+ Packet,
+ &Cursor,
Instance,
&Elapsed
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptServerId),
ServerId->Length,
ServerId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendIaOption (
- 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;
+ }
//
// Append user-defined when configurate Dhcp6 service.
//
for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
UserOpt = Instance->Config->OptionList[Index];
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
UserOpt->OpCode,
UserOpt->OpLen,
UserOpt->Data
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
}
- //
- // Determine the size/length of packet.
- //
- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
ASSERT (Packet->Size > Packet->Length + 8);
//
@@ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg (
Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet);
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ goto ON_ERROR;
}
//
@@ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg (
Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ 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;
}
/**
@@ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg (
//
Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
if (Packet == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
}
Packet->Size = DHCP6_BASE_PACKET_SIZE;
@@ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg (
Cursor = Packet->Dhcp6.Option;
Length = HTONS (ClientId->Length);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptClientId),
Length,
ClientId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendETOption (
- Cursor,
+ Status = Dhcp6AppendETOption (
+ Packet,
+ &Cursor,
Instance,
&Elapsed
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptServerId),
ServerId->Length,
ServerId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType);
+ Status = Dhcp6AppendIaOption (
+ Packet,
+ &Cursor,
+ DecIa,
+ 0,
+ 0,
+ Packet->Dhcp6.Header.MessageType
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- //
- // Determine the size/length of packet.
- //
- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
ASSERT (Packet->Size > Packet->Length + 8);
//
// Callback to user with the packet to be sent and check the user's feedback.
//
Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ goto ON_ERROR;
}
//
@@ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg (
Instance->StartTime = 0;
Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ 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;
}
/**
@@ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg (
//
Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
if (Packet == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
}
Packet->Size = DHCP6_BASE_PACKET_SIZE;
@@ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg (
Cursor = Packet->Dhcp6.Option;
Length = HTONS (ClientId->Length);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptClientId),
Length,
ClientId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
//
// ServerId is extracted from packet, it's network order.
//
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptServerId),
ServerId->Length,
ServerId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendETOption (
- Cursor,
+ Status = Dhcp6AppendETOption (
+ Packet,
+ &Cursor,
Instance,
&Elapsed
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType);
+ Status = Dhcp6AppendIaOption (
+ Packet,
+ &Cursor,
+ RelIa,
+ 0,
+ 0,
+ Packet->Dhcp6.Header.MessageType
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- //
- // Determine the size/length of packet
- //
- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
ASSERT (Packet->Size > Packet->Length + 8);
//
// Callback to user with the packet to be sent and check the user's feedback.
//
Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ goto ON_ERROR;
}
//
@@ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg (
Instance->IaCb.Ia->State = Dhcp6Releasing;
Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ 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;
}
/**
@@ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg (
//
Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
if (Packet == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
}
Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
@@ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg (
Cursor = Packet->Dhcp6.Option;
Length = HTONS (ClientId->Length);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptClientId),
Length,
ClientId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendETOption (
- Cursor,
+ Status = Dhcp6AppendETOption (
+ Packet,
+ &Cursor,
Instance,
&Elapsed
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendIaOption (
- 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 (!RebindRequest) {
//
@@ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg (
Dhcp6OptServerId
);
if (Option == NULL) {
- FreePool (Packet);
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ goto ON_ERROR;
}
ServerId = (EFI_DHCP6_DUID *)(Option + 2);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptServerId),
ServerId->Length,
ServerId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
}
//
@@ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg (
//
for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
UserOpt = Instance->Config->OptionList[Index];
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
UserOpt->OpCode,
UserOpt->OpLen,
UserOpt->Data
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
}
- //
- // Determine the size/length of packet.
- //
- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
ASSERT (Packet->Size > Packet->Length + 8);
//
@@ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg (
Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing;
Status = Dhcp6CallbackUser (Instance, Event, &Packet);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ goto ON_ERROR;
}
//
@@ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg (
Instance->StartTime = 0;
Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ 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;
}
/**
@@ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg (
//
Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
if (Packet == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
}
Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
@@ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg (
if (SendClientId) {
Length = HTONS (ClientId->Length);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptClientId),
Length,
ClientId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
}
- Cursor = Dhcp6AppendETOption (
- Cursor,
+ Status = Dhcp6AppendETOption (
+ Packet,
+ &Cursor,
Instance,
&Elapsed
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
OptionRequest->OpCode,
OptionRequest->OpLen,
OptionRequest->Data
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
//
// Append user-defined when configurate Dhcp6 service.
//
for (Index = 0; Index < OptionCount; Index++) {
UserOpt = OptionList[Index];
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
UserOpt->OpCode,
UserOpt->OpLen,
UserOpt->Data
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
}
- //
- // Determine the size/length of packet.
- //
- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
ASSERT (Packet->Size > Packet->Length + 8);
//
@@ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg (
// Send info-request packet with no state.
//
Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ 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;
}
/**
@@ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg (
//
Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
if (Packet == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
}
Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
@@ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg (
Cursor = Packet->Dhcp6.Option;
Length = HTONS (ClientId->Length);
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
HTONS (Dhcp6OptClientId),
Length,
ClientId->Duid
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendETOption (
- Cursor,
+ Status = Dhcp6AppendETOption (
+ Packet,
+ &Cursor,
Instance,
&Elapsed
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
- Cursor = Dhcp6AppendIaOption (
- 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;
+ }
//
// Append user-defined when configurate Dhcp6 service.
//
for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
UserOpt = Instance->Config->OptionList[Index];
- Cursor = Dhcp6AppendOption (
- Cursor,
+ Status = Dhcp6AppendOption (
+ Packet,
+ &Cursor,
UserOpt->OpCode,
UserOpt->OpLen,
UserOpt->Data
);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
}
- //
- // Determine the size/length of packet.
- //
- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
ASSERT (Packet->Size > Packet->Length + 8);
//
// Callback to user with the packet to be sent and check the user's feedback.
//
Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ goto ON_ERROR;
}
//
@@ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg (
Instance->StartTime = 0;
Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
-
if (EFI_ERROR (Status)) {
- FreePool (Packet);
- return Status;
+ 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;
}
/**
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
index e6368b5b1c6c..705c665c519d 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
@@ -577,24 +577,33 @@ Dhcp6OnTransmitted (
}
/**
- Append the option to Buf, and move Buf to the end.
+ Append the option to Buf, update the length of packet, and move Buf to the end.
- @param[in, out] Buf The pointer to the buffer.
- @param[in] OptType The option type.
- @param[in] OptLen The length of option contents.
- @param[in] Data The pointer to the option content.
+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
+ will be updated.
+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
+ will be moved to the end of the option.
+ @param[in] OptType The option type.
+ @param[in] OptLen The length of option contents.
+ @param[in] Data The pointer to the option content.
- @return Buf The position to append the next option.
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
-UINT8 *
+EFI_STATUS
Dhcp6AppendOption (
- IN OUT UINT8 *Buf,
- IN UINT16 OptType,
- IN UINT16 OptLen,
- IN UINT8 *Data
+ IN OUT EFI_DHCP6_PACKET *Packet,
+ IN OUT UINT8 **PacketCursor,
+ IN UINT16 OptType,
+ IN UINT16 OptLen,
+ IN UINT8 *Data
)
{
+ UINT32 Length;
+ UINT32 BytesNeeded;
+
//
// The format of Dhcp6 option:
//
@@ -607,35 +616,95 @@ Dhcp6AppendOption (
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
- ASSERT (OptLen != 0);
+ //
+ // Verify the arguments are valid
+ //
+ if (Packet == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
- WriteUnaligned16 ((UINT16 *)Buf, OptType);
- Buf += 2;
- WriteUnaligned16 ((UINT16 *)Buf, OptLen);
- Buf += 2;
- CopyMem (Buf, Data, NTOHS (OptLen));
- Buf += NTOHS (OptLen);
+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
- return Buf;
+ if (Data == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (OptLen == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Verify the PacketCursor is within the packet
+ //
+ if ( (*PacketCursor < Packet->Dhcp6.Option)
+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Calculate the bytes needed for the option
+ //
+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen);
+
+ //
+ // Space remaining in the packet
+ //
+ Length = Packet->Size - Packet->Length;
+ if (Length < BytesNeeded) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Verify the PacketCursor is within the packet
+ //
+ if ( (*PacketCursor < Packet->Dhcp6.Option)
+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType);
+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen);
+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
+ CopyMem (*PacketCursor, Data, NTOHS (OptLen));
+ *PacketCursor += NTOHS (OptLen);
+
+ // Update the packet length by the length of the option + 4 bytes
+ Packet->Length += BytesNeeded;
+
+ return EFI_SUCCESS;
}
/**
Append the appointed IA Address option to Buf, and move Buf to the end.
- @param[in, out] Buf The pointer to the position to append.
+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
+ will be updated.
+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
+ will be moved to the end of the option.
@param[in] IaAddr The pointer to the IA Address.
@param[in] MessageType Message type of DHCP6 package.
- @return Buf The position to append the next option.
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
-UINT8 *
+EFI_STATUS
Dhcp6AppendIaAddrOption (
- IN OUT UINT8 *Buf,
+ IN OUT EFI_DHCP6_PACKET *Packet,
+ IN OUT UINT8 **PacketCursor,
IN EFI_DHCP6_IA_ADDRESS *IaAddr,
IN UINT32 MessageType
)
{
+ UINT32 BytesNeeded;
+ UINT32 Length;
+
// The format of the IA Address option is:
//
// 0 1 2 3
@@ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption (
// . .
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ //
+ // Verify the arguments are valid
+ //
+ if (Packet == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IaAddr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Verify the PacketCursor is within the packet
+ //
+ if ( (*PacketCursor < Packet->Dhcp6.Option)
+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
+ BytesNeeded += sizeof (EFI_IPv6_ADDRESS);
+ //
+ // Even if the preferred-lifetime is 0, it still needs to store it.
+ //
+ BytesNeeded += sizeof (IaAddr->PreferredLifetime);
+ //
+ // Even if the valid-lifetime is 0, it still needs to store it.
+ //
+ BytesNeeded += sizeof (IaAddr->ValidLifetime);
+
+ //
+ // Space remaining in the packet
+ //
+ Length = Packet->Size - Packet->Length;
+ if (Length < BytesNeeded) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
//
// Fill the value of Ia Address option type
//
- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr));
- Buf += 2;
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr));
+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
- WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
- Buf += 2;
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
- CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
- Buf += sizeof (EFI_IPv6_ADDRESS);
+ CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
+ *PacketCursor += sizeof (EFI_IPv6_ADDRESS);
//
// Fill the value of preferred-lifetime and valid-lifetime.
@@ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption (
// should set to 0 when initiate a Confirm message.
//
if (MessageType != Dhcp6MsgConfirm) {
- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime));
+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime));
}
- Buf += 4;
+ *PacketCursor += sizeof (IaAddr->PreferredLifetime);
if (MessageType != Dhcp6MsgConfirm) {
- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime));
+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime));
}
- Buf += 4;
+ *PacketCursor += sizeof (IaAddr->ValidLifetime);
- return Buf;
+ //
+ // Update the packet length
+ //
+ Packet->Length += BytesNeeded;
+
+ return EFI_SUCCESS;
}
/**
Append the appointed Ia option to Buf, and move Buf to the end.
- @param[in, out] Buf The pointer to the position to append.
+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
+ will be updated.
+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
+ will be moved to the end of the option.
@param[in] Ia The pointer to the Ia.
@param[in] T1 The time of T1.
@param[in] T2 The time of T2.
@param[in] MessageType Message type of DHCP6 package.
- @return Buf The position to append the next Ia option.
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
-UINT8 *
+EFI_STATUS
Dhcp6AppendIaOption (
- IN OUT UINT8 *Buf,
- IN EFI_DHCP6_IA *Ia,
- IN UINT32 T1,
- IN UINT32 T2,
- IN UINT32 MessageType
+ IN OUT EFI_DHCP6_PACKET *Packet,
+ IN OUT UINT8 **PacketCursor,
+ IN EFI_DHCP6_IA *Ia,
+ IN UINT32 T1,
+ IN UINT32 T2,
+ IN UINT32 MessageType
)
{
- UINT8 *AddrOpt;
- UINT16 *Len;
- UINTN Index;
+ UINT8 *AddrOpt;
+ UINT16 *Len;
+ UINTN Index;
+ UINT32 BytesNeeded;
+ UINT32 Length;
+ EFI_STATUS Status;
//
// The format of IA_NA and IA_TA option:
@@ -733,32 +859,74 @@ Dhcp6AppendIaOption (
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+ //
+ // Verify the arguments are valid
+ //
+ if (Packet == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Ia == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Verify the PacketCursor is within the packet
+ //
+ if ( (*PacketCursor < Packet->Dhcp6.Option)
+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
+ BytesNeeded += sizeof (Ia->Descriptor.IaId);
+ //
+ // + N for the IA_NA-options/IA_TA-options
+ // Dhcp6AppendIaAddrOption will need to check the length for each address
+ //
+ if (Ia->Descriptor.Type == Dhcp6OptIana) {
+ BytesNeeded += sizeof (T1) + sizeof (T2);
+ }
+
+ //
+ // Space remaining in the packet
+ //
+ Length = (UINT16)(Packet->Size - Packet->Length);
+ if (Length < BytesNeeded) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
//
// Fill the value of Ia option type
//
- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type));
- Buf += 2;
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type));
+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
//
// Fill the len of Ia option later, keep the pointer first
//
- Len = (UINT16 *)Buf;
- Buf += 2;
+ Len = (UINT16 *)*PacketCursor;
+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
//
// Fill the value of iaid
//
- WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId));
- Buf += 4;
+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId));
+ *PacketCursor += sizeof (Ia->Descriptor.IaId);
//
// Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified.
//
if (Ia->Descriptor.Type == Dhcp6OptIana) {
- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff));
- Buf += 4;
- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff));
- Buf += 4;
+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff));
+ *PacketCursor += sizeof (T1);
+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff));
+ *PacketCursor += sizeof (T2);
}
//
@@ -766,35 +934,51 @@ Dhcp6AppendIaOption (
//
for (Index = 0; Index < Ia->IaAddressCount; Index++) {
AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS);
- Buf = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
+ Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
//
// Fill the value of Ia option length
//
- *Len = HTONS ((UINT16)(Buf - (UINT8 *)Len - 2));
+ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2));
- return Buf;
+ //
+ // Update the packet length
+ //
+ Packet->Length += BytesNeeded;
+
+ return EFI_SUCCESS;
}
/**
Append the appointed Elapsed time option to Buf, and move Buf to the end.
- @param[in, out] Buf The pointer to the position to append.
+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
+ will be moved to the end of the option.
@param[in] Instance The pointer to the Dhcp6 instance.
@param[out] Elapsed The pointer to the elapsed time value in
- the generated packet.
+ the generated packet.
- @return Buf The position to append the next Ia option.
+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
+ @retval EFI_SUCCESS The option is appended successfully.
**/
-UINT8 *
+EFI_STATUS
Dhcp6AppendETOption (
- IN OUT UINT8 *Buf,
- IN DHCP6_INSTANCE *Instance,
- OUT UINT16 **Elapsed
+ IN OUT EFI_DHCP6_PACKET *Packet,
+ IN OUT UINT8 **PacketCursor,
+ IN DHCP6_INSTANCE *Instance,
+ OUT UINT16 **Elapsed
)
{
+ UINT32 BytesNeeded;
+ UINT32 Length;
+
//
// The format of elapsed time option:
//
@@ -806,27 +990,70 @@ Dhcp6AppendETOption (
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+ //
+ // Verify the arguments are valid
+ //
+ if (Packet == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Instance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Elapsed == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Verify the PacketCursor is within the packet
+ //
+ if ( (*PacketCursor < Packet->Dhcp6.Option)
+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
+ //
+ // + 2 for elapsed-time
+ //
+ BytesNeeded += sizeof (UINT16);
+ //
+ // Space remaining in the packet
+ //
+ Length = Packet->Size - Packet->Length;
+ if (Length < BytesNeeded) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
//
// Fill the value of elapsed-time option type.
//
- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime));
- Buf += 2;
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime));
+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
//
// Fill the len of elapsed-time option, which is fixed.
//
- WriteUnaligned16 ((UINT16 *)Buf, HTONS (2));
- Buf += 2;
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2));
+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
//
// Fill in elapsed time value with 0 value for now. The actual value is
// filled in later just before the packet is transmitted.
//
- WriteUnaligned16 ((UINT16 *)Buf, HTONS (0));
- *Elapsed = (UINT16 *)Buf;
- Buf += 2;
+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0));
+ *Elapsed = (UINT16 *)*PacketCursor;
+ *PacketCursor += sizeof (UINT16);
- return Buf;
+ Packet->Length += BytesNeeded;
+
+ return EFI_SUCCESS;
}
/**
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114253): https://edk2.groups.io/g/devel/message/114253
Mute This Topic: https://groups.io/mt/103926731/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH 01/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch
2024-01-24 3:33 ` [edk2-devel] [PATCH 01/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch Doug Flick via groups.io
@ 2024-01-24 11:30 ` Gerd Hoffmann
0 siblings, 0 replies; 24+ messages in thread
From: Gerd Hoffmann @ 2024-01-24 11:30 UTC (permalink / raw)
To: devel, dougflick
Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams
On Tue, Jan 23, 2024 at 07:33:24PM -0800, Doug Flick via groups.io wrote:
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535
>
> SECURITY PATCH - Patch
Not needed, the CVE number below implies that.
> TCBZ4535
Not needed, the link to tianocore bugzilla is above.
> CVE-2023-45230
> CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
> CWE-119 Improper Restriction of Operations within the Bounds
> of a Memory Buffer
Good. Given that this series of bugs got a fancy name I think it makes
sense to include that too ("pixiefail bug #1").
Please include a description of the bug and how it is fixed.
[ the same applies to the following patches ]
> -UINT8 *
> +EFI_STATUS
> Dhcp6AppendOption (
> - IN OUT UINT8 *Buf,
> - IN UINT16 OptType,
> - IN UINT16 OptLen,
> - IN UINT8 *Data
> + IN OUT EFI_DHCP6_PACKET *Packet,
> + IN OUT UINT8 **PacketCursor,
> + IN UINT16 OptType,
> + IN UINT16 OptLen,
> + IN UINT8 *Data
> );
Dhcp6AppendOption() and variants can return errors now. All callsites
are adapted accordingly.
It gets passed in EFI_DHCP6_PACKET as additional parameter ...
> + //
> + // Verify the PacketCursor is within the packet
> + //
> + if ( (*PacketCursor < Packet->Dhcp6.Option)
> + || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
> + {
> + return EFI_INVALID_PARAMETER;
> + }
... so it can look at Packet->Size when checking buffer space.
Also to allow Packet->Length updates.
Lots of checks added.
The code changes look good to me. The key changes should be highlighted
in the commit message.
thanks,
Gerd
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114275): https://edk2.groups.io/g/devel/message/114275
Mute This Topic: https://groups.io/mt/103926731/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 02/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 01/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 11:39 ` Gerd Hoffmann
2024-01-24 3:33 ` [edk2-devel] [PATCH 03/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch Doug Flick via groups.io
` (12 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel; +Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4535
SECURITY PATCH - Unit Tests
TCBZ4535
CVE-2023-45230
CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
CWE-119 Improper Restriction of Operations within the Bounds
of a Memory Buffer
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>
---
NetworkPkg/Test/NetworkPkgHostTest.dsc | 99 ++++
.../GoogleTest/Dhcp6DxeGoogleTest.inf | 43 ++
.../GoogleTest/Dhcp6DxeGoogleTest.cpp | 20 +
.../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 478 ++++++++++++++++++
NetworkPkg/NetworkPkg.ci.yaml | 118 ++---
5 files changed, 695 insertions(+), 63 deletions(-)
create mode 100644 NetworkPkg/Test/NetworkPkgHostTest.dsc
create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc
new file mode 100644
index 000000000000..20bc90b1728d
--- /dev/null
+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc
@@ -0,0 +1,99 @@
+## @file
+# NetworkPkgHostTest DSC file used to build host-based unit tests.
+#
+# Copyright (c) Microsoft Corporation.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+ PLATFORM_NAME = NetworkPkgHostTest
+ PLATFORM_GUID = 3b68324e-fc07-4d49-9520-9347ede65879
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/NetworkPkg/HostTest
+ SUPPORTED_ARCHITECTURES = IA32|X64|AARCH64
+ BUILD_TARGETS = NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+[Packages]
+ MdePkg/MdePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[Components]
+ #
+ # Build HOST_APPLICATION that tests NetworkPkg
+ #
+ NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+
+# Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests.
+[LibraryClasses]
+ NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+ VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+!ifdef CONTINUOUS_INTEGRATION
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
+ TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf
+!else
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
+!endif
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+
+!if $(TOOL_CHAIN_TAG) == VS2019 or $(TOOL_CHAIN_TAG) == VS2022
+[LibraryClasses.X64]
+ # Provide StackCookie support lib so that we can link to /GS exports for VS builds
+ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+[LibraryClasses.common.UEFI_APPLICATION]
+ DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+ #
+ # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
+ # This library provides the instrinsic functions generated by a given compiler.
+ # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+ #
+!if $(TOOL_CHAIN_TAG) != VS2017 and $(TOOL_CHAIN_TAG) != VS2015 and $(TOOL_CHAIN_TAG) != VS2019
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+!endif
+ NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+[LibraryClasses.ARM]
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+[LibraryClasses.RISCV64]
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+
+[PcdsFixedAtBuild]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2
+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|0x4
diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
new file mode 100644
index 000000000000..8e9119a37158
--- /dev/null
+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
@@ -0,0 +1,43 @@
+## @file
+# Unit test suite for the Dhcp6Dxe using Google Test
+#
+# Copyright (c) Microsoft Corporation.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = Dhcp6DxeGoogleTest
+ FILE_GUID = 1D2A4C65-38C8-4C2F-BB60-B5FA49625AA9
+ VERSION_STRING = 1.0
+ MODULE_TYPE = HOST_APPLICATION
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+[Sources]
+ Dhcp6DxeGoogleTest.cpp
+ Dhcp6IoGoogleTest.cpp
+ ../Dhcp6Io.c
+ ../Dhcp6Utility.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+ DebugLib
+ NetLib
+ PcdLib
+
+[Protocols]
+ gEfiDhcp6ServiceBindingProtocolGuid
+
+[Pcd]
+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType
+
+[Guids]
+ gZeroGuid
diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
new file mode 100644
index 000000000000..9aeced2f9156
--- /dev/null
+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
@@ -0,0 +1,20 @@
+/** @file
+ Acts as the main entry point for the tests for the Dhcp6Dxe module.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <gtest/gtest.h>
+
+////////////////////////////////////////////////////////////////////////////////
+// Run the tests
+////////////////////////////////////////////////////////////////////////////////
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ testing::InitGoogleTest (&argc, argv);
+ return RUN_ALL_TESTS ();
+}
diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
new file mode 100644
index 000000000000..7ee40e4af480
--- /dev/null
+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
@@ -0,0 +1,478 @@
+/** @file
+ Tests for Dhcp6Io.c.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <gtest/gtest.h>
+
+extern "C" {
+ #include <Uefi.h>
+ #include <Library/BaseLib.h>
+ #include <Library/DebugLib.h>
+ #include <Library/BaseMemoryLib.h>
+ #include "../Dhcp6Impl.h"
+ #include "../Dhcp6Utility.h"
+}
+
+////////////////////////////////////////////////////////////////////////
+// Defines
+////////////////////////////////////////////////////////////////////////
+
+#define DHCP6_PACKET_MAX_LEN 1500
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+// Symbol Definitions
+// These functions are not directly under test - but required to compile
+////////////////////////////////////////////////////////////////////////
+
+// This definition is used by this test but is also required to compile
+// by Dhcp6Io.c
+EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = {
+ { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 }
+};
+
+EFI_STATUS
+EFIAPI
+UdpIoSendDatagram (
+ IN UDP_IO *UdpIo,
+ IN NET_BUF *Packet,
+ IN UDP_END_POINT *EndPoint OPTIONAL,
+ IN EFI_IP_ADDRESS *Gateway OPTIONAL,
+ IN UDP_IO_CALLBACK CallBack,
+ IN VOID *Context
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UdpIoRecvDatagram (
+ IN UDP_IO *UdpIo,
+ IN UDP_IO_CALLBACK CallBack,
+ IN VOID *Context,
+ IN UINT32 HeadLen
+ )
+{
+ return EFI_SUCCESS;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Dhcp6AppendOptionTest Tests
+////////////////////////////////////////////////////////////////////////
+
+class Dhcp6AppendOptionTest : public ::testing::Test {
+public:
+ UINT8 *Buffer = NULL;
+ EFI_DHCP6_PACKET *Packet;
+
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ // Initialize any resources or variables
+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
+ ASSERT_NE (Buffer, (UINT8 *)NULL);
+
+ Packet = (EFI_DHCP6_PACKET *)Buffer;
+ Packet->Size = DHCP6_PACKET_MAX_LEN;
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ // Clean up any resources or variables
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+ }
+};
+
+// Test Description:
+// Attempt to append an option to a packet that is too small by a duid that is too large
+TEST_F (Dhcp6AppendOptionTest, InvalidDataExpectBufferTooSmall) {
+ UINT8 *Cursor;
+ EFI_DHCP6_DUID *UntrustedDuid;
+ EFI_STATUS Status;
+
+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));
+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);
+
+ UntrustedDuid->Length = NTOHS (0xFFFF);
+
+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;
+
+ Status = Dhcp6AppendOption (
+ Dhcp6AppendOptionTest::Packet,
+ &Cursor,
+ HTONS (Dhcp6OptServerId),
+ UntrustedDuid->Length,
+ UntrustedDuid->Duid
+ );
+
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
+}
+
+// Test Description:
+// Attempt to append an option to a packet that is large enough
+TEST_F (Dhcp6AppendOptionTest, ValidDataExpectSuccess) {
+ UINT8 *Cursor;
+ EFI_DHCP6_DUID *UntrustedDuid;
+ EFI_STATUS Status;
+ UINTN OriginalLength;
+
+ UINT8 Duid[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+ OriginalLength = Packet->Length;
+
+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));
+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);
+
+ UntrustedDuid->Length = NTOHS (sizeof (Duid));
+ CopyMem (UntrustedDuid->Duid, Duid, sizeof (Duid));
+
+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;
+
+ Status = Dhcp6AppendOption (
+ Dhcp6AppendOptionTest::Packet,
+ &Cursor,
+ HTONS (Dhcp6OptServerId),
+ UntrustedDuid->Length,
+ UntrustedDuid->Duid
+ );
+
+ ASSERT_EQ (Status, EFI_SUCCESS);
+
+ // verify that the pointer to cursor moved by the expected amount
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendOptionTest::Packet->Dhcp6.Option + sizeof (Duid) + 4);
+
+ // verify that the length of the packet is now the expected amount
+ ASSERT_EQ (Dhcp6AppendOptionTest::Packet->Length, OriginalLength + sizeof (Duid) + 4);
+}
+
+////////////////////////////////////////////////////////////////////////
+// Dhcp6AppendETOption Tests
+////////////////////////////////////////////////////////////////////////
+
+class Dhcp6AppendETOptionTest : public ::testing::Test {
+public:
+ UINT8 *Buffer = NULL;
+ EFI_DHCP6_PACKET *Packet;
+
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ // Initialize any resources or variables
+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
+ ASSERT_NE (Buffer, (UINT8 *)NULL);
+
+ Packet = (EFI_DHCP6_PACKET *)Buffer;
+ Packet->Size = DHCP6_PACKET_MAX_LEN;
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ // Clean up any resources or variables
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+ }
+};
+
+// Test Description:
+// Attempt to append an option to a packet that is too small by a duid that is too large
+TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) {
+ UINT8 *Cursor;
+ EFI_STATUS Status;
+ DHCP6_INSTANCE Instance;
+ UINT16 ElapsedTimeVal;
+ UINT16 *ElapsedTime;
+
+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;
+ ElapsedTime = &ElapsedTimeVal;
+
+ Packet->Length = Packet->Size - 2;
+
+ Status = Dhcp6AppendETOption (
+ Dhcp6AppendETOptionTest::Packet,
+ &Cursor,
+ &Instance, // Instance is not used in this function
+ &ElapsedTime
+ );
+
+ // verify that we error out because the packet is too small for the option header
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
+
+ // reset the length
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+}
+
+// Test Description:
+// Attempt to append an option to a packet that is large enough
+TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) {
+ UINT8 *Cursor;
+ EFI_STATUS Status;
+ DHCP6_INSTANCE Instance;
+ UINT16 ElapsedTimeVal;
+ UINT16 *ElapsedTime;
+ UINTN ExpectedSize;
+ UINTN OriginalLength;
+
+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;
+ ElapsedTime = &ElapsedTimeVal;
+ ExpectedSize = 6;
+ OriginalLength = Packet->Length;
+
+ Status = Dhcp6AppendETOption (
+ Dhcp6AppendETOptionTest::Packet,
+ &Cursor,
+ &Instance, // Instance is not used in this function
+ &ElapsedTime
+ );
+
+ // verify that the status is EFI_SUCCESS
+ ASSERT_EQ (Status, EFI_SUCCESS);
+
+ // verify that the pointer to cursor moved by the expected amount
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendETOptionTest::Packet->Dhcp6.Option + ExpectedSize);
+
+ // verify that the length of the packet is now the expected amount
+ ASSERT_EQ (Dhcp6AppendETOptionTest::Packet->Length, OriginalLength + ExpectedSize);
+}
+
+////////////////////////////////////////////////////////////////////////
+// Dhcp6AppendIaOption Tests
+////////////////////////////////////////////////////////////////////////
+
+class Dhcp6AppendIaOptionTest : public ::testing::Test {
+public:
+ UINT8 *Buffer = NULL;
+ EFI_DHCP6_PACKET *Packet;
+ EFI_DHCP6_IA *Ia;
+
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ // Initialize any resources or variables
+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
+ ASSERT_NE (Buffer, (UINT8 *)NULL);
+
+ Packet = (EFI_DHCP6_PACKET *)Buffer;
+ Packet->Size = DHCP6_PACKET_MAX_LEN;
+
+ Ia = (EFI_DHCP6_IA *)AllocateZeroPool (sizeof (EFI_DHCP6_IA) + sizeof (EFI_DHCP6_IA_ADDRESS) * 2);
+ ASSERT_NE (Ia, (EFI_DHCP6_IA *)NULL);
+
+ CopyMem (Ia->IaAddress, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));
+ CopyMem (Ia->IaAddress + 1, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));
+
+ Ia->IaAddressCount = 2;
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ // Clean up any resources or variables
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+
+ if (Ia != NULL) {
+ FreePool (Ia);
+ }
+ }
+};
+
+// Test Description:
+// Attempt to append an option to a packet that doesn't have enough space
+// for the option header
+TEST_F (Dhcp6AppendIaOptionTest, IaNaInvalidDataExpectBufferTooSmall) {
+ UINT8 *Cursor;
+ EFI_STATUS Status;
+
+ Packet->Length = Packet->Size - 2;
+
+ Ia->Descriptor.Type = Dhcp6OptIana;
+ Ia->Descriptor.IaId = 0x12345678;
+
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
+
+ Status = Dhcp6AppendIaOption (
+ Dhcp6AppendIaOptionTest::Packet,
+ &Cursor,
+ Ia,
+ 0x12345678,
+ 0x11111111,
+ Dhcp6OptIana
+ );
+
+ // verify that we error out because the packet is too small for the option header
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
+
+ // reset the length
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+}
+
+// Test Description:
+// Attempt to append an option to a packet that doesn't have enough space
+// for the option header
+TEST_F (Dhcp6AppendIaOptionTest, IaTaInvalidDataExpectBufferTooSmall) {
+ UINT8 *Cursor;
+ EFI_STATUS Status;
+
+ // Use up nearly all the space in the packet
+ Packet->Length = Packet->Size - 2;
+
+ Ia->Descriptor.Type = Dhcp6OptIata;
+ Ia->Descriptor.IaId = 0x12345678;
+
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
+
+ Status = Dhcp6AppendIaOption (
+ Dhcp6AppendIaOptionTest::Packet,
+ &Cursor,
+ Ia,
+ 0,
+ 0,
+ Dhcp6OptIata
+ );
+
+ // verify that we error out because the packet is too small for the option header
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
+
+ // reset the length
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+}
+
+TEST_F (Dhcp6AppendIaOptionTest, IaNaValidDataExpectSuccess) {
+ UINT8 *Cursor;
+ EFI_STATUS Status;
+ UINTN ExpectedSize;
+ UINTN OriginalLength;
+
+ //
+ // 2 bytes for the option header type
+ //
+ ExpectedSize = 2;
+ //
+ // 2 bytes for the option header length
+ //
+ ExpectedSize += 2;
+ //
+ // 4 bytes for the IAID
+ //
+ ExpectedSize += 4;
+ //
+ // + 4 bytes for the T1
+ //
+ ExpectedSize += 4;
+ //
+ // + 4 bytes for the T2
+ //
+ ExpectedSize += 4;
+ //
+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
+ // + 2 bytes for the option header type
+ // + 2 bytes for the option header length
+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address
+ //
+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
+
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
+
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+ OriginalLength = Packet->Length;
+
+ Ia->Descriptor.Type = Dhcp6OptIana;
+ Ia->Descriptor.IaId = 0x12345678;
+
+ Status = Dhcp6AppendIaOption (
+ Dhcp6AppendIaOptionTest::Packet,
+ &Cursor,
+ Ia,
+ 0x12345678,
+ 0x12345678,
+ Dhcp6OptIana
+ );
+
+ // verify that the pointer to cursor moved by the expected amount
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);
+
+ // verify that the length of the packet is now the expected amount
+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);
+
+ // verify that the status is EFI_SUCCESS
+ ASSERT_EQ (Status, EFI_SUCCESS);
+}
+
+TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) {
+ UINT8 *Cursor;
+ EFI_STATUS Status;
+ UINTN ExpectedSize;
+ UINTN OriginalLength;
+
+ //
+ // 2 bytes for the option header type
+ //
+ ExpectedSize = 2;
+ //
+ // 2 bytes for the option header length
+ //
+ ExpectedSize += 2;
+ //
+ // 4 bytes for the IAID
+ //
+ ExpectedSize += 4;
+ //
+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
+ // + 2 bytes for the option header type
+ // + 2 bytes for the option header length
+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address
+ //
+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
+
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
+
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+ OriginalLength = Packet->Length;
+
+ Ia->Descriptor.Type = Dhcp6OptIata;
+ Ia->Descriptor.IaId = 0x12345678;
+
+ Status = Dhcp6AppendIaOption (
+ Dhcp6AppendIaOptionTest::Packet,
+ &Cursor,
+ Ia,
+ 0,
+ 0,
+ Dhcp6OptIata
+ );
+
+ // verify that the pointer to cursor moved by the expected amount
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);
+
+ // verify that the length of the packet is now the expected amount
+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);
+
+ // verify that the status is EFI_SUCCESS
+ ASSERT_EQ (Status, EFI_SUCCESS);
+}
diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml
index 07dc7abd6938..0060f7a2cb8f 100644
--- a/NetworkPkg/NetworkPkg.ci.yaml
+++ b/NetworkPkg/NetworkPkg.ci.yaml
@@ -7,73 +7,65 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
- "LicenseCheck": {
- "IgnoreFiles": []
- },
+ "LicenseCheck": { "IgnoreFiles": [] },
"EccCheck": {
- ## Exception sample looks like below:
- ## "ExceptionList": [
- ## "<ErrorID>", "<KeyWord>"
- ## ]
- "ExceptionList": [
- ],
- ## Both file path and directory path are accepted.
- "IgnoreFiles": [
- ]
- },
- "CompilerPlugin": {
- "DscPath": "NetworkPkg.dsc"
- },
- "CharEncodingCheck": {
- "IgnoreFiles": []
- },
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [],
+ },
+ "CompilerPlugin": { "DscPath": "NetworkPkg.dsc" },
+ "HostUnitTestCompilerPlugin": { "DscPath": "Test/NetworkPkgHostTest.dsc" },
+ "CharEncodingCheck": { "IgnoreFiles": [] },
"DependencyCheck": {
- "AcceptableDependencies": [
- "MdePkg/MdePkg.dec",
- "MdeModulePkg/MdeModulePkg.dec",
- "NetworkPkg/NetworkPkg.dec",
- "CryptoPkg/CryptoPkg.dec"
- ],
- # For host based unit tests
- "AcceptableDependencies-HOST_APPLICATION":[],
- # For UEFI shell based apps
- "AcceptableDependencies-UEFI_APPLICATION":[
- "ShellPkg/ShellPkg.dec"
- ],
- "IgnoreInf": []
- },
- "DscCompleteCheck": {
- "DscPath": "NetworkPkg.dsc",
- "IgnoreInf": []
- },
- "GuidCheck": {
- "IgnoreGuidName": [],
- "IgnoreGuidValue": [],
- "IgnoreFoldersAndFiles": []
- },
- "LibraryClassCheck": {
- "IgnoreHeaderFile": []
- },
+ "AcceptableDependencies":
+ [
+ "MdePkg/MdePkg.dec",
+ "MdeModulePkg/MdeModulePkg.dec",
+ "NetworkPkg/NetworkPkg.dec",
+ "CryptoPkg/CryptoPkg.dec",
+ ],
+ # For host based unit tests
+ "AcceptableDependencies-HOST_APPLICATION": [
+ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+ ],
+ # For UEFI shell based apps
+ "AcceptableDependencies-UEFI_APPLICATION":
+ ["ShellPkg/ShellPkg.dec"],
+ "IgnoreInf": [],
+ },
+ "DscCompleteCheck": { "DscPath": "NetworkPkg.dsc", "IgnoreInf": [] },
+ "GuidCheck":
+ {
+ "IgnoreGuidName": [],
+ "IgnoreGuidValue": [],
+ "IgnoreFoldersAndFiles": [],
+ },
+ "LibraryClassCheck": { "IgnoreHeaderFile": [] },
## options defined ci/Plugin/SpellCheck
"SpellCheck": {
- "AuditOnly": True, # Fails test but run in AuditOnly mode to collect log
- "IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files
- "ExtendWords": [], # words to extend to the dictionary for this package
- "IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore
- "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
- },
+ "AuditOnly": True, # Fails test but run in AuditOnly mode to collect log
+ "IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files
+ "ExtendWords": [], # words to extend to the dictionary for this package
+ "IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore
+ "AdditionalIncludePaths": [], # Additional paths to spell check (wildcards supported)
+ },
- "Defines": {
- "BLD_*_CONTINUOUS_INTEGRATION": "TRUE",
- "BLD_*_NETWORK_ENABLE": "TRUE",
- "BLD_*_NETWORK_SNP_ENABLE": "TRUE",
- "BLD_*_NETWORK_VLAN_ENABLE": "TRUE",
- "BLD_*_NETWORK_IP4_ENABLE": "TRUE",
- "BLD_*_NETWORK_IP6_ENABLE": "TRUE",
- "BLD_*_NETWORK_TLS_ENABLE": "TRUE",
- "BLD_*_NETWORK_HTTP_ENABLE": "FALSE",
- "BLD_*_NETWORK_HTTP_BOOT_ENABLE": "TRUE",
- "BLD_*_NETWORK_ISCSI_ENABLE": "TRUE",
- }
+ "Defines":
+ {
+ "BLD_*_CONTINUOUS_INTEGRATION": "TRUE",
+ "BLD_*_NETWORK_ENABLE": "TRUE",
+ "BLD_*_NETWORK_SNP_ENABLE": "TRUE",
+ "BLD_*_NETWORK_VLAN_ENABLE": "TRUE",
+ "BLD_*_NETWORK_IP4_ENABLE": "TRUE",
+ "BLD_*_NETWORK_IP6_ENABLE": "TRUE",
+ "BLD_*_NETWORK_TLS_ENABLE": "TRUE",
+ "BLD_*_NETWORK_HTTP_ENABLE": "FALSE",
+ "BLD_*_NETWORK_HTTP_BOOT_ENABLE": "TRUE",
+ "BLD_*_NETWORK_ISCSI_ENABLE": "TRUE",
+ },
}
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114254): https://edk2.groups.io/g/devel/message/114254
Mute This Topic: https://groups.io/mt/103926732/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH 02/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests
2024-01-24 3:33 ` [edk2-devel] [PATCH 02/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests Doug Flick via groups.io
@ 2024-01-24 11:39 ` Gerd Hoffmann
0 siblings, 0 replies; 24+ messages in thread
From: Gerd Hoffmann @ 2024-01-24 11:39 UTC (permalink / raw)
To: devel, dougflick
Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams
On Tue, Jan 23, 2024 at 07:33:25PM -0800, Doug Flick via groups.io wrote:
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4535
>
> SECURITY PATCH - Unit Tests
>
> TCBZ4535
> CVE-2023-45230
> CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
> CWE-119 Improper Restriction of Operations within the Bounds
> of a Memory Buffer
I don't think this is needed here, this patch doesn't fix CVE-2023-45230
after all. A description of what the tests are checking would be more
useful.
> diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml
> index 07dc7abd6938..0060f7a2cb8f 100644
> --- a/NetworkPkg/NetworkPkg.ci.yaml
> +++ b/NetworkPkg/NetworkPkg.ci.yaml
> @@ -7,73 +7,65 @@
> # SPDX-License-Identifier: BSD-2-Clause-Patent
> ##
> {
> - "LicenseCheck": {
> - "IgnoreFiles": []
> - },
> + "LicenseCheck": { "IgnoreFiles": [] },
I guess this patch hooks the unit tests into CI. The whitespace changes
make changes file hard to read though. Two options to deal with that:
(1) avoid to reformat the file, or
(2) split the patch into two, one with only the whitespace changes
and one with the functional change.
thanks & take care,
Gerd
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114276): https://edk2.groups.io/g/devel/message/114276
Mute This Topic: https://groups.io/mt/103926732/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 03/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 01/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 02/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 11:45 ` Gerd Hoffmann
2024-01-24 3:33 ` [edk2-devel] [PATCH 04/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests Doug Flick via groups.io
` (11 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel; +Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534
SECURITY PATCH - Patch
TCBZ4534
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
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>
---
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/Dhcp6Impl.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')
+#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)->OpCode))
+#define DHCP6_SIZE_OF_OPT_LEN (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen))
-//
// Combined size of Code and Length
-//
#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \
DHCP6_SIZE_OF_OPT_LEN)
@@ -73,34 +85,122 @@ STATIC_ASSERT (
"Combined size of Code and Length must be 4 per RFC 8415"
);
-//
// 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) == 2,
+ DHCP6_OFFSET_OF_OPT_LEN (0) == 2,
"Offset of length is + 2 past start of option"
);
-#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) == 4,
+ DHCP6_OFFSET_OF_OPT_DATA (0) == 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))
-#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 == 12,
+ "Combined size of IAID, T1, T2 must be 12 per RFC 8415"
+ );
-#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 == 8,
+ "Minimum combined size of IA_TA per RFC 8415"
+ );
-#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) == 8,
+ "Offset of IA_TA Inner option is + 8 past start of option"
+ );
-#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 == 16,
+ "Minimum combined size of IA_TA per RFC 8415"
+ );
-#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) == 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) == 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) == 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_AND_LEN)
+STATIC_ASSERT (
+ DHCP6_OFFSET_OF_STATUS_CODE (0) == 4,
+ "Offset of status is + 4 past start of option"
+ );
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 option-len.
//
if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {
- T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 8)));
- T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 12)));
+ 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
@@ -609,13 +609,14 @@ Dhcp6UpdateIaInfo (
return EFI_DEVICE_ERROR;
}
- IaInnerOpt = Option + 16;
- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2))) - 12);
+ 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 = Option + 8;
- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2))) - 4);
+ 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);
}
//
@@ -641,7 +642,7 @@ Dhcp6UpdateIaInfo (
Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);
if (Option != NULL) {
- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4)));
+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option))));
if (StsCode != Dhcp6StsSuccess) {
return EFI_DEVICE_ERROR;
}
@@ -661,6 +662,87 @@ 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;
+}
+
/**
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 option.
@@ -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 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
@@ -691,12 +779,12 @@ Dhcp6SeekStsOption (
//
*Option = Dhcp6SeekOption (
Packet->Dhcp6.Option,
- Packet->Length - 4,
+ OptionLen,
Dhcp6OptStatusCode
);
if (*Option != NULL) {
- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4)));
+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option))));
if (StsCode != Dhcp6StsSuccess) {
return EFI_DEVICE_ERROR;
}
@@ -707,7 +795,7 @@ Dhcp6SeekStsOption (
//
*Option = Dhcp6SeekIaOption (
Packet->Dhcp6.Option,
- Packet->Length - sizeof (EFI_DHCP6_HEADER),
+ OptionLen,
&Instance->Config->IaDescriptor
);
if (*Option == NULL) {
@@ -715,52 +803,35 @@ Dhcp6SeekStsOption (
}
//
- // 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->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.
//
- // The format of the IA_TA option is:
+ // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start 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 = OptionLen - (*Option - Packet->Dhcp6.Option);
//
- // sizeof (option-code + option-len + IaId) = 8
- // sizeof (option-code + option-len + IaId + T1) = 12
- // sizeof (option-code + option-len + IaId + T1 + T2) = 16
+ // Seek the inner option
//
- // The inner options still start with 2 bytes option-code and 2 bytes option-len.
- //
- if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {
- IaInnerOpt = *Option + 16;
- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2))) - 12);
- } else {
- IaInnerOpt = *Option + 8;
- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2))) - 4);
+ if (EFI_ERROR (
+ Dhcp6SeekInnerOptionSafe (
+ Instance->Config->IaDescriptor.Type,
+ *Option,
+ OptionLen,
+ &IaInnerOpt,
+ &IaInnerLen
+ )
+ ))
+ {
+ return EFI_DEVICE_ERROR;
}
//
@@ -784,7 +855,7 @@ Dhcp6SeekStsOption (
//
*Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);
if (*Option != NULL) {
- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4)));
+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option)))));
if (StsCode != Dhcp6StsSuccess) {
return EFI_DEVICE_ERROR;
}
@@ -1105,7 +1176,7 @@ Dhcp6SendRequestMsg (
//
Option = Dhcp6SeekOption (
Instance->AdSelect->Dhcp6.Option,
- Instance->AdSelect->Length - 4,
+ Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptServerId
);
if (Option == NULL) {
@@ -1289,7 +1360,7 @@ Dhcp6SendDeclineMsg (
//
Option = Dhcp6SeekOption (
LastReply->Dhcp6.Option,
- LastReply->Length - 4,
+ LastReply->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptServerId
);
if (Option == NULL) {
@@ -1448,7 +1519,7 @@ Dhcp6SendReleaseMsg (
//
Option = Dhcp6SeekOption (
LastReply->Dhcp6.Option,
- LastReply->Length - 4,
+ LastReply->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptServerId
);
if (Option == NULL) {
@@ -1673,7 +1744,7 @@ Dhcp6SendRenewRebindMsg (
Option = Dhcp6SeekOption (
LastReply->Dhcp6.Option,
- LastReply->Length - 4,
+ LastReply->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptServerId
);
if (Option == NULL) {
@@ -2208,7 +2279,7 @@ Dhcp6HandleReplyMsg (
//
Option = Dhcp6SeekOption (
Packet->Dhcp6.Option,
- Packet->Length - 4,
+ Packet->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptRapidCommit
);
@@ -2354,7 +2425,7 @@ Dhcp6HandleReplyMsg (
//
// Any error status code option is found.
//
- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4)));
+ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option)))));
switch (StsCode) {
case Dhcp6StsUnspecFail:
//
@@ -2487,7 +2558,7 @@ Dhcp6SelectAdvertiseMsg (
//
Option = Dhcp6SeekOption (
AdSelect->Dhcp6.Option,
- AdSelect->Length - 4,
+ AdSelect->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptServerUnicast
);
@@ -2498,7 +2569,7 @@ Dhcp6SelectAdvertiseMsg (
return EFI_OUT_OF_RESOURCES;
}
- CopyMem (Instance->Unicast, Option + 4, sizeof (EFI_IPv6_ADDRESS));
+ CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS));
}
//
@@ -2551,7 +2622,7 @@ Dhcp6HandleAdvertiseMsg (
//
Option = Dhcp6SeekOption (
Packet->Dhcp6.Option,
- Packet->Length - 4,
+ Packet->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptRapidCommit
);
@@ -2645,7 +2716,7 @@ Dhcp6HandleAdvertiseMsg (
CopyMem (Instance->AdSelect, Packet, Packet->Size);
if (Option != NULL) {
- Instance->AdPref = *(Option + 4);
+ Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option));
}
} else {
//
@@ -2714,11 +2785,11 @@ Dhcp6HandleStateful (
//
Option = Dhcp6SeekOption (
Packet->Dhcp6.Option,
- Packet->Length - 4,
+ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN,
Dhcp6OptClientId
);
- if ((Option == NULL) || (CompareMem (Option + 4, ClientId->Duid, ClientId->Length) != 0)) {
+ if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) {
goto ON_CONTINUE;
}
@@ -2727,7 +2798,7 @@ Dhcp6HandleStateful (
//
Option = Dhcp6SeekOption (
Packet->Dhcp6.Option,
- Packet->Length - 4,
+ Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN,
Dhcp6OptServerId
);
@@ -2832,7 +2903,7 @@ Dhcp6HandleStateless (
//
Option = Dhcp6SeekOption (
Packet->Dhcp6.Option,
- Packet->Length - 4,
+ Packet->Length - sizeof (EFI_DHCP6_HEADER),
Dhcp6OptServerId
);
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114255): https://edk2.groups.io/g/devel/message/114255
Mute This Topic: https://groups.io/mt/103926733/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 04/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (2 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 03/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 05/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Patch Doug Flick via groups.io
` (10 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel; +Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534
SECURITY PATCH - Unit Tests
TCBZ4534
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
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>
---
NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 +
.../GoogleTest/Dhcp6DxeGoogleTest.inf | 1 +
.../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h | 58 +++
NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 2 +-
.../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 365 +++++++++++++++++-
5 files changed, 424 insertions(+), 3 deletions(-)
create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h
diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc
index 20bc90b1728d..24dee654df2e 100644
--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc
+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc
@@ -16,6 +16,7 @@ [Defines]
SKUID_IDENTIFIER = DEFAULT
!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+
[Packages]
MdePkg/MdePkg.dec
UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
index 8e9119a37158..12532ed30cb3 100644
--- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
@@ -18,6 +18,7 @@ [Defines]
[Sources]
Dhcp6DxeGoogleTest.cpp
Dhcp6IoGoogleTest.cpp
+ Dhcp6IoGoogleTest.h
../Dhcp6Io.c
../Dhcp6Utility.c
diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h
new file mode 100644
index 000000000000..aed3b890827b
--- /dev/null
+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h
@@ -0,0 +1,58 @@
+/** @file
+ Acts as header for private functions under test in Dhcp6Io.c
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef DHCP6_IO_GOOGLE_TEST_H_
+#define DHCP6_IO_GOOGLE_TEST_H_
+
+////////////////////////////////////////////////////////////////////////////////
+// These are the functions that are being unit tested
+////////////////////////////////////////////////////////////////////////////////
+
+#include <Uefi.h>
+
+/**
+ 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.
+*/
+EFI_STATUS
+Dhcp6SeekInnerOptionSafe (
+ UINT16 IaType,
+ UINT8 *Option,
+ UINT32 OptionLen,
+ UINT8 **IaInnerOpt,
+ UINT16 *IaInnerLen
+ );
+
+/**
+ 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 option.
+ See details in section 22.13, RFC3315.
+
+ @param[in] Instance The pointer to the Dhcp6 instance.
+ @param[in] Packet The pointer to reply messages.
+ @param[out] Option The pointer to status code option.
+
+ @retval EFI_SUCCESS Seek status code option successfully.
+ @retval EFI_DEVICE_ERROR An unexpected error.
+
+**/
+EFI_STATUS
+Dhcp6SeekStsOption (
+ IN DHCP6_INSTANCE *Instance,
+ IN EFI_DHCP6_PACKET *Packet,
+ OUT UINT8 **Option
+ );
+
+#endif // DHCP6_IO_GOOGLE_TEST_H
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
index 89d16484a568..3b8feb4a2032 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
@@ -816,7 +816,7 @@ Dhcp6SeekStsOption (
// IA option to the end of the DHCP6 option area, thus subtract the space
// up until this option
//
- OptionLen = OptionLen - (*Option - Packet->Dhcp6.Option);
+ OptionLen = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option);
//
// Seek the inner option
diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
index 7ee40e4af480..7db253a7b87f 100644
--- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
@@ -13,6 +13,7 @@ extern "C" {
#include <Library/BaseMemoryLib.h>
#include "../Dhcp6Impl.h"
#include "../Dhcp6Utility.h"
+ #include "Dhcp6IoGoogleTest.h"
}
////////////////////////////////////////////////////////////////////////
@@ -21,7 +22,35 @@ extern "C" {
#define DHCP6_PACKET_MAX_LEN 1500
+// This definition is used by this test but is also required to compile
+// by Dhcp6Io.c
+#define DHCPV6_OPTION_IA_NA 3
+#define DHCPV6_OPTION_IA_TA 4
+
+#define SEARCH_PATTERN 0xDEADC0DE
+#define SEARCH_PATTERN_LEN sizeof(SEARCH_PATTERN)
+
////////////////////////////////////////////////////////////////////////
+// Test structures for IA_NA and IA_TA options
+////////////////////////////////////////////////////////////////////////
+typedef struct {
+ UINT16 Code;
+ UINT16 Len;
+ UINT32 IAID;
+} DHCPv6_OPTION;
+
+typedef struct {
+ DHCPv6_OPTION Header;
+ UINT32 T1;
+ UINT32 T2;
+ UINT8 InnerOptions[0];
+} DHCPv6_OPTION_IA_NA;
+
+typedef struct {
+ DHCPv6_OPTION Header;
+ UINT8 InnerOptions[0];
+} DHCPv6_OPTION_IA_TA;
+
////////////////////////////////////////////////////////////////////////
// Symbol Definitions
// These functions are not directly under test - but required to compile
@@ -210,7 +239,7 @@ TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) {
Status = Dhcp6AppendETOption (
Dhcp6AppendETOptionTest::Packet,
&Cursor,
- &Instance, // Instance is not used in this function
+ &Instance, // Instance is not used in this function
&ElapsedTime
);
@@ -240,7 +269,7 @@ TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) {
Status = Dhcp6AppendETOption (
Dhcp6AppendETOptionTest::Packet,
&Cursor,
- &Instance, // Instance is not used in this function
+ &Instance, // Instance is not used in this function
&ElapsedTime
);
@@ -476,3 +505,335 @@ TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) {
// verify that the status is EFI_SUCCESS
ASSERT_EQ (Status, EFI_SUCCESS);
}
+
+////////////////////////////////////////////////////////////////////////
+// Dhcp6SeekInnerOptionSafe Tests
+////////////////////////////////////////////////////////////////////////
+
+// Define a fixture for your tests if needed
+class Dhcp6SeekInnerOptionSafeTest : public ::testing::Test {
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ // Initialize any resources or variables
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ // Clean up any resources or variables
+ }
+};
+
+// Test Description:
+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IANA option is found.
+TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAValidOptionExpectSuccess) {
+ EFI_STATUS Result;
+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 };
+ UINT32 OptionLength = sizeof (Option);
+ DHCPv6_OPTION_IA_NA *OptionPtr = (DHCPv6_OPTION_IA_NA *)Option;
+ UINT32 SearchPattern = SEARCH_PATTERN;
+
+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN;
+ UINT8 *InnerOptionPtr = NULL;
+ UINT16 InnerOptionLength = 0;
+
+ OptionPtr->Header.Code = Dhcp6OptIana;
+ OptionPtr->Header.Len = HTONS (4 + 12); // Valid length has to be more than 12
+ OptionPtr->Header.IAID = 0x12345678;
+ OptionPtr->T1 = 0x11111111;
+ OptionPtr->T2 = 0x22222222;
+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);
+
+ Result = Dhcp6SeekInnerOptionSafe (
+ Dhcp6OptIana,
+ Option,
+ OptionLength,
+ &InnerOptionPtr,
+ &InnerOptionLength
+ );
+ ASSERT_EQ (Result, EFI_SUCCESS);
+ ASSERT_EQ (InnerOptionLength, 4);
+ ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0);
+}
+
+// Test Description:
+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_DEIVCE_ERROR when the IANA option size is invalid.
+TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAInvalidSizeExpectFail) {
+ // Lets add an inner option of bytes we expect to find
+ EFI_STATUS Status;
+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 };
+ UINT32 OptionLength = sizeof (Option);
+ DHCPv6_OPTION_IA_NA *OptionPtr = (DHCPv6_OPTION_IA_NA *)Option;
+ UINT32 SearchPattern = SEARCH_PATTERN;
+
+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN;
+ UINT8 *InnerOptionPtr = NULL;
+ UINT16 InnerOptionLength = 0;
+
+ OptionPtr->Header.Code = Dhcp6OptIana;
+ OptionPtr->Header.Len = HTONS (4); // Set the length to lower than expected (12)
+ OptionPtr->Header.IAID = 0x12345678;
+ OptionPtr->T1 = 0x11111111;
+ OptionPtr->T2 = 0x22222222;
+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);
+
+ // Set the InnerOptionLength to be less than the size of the option
+ Status = Dhcp6SeekInnerOptionSafe (
+ Dhcp6OptIana,
+ Option,
+ OptionLength,
+ &InnerOptionPtr,
+ &InnerOptionLength
+ );
+ ASSERT_EQ (Status, EFI_DEVICE_ERROR);
+
+ // Now set the OptionLength to be less than the size of the option
+ OptionLength = sizeof (DHCPv6_OPTION_IA_NA) - 1;
+ Status = Dhcp6SeekInnerOptionSafe (
+ Dhcp6OptIana,
+ Option,
+ OptionLength,
+ &InnerOptionPtr,
+ &InnerOptionLength
+ );
+ ASSERT_EQ (Status, EFI_DEVICE_ERROR);
+}
+
+// Test Description:
+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option is found
+TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAValidOptionExpectSuccess) {
+ // Lets add an inner option of bytes we expect to find
+ EFI_STATUS Status;
+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 };
+ UINT32 OptionLength = sizeof (Option);
+ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option;
+ UINT32 SearchPattern = SEARCH_PATTERN;
+
+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN;
+ UINT8 *InnerOptionPtr = NULL;
+ UINT16 InnerOptionLength = 0;
+
+ OptionPtr->Header.Code = Dhcp6OptIata;
+ OptionPtr->Header.Len = HTONS (4 + 4); // Valid length has to be more than 4
+ OptionPtr->Header.IAID = 0x12345678;
+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);
+
+ Status = Dhcp6SeekInnerOptionSafe (
+ Dhcp6OptIata,
+ Option,
+ OptionLength,
+ &InnerOptionPtr,
+ &InnerOptionLength
+ );
+ ASSERT_EQ (Status, EFI_SUCCESS);
+ ASSERT_EQ (InnerOptionLength, 4);
+ ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0);
+}
+
+// Test Description:
+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid.
+TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAInvalidSizeExpectFail) {
+ // Lets add an inner option of bytes we expect to find
+ EFI_STATUS Status;
+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 };
+ UINT32 OptionLength = sizeof (Option);
+ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option;
+ UINT32 SearchPattern = SEARCH_PATTERN;
+
+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN;
+ UINT8 *InnerOptionPtr = NULL;
+ UINT16 InnerOptionLength = 0;
+
+ OptionPtr->Header.Code = Dhcp6OptIata;
+ OptionPtr->Header.Len = HTONS (2); // Set the length to lower than expected (4)
+ OptionPtr->Header.IAID = 0x12345678;
+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);
+
+ Status = Dhcp6SeekInnerOptionSafe (
+ Dhcp6OptIata,
+ Option,
+ OptionLength,
+ &InnerOptionPtr,
+ &InnerOptionLength
+ );
+ ASSERT_EQ (Status, EFI_DEVICE_ERROR);
+
+ // Now lets try modifying the OptionLength to be less than the size of the option
+ OptionLength = sizeof (DHCPv6_OPTION_IA_TA) - 1;
+ Status = Dhcp6SeekInnerOptionSafe (
+ Dhcp6OptIata,
+ Option,
+ OptionLength,
+ &InnerOptionPtr,
+ &InnerOptionLength
+ );
+ ASSERT_EQ (Status, EFI_DEVICE_ERROR);
+}
+
+// Test Description:
+// This test verifies that any other Option Type fails
+TEST_F (Dhcp6SeekInnerOptionSafeTest, InvalidOption) {
+ // Lets add an inner option of bytes we expect to find
+ EFI_STATUS Result;
+ UINT8 Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 };
+ UINT32 OptionLength = sizeof (Option);
+ DHCPv6_OPTION_IA_TA *OptionPtr = (DHCPv6_OPTION_IA_TA *)Option;
+ UINT32 SearchPattern = SEARCH_PATTERN;
+
+ UINTN SearchPatternLength = SEARCH_PATTERN_LEN;
+ UINT8 *InnerOptionPtr = NULL;
+ UINT16 InnerOptionLength = 0;
+
+ OptionPtr->Header.Code = 0xC0DE;
+ OptionPtr->Header.Len = HTONS (2); // Set the length to lower than expected (4)
+ OptionPtr->Header.IAID = 0x12345678;
+ CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);
+
+ Result = Dhcp6SeekInnerOptionSafe (0xC0DE, Option, OptionLength, &InnerOptionPtr, &InnerOptionLength);
+ ASSERT_EQ (Result, EFI_DEVICE_ERROR);
+}
+
+////////////////////////////////////////////////////////////////////////
+// Dhcp6SeekStsOption Tests
+////////////////////////////////////////////////////////////////////////
+
+#define PACKET_SIZE (1500)
+
+class Dhcp6SeekStsOptionTest : public ::testing::Test {
+public:
+ DHCP6_INSTANCE Instance = { 0 };
+ EFI_DHCP6_PACKET *Packet = NULL;
+ EFI_DHCP6_CONFIG_DATA Config = { 0 };
+
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ // Allocate a packet
+ Packet = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);
+ ASSERT_NE (Packet, nullptr);
+
+ // Initialize the packet
+ Packet->Size = PACKET_SIZE;
+
+ Instance.Config = &Config;
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ // Clean up any resources or variables
+ FreePool (Packet);
+ }
+};
+
+// Test Description:
+// This test verifies that Dhcp6SeekStsOption returns EFI_DEVICE_ERROR when the option is invalid
+// This verifies that the calling function is working as expected
+TEST_F (Dhcp6SeekStsOptionTest, SeekIATAOptionExpectFail) {
+ EFI_STATUS Status;
+ UINT8 *Option = NULL;
+ UINT32 SearchPattern = SEARCH_PATTERN;
+ UINT16 SearchPatternLength = SEARCH_PATTERN_LEN;
+ UINT16 *Len = NULL;
+ EFI_DHCP6_IA Ia = { 0 };
+
+ Ia.Descriptor.Type = DHCPV6_OPTION_IA_TA;
+ Ia.IaAddressCount = 1;
+ Ia.IaAddress[0].PreferredLifetime = 0xDEADBEEF;
+ Ia.IaAddress[0].ValidLifetime = 0xDEADAAAA;
+ Ia.IaAddress[0].IpAddress = mAllDhcpRelayAndServersAddress;
+
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+
+ Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option;
+
+ // Let's append the option to the packet
+ Status = Dhcp6AppendOption (
+ Dhcp6SeekStsOptionTest::Packet,
+ &Option,
+ Dhcp6OptStatusCode,
+ SearchPatternLength,
+ (UINT8 *)&SearchPattern
+ );
+ ASSERT_EQ (Status, EFI_SUCCESS);
+
+ // Inner option length - this will be overwritten later
+ Len = (UINT16 *)(Option + 2);
+
+ // Fill in the inner IA option
+ Status = Dhcp6AppendIaOption (
+ Dhcp6SeekStsOptionTest::Packet,
+ &Option,
+ &Ia,
+ 0x12345678,
+ 0x11111111,
+ 0x22222222
+ );
+ ASSERT_EQ (Status, EFI_SUCCESS);
+
+ // overwrite the len of inner Ia option
+ *Len = HTONS (3);
+
+ Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_TA;
+
+ Option = NULL;
+ Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option);
+
+ ASSERT_EQ (Status, EFI_DEVICE_ERROR);
+}
+
+// Test Description:
+// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid.
+TEST_F (Dhcp6SeekStsOptionTest, SeekIANAOptionExpectSuccess) {
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT8 *Option = NULL;
+ UINT32 SearchPattern = SEARCH_PATTERN;
+ UINT16 SearchPatternLength = SEARCH_PATTERN_LEN;
+ EFI_DHCP6_IA Ia = { 0 };
+
+ Ia.Descriptor.Type = DHCPV6_OPTION_IA_NA;
+ Ia.IaAddressCount = 1;
+ Ia.IaAddress[0].PreferredLifetime = 0x11111111;
+ Ia.IaAddress[0].ValidLifetime = 0x22222222;
+ Ia.IaAddress[0].IpAddress = mAllDhcpRelayAndServersAddress;
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
+
+ Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option;
+
+ Status = Dhcp6AppendOption (
+ Dhcp6SeekStsOptionTest::Packet,
+ &Option,
+ Dhcp6OptStatusCode,
+ SearchPatternLength,
+ (UINT8 *)&SearchPattern
+ );
+ ASSERT_EQ (Status, EFI_SUCCESS);
+
+ Status = Dhcp6AppendIaOption (
+ Dhcp6SeekStsOptionTest::Packet,
+ &Option,
+ &Ia,
+ 0x12345678,
+ 0x11111111,
+ 0x22222222
+ );
+ ASSERT_EQ (Status, EFI_SUCCESS);
+
+ Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_NA;
+
+ Option = NULL;
+ Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option);
+
+ ASSERT_EQ (Status, EFI_SUCCESS);
+}
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114256): https://edk2.groups.io/g/devel/message/114256
Mute This Topic: https://groups.io/mt/103926734/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 05/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Patch
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (3 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 04/14] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 11:53 ` Gerd Hoffmann
2024-01-24 3:33 ` [edk2-devel] [PATCH 06/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Unit Tests Doug Flick via groups.io
` (9 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4536
SECURITY PATCH - Patch
TCBZ4536
CVE-2023-45231
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
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>
---
NetworkPkg/Ip6Dxe/Ip6Option.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c
index 199eea124dfe..8718d5d8756a 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Option.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Option.c
@@ -137,6 +137,14 @@ Ip6IsNDOptionValid (
return FALSE;
}
+ //
+ // Cannot process truncated options.
+ // Cannot process options with a length of 0 as there is no Type field.
+ //
+ if (OptionLen < sizeof (IP6_OPTION_HEADER)) {
+ return FALSE;
+ }
+
Offset = 0;
//
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114257): https://edk2.groups.io/g/devel/message/114257
Mute This Topic: https://groups.io/mt/103926735/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 06/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Unit Tests
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (4 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 05/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Patch Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 07/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch Doug Flick via groups.io
` (8 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4536
SECURITY PATCH - Unit Tests
TCBZ4536
CVE-2023-45231
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
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>
---
NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 +
.../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 42 ++++++
.../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp | 20 +++
.../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 129 ++++++++++++++++++
4 files changed, 192 insertions(+)
create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp
create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc
index 24dee654df2e..7fa7b0f9d5be 100644
--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc
+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc
@@ -26,6 +26,7 @@ [Components]
# Build HOST_APPLICATION that tests NetworkPkg
#
NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+ NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
# Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests.
[LibraryClasses]
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
new file mode 100644
index 000000000000..6e4de0745fb5
--- /dev/null
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
@@ -0,0 +1,42 @@
+## @file
+# Unit test suite for the Ip6Dxe using Google Test
+#
+# Copyright (c) Microsoft Corporation.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = Ip6DxeUnitTest
+ FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A
+ VERSION_STRING = 1.0
+ MODULE_TYPE = HOST_APPLICATION
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+[Sources]
+ Ip6DxeGoogleTest.cpp
+ Ip6OptionGoogleTest.cpp
+ ../Ip6Option.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+ DebugLib
+ NetLib
+ PcdLib
+
+[Protocols]
+ gEfiDhcp6ServiceBindingProtocolGuid
+
+[Pcd]
+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType
+
+[Guids]
+ gZeroGuid
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp
new file mode 100644
index 000000000000..6ebfd5fdfb70
--- /dev/null
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp
@@ -0,0 +1,20 @@
+/** @file
+ Acts as the main entry point for the tests for the Ip6Dxe module.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <gtest/gtest.h>
+
+////////////////////////////////////////////////////////////////////////////////
+// Run the tests
+////////////////////////////////////////////////////////////////////////////////
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ testing::InitGoogleTest (&argc, argv);
+ return RUN_ALL_TESTS ();
+}
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
new file mode 100644
index 000000000000..f2cd90e1a952
--- /dev/null
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
@@ -0,0 +1,129 @@
+/** @file
+ Tests for Ip6Option.c.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <gtest/gtest.h>
+
+extern "C" {
+ #include <Uefi.h>
+ #include <Library/BaseLib.h>
+ #include <Library/DebugLib.h>
+ #include "../Ip6Impl.h"
+ #include "../Ip6Option.h"
+}
+
+/////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////
+
+#define IP6_PREFIX_INFO_OPTION_DATA_LEN 32
+#define OPTION_HEADER_IP6_PREFIX_DATA_LEN (sizeof (IP6_OPTION_HEADER) + IP6_PREFIX_INFO_OPTION_DATA_LEN)
+
+////////////////////////////////////////////////////////////////////////
+// Symbol Definitions
+// These functions are not directly under test - but required to compile
+////////////////////////////////////////////////////////////////////////
+UINT32 mIp6Id;
+
+EFI_STATUS
+Ip6SendIcmpError (
+ IN IP6_SERVICE *IpSb,
+ IN NET_BUF *Packet,
+ IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL,
+ IN EFI_IPv6_ADDRESS *DestinationAddress,
+ IN UINT8 Type,
+ IN UINT8 Code,
+ IN UINT32 *Pointer OPTIONAL
+ )
+{
+ // ..
+ return EFI_SUCCESS;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Ip6OptionValidation Tests
+////////////////////////////////////////////////////////////////////////
+
+// Define a fixture for your tests if needed
+class Ip6OptionValidationTest : public ::testing::Test {
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ // Initialize any resources or variables
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ // Clean up any resources or variables
+ }
+};
+
+// Test Description:
+// Null option should return false
+TEST_F (Ip6OptionValidationTest, NullOptionShouldReturnFalse) {
+ UINT8 *option = nullptr;
+ UINT16 optionLen = 10; // Provide a suitable length
+
+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen));
+}
+
+// Test Description:
+// Truncated option should return false
+TEST_F (Ip6OptionValidationTest, TruncatedOptionShouldReturnFalse) {
+ UINT8 option[] = { 0x01 }; // Provide a truncated option
+ UINT16 optionLen = 1;
+
+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen));
+}
+
+// Test Description:
+// Ip6OptionPrefixInfo Option with zero length should return false
+TEST_F (Ip6OptionValidationTest, OptionWithZeroLengthShouldReturnFalse) {
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = Ip6OptionPrefixInfo;
+ optionHeader.Length = 0;
+ UINT8 option[sizeof (IP6_OPTION_HEADER)];
+
+ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER));
+ UINT16 optionLen = sizeof (IP6_OPTION_HEADER);
+
+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen));
+}
+
+// Test Description:
+// Ip6OptionPrefixInfo Option with valid length should return true
+TEST_F (Ip6OptionValidationTest, ValidPrefixInfoOptionShouldReturnTrue) {
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = Ip6OptionPrefixInfo;
+ optionHeader.Length = 4; // Length 4 * 8 = 32
+ UINT8 option[OPTION_HEADER_IP6_PREFIX_DATA_LEN];
+
+ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER));
+
+ EXPECT_TRUE (Ip6IsNDOptionValid (option, IP6_PREFIX_INFO_OPTION_DATA_LEN));
+}
+
+// Test Description:
+// Ip6OptionPrefixInfo Option with invalid length should return false
+TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse) {
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = Ip6OptionPrefixInfo;
+ optionHeader.Length = 3; // Length 3 * 8 = 24 (Invalid)
+ UINT8 option[sizeof (IP6_OPTION_HEADER)];
+
+ CopyMem (option, &optionHeader, sizeof (IP6_OPTION_HEADER));
+ UINT16 optionLen = sizeof (IP6_OPTION_HEADER);
+
+ EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen));
+}
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114258): https://edk2.groups.io/g/devel/message/114258
Mute This Topic: https://groups.io/mt/103926736/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 07/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (5 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 06/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Unit Tests Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 10:39 ` Pedro Falcato
2024-01-24 3:33 ` [edk2-devel] [PATCH 08/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests Doug Flick via groups.io
` (7 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538
SECURITY PATCH - Patch
TCBZ4537
CVE-2023-45232
CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
TCBZ4538
CVE-2023-45233
CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
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>
---
NetworkPkg/Ip6Dxe/Ip6Option.h | 89 +++++++++++++++++++++++++++++++++++
NetworkPkg/Ip6Dxe/Ip6Option.c | 76 +++++++++++++++++++++++++-----
2 files changed, 154 insertions(+), 11 deletions(-)
diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h
index bd8e223c8a67..5d786073ebcb 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Option.h
+++ b/NetworkPkg/Ip6Dxe/Ip6Option.h
@@ -12,6 +12,95 @@
#define IP6_FRAGMENT_OFFSET_MASK (~0x3)
+//
+// Per RFC8200 Section 4.2
+//
+// Two of the currently-defined extension headers -- the Hop-by-Hop
+// Options header and the Destination Options header -- carry a variable
+// number of type-length-value (TLV) encoded "options", of the following
+// format:
+//
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
+// | Option Type | Opt Data Len | Option Data
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
+//
+// Option Type 8-bit identifier of the type of option.
+//
+// Opt Data Len 8-bit unsigned integer. Length of the Option
+// Data field of this option, in octets.
+//
+// Option Data Variable-length field. Option-Type-specific
+// data.
+//
+#define IP6_SIZE_OF_OPT_TYPE (sizeof(UINT8))
+#define IP6_SIZE_OF_OPT_LEN (sizeof(UINT8))
+#define IP6_COMBINED_SIZE_OF_OPT_TAG_AND_LEN (IP6_SIZE_OF_OPT_TYPE + IP6_SIZE_OF_OPT_LEN)
+#define IP6_OFFSET_OF_OPT_LEN(a) (a + IP6_SIZE_OF_OPT_TYPE)
+STATIC_ASSERT (
+ IP6_OFFSET_OF_OPT_LEN (0) == 1,
+ "The Length field should be 1 octet (8 bits) past the start of the option"
+ );
+
+#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + IP6_COMBINED_SIZE_OF_OPT_TAG_AND_LEN + length)
+STATIC_ASSERT (
+ IP6_NEXT_OPTION_OFFSET (0, 0) == 2,
+ "The next option is minimally the combined size of the option tag and length"
+ );
+
+//
+// For more information see RFC 8200, Section 4.3, 4.4, and 4.6
+//
+// This example format is from section 4.6
+// This does not apply to fragment headers
+//
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// | Next Header | Hdr Ext Len | |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
+// | |
+// . .
+// . Header-Specific Data .
+// . .
+// | |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// Next Header 8-bit selector. Identifies the type of
+// header immediately following the extension
+// header. Uses the same values as the IPv4
+// Protocol field [IANA-PN].
+//
+// Hdr Ext Len 8-bit unsigned integer. Length of the
+// Destination Options header in 8-octet units,
+// not including the first 8 octets.
+
+//
+// These defines apply to the following:
+// 1. Hop by Hop
+// 2. Routing
+// 3. Destination
+//
+#define IP6_SIZE_OF_EXT_NEXT_HDR (sizeof(UINT8))
+#define IP6_SIZE_OF_HDR_EXT_LEN (sizeof(UINT8))
+
+#define IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN (IP6_SIZE_OF_EXT_NEXT_HDR + IP6_SIZE_OF_HDR_EXT_LEN)
+STATIC_ASSERT (
+ IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN == 2,
+ "The combined size of Next Header and Len is two 8 bit fields"
+ );
+
+//
+// The "+ 1" in this calculation is because of the "not including the first 8 octets"
+// part of the definition (meaning the value of 0 represents 64 bits)
+//
+#define IP6_HDR_EXT_LEN(a) (((UINT16)(UINT8)(a) + 1) * 8)
+
+// This is the maxmimum length permissible by a extension header
+// Length is UINT8 of 8 octets not including the first 8 octets
+#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN)
+STATIC_ASSERT (
+ IP6_MAX_EXT_DATA_LENGTH == 2046,
+ "Maximum data length is ((MAX_UINT8 + 1) * 8) - 2"
+ );
+
typedef struct _IP6_FRAGMENT_HEADER {
UINT8 NextHeader;
UINT8 Reserved;
diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c
index 8718d5d8756a..144f8d34dead 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Option.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Option.c
@@ -17,7 +17,8 @@
@param[in] IpSb The IP6 service data.
@param[in] Packet The to be validated packet.
@param[in] Option The first byte of the option.
- @param[in] OptionLen The length of the whole option.
+ @param[in] OptionLen The length of all options, expressed in byte length of octets.
+ Maximum length is 2046 bytes or ((n + 1) * 8) - 2 where n is 255.
@param[in] Pointer Identifies the octet offset within
the invoking packet where the error was detected.
@@ -31,12 +32,33 @@ Ip6IsOptionValid (
IN IP6_SERVICE *IpSb,
IN NET_BUF *Packet,
IN UINT8 *Option,
- IN UINT8 OptionLen,
+ IN UINT16 OptionLen,
IN UINT32 Pointer
)
{
- UINT8 Offset;
- UINT8 OptionType;
+ UINT16 Offset;
+ UINT8 OptionType;
+ UINT8 OptDataLen;
+
+ if (Option == NULL) {
+ ASSERT (Option != NULL);
+ return FALSE;
+ }
+
+ if ((OptionLen <= 0) || (OptionLen > IP6_MAX_EXT_DATA_LENGTH)) {
+ ASSERT (OptionLen > 0 && OptionLen <= IP6_MAX_EXT_DATA_LENGTH);
+ return FALSE;
+ }
+
+ if (Packet == NULL) {
+ ASSERT (Packet != NULL);
+ return FALSE;
+ }
+
+ if (IpSb == NULL) {
+ ASSERT (IpSb != NULL);
+ return FALSE;
+ }
Offset = 0;
@@ -54,7 +76,8 @@ Ip6IsOptionValid (
//
// It is a PadN option
//
- Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2);
+ OptDataLen = *(IP6_OFFSET_OF_OPT_LEN (Option + Offset));
+ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen);
break;
case Ip6OptionRouterAlert:
//
@@ -69,7 +92,8 @@ Ip6IsOptionValid (
//
switch (OptionType & Ip6OptionMask) {
case Ip6OptionSkip:
- Offset = (UINT8)(Offset + *(Option + Offset + 1));
+ OptDataLen = *(IP6_OFFSET_OF_OPT_LEN (Option + Offset));
+ Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen);
break;
case Ip6OptionDiscard:
return FALSE;
@@ -308,7 +332,7 @@ Ip6IsExtsValid (
UINT32 Pointer;
UINT32 Offset;
UINT8 *Option;
- UINT8 OptionLen;
+ UINT16 OptionLen;
BOOLEAN Flag;
UINT8 CountD;
UINT8 CountA;
@@ -385,6 +409,36 @@ Ip6IsExtsValid (
// Fall through
//
case IP6_DESTINATION:
+ //
+ // See https://www.rfc-editor.org/rfc/rfc2460#section-4.2 page 23
+ //
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Next Header | Hdr Ext Len | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
+ // | |
+ // . .
+ // . Options .
+ // . .
+ // | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ //
+ //
+ // Next Header 8-bit selector. Identifies the type of header
+ // immediately following the Destination Options
+ // header. Uses the same values as the IPv4
+ // Protocol field [RFC-1700 et seq.].
+ //
+ // Hdr Ext Len 8-bit unsigned integer. Length of the
+ // Destination Options header in 8-octet units, not
+ // including the first 8 octets.
+ //
+ // Options Variable-length field, of length such that the
+ // complete Destination Options header is an
+ // integer multiple of 8 octets long. Contains one
+ // or more TLV-encoded options, as described in
+ // section 4.2.
+ //
+
if (*NextHeader == IP6_DESTINATION) {
CountD++;
}
@@ -398,7 +452,7 @@ Ip6IsExtsValid (
Offset++;
Option = ExtHdrs + Offset;
- OptionLen = (UINT8)((*Option + 1) * 8 - 2);
+ OptionLen = IP6_HDR_EXT_LEN (*Option) - IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN;
Option++;
Offset++;
@@ -430,7 +484,7 @@ Ip6IsExtsValid (
//
// Ignore the routing header and proceed to process the next header.
//
- Offset = Offset + (RoutingHead->HeaderLen + 1) * 8;
+ Offset = Offset + IP6_HDR_EXT_LEN (RoutingHead->HeaderLen);
if (UnFragmentLen != NULL) {
*UnFragmentLen = Offset;
@@ -441,7 +495,7 @@ Ip6IsExtsValid (
// to the packet's source address, pointing to the unrecognized routing
// type.
//
- Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER);
+ Pointer = Offset + IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN + sizeof (EFI_IP6_HEADER);
if ((IpSb != NULL) && (Packet != NULL) &&
!IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))
{
@@ -527,7 +581,7 @@ Ip6IsExtsValid (
//
// RFC2402, Payload length is specified in 32-bit words, minus "2".
//
- OptionLen = (UINT8)((*Option + 2) * 4);
+ OptionLen = ((UINT16)(*Option + 2) * 4);
Offset = Offset + OptionLen;
break;
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114259): https://edk2.groups.io/g/devel/message/114259
Mute This Topic: https://groups.io/mt/103926738/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH 07/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch
2024-01-24 3:33 ` [edk2-devel] [PATCH 07/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch Doug Flick via groups.io
@ 2024-01-24 10:39 ` Pedro Falcato
2024-01-24 12:02 ` Gerd Hoffmann
0 siblings, 1 reply; 24+ messages in thread
From: Pedro Falcato @ 2024-01-24 10:39 UTC (permalink / raw)
To: devel, dougflick
Cc: Saloni Kasbekar, Zachary Clark-williams, Doug Flick [MSFT]
On Wed, Jan 24, 2024 at 5:20 AM Doug Flick via groups.io
<dougflick=microsoft.com@groups.io> wrote:
>
> From: Doug Flick <dougflick@microsoft.com>
>
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538
>
> SECURITY PATCH - Patch
>
> TCBZ4537
> CVE-2023-45232
> CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
> CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
>
> TCBZ4538
> CVE-2023-45233
> CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
> CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
>
> 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>
> ---
> NetworkPkg/Ip6Dxe/Ip6Option.h | 89 +++++++++++++++++++++++++++++++++++
> NetworkPkg/Ip6Dxe/Ip6Option.c | 76 +++++++++++++++++++++++++-----
> 2 files changed, 154 insertions(+), 11 deletions(-)
>
> diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h
> index bd8e223c8a67..5d786073ebcb 100644
> --- a/NetworkPkg/Ip6Dxe/Ip6Option.h
> +++ b/NetworkPkg/Ip6Dxe/Ip6Option.h
> @@ -12,6 +12,95 @@
>
> #define IP6_FRAGMENT_OFFSET_MASK (~0x3)
>
> +//
> +// Per RFC8200 Section 4.2
> +//
> +// Two of the currently-defined extension headers -- the Hop-by-Hop
> +// Options header and the Destination Options header -- carry a variable
> +// number of type-length-value (TLV) encoded "options", of the following
> +// format:
> +//
> +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
> +// | Option Type | Opt Data Len | Option Data
> +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
> +//
> +// Option Type 8-bit identifier of the type of option.
> +//
> +// Opt Data Len 8-bit unsigned integer. Length of the Option
> +// Data field of this option, in octets.
> +//
> +// Option Data Variable-length field. Option-Type-specific
> +// data.
> +//
Why isn't this just a
struct Ipv6Option {
UINT8 OptionType;
UINT8 OptionLength;
UINT8 OptionData[];
};
? You'd skip all of the weird obfuscated math below.
> +#define IP6_SIZE_OF_OPT_TYPE (sizeof(UINT8))
> +#define IP6_SIZE_OF_OPT_LEN (sizeof(UINT8))
sizeof(UINT8) can just be replaced by 1
> +#define IP6_COMBINED_SIZE_OF_OPT_TAG_AND_LEN (IP6_SIZE_OF_OPT_TYPE + IP6_SIZE_OF_OPT_LEN)
> +#define IP6_OFFSET_OF_OPT_LEN(a) (a + IP6_SIZE_OF_OPT_TYPE)
> +STATIC_ASSERT (
> + IP6_OFFSET_OF_OPT_LEN (0) == 1,
> + "The Length field should be 1 octet (8 bits) past the start of the option"
> + );
> +
> +#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + IP6_COMBINED_SIZE_OF_OPT_TAG_AND_LEN + length)
> +STATIC_ASSERT (
> + IP6_NEXT_OPTION_OFFSET (0, 0) == 2,
> + "The next option is minimally the combined size of the option tag and length"
> + );
> +
> +//
> +// For more information see RFC 8200, Section 4.3, 4.4, and 4.6
> +//
> +// This example format is from section 4.6
> +// This does not apply to fragment headers
> +//
> +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> +// | Next Header | Hdr Ext Len | |
> +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
> +// | |
> +// . .
> +// . Header-Specific Data .
> +// . .
> +// | |
> +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> +//
> +// Next Header 8-bit selector. Identifies the type of
> +// header immediately following the extension
> +// header. Uses the same values as the IPv4
> +// Protocol field [IANA-PN].
> +//
> +// Hdr Ext Len 8-bit unsigned integer. Length of the
> +// Destination Options header in 8-octet units,
> +// not including the first 8 octets.
> +
> +//
> +// These defines apply to the following:
> +// 1. Hop by Hop
> +// 2. Routing
> +// 3. Destination
> +//
Same comment as above (why is this not a struct?)
> +#define IP6_SIZE_OF_EXT_NEXT_HDR (sizeof(UINT8))
> +#define IP6_SIZE_OF_HDR_EXT_LEN (sizeof(UINT8))
Same for sizeof(UINT8) here.
> +
> +#define IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN (IP6_SIZE_OF_EXT_NEXT_HDR + IP6_SIZE_OF_HDR_EXT_LEN)
> +STATIC_ASSERT (
> + IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN == 2,
> + "The combined size of Next Header and Len is two 8 bit fields"
> + );
> +
> +//
> +// The "+ 1" in this calculation is because of the "not including the first 8 octets"
> +// part of the definition (meaning the value of 0 represents 64 bits)
> +//
> +#define IP6_HDR_EXT_LEN(a) (((UINT16)(UINT8)(a) + 1) * 8)
This expression is remarkably hard to understand correctly, operator
precedence is hard :( .
> +
> +// This is the maxmimum length permissible by a extension header
typo: maximum
> +// Length is UINT8 of 8 octets not including the first 8 octets
> +#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN)
> +STATIC_ASSERT (
> + IP6_MAX_EXT_DATA_LENGTH == 2046,
> + "Maximum data length is ((MAX_UINT8 + 1) * 8) - 2"
> + );
> +
> typedef struct _IP6_FRAGMENT_HEADER {
> UINT8 NextHeader;
> UINT8 Reserved;
> diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c
> index 8718d5d8756a..144f8d34dead 100644
> --- a/NetworkPkg/Ip6Dxe/Ip6Option.c
> +++ b/NetworkPkg/Ip6Dxe/Ip6Option.c
> @@ -17,7 +17,8 @@
> @param[in] IpSb The IP6 service data.
> @param[in] Packet The to be validated packet.
> @param[in] Option The first byte of the option.
> - @param[in] OptionLen The length of the whole option.
> + @param[in] OptionLen The length of all options, expressed in byte length of octets.
> + Maximum length is 2046 bytes or ((n + 1) * 8) - 2 where n is 255.
> @param[in] Pointer Identifies the octet offset within
> the invoking packet where the error was detected.
>
> @@ -31,12 +32,33 @@ Ip6IsOptionValid (
> IN IP6_SERVICE *IpSb,
> IN NET_BUF *Packet,
> IN UINT8 *Option,
> - IN UINT8 OptionLen,
> + IN UINT16 OptionLen,
> IN UINT32 Pointer
> )
> {
> - UINT8 Offset;
> - UINT8 OptionType;
> + UINT16 Offset;
> + UINT8 OptionType;
> + UINT8 OptDataLen;
> +
> + if (Option == NULL) {
> + ASSERT (Option != NULL);
> + return FALSE;
> + }
> +
> + if ((OptionLen <= 0) || (OptionLen > IP6_MAX_EXT_DATA_LENGTH)) {
OptionLen is unsigned hence < 0 is not a valid check
--
Pedro
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114274): https://edk2.groups.io/g/devel/message/114274
Mute This Topic: https://groups.io/mt/103926738/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 08/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (6 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 07/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 09/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch Doug Flick via groups.io
` (6 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538
SECURITY PATCH - Unit Tests
TCBZ4537
CVE-2023-45232
CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
TCBZ4538
CVE-2023-45233
CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
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>
---
.../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 10 +-
.../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h | 40 +++
.../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 282 ++++++++++++++++++
3 files changed, 328 insertions(+), 4 deletions(-)
create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
index 6e4de0745fb5..ba29dbabadb9 100644
--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
@@ -1,13 +1,13 @@
## @file
-# Unit test suite for the Ip6Dxe using Google Test
+# Unit test suite for the Ip6DxeGoogleTest using Google Test
#
# Copyright (c) Microsoft Corporation.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 0x00010017
- BASE_NAME = Ip6DxeUnitTest
- FILE_GUID = 4F05D17D-D3E7-4AAE-820C-576D46D2D34A
+ BASE_NAME = Ip6DxeGoogleTest
+ FILE_GUID = AE39981C-B7FE-41A8-A9C2-F41910477CA3
VERSION_STRING = 1.0
MODULE_TYPE = HOST_APPLICATION
#
@@ -16,9 +16,11 @@ [Defines]
# VALID_ARCHITECTURES = IA32 X64 AARCH64
#
[Sources]
+ ../Ip6Option.c
+ Ip6OptionGoogleTest.h
Ip6DxeGoogleTest.cpp
Ip6OptionGoogleTest.cpp
- ../Ip6Option.c
+ Ip6OptionGoogleTest.h
[Packages]
MdePkg/MdePkg.dec
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
new file mode 100644
index 000000000000..618a7e658e5a
--- /dev/null
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h
@@ -0,0 +1,40 @@
+/** @file
+ Exposes the functions needed to test the Ip6Option module.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef EFI_IP6_OPTION_GOOGLE_TEST_H_
+#define EFI_IP6_OPTION_GOOGLE_TEST_H_
+
+#include <Uefi.h>
+#include "../Ip6Impl.h"
+
+/**
+ Validate the IP6 option format for both the packets we received
+ and that we will transmit. It will compute the ICMPv6 error message fields
+ if the option is malformatted.
+
+ @param[in] IpSb The IP6 service data.
+ @param[in] Packet The to be validated packet.
+ @param[in] Option The first byte of the option.
+ @param[in] OptionLen The length of the whole option.
+ @param[in] Pointer Identifies the octet offset within
+ the invoking packet where the error was detected.
+
+
+ @retval TRUE The option is properly formatted.
+ @retval FALSE The option is malformatted.
+
+**/
+BOOLEAN
+Ip6IsOptionValid (
+ IN IP6_SERVICE *IpSb,
+ IN NET_BUF *Packet,
+ IN UINT8 *Option,
+ IN UINT16 OptionLen,
+ IN UINT32 Pointer
+ );
+
+#endif // __EFI_IP6_OPTION_GOOGLE_TEST_H__
diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
index f2cd90e1a952..69eef4b98ed2 100644
--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
+++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp
@@ -12,6 +12,7 @@ extern "C" {
#include <Library/DebugLib.h>
#include "../Ip6Impl.h"
#include "../Ip6Option.h"
+ #include "Ip6OptionGoogleTest.h"
}
/////////////////////////////////////////////////////////////////////////
@@ -127,3 +128,284 @@ TEST_F (Ip6OptionValidationTest, InvalidPrefixInfoOptionLengthShouldReturnFalse)
EXPECT_FALSE (Ip6IsNDOptionValid (option, optionLen));
}
+
+////////////////////////////////////////////////////////////////////////
+// Ip6IsOptionValid Tests
+////////////////////////////////////////////////////////////////////////
+
+// Define a fixture for your tests if needed
+class Ip6IsOptionValidTest : public ::testing::Test {
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ // Initialize any resources or variables
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ // Clean up any resources or variables
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Ip6IsOptionValidTest Tests
+///////////////////////////////////////////////////////////////////////////////
+
+// Test Description
+// Verify that a NULL option is Invalid
+TEST_F (Ip6IsOptionValidTest, NullOptionShouldReturnTrue) {
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ IP6_SERVICE *IpSb = NULL;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ EXPECT_FALSE (Ip6IsOptionValid (IpSb, &Packet, NULL, 0, 0));
+}
+
+// Test Description
+// Verify that an unknown option with a length of 0 and type of <unknown> does not cause an infinite loop
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength0) {
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ UINT32 DeadCode = 0xDeadC0de;
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = 23; // Unknown Option
+ optionHeader.Length = 0; // This will cause an infinite loop if the function is not working correctly
+
+ // This should be a valid option even though the length is 0
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+}
+
+// Test Description
+// Verify that an unknown option with a length of 1 and type of <unknown> does not cause an infinite loop
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLength1) {
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ UINT32 DeadCode = 0xDeadC0de;
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = 23; // Unknown Option
+ optionHeader.Length = 1; // This will cause an infinite loop if the function is not working correctly
+
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+}
+
+// Test Description
+// Verify that an unknown option with a length of 2 and type of <unknown> does not cause an infinite loop
+TEST_F (Ip6IsOptionValidTest, VerifyIpSkipUnknownOption) {
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ UINT32 DeadCode = 0xDeadC0de;
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = 23; // Unknown Option
+ optionHeader.Length = 2; // Valid length for an unknown option
+
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+}
+
+// Test Description
+// Verify that Ip6OptionPad1 is valid with a length of 0
+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPad1) {
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ UINT32 DeadCode = 0xDeadC0de;
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = Ip6OptionPad1;
+ optionHeader.Length = 0;
+
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+}
+
+// Test Description
+// Verify that Ip6OptionPadN doesn't overflow with various lengths
+TEST_F (Ip6IsOptionValidTest, VerifyIp6OptionPadN) {
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ UINT32 DeadCode = 0xDeadC0de;
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = Ip6OptionPadN;
+ optionHeader.Length = 0xFF;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+
+ optionHeader.Length = 0xFE;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+
+ optionHeader.Length = 0xFD;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+
+ optionHeader.Length = 0xFC;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+}
+
+// Test Description
+// Verify an unknown option doesn't cause an infinite loop with various lengths
+TEST_F (Ip6IsOptionValidTest, VerifyNoInfiniteLoopOnUnknownOptionLengthAttemptOverflow) {
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ UINT32 DeadCode = 0xDeadC0de;
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ IP6_OPTION_HEADER optionHeader;
+
+ optionHeader.Type = 23; // Unknown Option
+ optionHeader.Length = 0xFF;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+
+ optionHeader.Length = 0xFE;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+
+ optionHeader.Length = 0xFD;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+
+ optionHeader.Length = 0xFC;
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, (UINT8 *)&optionHeader, sizeof (optionHeader), 0));
+}
+
+// Test Description
+// Verify that the function supports multiple options
+TEST_F (Ip6IsOptionValidTest, MultiOptionSupport) {
+ UINT16 HdrLen;
+ NET_BUF Packet = { 0 };
+ // we need to define enough of the packet to make the function work
+ // The function being tested will pass IpSb to Ip6SendIcmpError which is defined above
+ UINT32 DeadCode = 0xDeadC0de;
+ // Don't actually use this pointer, just pass it to the function, nothing will be done with it
+ IP6_SERVICE *IpSb = (IP6_SERVICE *)&DeadCode;
+
+ EFI_IPv6_ADDRESS SourceAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IPv6_ADDRESS DestinationAddress = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x83, 0x29 };
+ EFI_IP6_HEADER Ip6Header = { 0 };
+
+ Ip6Header.SourceAddress = SourceAddress;
+ Ip6Header.DestinationAddress = DestinationAddress;
+ Packet.Ip.Ip6 = &Ip6Header;
+
+ UINT8 ExtHdr[1024] = { 0 };
+ UINT8 *Cursor = ExtHdr;
+ IP6_OPTION_HEADER *Option = (IP6_OPTION_HEADER *)ExtHdr;
+
+ // Let's start chaining options
+
+ Option->Type = 23; // Unknown Option
+ Option->Length = 0xFC;
+
+ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC;
+
+ Option = (IP6_OPTION_HEADER *)Cursor;
+ Option->Type = Ip6OptionPad1;
+
+ Cursor += sizeof (1);
+
+ // Type and length aren't processed, instead it just moves the pointer forward by 4 bytes
+ Option = (IP6_OPTION_HEADER *)Cursor;
+ Option->Type = Ip6OptionRouterAlert;
+ Option->Length = 4;
+
+ Cursor += sizeof (IP6_OPTION_HEADER) + 4;
+
+ Option = (IP6_OPTION_HEADER *)Cursor;
+ Option->Type = Ip6OptionPadN;
+ Option->Length = 0xFC;
+
+ Cursor += sizeof (IP6_OPTION_HEADER) + 0xFC;
+
+ Option = (IP6_OPTION_HEADER *)Cursor;
+ Option->Type = Ip6OptionRouterAlert;
+ Option->Length = 4;
+
+ Cursor += sizeof (IP6_OPTION_HEADER) + 4;
+
+ // Total 524
+
+ HdrLen = (UINT16)(Cursor - ExtHdr);
+
+ EXPECT_TRUE (Ip6IsOptionValid (IpSb, &Packet, ExtHdr, HdrLen, 0));
+}
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114260): https://edk2.groups.io/g/devel/message/114260
Mute This Topic: https://groups.io/mt/103926739/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 09/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (7 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 08/14] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 12:09 ` Gerd Hoffmann
2024-01-24 3:33 ` [edk2-devel] [PATCH 10/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Unit Tests Doug Flick via groups.io
` (5 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539
SECURITY PATCH - Patch
TCBZ4539
CVE-2023-45234
CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
CWE-119 Improper Restriction of Operations within the Bounds of
a Memory Buffer
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>
---
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 71 +++++++++++++++++++++++++---
1 file changed, 65 insertions(+), 6 deletions(-)
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
index 425e0cf8061d..2b2d372889a3 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
@@ -3,6 +3,7 @@
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -1312,6 +1313,65 @@ PxeBcSelectDhcp6Offer (
}
}
+/**
+ Cache the DHCPv6 DNS Server addresses
+
+ @param[in] Private The pointer to PXEBC_PRIVATE_DATA.
+ @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE.
+
+ @retval EFI_SUCCESS Cache the DHCPv6 DNS Server address successfully.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_DEVICE_ERROR The DNS Server Address Length provided by a untrusted
+ option is not a multiple of 16 bytes (sizeof (EFI_IPv6_ADDRESS)).
+**/
+EFI_STATUS
+PxeBcCacheDnsServerAddresses (
+ IN PXEBC_PRIVATE_DATA *Private,
+ IN PXEBC_DHCP6_PACKET_CACHE *Cache6
+ )
+{
+ UINT16 DnsServerLen;
+
+ DnsServerLen = NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen);
+ //
+ // Make sure that the number is nonzero
+ //
+ if (DnsServerLen == 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Make sure the DnsServerlen is a multiple of EFI_IPv6_ADDRESS (16)
+ //
+ if (DnsServerLen % sizeof (EFI_IPv6_ADDRESS) != 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // This code is currently written to only support a single DNS Server instead
+ // of multiple such as is spec defined (RFC3646, Section 3). The proper behavior
+ // would be to allocate the full space requested, CopyMem all of the data,
+ // and then add a DnsServerCount field to Private and update additional code
+ // that depends on this.
+ //
+ // To support multiple DNS servers the `AllocationSize` would need to be changed to DnsServerLen
+ //
+ // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886
+ //
+ Private->DnsServer = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));
+ if (Private->DnsServer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Intentionally only copy over the first server address.
+ // To support multiple DNS servers, the `Length` would need to be changed to DnsServerLen
+ //
+ CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS));
+
+ return EFI_SUCCESS;
+}
+
/**
Handle the DHCPv6 offer packet.
@@ -1335,6 +1395,7 @@ PxeBcHandleDhcp6Offer (
UINT32 SelectIndex;
UINT32 Index;
+ ASSERT (Private != NULL);
ASSERT (Private->SelectIndex > 0);
SelectIndex = (UINT32)(Private->SelectIndex - 1);
ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM);
@@ -1342,15 +1403,13 @@ PxeBcHandleDhcp6Offer (
Status = EFI_SUCCESS;
//
- // First try to cache DNS server address if DHCP6 offer provides.
+ // First try to cache DNS server addresses if DHCP6 offer provides.
//
if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] != NULL) {
- Private->DnsServer = AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen));
- if (Private->DnsServer == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = PxeBcCacheDnsServerAddresses (Private, Cache6);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
-
- CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS));
}
if (Cache6->OfferType == PxeOfferTypeDhcpBinl) {
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114261): https://edk2.groups.io/g/devel/message/114261
Mute This Topic: https://groups.io/mt/103926740/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 10/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Unit Tests
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (8 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 09/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 11/14] MdePkg: Test: Add gRT_GetTime Google Test Mock Doug Flick via groups.io
` (4 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539
SECURITY PATCH - Unit Tests
TCBZ4539
CVE-2023-45234
CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer
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>
---
NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 +
.../GoogleTest/UefiPxeBcDxeGoogleTest.inf | 48 +++
.../GoogleTest/PxeBcDhcp6GoogleTest.h | 50 +++
.../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 300 ++++++++++++++++++
.../GoogleTest/UefiPxeBcDxeGoogleTest.cpp | 19 ++
5 files changed, 418 insertions(+)
create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp
diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc
index 7fa7b0f9d5be..a0273c431025 100644
--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc
+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc
@@ -27,6 +27,7 @@ [Components]
#
NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
+ NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
# Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests.
[LibraryClasses]
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
new file mode 100644
index 000000000000..301dcdf61109
--- /dev/null
+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
@@ -0,0 +1,48 @@
+## @file
+# Unit test suite for the UefiPxeBcDxe using Google Test
+#
+# Copyright (c) Microsoft Corporation.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+[Defines]
+INF_VERSION = 0x00010005
+BASE_NAME = UefiPxeBcDxeGoogleTest
+FILE_GUID = 77D45C64-EC1E-4174-887B-886E89FD1EDF
+MODULE_TYPE = HOST_APPLICATION
+VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ UefiPxeBcDxeGoogleTest.cpp
+ PxeBcDhcp6GoogleTest.cpp
+ PxeBcDhcp6GoogleTest.h
+ ../PxeBcDhcp6.c
+ ../PxeBcSupport.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[LibraryClasses]
+ GoogleTestLib
+ DebugLib
+ NetLib
+ PcdLib
+
+[Protocols]
+ gEfiDhcp6ServiceBindingProtocolGuid
+ gEfiDns6ServiceBindingProtocolGuid
+ gEfiDns6ProtocolGuid
+
+[Pcd]
+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType
+
+[Guids]
+ gZeroGuid
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
new file mode 100644
index 000000000000..b17c314791c8
--- /dev/null
+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
@@ -0,0 +1,50 @@
+/** @file
+ This file exposes the internal interfaces which may be unit tested
+ for the PxeBcDhcp6Dxe driver.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef PXE_BC_DHCP6_GOOGLE_TEST_H_
+#define PXE_BC_DHCP6_GOOGLE_TEST_H_
+
+//
+// Minimal includes needed to compile
+//
+#include <Uefi.h>
+#include "../PxeBcImpl.h"
+
+/**
+ Handle the DHCPv6 offer packet.
+
+ @param[in] Private The pointer to PXEBC_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS Handled the DHCPv6 offer packet successfully.
+ @retval EFI_NO_RESPONSE No response to the following request packet.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_BUFFER_TOO_SMALL Can't cache the offer pacet.
+
+**/
+EFI_STATUS
+PxeBcHandleDhcp6Offer (
+ IN PXEBC_PRIVATE_DATA *Private
+ );
+
+/**
+ Cache the DHCPv6 Server address
+
+ @param[in] Private The pointer to PXEBC_PRIVATE_DATA.
+ @param[in] Cache6 The pointer to PXEBC_DHCP6_PACKET_CACHE.
+
+ @retval EFI_SUCCESS Cache the DHCPv6 Server address successfully.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_DEVICE_ERROR Failed to cache the DHCPv6 Server address.
+**/
+EFI_STATUS
+PxeBcCacheDnsServerAddresses (
+ IN PXEBC_PRIVATE_DATA *Private,
+ IN PXEBC_DHCP6_PACKET_CACHE *Cache6
+ );
+
+#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
new file mode 100644
index 000000000000..8260eeee50dc
--- /dev/null
+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
@@ -0,0 +1,300 @@
+/** @file
+ Host based unit test for PxeBcDhcp6.c.
+
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <gtest/gtest.h>
+
+extern "C" {
+ #include <Uefi.h>
+ #include <Library/BaseLib.h>
+ #include <Library/DebugLib.h>
+ #include "../PxeBcImpl.h"
+ #include "../PxeBcDhcp6.h"
+ #include "PxeBcDhcp6GoogleTest.h"
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions
+///////////////////////////////////////////////////////////////////////////////
+
+#define PACKET_SIZE (1500)
+
+typedef struct {
+ UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03)
+ UINT16 OptionLen; // The length of the option (e.g., 16 bytes)
+ UINT8 ServerId[16]; // The 16-byte DHCPv6 Server Identifier
+} DHCP6_OPTION_SERVER_ID;
+
+///////////////////////////////////////////////////////////////////////////////
+/// Symbol Definitions
+///////////////////////////////////////////////////////////////////////////////
+
+EFI_STATUS
+MockUdpWrite (
+ IN EFI_PXE_BASE_CODE_PROTOCOL *This,
+ IN UINT16 OpFlags,
+ IN EFI_IP_ADDRESS *DestIp,
+ IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort,
+ IN EFI_IP_ADDRESS *GatewayIp OPTIONAL,
+ IN EFI_IP_ADDRESS *SrcIp OPTIONAL,
+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL,
+ IN UINTN *HeaderSize OPTIONAL,
+ IN VOID *HeaderPtr OPTIONAL,
+ IN UINTN *BufferSize,
+ IN VOID *BufferPtr
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MockUdpRead (
+ IN EFI_PXE_BASE_CODE_PROTOCOL *This,
+ IN UINT16 OpFlags,
+ IN OUT EFI_IP_ADDRESS *DestIp OPTIONAL,
+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort OPTIONAL,
+ IN OUT EFI_IP_ADDRESS *SrcIp OPTIONAL,
+ IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL,
+ IN UINTN *HeaderSize OPTIONAL,
+ IN VOID *HeaderPtr OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ IN VOID *BufferPtr
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MockConfigure (
+ IN EFI_UDP6_PROTOCOL *This,
+ IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+// Needed by PxeBcSupport
+EFI_STATUS
+EFIAPI
+QueueDpc (
+ IN EFI_TPL DpcTpl,
+ IN EFI_DPC_PROCEDURE DpcProcedure,
+ IN VOID *DpcContext OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PxeBcHandleDhcp6OfferTest Tests
+///////////////////////////////////////////////////////////////////////////////
+
+class PxeBcHandleDhcp6OfferTest : public ::testing::Test {
+public:
+ PXEBC_PRIVATE_DATA Private = { 0 };
+ EFI_UDP6_PROTOCOL Udp6Read;
+ EFI_PXE_BASE_CODE_MODE Mode = { 0 };
+
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);
+
+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL
+ // The function under test really only needs the following:
+ // UdpWrite
+ // UdpRead
+
+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite;
+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead;
+
+ // Need to setup EFI_UDP6_PROTOCOL
+ // The function under test really only needs the following:
+ // Configure
+
+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure;
+ Private.Udp6Read = &Udp6Read;
+
+ // Need to setup the EFI_PXE_BASE_CODE_MODE
+ Private.PxeBc.Mode = &Mode;
+
+ // for this test it doesn't really matter what the Dhcpv6 ack is set to
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ if (Private.Dhcp6Request != NULL) {
+ FreePool (Private.Dhcp6Request);
+ }
+
+ // Clean up any resources or variables
+ }
+};
+
+// Note:
+// Testing PxeBcHandleDhcp6Offer() is difficult because it depends on a
+// properly setup Private structure. Attempting to properly test this function
+// without a signficant refactor is a fools errand. Instead, we will test
+// that we can prevent an overflow in the function.
+TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) {
+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL;
+ EFI_DHCP6_PACKET_OPTION Option = { 0 };
+
+ Private.SelectIndex = 1; // SelectIndex is 1-based
+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
+
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
+ // Setup the DHCPv6 offer packet
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (1337);
+
+ ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR);
+}
+
+class PxeBcCacheDnsServerAddressesTest : public ::testing::Test {
+public:
+ PXEBC_PRIVATE_DATA Private = { 0 };
+
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ }
+};
+
+// Test Description
+// Test that we cache the DNS server address from the DHCPv6 offer packet
+TEST_F (PxeBcCacheDnsServerAddressesTest, BasicUsageTest) {
+ UINT8 SearchPattern[16] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF };
+ EFI_DHCP6_PACKET_OPTION *Option;
+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL;
+
+ Option = (EFI_DHCP6_PACKET_OPTION *)AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + sizeof (SearchPattern));
+ ASSERT_NE (Option, nullptr);
+
+ Option->OpCode = DHCP6_OPT_SERVER_ID;
+ Option->OpLen = NTOHS (sizeof (SearchPattern));
+ CopyMem (Option->Data, SearchPattern, sizeof (SearchPattern));
+
+ Private.SelectIndex = 1; // SelectIndex is 1-based
+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option;
+
+ Private.DnsServer = nullptr;
+
+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS);
+ ASSERT_NE (Private.DnsServer, nullptr);
+ ASSERT_EQ (CompareMem (Private.DnsServer, SearchPattern, sizeof (SearchPattern)), 0);
+
+ if (Private.DnsServer) {
+ FreePool (Private.DnsServer);
+ }
+
+ if (Option) {
+ FreePool (Option);
+ }
+}
+// Test Description
+// Test that we can prevent an overflow in the function
+TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptOverflowTest) {
+ EFI_DHCP6_PACKET_OPTION Option = { 0 };
+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL;
+
+ Private.SelectIndex = 1; // SelectIndex is 1-based
+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
+ // Setup the DHCPv6 offer packet
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (1337);
+
+ Private.DnsServer = NULL;
+
+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR);
+ ASSERT_EQ (Private.DnsServer, nullptr);
+
+ if (Private.DnsServer) {
+ FreePool (Private.DnsServer);
+ }
+}
+
+// Test Description
+// Test that we can prevent an underflow in the function
+TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) {
+ EFI_DHCP6_PACKET_OPTION Option = { 0 };
+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL;
+
+ Private.SelectIndex = 1; // SelectIndex is 1-based
+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
+ // Setup the DHCPv6 offer packet
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (2);
+
+ Private.DnsServer = NULL;
+
+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_DEVICE_ERROR);
+ ASSERT_EQ (Private.DnsServer, nullptr);
+
+ if (Private.DnsServer) {
+ FreePool (Private.DnsServer);
+ }
+}
+
+// Test Description
+// Test that we can handle recursive dns (multiple dns entries)
+TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
+ EFI_DHCP6_PACKET_OPTION Option = { 0 };
+ PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL;
+
+ Private.SelectIndex = 1; // SelectIndex is 1-based
+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
+ // Setup the DHCPv6 offer packet
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
+
+ EFI_IPv6_ADDRESS addresses[2] = {
+ // 2001:db8:85a3::8a2e:370:7334
+ { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 },
+ // fe80::d478:91c3:ecd7:4ff9
+ { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 }
+ };
+
+ CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses));
+
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses));
+
+ Private.DnsServer = NULL;
+
+ ASSERT_EQ (PxeBcCacheDnsServerAddresses (&(PxeBcCacheDnsServerAddressesTest::Private), Cache6), EFI_SUCCESS);
+
+ ASSERT_NE (Private.DnsServer, nullptr);
+
+ //
+ // This is expected to fail until DnsServer supports multiple DNS servers
+ //
+ // This is tracked in https://bugzilla.tianocore.org/show_bug.cgi?id=1886
+ //
+ // Disabling:
+ // ASSERT_EQ (CompareMem(Private.DnsServer, &addresses, sizeof(addresses)), 0);
+
+ if (Private.DnsServer) {
+ FreePool (Private.DnsServer);
+ }
+}
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp
new file mode 100644
index 000000000000..cc4fdf525b62
--- /dev/null
+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp
@@ -0,0 +1,19 @@
+/** @file
+ Acts as the main entry point for the tests for the UefiPxeBcDxe module.
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <gtest/gtest.h>
+
+////////////////////////////////////////////////////////////////////////////////
+// Run the tests
+////////////////////////////////////////////////////////////////////////////////
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ testing::InitGoogleTest (&argc, argv);
+ return RUN_ALL_TESTS ();
+}
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114262): https://edk2.groups.io/g/devel/message/114262
Mute This Topic: https://groups.io/mt/103926741/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 11/14] MdePkg: Test: Add gRT_GetTime Google Test Mock
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (9 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 10/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Unit Tests Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 18:50 ` Michael D Kinney
2024-01-24 3:33 ` [edk2-devel] [PATCH 12/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch Doug Flick via groups.io
` (3 subsequent siblings)
14 siblings, 1 reply; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel; +Cc: Douglas Flick [MSFT], Michael D Kinney, Liming Gao, Zhiguang Liu
This adds support for GetTime Google Test Mock
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
---
.../GoogleTest/Library/MockUefiRuntimeServicesTableLib.h | 7 +++++++
.../MockUefiRuntimeServicesTableLib.cpp | 5 +++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h
index 241abc55c079..bcc902cb93c2 100644
--- a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h
+++ b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTableLib.h
@@ -37,6 +37,13 @@ struct MockUefiRuntimeServicesTableLib {
IN UINTN DataSize,
IN VOID *Data)
);
+
+ MOCK_FUNCTION_DECLARATION (
+ EFI_STATUS,
+ gRT_GetTime,
+ (OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL)
+ );
};
#endif
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp
index 14296b0ccb88..8d2afd5dd63a 100644
--- a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.cpp
@@ -10,11 +10,12 @@ MOCK_INTERFACE_DEFINITION (MockUefiRuntimeServicesTableLib);
MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_GetVariable, 5, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_SetVariable, 5, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_GetTime, 2, EFIAPI);
static EFI_RUNTIME_SERVICES localRt = {
- { 0 }, // EFI_TABLE_HEADER
+ { 0 }, // EFI_TABLE_HEADER
- NULL, // EFI_GET_TIME
+ gRT_GetTime, // EFI_GET_TIME
NULL, // EFI_SET_TIME
NULL, // EFI_GET_WAKEUP_TIME
NULL, // EFI_SET_WAKEUP_TIME
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114263): https://edk2.groups.io/g/devel/message/114263
Mute This Topic: https://groups.io/mt/103926742/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH 11/14] MdePkg: Test: Add gRT_GetTime Google Test Mock
2024-01-24 3:33 ` [edk2-devel] [PATCH 11/14] MdePkg: Test: Add gRT_GetTime Google Test Mock Doug Flick via groups.io
@ 2024-01-24 18:50 ` Michael D Kinney
0 siblings, 0 replies; 24+ messages in thread
From: Michael D Kinney @ 2024-01-24 18:50 UTC (permalink / raw)
To: Douglas Flick [MSFT], devel@edk2.groups.io
Cc: Liming Gao, Liu, Zhiguang, Kinney, Michael D
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
> -----Original Message-----
> From: Douglas Flick [MSFT] <doug.edk2@gmail.com>
> Sent: Tuesday, January 23, 2024 7:34 PM
> To: devel@edk2.groups.io
> Cc: Douglas Flick [MSFT] <doug.edk2@gmail.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>;
> Liu, Zhiguang <zhiguang.liu@intel.com>
> Subject: [PATCH 11/14] MdePkg: Test: Add gRT_GetTime Google Test Mock
>
> This adds support for GetTime Google Test Mock
>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
>
> Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
> ---
> .../GoogleTest/Library/MockUefiRuntimeServicesTableLib.h | 7 +++++++
> .../MockUefiRuntimeServicesTableLib.cpp | 5 +++--
> 2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git
> a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTab
> leLib.h
> b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTab
> leLib.h
> index 241abc55c079..bcc902cb93c2 100644
> ---
> a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTab
> leLib.h
> +++
> b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockUefiRuntimeServicesTab
> leLib.h
> @@ -37,6 +37,13 @@ struct MockUefiRuntimeServicesTableLib {
> IN UINTN DataSize,
>
> IN VOID *Data)
>
> );
>
> +
>
> + MOCK_FUNCTION_DECLARATION (
>
> + EFI_STATUS,
>
> + gRT_GetTime,
>
> + (OUT EFI_TIME *Time,
>
> + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL)
>
> + );
>
> };
>
>
>
> #endif
>
> diff --git
> a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/Mo
> ckUefiRuntimeServicesTableLib.cpp
> b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/Mo
> ckUefiRuntimeServicesTableLib.cpp
> index 14296b0ccb88..8d2afd5dd63a 100644
> ---
> a/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/Mo
> ckUefiRuntimeServicesTableLib.cpp
> +++
> b/MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/Mo
> ckUefiRuntimeServicesTableLib.cpp
> @@ -10,11 +10,12 @@ MOCK_INTERFACE_DEFINITION
> (MockUefiRuntimeServicesTableLib);
>
>
> MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib,
> gRT_GetVariable, 5, EFIAPI);
>
> MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib,
> gRT_SetVariable, 5, EFIAPI);
>
> +MOCK_FUNCTION_DEFINITION (MockUefiRuntimeServicesTableLib, gRT_GetTime,
> 2, EFIAPI);
>
>
>
> static EFI_RUNTIME_SERVICES localRt = {
>
> - { 0 }, // EFI_TABLE_HEADER
>
> + { 0 }, // EFI_TABLE_HEADER
>
>
>
> - NULL, // EFI_GET_TIME
>
> + gRT_GetTime, // EFI_GET_TIME
>
> NULL, // EFI_SET_TIME
>
> NULL, // EFI_GET_WAKEUP_TIME
>
> NULL, // EFI_SET_WAKEUP_TIME
>
> --
> 2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114349): https://edk2.groups.io/g/devel/message/114349
Mute This Topic: https://groups.io/mt/103926742/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/1913456212/xyzzy [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 12/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (10 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 11/14] MdePkg: Test: Add gRT_GetTime Google Test Mock Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 13/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit Tests Doug Flick via groups.io
` (2 subsequent siblings)
14 siblings, 0 replies; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540
SECURITY PATCH - Patch
TCBZ4540
CVE-2023-45235
CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
CWE-119 Improper Restriction of Operations within the Bounds of
a Memory Buffer
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>
---
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 ++++++
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 77 ++++++++++++++++++++++------
2 files changed, 78 insertions(+), 16 deletions(-)
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
index c86f6d391b80..6357d27faefd 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
@@ -34,6 +34,23 @@
#define PXEBC_ADDR_START_DELIMITER '['
#define PXEBC_ADDR_END_DELIMITER ']'
+//
+// A DUID consists of a 2-octet type code represented in network byte
+// order, followed by a variable number of octets that make up the
+// actual identifier. The length of the DUID (not including the type
+// code) is at least 1 octet and at most 128 octets.
+//
+#define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1)
+#define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128)
+
+//
+// This define represents the combineds code and length field from
+// https://datatracker.ietf.org/doc/html/rfc3315#section-22.1
+//
+#define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \
+ (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \
+ sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen))
+
#define GET_NEXT_DHCP6_OPTION(Opt) \
(EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \
sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1)
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
index 2b2d372889a3..7fd1281c1184 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
@@ -887,6 +887,7 @@ PxeBcRequestBootService (
EFI_STATUS Status;
EFI_DHCP6_PACKET *IndexOffer;
UINT8 *Option;
+ UINTN DiscoverLenNeeded;
PxeBc = &Private->PxeBc;
Request = Private->Dhcp6Request;
@@ -899,7 +900,8 @@ PxeBcRequestBootService (
return EFI_DEVICE_ERROR;
}
- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));
+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);
+ Discover = AllocateZeroPool (DiscoverLenNeeded);
if (Discover == NULL) {
return EFI_OUT_OF_RESOURCES;
}
@@ -924,16 +926,34 @@ PxeBcRequestBootService (
DHCP6_OPT_SERVER_ID
);
if (Option == NULL) {
- return EFI_NOT_FOUND;
+ Status = EFI_NOT_FOUND;
+ goto ON_ERROR;
}
//
// Add Server ID Option.
//
OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen);
- CopyMem (DiscoverOpt, Option, OpLen + 4);
- DiscoverOpt += (OpLen + 4);
- DiscoverLen += (OpLen + 4);
+
+ //
+ // Check that the minimum and maximum requirements are met
+ //
+ if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_ERROR;
+ }
+
+ //
+ // Check that the option length is valid.
+ //
+ if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+
+ CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
}
while (RequestLen < Request->Length) {
@@ -944,16 +964,24 @@ PxeBcRequestBootService (
(OpCode != DHCP6_OPT_SERVER_ID)
)
{
+ //
+ // Check that the option length is valid.
+ //
+ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+
//
// Copy all the options except IA option and Server ID
//
- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);
- DiscoverOpt += (OpLen + 4);
- DiscoverLen += (OpLen + 4);
+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
}
- RequestOpt += (OpLen + 4);
- RequestLen += (OpLen + 4);
+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
}
//
@@ -2154,6 +2182,7 @@ PxeBcDhcp6Discover (
UINT16 OpLen;
UINT32 Xid;
EFI_STATUS Status;
+ UINTN DiscoverLenNeeded;
PxeBc = &Private->PxeBc;
Mode = PxeBc->Mode;
@@ -2169,7 +2198,8 @@ PxeBcDhcp6Discover (
return EFI_DEVICE_ERROR;
}
- Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));
+ DiscoverLenNeeded = sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET);
+ Discover = AllocateZeroPool (DiscoverLenNeeded);
if (Discover == NULL) {
return EFI_OUT_OF_RESOURCES;
}
@@ -2185,22 +2215,37 @@ PxeBcDhcp6Discover (
DiscoverLen = sizeof (EFI_DHCP6_HEADER);
RequestLen = DiscoverLen;
+ //
+ // The request packet is generated by the UEFI network stack. In the DHCP4 DORA and DHCP6 SARR sequence,
+ // the first (discover in DHCP4 and solicit in DHCP6) and third (request in both DHCP4 and DHCP6) are
+ // generated by the DHCP client (the UEFI network stack in this case). By the time this function executes,
+ // the DHCP sequence already has been executed once (see UEFI Specification Figures 24.2 and 24.3), with
+ // Private->Dhcp6Request being a cached copy of the DHCP6 request packet that UEFI network stack previously
+ // generated and sent.
+ //
+ // Therefore while this code looks like it could overflow, in practice it's not possible.
+ //
while (RequestLen < Request->Length) {
OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpCode);
OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)RequestOpt)->OpLen);
if ((OpCode != EFI_DHCP6_IA_TYPE_NA) &&
(OpCode != EFI_DHCP6_IA_TYPE_TA))
{
+ if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+
//
// Copy all the options except IA option.
//
- CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);
- DiscoverOpt += (OpLen + 4);
- DiscoverLen += (OpLen + 4);
+ CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
}
- RequestOpt += (OpLen + 4);
- RequestLen += (OpLen + 4);
+ RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
+ RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
}
Status = PxeBc->UdpWrite (
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114264): https://edk2.groups.io/g/devel/message/114264
Mute This Topic: https://groups.io/mt/103926743/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 13/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit Tests
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (11 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 12/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 3:33 ` [edk2-devel] [PATCH 14/14] NetworkPkg: : Adds a SecurityFix.yaml file Doug Flick via groups.io
2024-01-24 10:17 ` [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Pedro Falcato
14 siblings, 0 replies; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel
Cc: Doug Flick, Saloni Kasbekar, Zachary Clark-williams,
Doug Flick [MSFT]
From: Doug Flick <dougflick@microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540
SECURITY PATCH - Unit Tests
TCBZ4540
CVE-2023-45235
CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
CWE-119 Improper Restriction of Operations within the Bounds of
a Memory Buffer
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>
---
NetworkPkg/Test/NetworkPkgHostTest.dsc | 5 +-
.../GoogleTest/PxeBcDhcp6GoogleTest.h | 18 ++
.../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 278 +++++++++++++++++-
3 files changed, 298 insertions(+), 3 deletions(-)
diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc
index a0273c431025..fa301a7a52ab 100644
--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc
+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc
@@ -27,7 +27,10 @@ [Components]
#
NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf
- NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf
+ NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf {
+ <LibraryClasses>
+ UefiRuntimeServicesTableLib|MdePkg/Test/Mock/Library/GoogleTest/MockUefiRuntimeServicesTableLib/MockUefiRuntimeServicesTableLib.inf
+ }
# Despite these library classes being listed in [LibraryClasses] below, they are not needed for the host-based unit tests.
[LibraryClasses]
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
index b17c314791c8..0d825e44250a 100644
--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h
@@ -47,4 +47,22 @@ PxeBcCacheDnsServerAddresses (
IN PXEBC_DHCP6_PACKET_CACHE *Cache6
);
+/**
+ Build and send out the request packet for the bootfile, and parse the reply.
+
+ @param[in] Private The pointer to PxeBc private data.
+ @param[in] Index PxeBc option boot item type.
+
+ @retval EFI_SUCCESS Successfully discovered the boot file.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_NOT_FOUND Can't get the PXE reply packet.
+ @retval Others Failed to discover the boot file.
+
+**/
+EFI_STATUS
+PxeBcRequestBootService (
+ IN PXEBC_PRIVATE_DATA *Private,
+ IN UINT32 Index
+ );
+
#endif // PXE_BC_DHCP6_GOOGLE_TEST_H_
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
index 8260eeee50dc..bd423ebadfce 100644
--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
@@ -4,7 +4,9 @@
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include <gtest/gtest.h>
+#include <Library/GoogleTestLib.h>
+#include <GoogleTest/Library/MockUefiLib.h>
+#include <GoogleTest/Library/MockUefiRuntimeServicesTableLib.h>
extern "C" {
#include <Uefi.h>
@@ -19,7 +21,8 @@ extern "C" {
// Definitions
///////////////////////////////////////////////////////////////////////////////
-#define PACKET_SIZE (1500)
+#define PACKET_SIZE (1500)
+#define REQUEST_OPTION_LENGTH (120)
typedef struct {
UINT16 OptionCode; // The option code for DHCP6_OPT_SERVER_ID (e.g., 0x03)
@@ -76,6 +79,26 @@ MockConfigure (
}
// Needed by PxeBcSupport
+EFI_STATUS
+PxeBcDns6 (
+ IN PXEBC_PRIVATE_DATA *Private,
+ IN CHAR16 *HostName,
+ OUT EFI_IPv6_ADDRESS *IpAddress
+ )
+{
+ return EFI_SUCCESS;
+}
+
+UINT32
+PxeBcBuildDhcp6Options (
+ IN PXEBC_PRIVATE_DATA *Private,
+ OUT EFI_DHCP6_PACKET_OPTION **OptList,
+ IN UINT8 *Buffer
+ )
+{
+ return EFI_SUCCESS;
+}
+
EFI_STATUS
EFIAPI
QueueDpc (
@@ -159,6 +182,10 @@ TEST_F (PxeBcHandleDhcp6OfferTest, BasicUsageTest) {
ASSERT_EQ (PxeBcHandleDhcp6Offer (&(PxeBcHandleDhcp6OfferTest::Private)), EFI_DEVICE_ERROR);
}
+///////////////////////////////////////////////////////////////////////////////
+// PxeBcCacheDnsServerAddresses Tests
+///////////////////////////////////////////////////////////////////////////////
+
class PxeBcCacheDnsServerAddressesTest : public ::testing::Test {
public:
PXEBC_PRIVATE_DATA Private = { 0 };
@@ -298,3 +325,250 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
FreePool (Private.DnsServer);
}
}
+
+///////////////////////////////////////////////////////////////////////////////
+// PxeBcRequestBootServiceTest Test Cases
+///////////////////////////////////////////////////////////////////////////////
+
+class PxeBcRequestBootServiceTest : public ::testing::Test {
+public:
+ PXEBC_PRIVATE_DATA Private = { 0 };
+ EFI_UDP6_PROTOCOL Udp6Read;
+
+protected:
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);
+
+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL
+ // The function under test really only needs the following:
+ // UdpWrite
+ // UdpRead
+
+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite;
+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead;
+
+ // Need to setup EFI_UDP6_PROTOCOL
+ // The function under test really only needs the following:
+ // Configure
+
+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure;
+ Private.Udp6Read = &Udp6Read;
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ if (Private.Dhcp6Request != NULL) {
+ FreePool (Private.Dhcp6Request);
+ }
+
+ // Clean up any resources or variables
+ }
+};
+
+TEST_F (PxeBcRequestBootServiceTest, ServerDiscoverBasicUsageTest) {
+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;
+
+ DHCP6_OPTION_SERVER_ID Server = { 0 };
+
+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID);
+ Server.OptionLen = HTONS (16); // valid length
+ UINT8 Index = 0;
+
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;
+
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
+
+ CopyMem (Cursor, &Server, sizeof (Server));
+ Cursor += sizeof (Server);
+
+ // Update the packet length
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
+ Packet->Size = PACKET_SIZE;
+
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);
+}
+
+TEST_F (PxeBcRequestBootServiceTest, AttemptDiscoverOverFlowExpectFailure) {
+ PxeBcRequestBootServiceTest::Private.OfferBuffer[0].Dhcp6.OfferType = PxeOfferTypeProxyBinl;
+
+ DHCP6_OPTION_SERVER_ID Server = { 0 };
+
+ Server.OptionCode = HTONS (DHCP6_OPT_SERVER_ID);
+ Server.OptionLen = HTONS (1500); // This length would overflow without a check
+ UINT8 Index = 0;
+
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.OfferBuffer[Index].Dhcp6.Packet.Offer;
+
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
+
+ CopyMem (Cursor, &Server, sizeof (Server));
+ Cursor += sizeof (Server);
+
+ // Update the packet length
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
+ Packet->Size = PACKET_SIZE;
+
+ // This is going to be stopped by the duid overflow check
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_INVALID_PARAMETER);
+}
+
+TEST_F (PxeBcRequestBootServiceTest, RequestBasicUsageTest) {
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
+
+ RequestOpt.OpCode = HTONS (0x1337);
+ RequestOpt.OpLen = 0; // valid length
+
+ UINT8 Index = 0;
+
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];
+
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
+
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
+ Cursor += sizeof (RequestOpt);
+
+ // Update the packet length
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
+ Packet->Size = PACKET_SIZE;
+
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_SUCCESS);
+}
+
+TEST_F (PxeBcRequestBootServiceTest, AttemptRequestOverFlowExpectFailure) {
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
+
+ RequestOpt.OpCode = HTONS (0x1337);
+ RequestOpt.OpLen = 1500; // this length would overflow without a check
+
+ UINT8 Index = 0;
+
+ EFI_DHCP6_PACKET *Packet = (EFI_DHCP6_PACKET *)&Private.Dhcp6Request[Index];
+
+ UINT8 *Cursor = (UINT8 *)(Packet->Dhcp6.Option);
+
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
+ Cursor += sizeof (RequestOpt);
+
+ // Update the packet length
+ Packet->Length = (UINT16)(Cursor - (UINT8 *)Packet);
+ Packet->Size = PACKET_SIZE;
+
+ ASSERT_EQ (PxeBcRequestBootService (&(PxeBcRequestBootServiceTest::Private), Index), EFI_OUT_OF_RESOURCES);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PxeBcDhcp6Discover Test
+///////////////////////////////////////////////////////////////////////////////
+
+class PxeBcDhcp6DiscoverTest : public ::testing::Test {
+public:
+ PXEBC_PRIVATE_DATA Private = { 0 };
+ EFI_UDP6_PROTOCOL Udp6Read;
+
+protected:
+ MockUefiRuntimeServicesTableLib RtServicesMock;
+
+ // Add any setup code if needed
+ virtual void
+ SetUp (
+ )
+ {
+ Private.Dhcp6Request = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);
+
+ // Need to setup the EFI_PXE_BASE_CODE_PROTOCOL
+ // The function under test really only needs the following:
+ // UdpWrite
+ // UdpRead
+
+ Private.PxeBc.UdpWrite = (EFI_PXE_BASE_CODE_UDP_WRITE)MockUdpWrite;
+ Private.PxeBc.UdpRead = (EFI_PXE_BASE_CODE_UDP_READ)MockUdpRead;
+
+ // Need to setup EFI_UDP6_PROTOCOL
+ // The function under test really only needs the following:
+ // Configure
+
+ Udp6Read.Configure = (EFI_UDP6_CONFIGURE)MockConfigure;
+ Private.Udp6Read = &Udp6Read;
+ }
+
+ // Add any cleanup code if needed
+ virtual void
+ TearDown (
+ )
+ {
+ if (Private.Dhcp6Request != NULL) {
+ FreePool (Private.Dhcp6Request);
+ }
+
+ // Clean up any resources or variables
+ }
+};
+
+// Test Description
+// This will cause an overflow by an untrusted packet during the option parsing
+TEST_F (PxeBcDhcp6DiscoverTest, BasicOverflowTest) {
+ EFI_IPv6_ADDRESS DestIp = { 0 };
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
+
+ RequestOpt.OpCode = HTONS (0x1337);
+ RequestOpt.OpLen = HTONS (0xFFFF); // overflow
+
+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);
+
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
+ Cursor += sizeof (RequestOpt);
+
+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);
+
+ EXPECT_CALL (RtServicesMock, gRT_GetTime)
+ .WillOnce (::testing::Return (0));
+
+ ASSERT_EQ (
+ PxeBcDhcp6Discover (
+ &(PxeBcDhcp6DiscoverTest::Private),
+ 0,
+ NULL,
+ FALSE,
+ (EFI_IP_ADDRESS *)&DestIp
+ ),
+ EFI_OUT_OF_RESOURCES
+ );
+}
+
+// Test Description
+// This will test that we can handle a packet with a valid option length
+TEST_F (PxeBcDhcp6DiscoverTest, BasicUsageTest) {
+ EFI_IPv6_ADDRESS DestIp = { 0 };
+ EFI_DHCP6_PACKET_OPTION RequestOpt = { 0 }; // the data section doesn't really matter
+
+ RequestOpt.OpCode = HTONS (0x1337);
+ RequestOpt.OpLen = HTONS (0x30);
+
+ UINT8 *Cursor = (UINT8 *)(Private.Dhcp6Request->Dhcp6.Option);
+
+ CopyMem (Cursor, &RequestOpt, sizeof (RequestOpt));
+ Cursor += sizeof (RequestOpt);
+
+ Private.Dhcp6Request->Length = (UINT16)(Cursor - (UINT8 *)Private.Dhcp6Request);
+
+ EXPECT_CALL (RtServicesMock, gRT_GetTime)
+ .WillOnce (::testing::Return (0));
+
+ ASSERT_EQ (
+ PxeBcDhcp6Discover (
+ &(PxeBcDhcp6DiscoverTest::Private),
+ 0,
+ NULL,
+ FALSE,
+ (EFI_IP_ADDRESS *)&DestIp
+ ),
+ EFI_SUCCESS
+ );
+}
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114265): https://edk2.groups.io/g/devel/message/114265
Mute This Topic: https://groups.io/mt/103926744/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [edk2-devel] [PATCH 14/14] NetworkPkg: : Adds a SecurityFix.yaml file
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (12 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 13/14] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit Tests Doug Flick via groups.io
@ 2024-01-24 3:33 ` Doug Flick via groups.io
2024-01-24 10:17 ` [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Pedro Falcato
14 siblings, 0 replies; 24+ messages in thread
From: Doug Flick via groups.io @ 2024-01-24 3:33 UTC (permalink / raw)
To: devel; +Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams
This creates / adds a security file that tracks the security fixes
found in this package and can be used to find the fixes that were
applied.
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>
---
NetworkPkg/SecurityFixes.yaml | 123 ++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
create mode 100644 NetworkPkg/SecurityFixes.yaml
diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml
new file mode 100644
index 000000000000..7e900483fec5
--- /dev/null
+++ b/NetworkPkg/SecurityFixes.yaml
@@ -0,0 +1,123 @@
+## @file
+# Security Fixes for SecurityPkg
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+CVE_2023_45229:
+ commit_titles:
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch"
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests"
+ cve: CVE-2023-45229
+ date_reported: 2023-08-28 13:56 UTC
+ description: "Bug 01 - edk2/NetworkPkg: Out-of-bounds read when processing IA_NA/IA_TA options in a DHCPv6 Advertise message"
+ note:
+ files_impacted:
+ - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c
+ - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4534
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45229
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
+CVE_2023_45230:
+ commit_titles:
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch"
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests"
+ cve: CVE-2023-45230
+ date_reported: 2023-08-28 13:56 UTC
+ description: "Bug 02 - edk2/NetworkPkg: Buffer overflow in the DHCPv6 client via a long Server ID option"
+ note:
+ files_impacted:
+ - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c
+ - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4535
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45230
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
+CVE_2023_45231:
+ commit_titles:
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Patch"
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Unit Tests"
+ cve: CVE-2023-45231
+ date_reported: 2023-08-28 13:56 UTC
+ description: "Bug 03 - edk2/NetworkPkg: Out-of-bounds read when handling a ND Redirect message with truncated options"
+ note:
+ files_impacted:
+ - NetworkPkg/Ip6Dxe/Ip6Option.c
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4536
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45231
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
+CVE_2023_45232:
+ commit_titles:
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch"
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests"
+ cve: CVE-2023-45232
+ date_reported: 2023-08-28 13:56 UTC
+ description: "Bug 04 - edk2/NetworkPkg: Infinite loop when parsing unknown options in the Destination Options header"
+ note:
+ files_impacted:
+ - NetworkPkg/Ip6Dxe/Ip6Option.c
+ - NetworkPkg/Ip6Dxe/Ip6Option.h
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4537
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45232
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
+CVE_2023_45233:
+ commit_titles:
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch"
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests"
+ cve: CVE-2023-45233
+ date_reported: 2023-08-28 13:56 UTC
+ description: "Bug 05 - edk2/NetworkPkg: Infinite loop when parsing a PadN option in the Destination Options header "
+ note: This was fixed along with CVE-2023-45233
+ files_impacted:
+ - NetworkPkg/Ip6Dxe/Ip6Option.c
+ - NetworkPkg/Ip6Dxe/Ip6Option.h
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4538
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45233
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
+CVE_2023_45234:
+ commit_titles:
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Patch"
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Unit Tests"
+ cve: CVE-2023-45234
+ date_reported: 2023-08-28 13:56 UTC
+ description: "Bug 06 - edk2/NetworkPkg: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message"
+ note:
+ files_impacted:
+ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4539
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45234
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
+CVE_2023_45235:
+ commit_titles:
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Patch"
+ - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Unit Tests"
+ cve: CVE-2023-45235
+ date_reported: 2023-08-28 13:56 UTC
+ description: "Bug 07 - edk2/NetworkPkg: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message"
+ note:
+ files_impacted:
+ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+ - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
+ links:
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=4540
+ - https://nvd.nist.gov/vuln/detail/CVE-2023-45235
+ - http://www.openwall.com/lists/oss-security/2024/01/16/2
+ - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html
+ - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html
--
2.43.0
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114266): https://edk2.groups.io/g/devel/message/114266
Mute This Topic: https://groups.io/mt/103926745/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack
2024-01-24 3:33 [edk2-devel] [PATCH 00/14] Security Patches for EDK II Network Stack Doug Flick via groups.io
` (13 preceding siblings ...)
2024-01-24 3:33 ` [edk2-devel] [PATCH 14/14] NetworkPkg: : Adds a SecurityFix.yaml file Doug Flick via groups.io
@ 2024-01-24 10:17 ` Pedro Falcato
14 siblings, 0 replies; 24+ messages in thread
From: Pedro Falcato @ 2024-01-24 10:17 UTC (permalink / raw)
To: devel, dougflick
Cc: Douglas Flick [MSFT], Saloni Kasbekar, Zachary Clark-williams,
Michael D Kinney, Liming Gao, Zhiguang Liu
On Wed, Jan 24, 2024 at 5:20 AM Doug Flick via groups.io
<dougflick=microsoft.com@groups.io> wrote:
>
> The security patches contained in this series with the exception of
> "MdePkg/Test: Add gRT_GetTime Google Test Mock" and
> "NetworkPkg: : Adds a SecurityFix.yaml file" have been reviewed
> during GHSA-hc6x-cw6p-gj7h infosec review.
>
> This patch series contains the following security patches for the
> security vulnerabilities found by QuarksLab in the EDK II Network
> Stack:
>
> 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
>
> CVE-2023-45230
> CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
> CWE-119 Improper Restriction of Operations within the Bounds
> of a Memory Buffer
>
> CVE-2023-45231
> 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
>
> CVE-2023-45232
> CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
> CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
>
> CVE-2023-45233
> CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
> CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop')
>
> CVE-2023-45234
> CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
> CWE-119 Improper Restriction of Operations within the Bounds
> of a Memory Buffer
>
> CVE-2023-45235
> CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
> CWE-119 Improper Restriction of Operations within the Bounds
> of a Memory Buffer
>
> NetworkPkg:
> Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
> Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
>
> MdePkg:
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
>
> Doug Flick (8):
> NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Patch
> NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 - Unit Tests
> NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch
> NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests
> NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch
> NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Unit Tests
> NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch
> NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit Tests
>
> Douglas Flick [MSFT] (6):
> NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch
> NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests
> NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch
> NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests
> MdePkg: Test: Add gRT_GetTime Google Test Mock
> NetworkPkg: : Adds a SecurityFix.yaml file
Thanks for the patches. Please rewrite the commit messages for each
specific patch to contain relevant details on the problem and fix. The
commits as-is are somewhat useless unless one wants to track down the
CVEs. Thanks!
--
Pedro
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114271): https://edk2.groups.io/g/devel/message/114271
Mute This Topic: https://groups.io/mt/103926729/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 24+ messages in thread