From 0aa9ecf1e32f222ee40a7bbdd196d654ed64da5b Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Tue, 27 Feb 2024 06:10:11 -0500 Subject: [PATCH] * Tue Feb 27 2024 Miroslav Rezanina - 20220126gitbb1bba3d77-12 - edk2-Apply-uncrustify-changes-to-.c-.h-files-in-the-Netwo.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Apply-uncrustify-changes.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Apply-uncrustify-changes-p2.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - edk2-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] - Resolves: RHEL-21840 (CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8]) - Resolves: RHEL-21844 (CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8]) - Resolves: RHEL-21846 (CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8]) - Resolves: RHEL-21848 (CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8]) - Resolves: RHEL-21850 (CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8]) - Resolves: RHEL-21852 (CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8]) --- ...-changes-to-.c-.h-files-in-the-Netwo.patch | 1735 ++++++++++++++ ...workPkg-Adds-a-SecurityFix.yaml-file.patch | 170 ++ ...tworkPkg-Apply-uncrustify-changes-p2.patch | 2054 +++++++++++++++++ ...-NetworkPkg-Apply-uncrustify-changes.patch | 1937 ++++++++++++++++ ...Dxe-Packet-Length-is-not-updated-bef.patch | 69 + ...Dxe-Removes-duplicate-check-and-repl.patch | 161 ++ ...Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch | 257 +++ ...e-SECURITY-PATCH-CVE-2023-45231-Patc.patch | 78 + ...e-SECURITY-PATCH-CVE-2023-45231-Unit.patch | 277 +++ ...e-SECURITY-PATCH-CVE-2023-45232-Patc.patch | 377 +++ ...e-SECURITY-PATCH-CVE-2023-45232-Unit.patch | 430 ++++ ...xeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch | 168 ++ ...BcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch | 511 ++++ ...BcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch | 257 +++ ...BcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch | 409 ++++ edk2.spec | 138 +- 16 files changed, 9027 insertions(+), 1 deletion(-) create mode 100644 edk2-Apply-uncrustify-changes-to-.c-.h-files-in-the-Netwo.patch create mode 100644 edk2-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch create mode 100644 edk2-NetworkPkg-Apply-uncrustify-changes-p2.patch create mode 100644 edk2-NetworkPkg-Apply-uncrustify-changes.patch create mode 100644 edk2-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch create mode 100644 edk2-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch create mode 100644 edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch create mode 100644 edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch create mode 100644 edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch create mode 100644 edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch create mode 100644 edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch create mode 100644 edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch create mode 100644 edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch create mode 100644 edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch create mode 100644 edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch diff --git a/edk2-Apply-uncrustify-changes-to-.c-.h-files-in-the-Netwo.patch b/edk2-Apply-uncrustify-changes-to-.c-.h-files-in-the-Netwo.patch new file mode 100644 index 0000000..0ef1750 --- /dev/null +++ b/edk2-Apply-uncrustify-changes-to-.c-.h-files-in-the-Netwo.patch @@ -0,0 +1,1735 @@ +From 0f2a885790fe3f397dee527a19ef7753a1961688 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 15 Feb 2024 11:38:46 -0500 +Subject: [PATCH 01/15] Apply uncrustify changes to .c/.h files in the + NetworkPkg package + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [1/15] 7a6f3c908d076e6497e0c8978785b679a23b83cf + +JIRA: https://issues.redhat.com/browse/RHEL-21844 +CVE: CVE-2022-45231 +Upstream: Merged +Conflicts: This commit is too intrusive to apply completely. We still save + us a lot of problems (git cherry-pick basically bails out) in + the following commits in this series if we apply it on the files + modified by those commits. + +commit d1050b9dff1cace252aff86630bfdb59dff5f507 +Author: Michael Kubacki +Date: Sun Dec 5 14:54:07 2021 -0800 + + NetworkPkg: Apply uncrustify changes + + REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 + + Apply uncrustify changes to .c/.h files in the NetworkPkg package + + Cc: Andrew Fish + Cc: Leif Lindholm + Cc: Michael D Kinney + Signed-off-by: Michael Kubacki + Reviewed-by: Maciej Rabeda + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Ip6Dxe/Ip6Nd.h | 312 ++++++------- + NetworkPkg/Ip6Dxe/Ip6Option.c | 805 +++++++++++++++++----------------- + NetworkPkg/Ip6Dxe/Ip6Option.h | 88 ++-- + 3 files changed, 605 insertions(+), 600 deletions(-) + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h +index 5f1bd6fb92..860934a167 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Nd.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h +@@ -13,82 +13,82 @@ + #define IP6_GET_TICKS(Ms) (((Ms) + IP6_TIMER_INTERVAL_IN_MS - 1) / IP6_TIMER_INTERVAL_IN_MS) + + enum { +- IP6_INF_ROUTER_LIFETIME = 0xFFFF, ++ IP6_INF_ROUTER_LIFETIME = 0xFFFF, + + IP6_MAX_RTR_SOLICITATION_DELAY = 1000, ///< 1000 milliseconds + IP6_MAX_RTR_SOLICITATIONS = 3, + IP6_RTR_SOLICITATION_INTERVAL = 4000, + +- IP6_MIN_RANDOM_FACTOR_SCALED = 1, +- IP6_MAX_RANDOM_FACTOR_SCALED = 3, +- IP6_RANDOM_FACTOR_SCALE = 2, ++ IP6_MIN_RANDOM_FACTOR_SCALED = 1, ++ IP6_MAX_RANDOM_FACTOR_SCALED = 3, ++ IP6_RANDOM_FACTOR_SCALE = 2, + +- IP6_MAX_MULTICAST_SOLICIT = 3, +- IP6_MAX_UNICAST_SOLICIT = 3, +- IP6_MAX_ANYCAST_DELAY_TIME = 1, +- IP6_MAX_NEIGHBOR_ADV = 3, +- IP6_REACHABLE_TIME = 30000, +- IP6_RETRANS_TIMER = 1000, +- IP6_DELAY_FIRST_PROBE_TIME = 5000, ++ IP6_MAX_MULTICAST_SOLICIT = 3, ++ IP6_MAX_UNICAST_SOLICIT = 3, ++ IP6_MAX_ANYCAST_DELAY_TIME = 1, ++ IP6_MAX_NEIGHBOR_ADV = 3, ++ IP6_REACHABLE_TIME = 30000, ++ IP6_RETRANS_TIMER = 1000, ++ IP6_DELAY_FIRST_PROBE_TIME = 5000, + +- IP6_MIN_LINK_MTU = 1280, +- IP6_MAX_LINK_MTU = 1500, ++ IP6_MIN_LINK_MTU = 1280, ++ IP6_MAX_LINK_MTU = 1500, + +- IP6_IS_ROUTER_FLAG = 0x80, +- IP6_SOLICITED_FLAG = 0x40, +- IP6_OVERRIDE_FLAG = 0x20, ++ IP6_IS_ROUTER_FLAG = 0x80, ++ IP6_SOLICITED_FLAG = 0x40, ++ IP6_OVERRIDE_FLAG = 0x20, + +- IP6_M_ADDR_CONFIG_FLAG = 0x80, +- IP6_O_CONFIG_FLAG = 0x40, ++ IP6_M_ADDR_CONFIG_FLAG = 0x80, ++ IP6_O_CONFIG_FLAG = 0x40, + +- IP6_ON_LINK_FLAG = 0x80, +- IP6_AUTO_CONFIG_FLAG = 0x40, ++ IP6_ON_LINK_FLAG = 0x80, ++ IP6_AUTO_CONFIG_FLAG = 0x40, + +- IP6_ND_LENGTH = 24, +- IP6_RA_LENGTH = 16, +- IP6_REDITECT_LENGTH = 40, +- IP6_DAD_ENTRY_SIGNATURE = SIGNATURE_32 ('I', 'P', 'D', 'E') ++ IP6_ND_LENGTH = 24, ++ IP6_RA_LENGTH = 16, ++ IP6_REDITECT_LENGTH = 40, ++ IP6_DAD_ENTRY_SIGNATURE = SIGNATURE_32 ('I', 'P', 'D', 'E') + }; + + typedef + VOID + (*IP6_ARP_CALLBACK) ( +- VOID *Context ++ VOID *Context + ); + + typedef struct _IP6_OPTION_HEADER { +- UINT8 Type; +- UINT8 Length; ++ UINT8 Type; ++ UINT8 Length; + } IP6_OPTION_HEADER; + + STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) == 2, "IP6_OPTION_HEADER is expected to be exactly 2 bytes long."); + + typedef struct _IP6_ETHE_ADDR_OPTION { +- UINT8 Type; +- UINT8 Length; +- UINT8 EtherAddr[6]; ++ UINT8 Type; ++ UINT8 Length; ++ UINT8 EtherAddr[6]; + } IP6_ETHER_ADDR_OPTION; + + STATIC_ASSERT (sizeof (IP6_ETHER_ADDR_OPTION) == 8, "IP6_ETHER_ADDR_OPTION is expected to be exactly 8 bytes long."); + + typedef struct _IP6_MTU_OPTION { +- UINT8 Type; +- UINT8 Length; +- UINT16 Reserved; +- UINT32 Mtu; ++ UINT8 Type; ++ UINT8 Length; ++ UINT16 Reserved; ++ UINT32 Mtu; + } IP6_MTU_OPTION; + + STATIC_ASSERT (sizeof (IP6_MTU_OPTION) == 8, "IP6_MTU_OPTION is expected to be exactly 8 bytes long."); + + typedef struct _IP6_PREFIX_INFO_OPTION { +- UINT8 Type; +- UINT8 Length; +- UINT8 PrefixLength; +- UINT8 Reserved1; +- UINT32 ValidLifetime; +- UINT32 PreferredLifetime; +- UINT32 Reserved2; +- EFI_IPv6_ADDRESS Prefix; ++ UINT8 Type; ++ UINT8 Length; ++ UINT8 PrefixLength; ++ UINT8 Reserved1; ++ UINT32 ValidLifetime; ++ UINT32 PreferredLifetime; ++ UINT32 Reserved2; ++ EFI_IPv6_ADDRESS Prefix; + } IP6_PREFIX_INFO_OPTION; + + STATIC_ASSERT (sizeof (IP6_PREFIX_INFO_OPTION) == 32, "IP6_PREFIX_INFO_OPTION is expected to be exactly 32 bytes long."); +@@ -102,25 +102,25 @@ VOID + ); + + typedef struct _IP6_DAD_ENTRY { +- UINT32 Signature; +- LIST_ENTRY Link; +- UINT32 MaxTransmit; +- UINT32 Transmit; +- UINT32 Receive; +- UINT32 RetransTick; +- IP6_ADDRESS_INFO *AddressInfo; +- EFI_IPv6_ADDRESS Destination; +- IP6_DAD_CALLBACK Callback; +- VOID *Context; ++ UINT32 Signature; ++ LIST_ENTRY Link; ++ UINT32 MaxTransmit; ++ UINT32 Transmit; ++ UINT32 Receive; ++ UINT32 RetransTick; ++ IP6_ADDRESS_INFO *AddressInfo; ++ EFI_IPv6_ADDRESS Destination; ++ IP6_DAD_CALLBACK Callback; ++ VOID *Context; + } IP6_DAD_ENTRY; + + typedef struct _IP6_DELAY_JOIN_LIST { +- LIST_ENTRY Link; +- UINT32 DelayTime; ///< in tick per 50 milliseconds +- IP6_INTERFACE *Interface; +- IP6_ADDRESS_INFO *AddressInfo; +- IP6_DAD_CALLBACK DadCallback; +- VOID *Context; ++ LIST_ENTRY Link; ++ UINT32 DelayTime; ///< in tick per 50 milliseconds ++ IP6_INTERFACE *Interface; ++ IP6_ADDRESS_INFO *AddressInfo; ++ IP6_DAD_CALLBACK DadCallback; ++ VOID *Context; + } IP6_DELAY_JOIN_LIST; + + typedef struct _IP6_NEIGHBOR_ENTRY { +@@ -142,20 +142,20 @@ typedef struct _IP6_NEIGHBOR_ENTRY { + } IP6_NEIGHBOR_ENTRY; + + typedef struct _IP6_DEFAULT_ROUTER { +- LIST_ENTRY Link; +- INTN RefCnt; +- UINT16 Lifetime; +- EFI_IPv6_ADDRESS Router; +- IP6_NEIGHBOR_ENTRY *NeighborCache; ++ LIST_ENTRY Link; ++ INTN RefCnt; ++ UINT16 Lifetime; ++ EFI_IPv6_ADDRESS Router; ++ IP6_NEIGHBOR_ENTRY *NeighborCache; + } IP6_DEFAULT_ROUTER; + + typedef struct _IP6_PREFIX_LIST_ENTRY { +- LIST_ENTRY Link; +- INTN RefCnt; +- UINT32 ValidLifetime; +- UINT32 PreferredLifetime; +- UINT8 PrefixLength; +- EFI_IPv6_ADDRESS Prefix; ++ LIST_ENTRY Link; ++ INTN RefCnt; ++ UINT32 ValidLifetime; ++ UINT32 PreferredLifetime; ++ UINT8 PrefixLength; ++ EFI_IPv6_ADDRESS Prefix; + } IP6_PREFIX_LIST_ENTRY; + + /** +@@ -172,9 +172,9 @@ typedef struct _IP6_PREFIX_LIST_ENTRY { + **/ + EFI_STATUS + Ip6BuildEfiNeighborCache ( +- IN IP6_PROTOCOL *IpInstance, +- OUT UINT32 *NeighborCount, +- OUT EFI_IP6_NEIGHBOR_CACHE **NeighborCache ++ IN IP6_PROTOCOL *IpInstance, ++ OUT UINT32 *NeighborCount, ++ OUT EFI_IP6_NEIGHBOR_CACHE **NeighborCache + ); + + /** +@@ -210,9 +210,9 @@ Ip6BuildPrefixTable ( + **/ + IP6_DEFAULT_ROUTER * + Ip6CreateDefaultRouter ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IPv6_ADDRESS *Ip6Address, +- IN UINT16 RouterLifetime ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IPv6_ADDRESS *Ip6Address, ++ IN UINT16 RouterLifetime + ); + + /** +@@ -224,8 +224,8 @@ Ip6CreateDefaultRouter ( + **/ + VOID + Ip6DestroyDefaultRouter ( +- IN IP6_SERVICE *IpSb, +- IN IP6_DEFAULT_ROUTER *DefaultRouter ++ IN IP6_SERVICE *IpSb, ++ IN IP6_DEFAULT_ROUTER *DefaultRouter + ); + + /** +@@ -236,7 +236,7 @@ Ip6DestroyDefaultRouter ( + **/ + VOID + Ip6CleanDefaultRouterList ( +- IN IP6_SERVICE *IpSb ++ IN IP6_SERVICE *IpSb + ); + + /** +@@ -251,8 +251,8 @@ Ip6CleanDefaultRouterList ( + **/ + IP6_DEFAULT_ROUTER * + Ip6FindDefaultRouter ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IPv6_ADDRESS *Ip6Address ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IPv6_ADDRESS *Ip6Address + ); + + /** +@@ -289,10 +289,10 @@ Ip6OnDADFinished ( + **/ + EFI_STATUS + Ip6InitDADProcess ( +- IN IP6_INTERFACE *IpIf, +- IN IP6_ADDRESS_INFO *AddressInfo, +- IN IP6_DAD_CALLBACK Callback OPTIONAL, +- IN VOID *Context OPTIONAL ++ IN IP6_INTERFACE *IpIf, ++ IN IP6_ADDRESS_INFO *AddressInfo, ++ IN IP6_DAD_CALLBACK Callback OPTIONAL, ++ IN VOID *Context OPTIONAL + ); + + /** +@@ -309,9 +309,9 @@ Ip6InitDADProcess ( + **/ + IP6_DAD_ENTRY * + Ip6FindDADEntry ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IPv6_ADDRESS *Target, +- OUT IP6_INTERFACE **Interface OPTIONAL ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IPv6_ADDRESS *Target, ++ OUT IP6_INTERFACE **Interface OPTIONAL + ); + + /** +@@ -334,12 +334,12 @@ Ip6FindDADEntry ( + **/ + IP6_PREFIX_LIST_ENTRY * + Ip6CreatePrefixListEntry ( +- IN IP6_SERVICE *IpSb, +- IN BOOLEAN OnLinkOrAuto, +- IN UINT32 ValidLifetime, +- IN UINT32 PreferredLifetime, +- IN UINT8 PrefixLength, +- IN EFI_IPv6_ADDRESS *Prefix ++ IN IP6_SERVICE *IpSb, ++ IN BOOLEAN OnLinkOrAuto, ++ IN UINT32 ValidLifetime, ++ IN UINT32 PreferredLifetime, ++ IN UINT8 PrefixLength, ++ IN EFI_IPv6_ADDRESS *Prefix + ); + + /** +@@ -377,10 +377,10 @@ Ip6DestroyPrefixListEntry ( + **/ + IP6_PREFIX_LIST_ENTRY * + Ip6FindPrefixListEntry ( +- IN IP6_SERVICE *IpSb, +- IN BOOLEAN OnLinkOrAuto, +- IN UINT8 PrefixLength, +- IN EFI_IPv6_ADDRESS *Prefix ++ IN IP6_SERVICE *IpSb, ++ IN BOOLEAN OnLinkOrAuto, ++ IN UINT8 PrefixLength, ++ IN EFI_IPv6_ADDRESS *Prefix + ); + + /** +@@ -393,8 +393,8 @@ Ip6FindPrefixListEntry ( + **/ + VOID + Ip6CleanPrefixListTable ( +- IN IP6_SERVICE *IpSb, +- IN LIST_ENTRY *ListHead ++ IN IP6_SERVICE *IpSb, ++ IN LIST_ENTRY *ListHead + ); + + /** +@@ -413,10 +413,10 @@ Ip6CleanPrefixListTable ( + **/ + IP6_NEIGHBOR_ENTRY * + Ip6CreateNeighborEntry ( +- IN IP6_SERVICE *IpSb, +- IN IP6_ARP_CALLBACK CallBack, +- IN EFI_IPv6_ADDRESS *Ip6Address, +- IN EFI_MAC_ADDRESS *LinkAddress OPTIONAL ++ IN IP6_SERVICE *IpSb, ++ IN IP6_ARP_CALLBACK CallBack, ++ IN EFI_IPv6_ADDRESS *Ip6Address, ++ IN EFI_MAC_ADDRESS *LinkAddress OPTIONAL + ); + + /** +@@ -431,8 +431,8 @@ Ip6CreateNeighborEntry ( + **/ + IP6_NEIGHBOR_ENTRY * + Ip6FindNeighborEntry ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IPv6_ADDRESS *Ip6Address ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IPv6_ADDRESS *Ip6Address + ); + + /** +@@ -458,13 +458,13 @@ Ip6FindNeighborEntry ( + **/ + EFI_STATUS + Ip6FreeNeighborEntry ( +- IN IP6_SERVICE *IpSb, +- IN IP6_NEIGHBOR_ENTRY *NeighborCache, +- IN BOOLEAN SendIcmpError, +- IN BOOLEAN FullFree, +- IN EFI_STATUS IoStatus, +- IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, +- IN VOID *Context OPTIONAL ++ IN IP6_SERVICE *IpSb, ++ IN IP6_NEIGHBOR_ENTRY *NeighborCache, ++ IN BOOLEAN SendIcmpError, ++ IN BOOLEAN FullFree, ++ IN EFI_STATUS IoStatus, ++ IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, ++ IN VOID *Context OPTIONAL + ); + + /** +@@ -493,11 +493,11 @@ Ip6FreeNeighborEntry ( + **/ + EFI_STATUS + Ip6AddNeighbor ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IPv6_ADDRESS *TargetIp6Address, +- IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, +- IN UINT32 Timeout, +- IN BOOLEAN Override ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IPv6_ADDRESS *TargetIp6Address, ++ IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, ++ IN UINT32 Timeout, ++ IN BOOLEAN Override + ); + + /** +@@ -521,11 +521,11 @@ Ip6AddNeighbor ( + **/ + EFI_STATUS + Ip6DelNeighbor ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IPv6_ADDRESS *TargetIp6Address, +- IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, +- IN UINT32 Timeout, +- IN BOOLEAN Override ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IPv6_ADDRESS *TargetIp6Address, ++ IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, ++ IN UINT32 Timeout, ++ IN BOOLEAN Override + ); + + /** +@@ -544,9 +544,9 @@ Ip6DelNeighbor ( + **/ + EFI_STATUS + Ip6ProcessNeighborSolicit ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IP6_HEADER *Head, +- IN NET_BUF *Packet ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IP6_HEADER *Head, ++ IN NET_BUF *Packet + ); + + /** +@@ -564,9 +564,9 @@ Ip6ProcessNeighborSolicit ( + **/ + EFI_STATUS + Ip6ProcessNeighborAdvertise ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IP6_HEADER *Head, +- IN NET_BUF *Packet ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IP6_HEADER *Head, ++ IN NET_BUF *Packet + ); + + /** +@@ -584,9 +584,9 @@ Ip6ProcessNeighborAdvertise ( + **/ + EFI_STATUS + Ip6ProcessRouterAdvertise ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IP6_HEADER *Head, +- IN NET_BUF *Packet ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IP6_HEADER *Head, ++ IN NET_BUF *Packet + ); + + /** +@@ -607,9 +607,9 @@ Ip6ProcessRouterAdvertise ( + **/ + EFI_STATUS + Ip6ProcessRedirect ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IP6_HEADER *Head, +- IN NET_BUF *Packet ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IP6_HEADER *Head, ++ IN NET_BUF *Packet + ); + + /** +@@ -631,11 +631,11 @@ Ip6ProcessRedirect ( + **/ + EFI_STATUS + Ip6SendRouterSolicit ( +- IN IP6_SERVICE *IpSb, +- IN IP6_INTERFACE *Interface OPTIONAL, +- IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, +- IN EFI_IPv6_ADDRESS *DestinationAddress OPTIONAL, +- IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL ++ IN IP6_SERVICE *IpSb, ++ IN IP6_INTERFACE *Interface OPTIONAL, ++ IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, ++ IN EFI_IPv6_ADDRESS *DestinationAddress OPTIONAL, ++ IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL + ); + + /** +@@ -658,11 +658,11 @@ Ip6SendRouterSolicit ( + **/ + EFI_STATUS + Ip6SendNeighborSolicit ( +- IN IP6_SERVICE *IpSb, +- IN EFI_IPv6_ADDRESS *SourceAddress, +- IN EFI_IPv6_ADDRESS *DestinationAddress, +- IN EFI_IPv6_ADDRESS *TargetIp6Address, +- IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL ++ IN IP6_SERVICE *IpSb, ++ IN EFI_IPv6_ADDRESS *SourceAddress, ++ IN EFI_IPv6_ADDRESS *DestinationAddress, ++ IN EFI_IPv6_ADDRESS *TargetIp6Address, ++ IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL + ); + + /** +@@ -690,14 +690,14 @@ Ip6SendNeighborSolicit ( + **/ + EFI_STATUS + Ip6SetAddress ( +- IN IP6_INTERFACE *Interface, +- IN EFI_IPv6_ADDRESS *Ip6Addr, +- IN BOOLEAN IsAnycast, +- IN UINT8 PrefixLength, +- IN UINT32 ValidLifetime, +- IN UINT32 PreferredLifetime, +- IN IP6_DAD_CALLBACK DadCallback OPTIONAL, +- IN VOID *Context OPTIONAL ++ IN IP6_INTERFACE *Interface, ++ IN EFI_IPv6_ADDRESS *Ip6Addr, ++ IN BOOLEAN IsAnycast, ++ IN UINT8 PrefixLength, ++ IN UINT32 ValidLifetime, ++ IN UINT32 PreferredLifetime, ++ IN IP6_DAD_CALLBACK DadCallback OPTIONAL, ++ IN VOID *Context OPTIONAL + ); + + /** +@@ -712,8 +712,8 @@ Ip6SetAddress ( + VOID + EFIAPI + Ip6NdFasterTimerTicking ( +- IN EFI_EVENT Event, +- IN VOID *Context ++ IN EFI_EVENT Event, ++ IN VOID *Context + ); + + /** +@@ -726,7 +726,7 @@ Ip6NdFasterTimerTicking ( + **/ + VOID + Ip6NdTimerTicking ( +- IN IP6_SERVICE *IpSb ++ IN IP6_SERVICE *IpSb + ); + + /** +@@ -739,7 +739,7 @@ Ip6NdTimerTicking ( + **/ + VOID + Ip6OnArpResolved ( +- IN VOID *Context ++ IN VOID *Context + ); + + /** +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c +index 6b4b029d14..199eea124d 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.c ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.c +@@ -28,15 +28,15 @@ + **/ + BOOLEAN + Ip6IsOptionValid ( +- IN IP6_SERVICE *IpSb, +- IN NET_BUF *Packet, +- IN UINT8 *Option, +- IN UINT8 OptionLen, +- IN UINT32 Pointer ++ IN IP6_SERVICE *IpSb, ++ IN NET_BUF *Packet, ++ IN UINT8 *Option, ++ IN UINT8 OptionLen, ++ IN UINT32 Pointer + ) + { +- UINT8 Offset; +- UINT8 OptionType; ++ UINT8 Offset; ++ UINT8 OptionType; + + Offset = 0; + +@@ -44,68 +44,67 @@ Ip6IsOptionValid ( + OptionType = *(Option + Offset); + + switch (OptionType) { +- case Ip6OptionPad1: +- // +- // It is a Pad1 option +- // +- Offset++; +- break; +- case Ip6OptionPadN: +- // +- // It is a PadN option +- // +- Offset = (UINT8) (Offset + *(Option + Offset + 1) + 2); +- break; +- case Ip6OptionRouterAlert: +- // +- // It is a Router Alert Option +- // +- Offset += 4; +- break; +- default: +- // +- // The highest-order two bits specify the action must be taken if +- // the processing IPv6 node does not recognize the option type. +- // +- switch (OptionType & Ip6OptionMask) { +- case Ip6OptionSkip: +- Offset = (UINT8) (Offset + *(Option + Offset + 1)); ++ case Ip6OptionPad1: ++ // ++ // It is a Pad1 option ++ // ++ Offset++; + break; +- case Ip6OptionDiscard: +- return FALSE; +- case Ip6OptionParameterProblem: +- Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER); +- Ip6SendIcmpError ( +- IpSb, +- Packet, +- NULL, +- &Packet->Ip.Ip6->SourceAddress, +- ICMP_V6_PARAMETER_PROBLEM, +- 2, +- &Pointer +- ); +- return FALSE; +- case Ip6OptionMask: +- if (!IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { +- Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER); +- Ip6SendIcmpError ( +- IpSb, +- Packet, +- NULL, +- &Packet->Ip.Ip6->SourceAddress, +- ICMP_V6_PARAMETER_PROBLEM, +- 2, +- &Pointer +- ); ++ case Ip6OptionPadN: ++ // ++ // It is a PadN option ++ // ++ Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); ++ break; ++ case Ip6OptionRouterAlert: ++ // ++ // It is a Router Alert Option ++ // ++ Offset += 4; ++ break; ++ default: ++ // ++ // The highest-order two bits specify the action must be taken if ++ // the processing IPv6 node does not recognize the option type. ++ // ++ switch (OptionType & Ip6OptionMask) { ++ case Ip6OptionSkip: ++ Offset = (UINT8)(Offset + *(Option + Offset + 1)); ++ break; ++ case Ip6OptionDiscard: ++ return FALSE; ++ case Ip6OptionParameterProblem: ++ Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER); ++ Ip6SendIcmpError ( ++ IpSb, ++ Packet, ++ NULL, ++ &Packet->Ip.Ip6->SourceAddress, ++ ICMP_V6_PARAMETER_PROBLEM, ++ 2, ++ &Pointer ++ ); ++ return FALSE; ++ case Ip6OptionMask: ++ if (!IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { ++ Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER); ++ Ip6SendIcmpError ( ++ IpSb, ++ Packet, ++ NULL, ++ &Packet->Ip.Ip6->SourceAddress, ++ ICMP_V6_PARAMETER_PROBLEM, ++ 2, ++ &Pointer ++ ); ++ } ++ ++ return FALSE; ++ break; + } + +- return FALSE; + break; +- } +- +- break; + } +- + } + + return TRUE; +@@ -125,13 +124,13 @@ Ip6IsOptionValid ( + **/ + BOOLEAN + Ip6IsNDOptionValid ( +- IN UINT8 *Option, +- IN UINT16 OptionLen ++ IN UINT8 *Option, ++ IN UINT16 OptionLen + ) + { +- UINT32 Offset; +- UINT16 Length; +- IP6_OPTION_HEADER *OptionHeader; ++ UINT32 Offset; ++ UINT16 Length; ++ IP6_OPTION_HEADER *OptionHeader; + + if (Option == NULL) { + ASSERT (Option != NULL); +@@ -146,50 +145,54 @@ Ip6IsNDOptionValid ( + // fit within the input buffer. + // + while (Offset + sizeof (IP6_OPTION_HEADER) - 1 < OptionLen) { +- OptionHeader = (IP6_OPTION_HEADER*) (Option + Offset); +- Length = (UINT16) OptionHeader->Length * 8; ++ OptionHeader = (IP6_OPTION_HEADER *)(Option + Offset); ++ Length = (UINT16)OptionHeader->Length * 8; + + switch (OptionHeader->Type) { +- case Ip6OptionPrefixInfo: +- if (Length != 32) { +- return FALSE; +- } +- break; ++ case Ip6OptionPrefixInfo: ++ if (Length != 32) { ++ return FALSE; ++ } + +- case Ip6OptionMtu: +- if (Length != 8) { +- return FALSE; +- } +- break; ++ break; + +- default: +- // RFC 4861 states that Length field cannot be 0. +- if (Length == 0) { +- return FALSE; +- } +- break; ++ case Ip6OptionMtu: ++ if (Length != 8) { ++ return FALSE; ++ } ++ ++ break; ++ ++ default: ++ // RFC 4861 states that Length field cannot be 0. ++ if (Length == 0) { ++ return FALSE; ++ } ++ ++ break; + } + + // + // Check whether recognized options are within the input buffer's scope. + // + switch (OptionHeader->Type) { +- case Ip6OptionEtherSource: +- case Ip6OptionEtherTarget: +- case Ip6OptionPrefixInfo: +- case Ip6OptionRedirected: +- case Ip6OptionMtu: +- if (Offset + Length > (UINT32) OptionLen) { +- return FALSE; +- } +- break; ++ case Ip6OptionEtherSource: ++ case Ip6OptionEtherTarget: ++ case Ip6OptionPrefixInfo: ++ case Ip6OptionRedirected: ++ case Ip6OptionMtu: ++ if (Offset + Length > (UINT32)OptionLen) { ++ return FALSE; ++ } + +- default: +- // +- // Unrecognized options can be either valid (but unused) or invalid +- // (garbage in between or right after valid options). Silently ignore. +- // +- break; ++ break; ++ ++ default: ++ // ++ // Unrecognized options can be either valid (but unused) or invalid ++ // (garbage in between or right after valid options). Silently ignore. ++ // ++ break; + } + + // +@@ -202,7 +205,6 @@ Ip6IsNDOptionValid ( + return TRUE; + } + +- + /** + Validate whether the NextHeader is a known valid protocol or one of the user configured + protocols from the upper layer. +@@ -216,18 +218,19 @@ Ip6IsNDOptionValid ( + **/ + BOOLEAN + Ip6IsValidProtocol ( +- IN IP6_SERVICE *IpSb, +- IN UINT8 NextHeader ++ IN IP6_SERVICE *IpSb, ++ IN UINT8 NextHeader + ) + { +- LIST_ENTRY *Entry; +- IP6_PROTOCOL *IpInstance; +- +- if (NextHeader == EFI_IP_PROTO_TCP || +- NextHeader == EFI_IP_PROTO_UDP || +- NextHeader == IP6_ICMP || +- NextHeader == IP6_ESP +- ) { ++ LIST_ENTRY *Entry; ++ IP6_PROTOCOL *IpInstance; ++ ++ if ((NextHeader == EFI_IP_PROTO_TCP) || ++ (NextHeader == EFI_IP_PROTO_UDP) || ++ (NextHeader == IP6_ICMP) || ++ (NextHeader == IP6_ESP) ++ ) ++ { + return TRUE; + } + +@@ -281,29 +284,29 @@ Ip6IsValidProtocol ( + **/ + BOOLEAN + Ip6IsExtsValid ( +- IN IP6_SERVICE *IpSb OPTIONAL, +- IN NET_BUF *Packet OPTIONAL, +- IN UINT8 *NextHeader, +- IN UINT8 *ExtHdrs, +- IN UINT32 ExtHdrsLen, +- IN BOOLEAN Rcvd, +- OUT UINT32 *FormerHeader OPTIONAL, +- OUT UINT8 **LastHeader, +- OUT UINT32 *RealExtsLen OPTIONAL, +- OUT UINT32 *UnFragmentLen OPTIONAL, +- OUT BOOLEAN *Fragmented OPTIONAL ++ IN IP6_SERVICE *IpSb OPTIONAL, ++ IN NET_BUF *Packet OPTIONAL, ++ IN UINT8 *NextHeader, ++ IN UINT8 *ExtHdrs, ++ IN UINT32 ExtHdrsLen, ++ IN BOOLEAN Rcvd, ++ OUT UINT32 *FormerHeader OPTIONAL, ++ OUT UINT8 **LastHeader, ++ OUT UINT32 *RealExtsLen OPTIONAL, ++ OUT UINT32 *UnFragmentLen OPTIONAL, ++ OUT BOOLEAN *Fragmented OPTIONAL + ) + { +- UINT32 Pointer; +- UINT32 Offset; +- UINT8 *Option; +- UINT8 OptionLen; +- BOOLEAN Flag; +- UINT8 CountD; +- UINT8 CountA; +- IP6_FRAGMENT_HEADER *FragmentHead; +- UINT16 FragmentOffset; +- IP6_ROUTING_HEADER *RoutingHead; ++ UINT32 Pointer; ++ UINT32 Offset; ++ UINT8 *Option; ++ UINT8 OptionLen; ++ BOOLEAN Flag; ++ UINT8 CountD; ++ UINT8 CountA; ++ IP6_FRAGMENT_HEADER *FragmentHead; ++ UINT16 FragmentOffset; ++ IP6_ROUTING_HEADER *RoutingHead; + + if (RealExtsLen != NULL) { + *RealExtsLen = 0; +@@ -319,11 +322,11 @@ Ip6IsExtsValid ( + + *LastHeader = NextHeader; + +- if (ExtHdrs == NULL && ExtHdrsLen == 0) { ++ if ((ExtHdrs == NULL) && (ExtHdrsLen == 0)) { + return TRUE; + } + +- if ((ExtHdrs == NULL && ExtHdrsLen != 0) || (ExtHdrs != NULL && ExtHdrsLen == 0)) { ++ if (((ExtHdrs == NULL) && (ExtHdrsLen != 0)) || ((ExtHdrs != NULL) && (ExtHdrsLen == 0))) { + return FALSE; + } + +@@ -334,236 +337,240 @@ Ip6IsExtsValid ( + CountA = 0; + + while (Offset <= ExtHdrsLen) { +- + switch (*NextHeader) { +- case IP6_HOP_BY_HOP: +- if (Offset != 0) { +- if (!Rcvd) { ++ case IP6_HOP_BY_HOP: ++ if (Offset != 0) { ++ if (!Rcvd) { ++ return FALSE; ++ } ++ ++ // ++ // Hop-by-Hop Options header is restricted to appear immediately after an IPv6 header only. ++ // If not, generate a ICMP parameter problem message with code value of 1. ++ // ++ if (Pointer == 0) { ++ Pointer = sizeof (EFI_IP6_HEADER); ++ } else { ++ Pointer = Offset + sizeof (EFI_IP6_HEADER); ++ } ++ ++ if ((IpSb != NULL) && (Packet != NULL) && ++ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) ++ { ++ Ip6SendIcmpError ( ++ IpSb, ++ Packet, ++ NULL, ++ &Packet->Ip.Ip6->SourceAddress, ++ ICMP_V6_PARAMETER_PROBLEM, ++ 1, ++ &Pointer ++ ); ++ } ++ + return FALSE; + } +- // +- // Hop-by-Hop Options header is restricted to appear immediately after an IPv6 header only. +- // If not, generate a ICMP parameter problem message with code value of 1. +- // +- if (Pointer == 0) { +- Pointer = sizeof (EFI_IP6_HEADER); +- } else { +- Pointer = Offset + sizeof (EFI_IP6_HEADER); ++ ++ Flag = TRUE; ++ ++ // ++ // Fall through ++ // ++ case IP6_DESTINATION: ++ if (*NextHeader == IP6_DESTINATION) { ++ CountD++; + } + +- if ((IpSb != NULL) && (Packet != NULL) && +- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { +- Ip6SendIcmpError ( +- IpSb, +- Packet, +- NULL, +- &Packet->Ip.Ip6->SourceAddress, +- ICMP_V6_PARAMETER_PROBLEM, +- 1, +- &Pointer +- ); ++ if (CountD > 2) { ++ return FALSE; + } +- return FALSE; +- } + +- Flag = TRUE; ++ NextHeader = ExtHdrs + Offset; ++ Pointer = Offset; + +- // +- // Fall through +- // +- case IP6_DESTINATION: +- if (*NextHeader == IP6_DESTINATION) { +- CountD++; +- } ++ Offset++; ++ Option = ExtHdrs + Offset; ++ OptionLen = (UINT8)((*Option + 1) * 8 - 2); ++ Option++; ++ Offset++; + +- if (CountD > 2) { +- return FALSE; +- } ++ if ((IpSb != NULL) && (Packet != NULL) && !Ip6IsOptionValid (IpSb, Packet, Option, OptionLen, Offset)) { ++ return FALSE; ++ } + +- NextHeader = ExtHdrs + Offset; +- Pointer = Offset; ++ Offset = Offset + OptionLen; + +- Offset++; +- Option = ExtHdrs + Offset; +- OptionLen = (UINT8) ((*Option + 1) * 8 - 2); +- Option++; +- Offset++; ++ if (Flag) { ++ if (UnFragmentLen != NULL) { ++ *UnFragmentLen = Offset; ++ } + +- if (IpSb != NULL && Packet != NULL && !Ip6IsOptionValid (IpSb, Packet, Option, OptionLen, Offset)) { +- return FALSE; +- } ++ Flag = FALSE; ++ } ++ ++ break; + +- Offset = Offset + OptionLen; ++ case IP6_ROUTING: ++ NextHeader = ExtHdrs + Offset; ++ RoutingHead = (IP6_ROUTING_HEADER *)NextHeader; + +- if (Flag) { +- if (UnFragmentLen != NULL) { +- *UnFragmentLen = Offset; ++ // ++ // Type 0 routing header is defined in RFC2460 and deprecated in RFC5095. ++ // Thus all routing types are processed as unrecognized. ++ // ++ if (RoutingHead->SegmentsLeft == 0) { ++ // ++ // Ignore the routing header and proceed to process the next header. ++ // ++ Offset = Offset + (RoutingHead->HeaderLen + 1) * 8; ++ ++ if (UnFragmentLen != NULL) { ++ *UnFragmentLen = Offset; ++ } ++ } else { ++ // ++ // Discard the packet and send an ICMP Parameter Problem, Code 0, message ++ // to the packet's source address, pointing to the unrecognized routing ++ // type. ++ // ++ Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER); ++ if ((IpSb != NULL) && (Packet != NULL) && ++ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) ++ { ++ Ip6SendIcmpError ( ++ IpSb, ++ Packet, ++ NULL, ++ &Packet->Ip.Ip6->SourceAddress, ++ ICMP_V6_PARAMETER_PROBLEM, ++ 0, ++ &Pointer ++ ); ++ } ++ ++ return FALSE; + } + +- Flag = FALSE; +- } ++ break; + +- break; ++ case IP6_FRAGMENT: + +- case IP6_ROUTING: +- NextHeader = ExtHdrs + Offset; +- RoutingHead = (IP6_ROUTING_HEADER *) NextHeader; ++ // ++ // RFC2402, AH header should after fragment header. ++ // ++ if (CountA > 1) { ++ return FALSE; ++ } + +- // +- // Type 0 routing header is defined in RFC2460 and deprecated in RFC5095. +- // Thus all routing types are processed as unrecognized. +- // +- if (RoutingHead->SegmentsLeft == 0) { + // +- // Ignore the routing header and proceed to process the next header. ++ // RFC2460, ICMP Parameter Problem message with code 0 should be sent ++ // if the length of a fragment is not a multiple of 8 octets and the M ++ // flag of that fragment is 1, pointing to the Payload length field of the ++ // fragment packet. + // +- Offset = Offset + (RoutingHead->HeaderLen + 1) * 8; ++ if ((IpSb != NULL) && (Packet != NULL) && ((ExtHdrsLen % 8) != 0)) { ++ // ++ // Check whether it is the last fragment. ++ // ++ FragmentHead = (IP6_FRAGMENT_HEADER *)(ExtHdrs + Offset); ++ if (FragmentHead == NULL) { ++ return FALSE; ++ } ++ ++ FragmentOffset = NTOHS (FragmentHead->FragmentOffset); ++ ++ if (((FragmentOffset & 0x1) == 0x1) && ++ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) ++ { ++ Pointer = sizeof (UINT32); ++ Ip6SendIcmpError ( ++ IpSb, ++ Packet, ++ NULL, ++ &Packet->Ip.Ip6->SourceAddress, ++ ICMP_V6_PARAMETER_PROBLEM, ++ 0, ++ &Pointer ++ ); ++ return FALSE; ++ } ++ } ++ ++ if (Fragmented != NULL) { ++ *Fragmented = TRUE; ++ } ++ ++ if (Rcvd && (FormerHeader != NULL)) { ++ *FormerHeader = (UINT32)(NextHeader - ExtHdrs); ++ } ++ ++ NextHeader = ExtHdrs + Offset; ++ Offset = Offset + 8; ++ break; + +- if (UnFragmentLen != NULL) { +- *UnFragmentLen = Offset; ++ case IP6_AH: ++ if (++CountA > 1) { ++ return FALSE; + } + +- } else { ++ Option = ExtHdrs + Offset; ++ NextHeader = Option; ++ Option++; + // +- // Discard the packet and send an ICMP Parameter Problem, Code 0, message +- // to the packet's source address, pointing to the unrecognized routing +- // type. ++ // RFC2402, Payload length is specified in 32-bit words, minus "2". + // +- Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER); +- if ((IpSb != NULL) && (Packet != NULL) && +- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { +- Ip6SendIcmpError ( +- IpSb, +- Packet, +- NULL, +- &Packet->Ip.Ip6->SourceAddress, +- ICMP_V6_PARAMETER_PROBLEM, +- 0, +- &Pointer +- ); +- } ++ OptionLen = (UINT8)((*Option + 2) * 4); ++ Offset = Offset + OptionLen; ++ break; + ++ case IP6_NO_NEXT_HEADER: ++ *LastHeader = NextHeader; + return FALSE; +- } ++ break; + +- break; ++ default: ++ if (Ip6IsValidProtocol (IpSb, *NextHeader)) { ++ *LastHeader = NextHeader; + +- case IP6_FRAGMENT: ++ if (RealExtsLen != NULL) { ++ *RealExtsLen = Offset; ++ } + +- // +- // RFC2402, AH header should after fragment header. +- // +- if (CountA > 1) { +- return FALSE; +- } ++ return TRUE; ++ } + +- // +- // RFC2460, ICMP Parameter Problem message with code 0 should be sent +- // if the length of a fragment is not a multiple of 8 octets and the M +- // flag of that fragment is 1, pointing to the Payload length field of the +- // fragment packet. +- // +- if (IpSb != NULL && Packet != NULL && (ExtHdrsLen % 8) != 0) { + // +- // Check whether it is the last fragment. ++ // The Next Header value is unrecognized by the node, discard the packet and ++ // send an ICMP parameter problem message with code value of 1. + // +- FragmentHead = (IP6_FRAGMENT_HEADER *) (ExtHdrs + Offset); +- if (FragmentHead == NULL) { +- return FALSE; ++ if (Offset == 0) { ++ // ++ // The Next Header directly follows IPv6 basic header. ++ // ++ Pointer = 6; ++ } else { ++ if (Pointer == 0) { ++ Pointer = sizeof (EFI_IP6_HEADER); ++ } else { ++ Pointer = Offset + sizeof (EFI_IP6_HEADER); ++ } + } + +- FragmentOffset = NTOHS (FragmentHead->FragmentOffset); +- +- if (((FragmentOffset & 0x1) == 0x1) && +- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { +- Pointer = sizeof (UINT32); ++ if ((IpSb != NULL) && (Packet != NULL) && ++ !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) ++ { + Ip6SendIcmpError ( + IpSb, + Packet, + NULL, + &Packet->Ip.Ip6->SourceAddress, + ICMP_V6_PARAMETER_PROBLEM, +- 0, ++ 1, + &Pointer + ); +- return FALSE; + } +- } +- +- if (Fragmented != NULL) { +- *Fragmented = TRUE; +- } + +- if (Rcvd && FormerHeader != NULL) { +- *FormerHeader = (UINT32) (NextHeader - ExtHdrs); +- } +- +- NextHeader = ExtHdrs + Offset; +- Offset = Offset + 8; +- break; +- +- case IP6_AH: +- if (++CountA > 1) { + return FALSE; +- } +- +- Option = ExtHdrs + Offset; +- NextHeader = Option; +- Option++; +- // +- // RFC2402, Payload length is specified in 32-bit words, minus "2". +- // +- OptionLen = (UINT8) ((*Option + 2) * 4); +- Offset = Offset + OptionLen; +- break; +- +- case IP6_NO_NEXT_HEADER: +- *LastHeader = NextHeader; +- return FALSE; +- break; +- +- default: +- if (Ip6IsValidProtocol (IpSb, *NextHeader)) { +- +- *LastHeader = NextHeader; +- +- if (RealExtsLen != NULL) { +- *RealExtsLen = Offset; +- } +- +- return TRUE; +- } +- +- // +- // The Next Header value is unrecognized by the node, discard the packet and +- // send an ICMP parameter problem message with code value of 1. +- // +- if (Offset == 0) { +- // +- // The Next Header directly follows IPv6 basic header. +- // +- Pointer = 6; +- } else { +- if (Pointer == 0) { +- Pointer = sizeof (EFI_IP6_HEADER); +- } else { +- Pointer = Offset + sizeof (EFI_IP6_HEADER); +- } +- } +- +- if ((IpSb != NULL) && (Packet != NULL) && +- !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { +- Ip6SendIcmpError ( +- IpSb, +- Packet, +- NULL, +- &Packet->Ip.Ip6->SourceAddress, +- ICMP_V6_PARAMETER_PROBLEM, +- 1, +- &Pointer +- ); +- } +- return FALSE; + } + } + +@@ -592,12 +599,12 @@ Ip6IsExtsValid ( + **/ + EFI_STATUS + Ip6FillHopByHop ( +- OUT UINT8 *Buffer, +- IN OUT UINTN *BufferLen, +- IN UINT8 NextHeader ++ OUT UINT8 *Buffer, ++ IN OUT UINTN *BufferLen, ++ IN UINT8 NextHeader + ) + { +- UINT8 BufferArray[8]; ++ UINT8 BufferArray[8]; + + if (*BufferLen < 8) { + *BufferLen = 8; +@@ -640,23 +647,23 @@ Ip6FillHopByHop ( + **/ + EFI_STATUS + Ip6FillFragmentHeader ( +- IN IP6_SERVICE *IpSb, +- IN UINT8 NextHeader, +- IN UINT8 LastHeader, +- IN UINT8 *ExtHdrs, +- IN UINT32 ExtHdrsLen, +- IN UINT16 FragmentOffset, +- OUT UINT8 **UpdatedExtHdrs ++ IN IP6_SERVICE *IpSb, ++ IN UINT8 NextHeader, ++ IN UINT8 LastHeader, ++ IN UINT8 *ExtHdrs, ++ IN UINT32 ExtHdrsLen, ++ IN UINT16 FragmentOffset, ++ OUT UINT8 **UpdatedExtHdrs + ) + { +- UINT32 Length; +- UINT8 *Buffer; +- UINT32 FormerHeader; +- UINT32 Offset; +- UINT32 Part1Len; +- UINT32 HeaderLen; +- UINT8 Current; +- IP6_FRAGMENT_HEADER FragmentHead; ++ UINT32 Length; ++ UINT8 *Buffer; ++ UINT32 FormerHeader; ++ UINT32 Offset; ++ UINT32 Part1Len; ++ UINT32 HeaderLen; ++ UINT8 Current; ++ IP6_FRAGMENT_HEADER FragmentHead; + + if (UpdatedExtHdrs == NULL) { + return EFI_INVALID_PARAMETER; +@@ -668,82 +675,81 @@ Ip6FillFragmentHeader ( + return EFI_OUT_OF_RESOURCES; + } + +- Offset = 0; +- Part1Len = 0; +- FormerHeader = 0; +- Current = NextHeader; ++ Offset = 0; ++ Part1Len = 0; ++ FormerHeader = 0; ++ Current = NextHeader; + + while ((ExtHdrs != NULL) && (Offset <= ExtHdrsLen)) { + switch (NextHeader) { +- case IP6_ROUTING: +- case IP6_HOP_BY_HOP: +- case IP6_DESTINATION: +- Current = NextHeader; +- NextHeader = *(ExtHdrs + Offset); ++ case IP6_ROUTING: ++ case IP6_HOP_BY_HOP: ++ case IP6_DESTINATION: ++ Current = NextHeader; ++ NextHeader = *(ExtHdrs + Offset); ++ ++ if ((Current == IP6_DESTINATION) && (NextHeader != IP6_ROUTING)) { ++ // ++ // Destination Options header should occur at most twice, once before ++ // a Routing header and once before the upper-layer header. Here we ++ // find the one before the upper-layer header. Insert the Fragment ++ // Header before it. ++ // ++ CopyMem (Buffer, ExtHdrs, Part1Len); ++ *(Buffer + FormerHeader) = IP6_FRAGMENT; ++ // ++ // Exit the loop. ++ // ++ Offset = ExtHdrsLen + 1; ++ break; ++ } + +- if ((Current == IP6_DESTINATION) && (NextHeader != IP6_ROUTING)) { +- // +- // Destination Options header should occur at most twice, once before +- // a Routing header and once before the upper-layer header. Here we +- // find the one before the upper-layer header. Insert the Fragment +- // Header before it. +- // +- CopyMem (Buffer, ExtHdrs, Part1Len); +- *(Buffer + FormerHeader) = IP6_FRAGMENT; +- // +- // Exit the loop. +- // +- Offset = ExtHdrsLen + 1; ++ FormerHeader = Offset; ++ HeaderLen = (*(ExtHdrs + Offset + 1) + 1) * 8; ++ Part1Len = Part1Len + HeaderLen; ++ Offset = Offset + HeaderLen; + break; +- } +- + +- FormerHeader = Offset; +- HeaderLen = (*(ExtHdrs + Offset + 1) + 1) * 8; +- Part1Len = Part1Len + HeaderLen; +- Offset = Offset + HeaderLen; +- break; +- +- case IP6_FRAGMENT: +- Current = NextHeader; +- +- if (Part1Len != 0) { +- CopyMem (Buffer, ExtHdrs, Part1Len); +- } +- +- *(Buffer + FormerHeader) = IP6_FRAGMENT; +- +- // +- // Exit the loop. +- // +- Offset = ExtHdrsLen + 1; +- break; ++ case IP6_FRAGMENT: ++ Current = NextHeader; + +- case IP6_AH: +- Current = NextHeader; +- NextHeader = *(ExtHdrs + Offset); +- // +- // RFC2402, Payload length is specified in 32-bit words, minus "2". +- // +- HeaderLen = (*(ExtHdrs + Offset + 1) + 2) * 4; +- Part1Len = Part1Len + HeaderLen; +- Offset = Offset + HeaderLen; +- break; ++ if (Part1Len != 0) { ++ CopyMem (Buffer, ExtHdrs, Part1Len); ++ } + +- default: +- if (Ip6IsValidProtocol (IpSb, NextHeader)) { +- Current = NextHeader; +- CopyMem (Buffer, ExtHdrs, Part1Len); + *(Buffer + FormerHeader) = IP6_FRAGMENT; ++ + // + // Exit the loop. + // + Offset = ExtHdrsLen + 1; + break; +- } + +- FreePool (Buffer); +- return EFI_UNSUPPORTED; ++ case IP6_AH: ++ Current = NextHeader; ++ NextHeader = *(ExtHdrs + Offset); ++ // ++ // RFC2402, Payload length is specified in 32-bit words, minus "2". ++ // ++ HeaderLen = (*(ExtHdrs + Offset + 1) + 2) * 4; ++ Part1Len = Part1Len + HeaderLen; ++ Offset = Offset + HeaderLen; ++ break; ++ ++ default: ++ if (Ip6IsValidProtocol (IpSb, NextHeader)) { ++ Current = NextHeader; ++ CopyMem (Buffer, ExtHdrs, Part1Len); ++ *(Buffer + FormerHeader) = IP6_FRAGMENT; ++ // ++ // Exit the loop. ++ // ++ Offset = ExtHdrsLen + 1; ++ break; ++ } ++ ++ FreePool (Buffer); ++ return EFI_UNSUPPORTED; + } + } + +@@ -778,4 +784,3 @@ Ip6FillFragmentHeader ( + + return EFI_SUCCESS; + } +- +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h +index c81b3fda2f..bd8e223c8a 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.h +@@ -10,20 +10,20 @@ + #ifndef __EFI_IP6_OPTION_H__ + #define __EFI_IP6_OPTION_H__ + +-#define IP6_FRAGMENT_OFFSET_MASK (~0x3) ++#define IP6_FRAGMENT_OFFSET_MASK (~0x3) + + typedef struct _IP6_FRAGMENT_HEADER { +- UINT8 NextHeader; +- UINT8 Reserved; +- UINT16 FragmentOffset; +- UINT32 Identification; ++ UINT8 NextHeader; ++ UINT8 Reserved; ++ UINT16 FragmentOffset; ++ UINT32 Identification; + } IP6_FRAGMENT_HEADER; + + typedef struct _IP6_ROUTING_HEADER { +- UINT8 NextHeader; +- UINT8 HeaderLen; +- UINT8 RoutingType; +- UINT8 SegmentsLeft; ++ UINT8 NextHeader; ++ UINT8 HeaderLen; ++ UINT8 RoutingType; ++ UINT8 SegmentsLeft; + } IP6_ROUTING_HEADER; + + typedef enum { +@@ -35,11 +35,11 @@ typedef enum { + Ip6OptionParameterProblem = 0x80, + Ip6OptionMask = 0xc0, + +- Ip6OptionEtherSource = 1, +- Ip6OptionEtherTarget = 2, +- Ip6OptionPrefixInfo = 3, +- Ip6OptionRedirected = 4, +- Ip6OptionMtu = 5 ++ Ip6OptionEtherSource = 1, ++ Ip6OptionEtherTarget = 2, ++ Ip6OptionPrefixInfo = 3, ++ Ip6OptionRedirected = 4, ++ Ip6OptionMtu = 5 + } IP6_OPTION_TYPE; + + /** +@@ -72,17 +72,17 @@ typedef enum { + **/ + BOOLEAN + Ip6IsExtsValid ( +- IN IP6_SERVICE *IpSb OPTIONAL, +- IN NET_BUF *Packet OPTIONAL, +- IN UINT8 *NextHeader, +- IN UINT8 *ExtHdrs, +- IN UINT32 ExtHdrsLen, +- IN BOOLEAN Rcvd, +- OUT UINT32 *FormerHeader OPTIONAL, +- OUT UINT8 **LastHeader, +- OUT UINT32 *RealExtsLen OPTIONAL, +- OUT UINT32 *UnFragmentLen OPTIONAL, +- OUT BOOLEAN *Fragmented OPTIONAL ++ IN IP6_SERVICE *IpSb OPTIONAL, ++ IN NET_BUF *Packet OPTIONAL, ++ IN UINT8 *NextHeader, ++ IN UINT8 *ExtHdrs, ++ IN UINT32 ExtHdrsLen, ++ IN BOOLEAN Rcvd, ++ OUT UINT32 *FormerHeader OPTIONAL, ++ OUT UINT8 **LastHeader, ++ OUT UINT32 *RealExtsLen OPTIONAL, ++ OUT UINT32 *UnFragmentLen OPTIONAL, ++ OUT BOOLEAN *Fragmented OPTIONAL + ); + + /** +@@ -101,9 +101,9 @@ Ip6IsExtsValid ( + **/ + EFI_STATUS + Ip6FillHopByHop ( +- OUT UINT8 *Buffer, +- IN OUT UINTN *BufferLen, +- IN UINT8 NextHeader ++ OUT UINT8 *Buffer, ++ IN OUT UINTN *BufferLen, ++ IN UINT8 NextHeader + ); + + /** +@@ -127,13 +127,13 @@ Ip6FillHopByHop ( + **/ + EFI_STATUS + Ip6FillFragmentHeader ( +- IN IP6_SERVICE *IpSb, +- IN UINT8 NextHeader, +- IN UINT8 LastHeader, +- IN UINT8 *ExtHdrs, +- IN UINT32 ExtHdrsLen, +- IN UINT16 FragmentOffset, +- OUT UINT8 **UpdatedExtHdrs ++ IN IP6_SERVICE *IpSb, ++ IN UINT8 NextHeader, ++ IN UINT8 LastHeader, ++ IN UINT8 *ExtHdrs, ++ IN UINT32 ExtHdrsLen, ++ IN UINT16 FragmentOffset, ++ OUT UINT8 **UpdatedExtHdrs + ); + + /** +@@ -155,13 +155,13 @@ Ip6FillFragmentHeader ( + **/ + EFI_STATUS + Ip6CopyExts ( +- IN UINT8 NextHeader, +- IN UINT8 *ExtHdrs, +- IN UINT8 *LastHeader, +- IN UINT16 FragmentOffset, +- IN UINT32 UnFragmentHdrLen, +- IN OUT UINT8 *Buf, +- IN OUT UINT32 *BufLen ++ IN UINT8 NextHeader, ++ IN UINT8 *ExtHdrs, ++ IN UINT8 *LastHeader, ++ IN UINT16 FragmentOffset, ++ IN UINT32 UnFragmentHdrLen, ++ IN OUT UINT8 *Buf, ++ IN OUT UINT32 *BufLen + ); + + /** +@@ -178,8 +178,8 @@ Ip6CopyExts ( + **/ + BOOLEAN + Ip6IsNDOptionValid ( +- IN UINT8 *Option, +- IN UINT16 OptionLen ++ IN UINT8 *Option, ++ IN UINT16 OptionLen + ); + + #endif +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch b/edk2-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch new file mode 100644 index 0000000..2c0ae8b --- /dev/null +++ b/edk2-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch @@ -0,0 +1,170 @@ +From ffa1202da2f55c1f540240e8267db9a7ec8d6a60 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 11/15] NetworkPkg: : Adds a SecurityFix.yaml file + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [11/15] 8a46b763887843d00293997bdd7d50ea120104d9 + +JIRA: https://issues.redhat.com/browse/RHEL-21852 +CVE: CVE-2022-45235 +Upstream: Merged + +commit 1d0b95f6457d225c5108302a9da74b4ed7aa5a38 +Author: Doug Flick via groups.io +Date: Fri Jan 26 05:54:57 2024 +0800 + + NetworkPkg: : Adds a SecurityFix.yaml file + + 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 + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + 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 0000000000..7e900483fe +--- /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.39.3 + diff --git a/edk2-NetworkPkg-Apply-uncrustify-changes-p2.patch b/edk2-NetworkPkg-Apply-uncrustify-changes-p2.patch new file mode 100644 index 0000000..d51d127 --- /dev/null +++ b/edk2-NetworkPkg-Apply-uncrustify-changes-p2.patch @@ -0,0 +1,2054 @@ +From f7e6d9e61173d76ab9827e1af62dc9966a21e14c Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 17:28:51 -0500 +Subject: [PATCH 12/15] NetworkPkg: Apply uncrustify changes + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [12/15] 880596c246c87181f19fcb0a7a21f4e32d234c13 + +JIRA: https://issues.redhat.com/browse/RHEL-21840 +CVE: CVE-2022-45229 +Upstream: Merged +Conflicts: There has already been added two commits after the point where + this commit was added upstream, so we cannot apply that commit, + or even parts of it, directly. Instead, we only introduce the + whitespace changes needed to make future commits touching + the file NetworkPkg/Dhcp6Dxe/Dhcp6Io.c apply cleanly. + +commit d1050b9dff1cace252aff86630bfdb59dff5f507 +Author: Michael Kubacki +Date: Sun Dec 5 14:54:07 2021 -0800 + + NetworkPkg: Apply uncrustify changes + + REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 + + Apply uncrustify changes to .c/.h files in the NetworkPkg package + + Cc: Andrew Fish + Cc: Leif Lindholm + Cc: Michael D Kinney + Signed-off-by: Michael Kubacki + Reviewed-by: Maciej Rabeda + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 1091 ++++++++++++++++----------------- + 1 file changed, 529 insertions(+), 562 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +index d680febbf1..3b8feb4a20 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +@@ -10,7 +10,6 @@ + + #include "Dhcp6Impl.h" + +- + /** + Enqueue the packet into the retry list in case of timeout. + +@@ -34,8 +33,8 @@ Dhcp6EnqueueRetry ( + IN EFI_DHCP6_RETRANSMISSION *RetryCtl OPTIONAL + ) + { +- DHCP6_TX_CB *TxCb; +- DHCP6_IA_CB *IaCb; ++ DHCP6_TX_CB *TxCb; ++ DHCP6_IA_CB *IaCb; + + ASSERT (Packet != NULL); + +@@ -55,156 +54,156 @@ Dhcp6EnqueueRetry ( + // + // Save pointer to elapsed-time value so we can update it on retransmits. + // +- TxCb->Elapsed = Elapsed; ++ TxCb->Elapsed = Elapsed; + + // + // Calculate the retransmission according to the message type. + // + switch (Packet->Dhcp6.Header.MessageType) { +- case Dhcp6MsgSolicit: +- // +- // Calculate the retransmission threshold value for solicit packet. +- // Use the default value by rfc-3315 if user doesn't configure. +- // +- if (RetryCtl == NULL) { +- TxCb->RetryCtl.Irt = DHCP6_SOL_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_SOL_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_SOL_MRT; +- TxCb->RetryCtl.Mrd = DHCP6_SOL_MRD; +- } else { +- TxCb->RetryCtl.Irt = (RetryCtl->Irt != 0) ? RetryCtl->Irt : DHCP6_SOL_IRT; +- TxCb->RetryCtl.Mrc = (RetryCtl->Mrc != 0) ? RetryCtl->Mrc : DHCP6_SOL_MRC; +- TxCb->RetryCtl.Mrt = (RetryCtl->Mrt != 0) ? RetryCtl->Mrt : DHCP6_SOL_MRT; +- TxCb->RetryCtl.Mrd = (RetryCtl->Mrd != 0) ? RetryCtl->Mrd : DHCP6_SOL_MRD; +- } ++ case Dhcp6MsgSolicit: ++ // ++ // Calculate the retransmission threshold value for solicit packet. ++ // Use the default value by rfc-3315 if user doesn't configure. ++ // ++ if (RetryCtl == NULL) { ++ TxCb->RetryCtl.Irt = DHCP6_SOL_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_SOL_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_SOL_MRT; ++ TxCb->RetryCtl.Mrd = DHCP6_SOL_MRD; ++ } else { ++ TxCb->RetryCtl.Irt = (RetryCtl->Irt != 0) ? RetryCtl->Irt : DHCP6_SOL_IRT; ++ TxCb->RetryCtl.Mrc = (RetryCtl->Mrc != 0) ? RetryCtl->Mrc : DHCP6_SOL_MRC; ++ TxCb->RetryCtl.Mrt = (RetryCtl->Mrt != 0) ? RetryCtl->Mrt : DHCP6_SOL_MRT; ++ TxCb->RetryCtl.Mrd = (RetryCtl->Mrd != 0) ? RetryCtl->Mrd : DHCP6_SOL_MRD; ++ } ++ ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ TxCb->RetryCtl.Irt, ++ TRUE, ++ FALSE ++ ); ++ break; + +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ case Dhcp6MsgRequest: ++ // ++ // Calculate the retransmission threshold value for request packet. ++ // ++ TxCb->RetryCtl.Irt = DHCP6_REQ_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_REQ_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_REQ_MRT; ++ TxCb->RetryCtl.Mrd = DHCP6_REQ_MRD; ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( + TxCb->RetryCtl.Irt, + TRUE, +- FALSE ++ TRUE + ); +- break; +- +- case Dhcp6MsgRequest: +- // +- // Calculate the retransmission threshold value for request packet. +- // +- TxCb->RetryCtl.Irt = DHCP6_REQ_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_REQ_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_REQ_MRT; +- TxCb->RetryCtl.Mrd = DHCP6_REQ_MRD; +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( +- TxCb->RetryCtl.Irt, +- TRUE, +- TRUE +- ); +- break; +- +- case Dhcp6MsgConfirm: +- // +- // Calculate the retransmission threshold value for confirm packet. +- // +- TxCb->RetryCtl.Irt = DHCP6_CNF_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_CNF_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_CNF_MRT; +- TxCb->RetryCtl.Mrd = DHCP6_CNF_MRD; +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( +- TxCb->RetryCtl.Irt, +- TRUE, +- TRUE +- ); +- break; +- +- case Dhcp6MsgRenew: +- // +- // Calculate the retransmission threshold value for renew packet. +- // +- TxCb->RetryCtl.Irt = DHCP6_REB_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_REB_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_REB_MRT; +- TxCb->RetryCtl.Mrd = IaCb->T2 - IaCb->T1; +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( +- TxCb->RetryCtl.Irt, +- TRUE, +- TRUE +- ); +- break; ++ break; + +- case Dhcp6MsgRebind: +- // +- // Calculate the retransmission threshold value for rebind packet. +- // +- TxCb->RetryCtl.Irt = DHCP6_REN_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_REN_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_REN_MRT; +- TxCb->RetryCtl.Mrd = IaCb->AllExpireTime - IaCb->T2; +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( +- TxCb->RetryCtl.Irt, +- TRUE, +- TRUE +- ); +- break; ++ case Dhcp6MsgConfirm: ++ // ++ // Calculate the retransmission threshold value for confirm packet. ++ // ++ TxCb->RetryCtl.Irt = DHCP6_CNF_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_CNF_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_CNF_MRT; ++ TxCb->RetryCtl.Mrd = DHCP6_CNF_MRD; ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ TxCb->RetryCtl.Irt, ++ TRUE, ++ TRUE ++ ); ++ break; + +- case Dhcp6MsgDecline: +- // +- // Calculate the retransmission threshold value for decline packet. +- // +- TxCb->RetryCtl.Irt = DHCP6_DEC_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_DEC_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_DEC_MRT; +- TxCb->RetryCtl.Mrd = DHCP6_DEC_MRD; +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( +- TxCb->RetryCtl.Irt, +- TRUE, +- TRUE +- ); +- break; ++ case Dhcp6MsgRenew: ++ // ++ // Calculate the retransmission threshold value for renew packet. ++ // ++ TxCb->RetryCtl.Irt = DHCP6_REB_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_REB_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_REB_MRT; ++ TxCb->RetryCtl.Mrd = IaCb->T2 - IaCb->T1; ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ TxCb->RetryCtl.Irt, ++ TRUE, ++ TRUE ++ ); ++ break; + +- case Dhcp6MsgRelease: +- // +- // Calculate the retransmission threshold value for release packet. +- // +- TxCb->RetryCtl.Irt = DHCP6_REL_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_REL_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_REL_MRT; +- TxCb->RetryCtl.Mrd = DHCP6_REL_MRD; +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( +- TxCb->RetryCtl.Irt, +- TRUE, +- TRUE +- ); +- break; ++ case Dhcp6MsgRebind: ++ // ++ // Calculate the retransmission threshold value for rebind packet. ++ // ++ TxCb->RetryCtl.Irt = DHCP6_REN_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_REN_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_REN_MRT; ++ TxCb->RetryCtl.Mrd = IaCb->AllExpireTime - IaCb->T2; ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ TxCb->RetryCtl.Irt, ++ TRUE, ++ TRUE ++ ); ++ break; + +- case Dhcp6MsgInfoRequest: +- // +- // Calculate the retransmission threshold value for info-request packet. +- // Use the default value by rfc-3315 if user doesn't configure. +- // +- if (RetryCtl == NULL) { +- TxCb->RetryCtl.Irt = DHCP6_INF_IRT; +- TxCb->RetryCtl.Mrc = DHCP6_INF_MRC; +- TxCb->RetryCtl.Mrt = DHCP6_INF_MRT; +- TxCb->RetryCtl.Mrd = DHCP6_INF_MRD; +- } else { +- TxCb->RetryCtl.Irt = (RetryCtl->Irt != 0) ? RetryCtl->Irt : DHCP6_INF_IRT; +- TxCb->RetryCtl.Mrc = (RetryCtl->Mrc != 0) ? RetryCtl->Mrc : DHCP6_INF_MRC; +- TxCb->RetryCtl.Mrt = (RetryCtl->Mrt != 0) ? RetryCtl->Mrt : DHCP6_INF_MRT; +- TxCb->RetryCtl.Mrd = (RetryCtl->Mrd != 0) ? RetryCtl->Mrd : DHCP6_INF_MRD; +- } ++ case Dhcp6MsgDecline: ++ // ++ // Calculate the retransmission threshold value for decline packet. ++ // ++ TxCb->RetryCtl.Irt = DHCP6_DEC_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_DEC_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_DEC_MRT; ++ TxCb->RetryCtl.Mrd = DHCP6_DEC_MRD; ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ TxCb->RetryCtl.Irt, ++ TRUE, ++ TRUE ++ ); ++ break; + +- TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ case Dhcp6MsgRelease: ++ // ++ // Calculate the retransmission threshold value for release packet. ++ // ++ TxCb->RetryCtl.Irt = DHCP6_REL_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_REL_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_REL_MRT; ++ TxCb->RetryCtl.Mrd = DHCP6_REL_MRD; ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( + TxCb->RetryCtl.Irt, + TRUE, + TRUE + ); +- break; ++ break; + +- default: +- // +- // Unexpected message type. +- // +- FreePool(TxCb); +- return EFI_DEVICE_ERROR; ++ case Dhcp6MsgInfoRequest: ++ // ++ // Calculate the retransmission threshold value for info-request packet. ++ // Use the default value by rfc-3315 if user doesn't configure. ++ // ++ if (RetryCtl == NULL) { ++ TxCb->RetryCtl.Irt = DHCP6_INF_IRT; ++ TxCb->RetryCtl.Mrc = DHCP6_INF_MRC; ++ TxCb->RetryCtl.Mrt = DHCP6_INF_MRT; ++ TxCb->RetryCtl.Mrd = DHCP6_INF_MRD; ++ } else { ++ TxCb->RetryCtl.Irt = (RetryCtl->Irt != 0) ? RetryCtl->Irt : DHCP6_INF_IRT; ++ TxCb->RetryCtl.Mrc = (RetryCtl->Mrc != 0) ? RetryCtl->Mrc : DHCP6_INF_MRC; ++ TxCb->RetryCtl.Mrt = (RetryCtl->Mrt != 0) ? RetryCtl->Mrt : DHCP6_INF_MRT; ++ TxCb->RetryCtl.Mrd = (RetryCtl->Mrd != 0) ? RetryCtl->Mrd : DHCP6_INF_MRD; ++ } ++ ++ TxCb->RetryExp = Dhcp6CalculateExpireTime ( ++ TxCb->RetryCtl.Irt, ++ TRUE, ++ TRUE ++ ); ++ break; ++ ++ default: ++ // ++ // Unexpected message type. ++ // ++ FreePool (TxCb); ++ return EFI_DEVICE_ERROR; + } + + // +@@ -215,7 +214,6 @@ Dhcp6EnqueueRetry ( + return EFI_SUCCESS; + } + +- + /** + Dequeue the packet from retry list if reply received or timeout at last. + +@@ -230,40 +228,36 @@ Dhcp6EnqueueRetry ( + **/ + EFI_STATUS + Dhcp6DequeueRetry ( +- IN DHCP6_INSTANCE *Instance, +- IN UINT32 PacketXid, +- IN BOOLEAN NeedSignal ++ IN DHCP6_INSTANCE *Instance, ++ IN UINT32 PacketXid, ++ IN BOOLEAN NeedSignal + ) + { +- LIST_ENTRY *Entry; +- LIST_ENTRY *NextEntry; +- DHCP6_TX_CB *TxCb; +- DHCP6_INF_CB *InfCb; ++ LIST_ENTRY *Entry; ++ LIST_ENTRY *NextEntry; ++ DHCP6_TX_CB *TxCb; ++ DHCP6_INF_CB *InfCb; + + // + // Seek the retransmit node in the retransmit list by packet xid. + // + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) { +- + TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link); +- ASSERT(TxCb->TxPacket); ++ ASSERT (TxCb->TxPacket); + + if (TxCb->Xid == PacketXid) { +- + if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) { +- + // + // Seek the info-request node in the info-request list by packet xid. + // + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->InfList) { +- + InfCb = NET_LIST_USER_STRUCT (Entry, DHCP6_INF_CB, Link); + + if (InfCb->Xid == PacketXid) { + // + // Remove the info-request node, and signal the event if timeout. + // +- if (InfCb->TimeoutEvent != NULL && NeedSignal) { ++ if ((InfCb->TimeoutEvent != NULL) && NeedSignal) { + gBS->SignalEvent (InfCb->TimeoutEvent); + } + +@@ -272,11 +266,12 @@ Dhcp6DequeueRetry ( + } + } + } ++ + // + // Remove the retransmit node. + // + RemoveEntryList (&TxCb->Link); +- ASSERT(TxCb->TxPacket); ++ ASSERT (TxCb->TxPacket); + FreePool (TxCb->TxPacket); + FreePool (TxCb); + return EFI_SUCCESS; +@@ -286,7 +281,6 @@ Dhcp6DequeueRetry ( + return EFI_NOT_FOUND; + } + +- + /** + Clean up the specific nodes in the retry list. + +@@ -296,24 +290,22 @@ Dhcp6DequeueRetry ( + **/ + VOID + Dhcp6CleanupRetry ( +- IN DHCP6_INSTANCE *Instance, +- IN UINT32 Scope ++ IN DHCP6_INSTANCE *Instance, ++ IN UINT32 Scope + ) + { +- LIST_ENTRY *Entry; +- LIST_ENTRY *NextEntry; +- DHCP6_TX_CB *TxCb; +- DHCP6_INF_CB *InfCb; ++ LIST_ENTRY *Entry; ++ LIST_ENTRY *NextEntry; ++ DHCP6_TX_CB *TxCb; ++ DHCP6_INF_CB *InfCb; + + // + // Clean up all the stateful messages from the retransmit list. + // +- if (Scope == DHCP6_PACKET_STATEFUL || Scope == DHCP6_PACKET_ALL) { +- ++ if ((Scope == DHCP6_PACKET_STATEFUL) || (Scope == DHCP6_PACKET_ALL)) { + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) { +- + TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link); +- ASSERT(TxCb->TxPacket); ++ ASSERT (TxCb->TxPacket); + + if (TxCb->TxPacket->Dhcp6.Header.MessageType != Dhcp6MsgInfoRequest) { + RemoveEntryList (&TxCb->Link); +@@ -326,15 +318,13 @@ Dhcp6CleanupRetry ( + // + // Clean up all the stateless messages from the retransmit list. + // +- if (Scope == DHCP6_PACKET_STATELESS || Scope == DHCP6_PACKET_ALL) { +- ++ if ((Scope == DHCP6_PACKET_STATELESS) || (Scope == DHCP6_PACKET_ALL)) { + // + // Clean up all the retransmit list for stateless messages. + // + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) { +- + TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link); +- ASSERT(TxCb->TxPacket); ++ ASSERT (TxCb->TxPacket); + + if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) { + RemoveEntryList (&TxCb->Link); +@@ -347,12 +337,12 @@ Dhcp6CleanupRetry ( + // Clean up all the info-request messages list. + // + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->InfList) { +- + InfCb = NET_LIST_USER_STRUCT (Entry, DHCP6_INF_CB, Link); + + if (InfCb->TimeoutEvent != NULL) { + gBS->SignalEvent (InfCb->TimeoutEvent); + } ++ + RemoveEntryList (&InfCb->Link); + FreePool (InfCb); + } +@@ -371,11 +361,11 @@ Dhcp6CleanupRetry ( + **/ + BOOLEAN + Dhcp6IsValidTxCb ( +- IN DHCP6_INSTANCE *Instance, +- IN DHCP6_TX_CB *TxCb ++ IN DHCP6_INSTANCE *Instance, ++ IN DHCP6_TX_CB *TxCb + ) + { +- LIST_ENTRY *Entry; ++ LIST_ENTRY *Entry; + + NET_LIST_FOR_EACH (Entry, &Instance->TxList) { + if (TxCb == NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link)) { +@@ -395,15 +385,15 @@ Dhcp6IsValidTxCb ( + **/ + VOID + Dhcp6CleanupSession ( +- IN OUT DHCP6_INSTANCE *Instance, +- IN EFI_STATUS Status ++ IN OUT DHCP6_INSTANCE *Instance, ++ IN EFI_STATUS Status + ) + { +- UINTN Index; +- EFI_DHCP6_IA *Ia; ++ UINTN Index; ++ EFI_DHCP6_IA *Ia; + +- ASSERT(Instance->Config); +- ASSERT(Instance->IaCb.Ia); ++ ASSERT (Instance->Config); ++ ASSERT (Instance->IaCb.Ia); + + // + // Clean up the retransmit list for stateful messages. +@@ -425,23 +415,23 @@ Dhcp6CleanupSession ( + // + // Reinitialize the Ia fields of the instance. + // +- Instance->UdpSts = Status; +- Instance->AdSelect = NULL; +- Instance->AdPref = 0; +- Instance->Unicast = NULL; +- Instance->IaCb.T1 = 0; +- Instance->IaCb.T2 = 0; +- Instance->IaCb.AllExpireTime = 0; +- Instance->IaCb.LeaseTime = 0; ++ Instance->UdpSts = Status; ++ Instance->AdSelect = NULL; ++ Instance->AdPref = 0; ++ Instance->Unicast = NULL; ++ Instance->IaCb.T1 = 0; ++ Instance->IaCb.T2 = 0; ++ Instance->IaCb.AllExpireTime = 0; ++ Instance->IaCb.LeaseTime = 0; + + // + // Clear start time + // +- Instance->StartTime = 0; ++ Instance->StartTime = 0; + +- Ia = Instance->IaCb.Ia; +- Ia->State = Dhcp6Init; +- Ia->ReplyPacket = NULL; ++ Ia = Instance->IaCb.Ia; ++ Ia->State = Dhcp6Init; ++ Ia->ReplyPacket = NULL; + + // + // Set the addresses as zero lifetime, and then the notify +@@ -461,7 +451,6 @@ Dhcp6CleanupSession ( + } + } + +- + /** + Callback to user when Dhcp6 transmit/receive occurs. + +@@ -477,15 +466,15 @@ Dhcp6CleanupSession ( + EFI_STATUS + EFIAPI + Dhcp6CallbackUser ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_EVENT Event, +- IN OUT EFI_DHCP6_PACKET **Packet ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_EVENT Event, ++ IN OUT EFI_DHCP6_PACKET **Packet + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *NewPacket; +- EFI_DHCP6_CALLBACK Callback; +- VOID *Context; ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *NewPacket; ++ EFI_DHCP6_CALLBACK Callback; ++ VOID *Context; + + ASSERT (Packet != NULL); + ASSERT (Instance->Config != NULL); +@@ -500,7 +489,6 @@ Dhcp6CallbackUser ( + // Callback to user with the new message if has. + // + if (Callback != NULL) { +- + Status = Callback ( + &Instance->Dhcp6, + Context, +@@ -522,7 +510,6 @@ Dhcp6CallbackUser ( + return Status; + } + +- + /** + Update Ia according to the new reply message. + +@@ -535,17 +522,17 @@ Dhcp6CallbackUser ( + **/ + EFI_STATUS + Dhcp6UpdateIaInfo ( +- IN OUT DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *Packet ++ IN OUT DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet + ) + { +- EFI_STATUS Status; +- UINT8 *Option; +- UINT8 *IaInnerOpt; +- UINT16 IaInnerLen; +- UINT16 StsCode; +- UINT32 T1; +- UINT32 T2; ++ EFI_STATUS Status; ++ UINT8 *Option; ++ UINT8 *IaInnerOpt; ++ UINT16 IaInnerLen; ++ UINT16 StsCode; ++ UINT32 T1; ++ UINT32 T2; + + ASSERT (Instance->Config != NULL); + // +@@ -618,9 +605,10 @@ Dhcp6UpdateIaInfo ( + // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes + // the remainder of the message as though the server had not included the invalid IA_NA option. + // +- if (T1 > T2 && T2 > 0) { ++ if ((T1 > T2) && (T2 > 0)) { + return EFI_DEVICE_ERROR; + } ++ + IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); + IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); + } else { +@@ -674,8 +662,6 @@ Dhcp6UpdateIaInfo ( + return Status; + } + +- +- + /** + Seeks the Inner Options from a DHCP6 Option + +@@ -772,9 +758,9 @@ Dhcp6SeekInnerOptionSafe ( + **/ + EFI_STATUS + Dhcp6SeekStsOption ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *Packet, +- OUT UINT8 **Option ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet, ++ OUT UINT8 **Option + ) + { + UINT8 *IaInnerOpt; +@@ -830,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 +@@ -867,7 +853,7 @@ Dhcp6SeekStsOption ( + // + // sizeof (option-code + option-len) = 4 + // +- *Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); ++ *Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); + if (*Option != NULL) { + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option))))); + if (StsCode != Dhcp6StsSuccess) { +@@ -878,7 +864,6 @@ Dhcp6SeekStsOption ( + return EFI_SUCCESS; + } + +- + /** + Transmit Dhcp6 message by udpio. + +@@ -893,23 +878,23 @@ Dhcp6SeekStsOption ( + **/ + EFI_STATUS + Dhcp6TransmitPacket ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *Packet, +- IN UINT16 *Elapsed ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet, ++ IN UINT16 *Elapsed + ) + { +- EFI_STATUS Status; +- NET_BUF *Wrap; +- NET_FRAGMENT Frag; +- UDP_END_POINT EndPt; +- DHCP6_SERVICE *Service; ++ EFI_STATUS Status; ++ NET_BUF *Wrap; ++ NET_FRAGMENT Frag; ++ UDP_END_POINT EndPt; ++ DHCP6_SERVICE *Service; + + Service = Instance->Service; + + // + // Wrap it into a netbuf then send it. + // +- Frag.Bulk = (UINT8 *) &Packet->Dhcp6.Header; ++ Frag.Bulk = (UINT8 *)&Packet->Dhcp6.Header; + Frag.Len = Packet->Length; + + // +@@ -970,7 +955,6 @@ Dhcp6TransmitPacket ( + return EFI_SUCCESS; + } + +- + /** + Create the solicit message and send it. + +@@ -983,19 +967,19 @@ Dhcp6TransmitPacket ( + **/ + EFI_STATUS + Dhcp6SendSolicitMsg ( +- IN DHCP6_INSTANCE *Instance ++ IN DHCP6_INSTANCE *Instance + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *Packet; +- EFI_DHCP6_PACKET_OPTION *UserOpt; +- EFI_DHCP6_DUID *ClientId; +- DHCP6_SERVICE *Service; +- UINT8 *Cursor; +- UINT16 *Elapsed; +- UINT32 UserLen; +- UINTN Index; +- UINT16 Length; ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_PACKET_OPTION *UserOpt; ++ EFI_DHCP6_DUID *ClientId; ++ DHCP6_SERVICE *Service; ++ UINT8 *Cursor; ++ UINT16 *Elapsed; ++ UINT32 UserLen; ++ UINTN Index; ++ UINT16 Length; + + Service = Instance->Service; + ClientId = Service->ClientId; +@@ -1069,7 +1053,6 @@ Dhcp6SendSolicitMsg ( + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { +- + UserOpt = Instance->Config->OptionList[Index]; + Status = Dhcp6AppendOption ( + Packet, +@@ -1139,17 +1122,16 @@ ON_ERROR: + **/ + EFI_STATUS + Dhcp6InitSolicitMsg ( +- IN DHCP6_INSTANCE *Instance ++ IN DHCP6_INSTANCE *Instance + ) + { +- Instance->IaCb.T1 = 0; +- Instance->IaCb.T2 = 0; ++ Instance->IaCb.T1 = 0; ++ Instance->IaCb.T2 = 0; + Instance->IaCb.Ia->IaAddressCount = 0; + + return Dhcp6SendSolicitMsg (Instance); + } + +- + /** + Create the request message and send it. + +@@ -1163,31 +1145,31 @@ Dhcp6InitSolicitMsg ( + **/ + EFI_STATUS + Dhcp6SendRequestMsg ( +- IN DHCP6_INSTANCE *Instance ++ IN DHCP6_INSTANCE *Instance + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *Packet; +- EFI_DHCP6_PACKET_OPTION *UserOpt; +- EFI_DHCP6_DUID *ClientId; +- EFI_DHCP6_DUID *ServerId; +- DHCP6_SERVICE *Service; +- UINT8 *Option; +- UINT8 *Cursor; +- UINT16 *Elapsed; +- UINT32 UserLen; +- UINTN Index; +- UINT16 Length; +- +- ASSERT(Instance->AdSelect != NULL); +- ASSERT(Instance->Config != NULL); +- ASSERT(Instance->IaCb.Ia != NULL); +- ASSERT(Instance->Service != NULL); ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_PACKET_OPTION *UserOpt; ++ EFI_DHCP6_DUID *ClientId; ++ EFI_DHCP6_DUID *ServerId; ++ DHCP6_SERVICE *Service; ++ UINT8 *Option; ++ UINT8 *Cursor; ++ UINT16 *Elapsed; ++ UINT32 UserLen; ++ UINTN Index; ++ UINT16 Length; ++ ++ ASSERT (Instance->AdSelect != NULL); ++ ASSERT (Instance->Config != NULL); ++ ASSERT (Instance->IaCb.Ia != NULL); ++ ASSERT (Instance->Service != NULL); + + Service = Instance->Service; + ClientId = Service->ClientId; + +- ASSERT(ClientId != NULL); ++ ASSERT (ClientId != NULL); + + // + // Get the server Id from the selected advertisement message. +@@ -1201,7 +1183,7 @@ Dhcp6SendRequestMsg ( + return EFI_DEVICE_ERROR; + } + +- ServerId = (EFI_DHCP6_DUID *) (Option + 2); ++ ServerId = (EFI_DHCP6_DUID *)(Option + 2); + + // + // Calculate the added length of customized option list. +@@ -1279,7 +1261,6 @@ Dhcp6SendRequestMsg ( + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { +- + UserOpt = Instance->Config->OptionList[Index]; + Status = Dhcp6AppendOption ( + Packet, +@@ -1334,7 +1315,6 @@ ON_ERROR: + return Status; + } + +- + /** + Create the decline message and send it. + +@@ -1349,20 +1329,20 @@ ON_ERROR: + **/ + EFI_STATUS + Dhcp6SendDeclineMsg ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_IA *DecIa ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_IA *DecIa + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *Packet; +- EFI_DHCP6_PACKET *LastReply; +- EFI_DHCP6_DUID *ClientId; +- EFI_DHCP6_DUID *ServerId; +- DHCP6_SERVICE *Service; +- UINT8 *Option; +- UINT8 *Cursor; +- UINT16 *Elapsed; +- UINT16 Length; ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_PACKET *LastReply; ++ EFI_DHCP6_DUID *ClientId; ++ EFI_DHCP6_DUID *ServerId; ++ DHCP6_SERVICE *Service; ++ UINT8 *Option; ++ UINT8 *Cursor; ++ UINT16 *Elapsed; ++ UINT16 Length; + + ASSERT (Instance->Config != NULL); + ASSERT (Instance->IaCb.Ia != NULL); +@@ -1390,7 +1370,7 @@ Dhcp6SendDeclineMsg ( + // + // EFI_DHCP6_DUID contains a length field of 2 bytes. + // +- ServerId = (EFI_DHCP6_DUID *) (Option + 2); ++ ServerId = (EFI_DHCP6_DUID *)(Option + 2); + + // + // Create the Dhcp6 packet and initialize common fields. +@@ -1495,7 +1475,6 @@ ON_ERROR: + return Status; + } + +- + /** + Create the release message and send it. + +@@ -1510,30 +1489,30 @@ ON_ERROR: + **/ + EFI_STATUS + Dhcp6SendReleaseMsg ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_IA *RelIa ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_IA *RelIa + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *Packet; +- EFI_DHCP6_PACKET *LastReply; +- EFI_DHCP6_DUID *ClientId; +- EFI_DHCP6_DUID *ServerId; +- DHCP6_SERVICE *Service; +- UINT8 *Option; +- UINT8 *Cursor; +- UINT16 *Elapsed; +- UINT16 Length; +- +- ASSERT(Instance->Config); +- ASSERT(Instance->IaCb.Ia); ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_PACKET *LastReply; ++ EFI_DHCP6_DUID *ClientId; ++ EFI_DHCP6_DUID *ServerId; ++ DHCP6_SERVICE *Service; ++ UINT8 *Option; ++ UINT8 *Cursor; ++ UINT16 *Elapsed; ++ UINT16 Length; ++ ++ ASSERT (Instance->Config); ++ ASSERT (Instance->IaCb.Ia); + + Service = Instance->Service; + ClientId = Service->ClientId; + LastReply = Instance->IaCb.Ia->ReplyPacket; + +- ASSERT(ClientId); +- ASSERT(LastReply); ++ ASSERT (ClientId); ++ ASSERT (LastReply); + + // + // Get the server Id from the last reply message. +@@ -1547,7 +1526,7 @@ Dhcp6SendReleaseMsg ( + return EFI_DEVICE_ERROR; + } + +- ServerId = (EFI_DHCP6_DUID *) (Option + 2); ++ ServerId = (EFI_DHCP6_DUID *)(Option + 2); + + // + // Create the Dhcp6 packet and initialize common fields. +@@ -1651,7 +1630,6 @@ ON_ERROR: + return Status; + } + +- + /** + Create the renew/rebind message and send it. + +@@ -1667,33 +1645,33 @@ ON_ERROR: + **/ + EFI_STATUS + Dhcp6SendRenewRebindMsg ( +- IN DHCP6_INSTANCE *Instance, +- IN BOOLEAN RebindRequest ++ IN DHCP6_INSTANCE *Instance, ++ IN BOOLEAN RebindRequest + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *Packet; +- EFI_DHCP6_PACKET *LastReply; +- EFI_DHCP6_PACKET_OPTION *UserOpt; +- EFI_DHCP6_DUID *ClientId; +- EFI_DHCP6_DUID *ServerId; +- EFI_DHCP6_STATE State; +- EFI_DHCP6_EVENT Event; +- DHCP6_SERVICE *Service; +- UINT8 *Option; +- UINT8 *Cursor; +- UINT16 *Elapsed; +- UINT32 UserLen; +- UINTN Index; +- UINT16 Length; +- +- ASSERT(Instance->Config); +- ASSERT(Instance->IaCb.Ia); ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_PACKET *LastReply; ++ EFI_DHCP6_PACKET_OPTION *UserOpt; ++ EFI_DHCP6_DUID *ClientId; ++ EFI_DHCP6_DUID *ServerId; ++ EFI_DHCP6_STATE State; ++ EFI_DHCP6_EVENT Event; ++ DHCP6_SERVICE *Service; ++ UINT8 *Option; ++ UINT8 *Cursor; ++ UINT16 *Elapsed; ++ UINT32 UserLen; ++ UINTN Index; ++ UINT16 Length; + +- Service = Instance->Service; +- ClientId = Service->ClientId; ++ ASSERT (Instance->Config); ++ ASSERT (Instance->IaCb.Ia); + +- ASSERT(ClientId); ++ Service = Instance->Service; ++ ClientId = Service->ClientId; ++ ++ ASSERT (ClientId); + + // + // Calculate the added length of customized option list. +@@ -1774,7 +1752,7 @@ Dhcp6SendRenewRebindMsg ( + goto ON_ERROR; + } + +- ServerId = (EFI_DHCP6_DUID *) (Option + 2); ++ ServerId = (EFI_DHCP6_DUID *)(Option + 2); + + Status = Dhcp6AppendOption ( + Packet, +@@ -1792,7 +1770,6 @@ Dhcp6SendRenewRebindMsg ( + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < Instance->Config->OptionCount; Index++) { +- + UserOpt = Instance->Config->OptionList[Index]; + Status = Dhcp6AppendOption ( + Packet, +@@ -1811,8 +1788,8 @@ Dhcp6SendRenewRebindMsg ( + // + // Callback to user with the packet to be sent and check the user's feedback. + // +- State = (RebindRequest) ? Dhcp6Rebinding : Dhcp6Renewing; +- Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing; ++ State = (RebindRequest) ? Dhcp6Rebinding : Dhcp6Renewing; ++ Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing; + + Status = Dhcp6CallbackUser (Instance, Event, &Packet); + if (EFI_ERROR (Status)) { +@@ -1885,19 +1862,19 @@ Dhcp6StartInfoRequest ( + IN VOID *CallbackContext OPTIONAL + ) + { +- EFI_STATUS Status; +- DHCP6_INF_CB *InfCb; +- DHCP6_SERVICE *Service; +- EFI_TPL OldTpl; ++ EFI_STATUS Status; ++ DHCP6_INF_CB *InfCb; ++ DHCP6_SERVICE *Service; ++ EFI_TPL OldTpl; + +- Service = Instance->Service; ++ Service = Instance->Service; + +- OldTpl = gBS->RaiseTPL (TPL_CALLBACK); ++ OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Instance->UdpSts = EFI_ALREADY_STARTED; + // + // Create and initialize the control block for the info-request. + // +- InfCb = AllocateZeroPool (sizeof(DHCP6_INF_CB)); ++ InfCb = AllocateZeroPool (sizeof (DHCP6_INF_CB)); + + if (InfCb == NULL) { + gBS->RestoreTPL (OldTpl); +@@ -1930,7 +1907,7 @@ Dhcp6StartInfoRequest ( + // + // Register receive callback for the stateless exchange process. + // +- Status = UdpIoRecvDatagram( ++ Status = UdpIoRecvDatagram ( + Service->UdpIo, + Dhcp6ReceivePacket, + Service, +@@ -1981,24 +1958,24 @@ Dhcp6SendInfoRequestMsg ( + IN EFI_DHCP6_RETRANSMISSION *Retransmission + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *Packet; +- EFI_DHCP6_PACKET_OPTION *UserOpt; +- EFI_DHCP6_DUID *ClientId; +- DHCP6_SERVICE *Service; +- UINT8 *Cursor; +- UINT16 *Elapsed; +- UINT32 UserLen; +- UINTN Index; +- UINT16 Length; +- +- ASSERT(OptionRequest); ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_PACKET_OPTION *UserOpt; ++ EFI_DHCP6_DUID *ClientId; ++ DHCP6_SERVICE *Service; ++ UINT8 *Cursor; ++ UINT16 *Elapsed; ++ UINT32 UserLen; ++ UINTN Index; ++ UINT16 Length; ++ ++ ASSERT (OptionRequest); + + Service = Instance->Service; + ClientId = Service->ClientId; + UserLen = NTOHS (OptionRequest->OpLen) + 4; + +- ASSERT(ClientId); ++ ASSERT (ClientId); + + // + // Calculate the added length of customized option list. +@@ -2021,7 +1998,7 @@ Dhcp6SendInfoRequestMsg ( + Packet->Dhcp6.Header.MessageType = Dhcp6MsgInfoRequest; + Packet->Dhcp6.Header.TransactionId = Service->Xid++; + +- InfCb->Xid = Packet->Dhcp6.Header.TransactionId; ++ InfCb->Xid = Packet->Dhcp6.Header.TransactionId; + + // + // Assembly Dhcp6 options for info-request message. +@@ -2067,7 +2044,6 @@ Dhcp6SendInfoRequestMsg ( + // Append user-defined when configurate Dhcp6 service. + // + for (Index = 0; Index < OptionCount; Index++) { +- + UserOpt = OptionList[Index]; + Status = Dhcp6AppendOption ( + Packet, +@@ -2110,7 +2086,6 @@ ON_ERROR: + return Status; + } + +- + /** + Create the Confirm message and send it. + +@@ -2124,19 +2099,19 @@ ON_ERROR: + **/ + EFI_STATUS + Dhcp6SendConfirmMsg ( +- IN DHCP6_INSTANCE *Instance ++ IN DHCP6_INSTANCE *Instance + ) + { +- UINT8 *Cursor; +- UINTN Index; +- UINT16 Length; +- UINT32 UserLen; +- EFI_STATUS Status; +- DHCP6_SERVICE *Service; +- EFI_DHCP6_DUID *ClientId; +- EFI_DHCP6_PACKET *Packet; +- EFI_DHCP6_PACKET_OPTION *UserOpt; +- UINT16 *Elapsed; ++ UINT8 *Cursor; ++ UINTN Index; ++ UINT16 Length; ++ UINT32 UserLen; ++ EFI_STATUS Status; ++ DHCP6_SERVICE *Service; ++ EFI_DHCP6_DUID *ClientId; ++ EFI_DHCP6_PACKET *Packet; ++ EFI_DHCP6_PACKET_OPTION *UserOpt; ++ UINT16 *Elapsed; + + ASSERT (Instance->Config != NULL); + ASSERT (Instance->IaCb.Ia != NULL); +@@ -2263,8 +2238,6 @@ ON_ERROR: + return Status; + } + +- +- + /** + Handle with the Dhcp6 reply message. + +@@ -2279,13 +2252,13 @@ ON_ERROR: + **/ + EFI_STATUS + Dhcp6HandleReplyMsg ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *Packet ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet + ) + { +- EFI_STATUS Status; +- UINT8 *Option; +- UINT16 StsCode; ++ EFI_STATUS Status; ++ UINT8 *Option; ++ UINT16 StsCode; + + ASSERT (Instance->Config != NULL); + ASSERT (Instance->IaCb.Ia != NULL); +@@ -2310,7 +2283,7 @@ Dhcp6HandleReplyMsg ( + Dhcp6OptRapidCommit + ); + +- if ((Option != NULL && !Instance->Config->RapidCommit) || (Option == NULL && Instance->Config->RapidCommit)) { ++ if (((Option != NULL) && !Instance->Config->RapidCommit) || ((Option == NULL) && Instance->Config->RapidCommit)) { + return EFI_DEVICE_ERROR; + } + +@@ -2318,11 +2291,11 @@ Dhcp6HandleReplyMsg ( + // As to a valid reply packet in response to a request/renew/rebind packet, + // ignore the packet if not contains the Ia option + // +- if (Instance->IaCb.Ia->State == Dhcp6Requesting || +- Instance->IaCb.Ia->State == Dhcp6Renewing || +- Instance->IaCb.Ia->State == Dhcp6Rebinding +- ) { +- ++ if ((Instance->IaCb.Ia->State == Dhcp6Requesting) || ++ (Instance->IaCb.Ia->State == Dhcp6Renewing) || ++ (Instance->IaCb.Ia->State == Dhcp6Rebinding) ++ ) ++ { + Option = Dhcp6SeekIaOption ( + Packet->Dhcp6.Option, + Packet->Length, +@@ -2347,10 +2320,9 @@ Dhcp6HandleReplyMsg ( + // the client considers the decline/release event completed regardless of the + // status code. + // +- if (Instance->IaCb.Ia->State == Dhcp6Declining || Instance->IaCb.Ia->State == Dhcp6Releasing) { +- ++ if ((Instance->IaCb.Ia->State == Dhcp6Declining) || (Instance->IaCb.Ia->State == Dhcp6Releasing)) { + if (Instance->IaCb.Ia->IaAddressCount != 0) { +- Instance->IaCb.Ia->State = Dhcp6Bound; ++ Instance->IaCb.Ia->State = Dhcp6Bound; + } else { + ASSERT (Instance->IaCb.Ia->ReplyPacket); + FreePool (Instance->IaCb.Ia->ReplyPacket); +@@ -2373,7 +2345,7 @@ Dhcp6HandleReplyMsg ( + // + // Reset start time for next exchange. + // +- Instance->StartTime = 0; ++ Instance->StartTime = 0; + + Status = EFI_SUCCESS; + goto ON_EXIT; +@@ -2400,7 +2372,7 @@ Dhcp6HandleReplyMsg ( + // + // Reset start time for next exchange. + // +- Instance->StartTime = 0; ++ Instance->StartTime = 0; + + // + // Set bound state and store the reply packet. +@@ -2423,7 +2395,7 @@ Dhcp6HandleReplyMsg ( + // + // For sync, set the success flag out of polling in start/renewrebind. + // +- Instance->UdpSts = EFI_SUCCESS; ++ Instance->UdpSts = EFI_SUCCESS; + + // + // Maybe this is a new round DHCP process due to some reason, such as NotOnLink +@@ -2449,70 +2421,72 @@ Dhcp6HandleReplyMsg ( + } + + goto ON_EXIT; +- + } else if (Option != NULL) { + // + // Any error status code option is found. + // + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option))))); + switch (StsCode) { +- case Dhcp6StsUnspecFail: +- // +- // It indicates the server is unable to process the message due to an +- // unspecified failure condition, so just retry if possible. +- // +- break; +- +- case Dhcp6StsUseMulticast: +- // +- // It indicates the server receives a message via unicast from a client +- // to which the server has not sent a unicast option, so retry it by +- // multi-cast address. +- // +- if (Instance->Unicast != NULL) { +- FreePool (Instance->Unicast); +- Instance->Unicast = NULL; +- } +- break; +- +- case Dhcp6StsNotOnLink: +- if (Instance->IaCb.Ia->State == Dhcp6Confirming) { ++ case Dhcp6StsUnspecFail: + // +- // Before initiate new round DHCP, cache the current IA. ++ // It indicates the server is unable to process the message due to an ++ // unspecified failure condition, so just retry if possible. + // +- Status = Dhcp6CacheIa (Instance); +- if (EFI_ERROR (Status)) { +- return Status; +- } ++ break; + ++ case Dhcp6StsUseMulticast: + // +- // Restart S.A.R.R process to acquire new address. ++ // It indicates the server receives a message via unicast from a client ++ // to which the server has not sent a unicast option, so retry it by ++ // multi-cast address. + // +- Status = Dhcp6InitSolicitMsg (Instance); +- if (EFI_ERROR (Status)) { +- return Status; ++ if (Instance->Unicast != NULL) { ++ FreePool (Instance->Unicast); ++ Instance->Unicast = NULL; + } +- } +- break; + +- case Dhcp6StsNoBinding: +- if (Instance->IaCb.Ia->State == Dhcp6Renewing || Instance->IaCb.Ia->State == Dhcp6Rebinding) { +- // +- // Refer to RFC3315 Chapter 18.1.8, for each IA in the original Renew or Rebind message, the client +- // sends a Request message if the IA contained a Status Code option with the NoBinding status. +- // +- Status = Dhcp6SendRequestMsg(Instance); +- if (EFI_ERROR (Status)) { +- return Status; ++ break; ++ ++ case Dhcp6StsNotOnLink: ++ if (Instance->IaCb.Ia->State == Dhcp6Confirming) { ++ // ++ // Before initiate new round DHCP, cache the current IA. ++ // ++ Status = Dhcp6CacheIa (Instance); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ ++ // ++ // Restart S.A.R.R process to acquire new address. ++ // ++ Status = Dhcp6InitSolicitMsg (Instance); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } + } +- } +- break; + +- default: +- // +- // The other status code, just restart solicitation. +- // +- break; ++ break; ++ ++ case Dhcp6StsNoBinding: ++ if ((Instance->IaCb.Ia->State == Dhcp6Renewing) || (Instance->IaCb.Ia->State == Dhcp6Rebinding)) { ++ // ++ // Refer to RFC3315 Chapter 18.1.8, for each IA in the original Renew or Rebind message, the client ++ // sends a Request message if the IA contained a Status Code option with the NoBinding status. ++ // ++ Status = Dhcp6SendRequestMsg (Instance); ++ if (EFI_ERROR (Status)) { ++ return Status; ++ } ++ } ++ ++ break; ++ ++ default: ++ // ++ // The other status code, just restart solicitation. ++ // ++ break; + } + } + +@@ -2520,7 +2494,7 @@ Dhcp6HandleReplyMsg ( + + ON_EXIT: + +- if (!EFI_ERROR(Status)) { ++ if (!EFI_ERROR (Status)) { + Status = Dhcp6DequeueRetry ( + Instance, + Packet->Dhcp6.Header.TransactionId, +@@ -2531,7 +2505,6 @@ ON_EXIT: + return Status; + } + +- + /** + Select the appointed Dhcp6 advertisement message. + +@@ -2545,12 +2518,12 @@ ON_EXIT: + **/ + EFI_STATUS + Dhcp6SelectAdvertiseMsg ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *AdSelect ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *AdSelect + ) + { +- EFI_STATUS Status; +- UINT8 *Option; ++ EFI_STATUS Status; ++ UINT8 *Option; + + ASSERT (AdSelect != NULL); + +@@ -2575,7 +2548,7 @@ Dhcp6SelectAdvertiseMsg ( + FALSE + ); + +- if (EFI_ERROR(Status)) { ++ if (EFI_ERROR (Status)) { + return Status; + } + +@@ -2583,15 +2556,14 @@ Dhcp6SelectAdvertiseMsg ( + // Check whether there is server unicast option in the selected advertise + // packet, and update it. + // +- Option = Dhcp6SeekOption( ++ Option = Dhcp6SeekOption ( + AdSelect->Dhcp6.Option, + AdSelect->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptServerUnicast + ); + + if (Option != NULL) { +- +- Instance->Unicast = AllocateZeroPool (sizeof(EFI_IPv6_ADDRESS)); ++ Instance->Unicast = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS)); + + if (Instance->Unicast == NULL) { + return EFI_OUT_OF_RESOURCES; +@@ -2615,7 +2587,6 @@ Dhcp6SelectAdvertiseMsg ( + return Dhcp6SendRequestMsg (Instance); + } + +- + /** + Handle with the Dhcp6 advertisement message. + +@@ -2630,16 +2601,16 @@ Dhcp6SelectAdvertiseMsg ( + **/ + EFI_STATUS + Dhcp6HandleAdvertiseMsg ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *Packet ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet + ) + { +- EFI_STATUS Status; +- UINT8 *Option; +- BOOLEAN Timeout; ++ EFI_STATUS Status; ++ UINT8 *Option; ++ BOOLEAN Timeout; + +- ASSERT(Instance->Config); +- ASSERT(Instance->IaCb.Ia); ++ ASSERT (Instance->Config); ++ ASSERT (Instance->IaCb.Ia); + + Timeout = FALSE; + +@@ -2649,14 +2620,13 @@ Dhcp6HandleAdvertiseMsg ( + // this reply message. Or else, process the advertise messages as normal. + // See details in the section-17.1.4 of rfc-3315. + // +- Option = Dhcp6SeekOption( ++ Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, + Packet->Length - sizeof (EFI_DHCP6_HEADER), + Dhcp6OptRapidCommit + ); + +- if (Option != NULL && Instance->Config->RapidCommit && Packet->Dhcp6.Header.MessageType == Dhcp6MsgReply) { +- ++ if ((Option != NULL) && Instance->Config->RapidCommit && (Packet->Dhcp6.Header.MessageType == Dhcp6MsgReply)) { + return Dhcp6HandleReplyMsg (Instance, Packet); + } + +@@ -2704,12 +2674,11 @@ Dhcp6HandleAdvertiseMsg ( + CopyMem (Instance->AdSelect, Packet, Packet->Size); + + Instance->AdPref = 0xff; +- + } else if (Status == EFI_NOT_READY) { + // + // Not_ready means user wants to continue to receive more advertise packets. + // +- if (Instance->AdPref == 0xff && Instance->AdSelect == NULL) { ++ if ((Instance->AdPref == 0xff) && (Instance->AdSelect == NULL)) { + // + // It's a tricky point. The timer routine set adpref as 0xff if the first + // rt timeout and no advertisement received, which means any advertisement +@@ -2722,13 +2691,13 @@ Dhcp6HandleAdvertiseMsg ( + // Check whether the current packet has a 255 preference option or not. + // Take non-preference option as 0 value. + // +- Option = Dhcp6SeekOption( ++ Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, + Packet->Length - 4, + Dhcp6OptPreference + ); + +- if (Instance->AdSelect == NULL || (Option != NULL && *(Option + 4) > Instance->AdPref)) { ++ if ((Instance->AdSelect == NULL) || ((Option != NULL) && (*(Option + 4) > Instance->AdPref))) { + // + // No advertisements received before or preference is more than other + // advertisements received before. Then store the new packet and the +@@ -2755,7 +2724,6 @@ Dhcp6HandleAdvertiseMsg ( + // preference is less than other advertisements received before. + // Leave the packet alone. + } +- + } else { + // + // Other error status means termination. +@@ -2768,14 +2736,13 @@ Dhcp6HandleAdvertiseMsg ( + // RT has elapsed, or get a highest preference 255 advertise. + // See details in the section-17.1.2 of rfc-3315. + // +- if (Instance->AdPref == 0xff || Timeout) { ++ if ((Instance->AdPref == 0xff) || Timeout) { + Status = Dhcp6SelectAdvertiseMsg (Instance, Instance->AdSelect); + } + + return Status; + } + +- + /** + The Dhcp6 stateful exchange process routine. + +@@ -2785,14 +2752,14 @@ Dhcp6HandleAdvertiseMsg ( + **/ + VOID + Dhcp6HandleStateful ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *Packet ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_DUID *ClientId; +- DHCP6_SERVICE *Service; +- UINT8 *Option; ++ EFI_STATUS Status; ++ EFI_DHCP6_DUID *ClientId; ++ DHCP6_SERVICE *Service; ++ UINT8 *Option; + + Service = Instance->Service; + ClientId = Service->ClientId; +@@ -2809,14 +2776,14 @@ Dhcp6HandleStateful ( + // + // Discard the packet if not advertisement or reply packet. + // +- if (Packet->Dhcp6.Header.MessageType != Dhcp6MsgAdvertise && Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply) { ++ if ((Packet->Dhcp6.Header.MessageType != Dhcp6MsgAdvertise) && (Packet->Dhcp6.Header.MessageType != Dhcp6MsgReply)) { + goto ON_CONTINUE; + } + + // + // Check whether include client Id or not. + // +- Option = Dhcp6SeekOption( ++ Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Dhcp6OptClientId +@@ -2829,7 +2796,7 @@ Dhcp6HandleStateful ( + // + // Check whether include server Id or not. + // +- Option = Dhcp6SeekOption( ++ Option = Dhcp6SeekOption ( + Packet->Dhcp6.Option, + Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN, + Dhcp6OptServerId +@@ -2840,35 +2807,36 @@ Dhcp6HandleStateful ( + } + + switch (Instance->IaCb.Ia->State) { +- case Dhcp6Selecting: +- // +- // Handle the advertisement message when in the Dhcp6Selecting state. +- // Do not need check return status, if failed, just continue to the next. +- // +- Dhcp6HandleAdvertiseMsg (Instance, Packet); +- break; +- +- case Dhcp6Requesting: +- case Dhcp6Confirming: +- case Dhcp6Renewing: +- case Dhcp6Rebinding: +- case Dhcp6Releasing: +- case Dhcp6Declining: +- // +- // Handle the reply message when in the Dhcp6Requesting, Dhcp6Renewing +- // Dhcp6Rebinding, Dhcp6Releasing and Dhcp6Declining state. +- // If failed here, it should reset the current session. +- // +- Status = Dhcp6HandleReplyMsg (Instance, Packet); +- if (EFI_ERROR (Status)) { +- goto ON_EXIT; +- } +- break; +- default: +- // +- // Other state has not supported yet. +- // +- break; ++ case Dhcp6Selecting: ++ // ++ // Handle the advertisement message when in the Dhcp6Selecting state. ++ // Do not need check return status, if failed, just continue to the next. ++ // ++ Dhcp6HandleAdvertiseMsg (Instance, Packet); ++ break; ++ ++ case Dhcp6Requesting: ++ case Dhcp6Confirming: ++ case Dhcp6Renewing: ++ case Dhcp6Rebinding: ++ case Dhcp6Releasing: ++ case Dhcp6Declining: ++ // ++ // Handle the reply message when in the Dhcp6Requesting, Dhcp6Renewing ++ // Dhcp6Rebinding, Dhcp6Releasing and Dhcp6Declining state. ++ // If failed here, it should reset the current session. ++ // ++ Status = Dhcp6HandleReplyMsg (Instance, Packet); ++ if (EFI_ERROR (Status)) { ++ goto ON_EXIT; ++ } ++ ++ break; ++ default: ++ // ++ // Other state has not supported yet. ++ // ++ break; + } + + ON_CONTINUE: +@@ -2887,7 +2855,6 @@ ON_EXIT: + } + } + +- + /** + The Dhcp6 stateless exchange process routine. + +@@ -2897,15 +2864,15 @@ ON_EXIT: + **/ + VOID + Dhcp6HandleStateless ( +- IN DHCP6_INSTANCE *Instance, +- IN EFI_DHCP6_PACKET *Packet ++ IN DHCP6_INSTANCE *Instance, ++ IN EFI_DHCP6_PACKET *Packet + ) + { +- EFI_STATUS Status; +- DHCP6_SERVICE *Service; +- DHCP6_INF_CB *InfCb; +- UINT8 *Option; +- BOOLEAN IsMatched; ++ EFI_STATUS Status; ++ DHCP6_SERVICE *Service; ++ DHCP6_INF_CB *InfCb; ++ UINT8 *Option; ++ BOOLEAN IsMatched; + + Service = Instance->Service; + Status = EFI_SUCCESS; +@@ -2990,7 +2957,6 @@ ON_EXIT: + } + } + +- + /** + The receive callback function for Dhcp6 exchange process. + +@@ -3003,37 +2969,37 @@ ON_EXIT: + VOID + EFIAPI + Dhcp6ReceivePacket ( +- IN NET_BUF *Udp6Wrap, +- IN UDP_END_POINT *EndPoint, +- IN EFI_STATUS IoStatus, +- IN VOID *Context ++ IN NET_BUF *Udp6Wrap, ++ IN UDP_END_POINT *EndPoint, ++ IN EFI_STATUS IoStatus, ++ IN VOID *Context + ) + { +- EFI_DHCP6_HEADER *Head; +- EFI_DHCP6_PACKET *Packet; +- DHCP6_SERVICE *Service; +- DHCP6_INSTANCE *Instance; +- DHCP6_TX_CB *TxCb; +- UINT32 Size; +- BOOLEAN IsDispatched; +- BOOLEAN IsStateless; +- LIST_ENTRY *Entry1; +- LIST_ENTRY *Next1; +- LIST_ENTRY *Entry2; +- LIST_ENTRY *Next2; +- EFI_STATUS Status; ++ EFI_DHCP6_HEADER *Head; ++ EFI_DHCP6_PACKET *Packet; ++ DHCP6_SERVICE *Service; ++ DHCP6_INSTANCE *Instance; ++ DHCP6_TX_CB *TxCb; ++ UINT32 Size; ++ BOOLEAN IsDispatched; ++ BOOLEAN IsStateless; ++ LIST_ENTRY *Entry1; ++ LIST_ENTRY *Next1; ++ LIST_ENTRY *Entry2; ++ LIST_ENTRY *Next2; ++ EFI_STATUS Status; + + ASSERT (Udp6Wrap != NULL); + ASSERT (Context != NULL); + +- Service = (DHCP6_SERVICE *) Context; ++ Service = (DHCP6_SERVICE *)Context; + Instance = NULL; + Packet = NULL; + IsDispatched = FALSE; + IsStateless = FALSE; + + if (EFI_ERROR (IoStatus)) { +- return ; ++ return; + } + + if (Udp6Wrap->TotalSize < sizeof (EFI_DHCP6_HEADER)) { +@@ -3044,7 +3010,7 @@ Dhcp6ReceivePacket ( + // Copy the net buffer received from upd6 to a Dhcp6 packet. + // + Size = sizeof (EFI_DHCP6_PACKET) + Udp6Wrap->TotalSize; +- Packet = (EFI_DHCP6_PACKET *) AllocateZeroPool (Size); ++ Packet = (EFI_DHCP6_PACKET *)AllocateZeroPool (Size); + + if (Packet == NULL) { + goto ON_CONTINUE; +@@ -3052,7 +3018,7 @@ Dhcp6ReceivePacket ( + + Packet->Size = Size; + Head = &Packet->Dhcp6.Header; +- Packet->Length = NetbufCopy (Udp6Wrap, 0, Udp6Wrap->TotalSize, (UINT8 *) Head); ++ Packet->Length = NetbufCopy (Udp6Wrap, 0, Udp6Wrap->TotalSize, (UINT8 *)Head); + + if (Packet->Length == 0) { + goto ON_CONTINUE; +@@ -3062,11 +3028,9 @@ Dhcp6ReceivePacket ( + // Dispatch packet to right instance by transaction id. + // + NET_LIST_FOR_EACH_SAFE (Entry1, Next1, &Service->Child) { +- + Instance = NET_LIST_USER_STRUCT (Entry1, DHCP6_INSTANCE, Link); + + NET_LIST_FOR_EACH_SAFE (Entry2, Next2, &Instance->TxList) { +- + TxCb = NET_LIST_USER_STRUCT (Entry2, DHCP6_TX_CB, Link); + + if (Packet->Dhcp6.Header.TransactionId == TxCb->Xid) { +@@ -3077,7 +3041,8 @@ Dhcp6ReceivePacket ( + if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) { + IsStateless = TRUE; + } +- IsDispatched = TRUE; ++ ++ IsDispatched = TRUE; + break; + } + } +@@ -3107,11 +3072,11 @@ ON_CONTINUE: + + if (!IsDispatched) { + Status = UdpIoRecvDatagram ( +- Service->UdpIo, +- Dhcp6ReceivePacket, +- Service, +- 0 +- ); ++ Service->UdpIo, ++ Dhcp6ReceivePacket, ++ Service, ++ 0 ++ ); + if (EFI_ERROR (Status)) { + NET_LIST_FOR_EACH_SAFE (Entry1, Next1, &Service->Child) { + Instance = NET_LIST_USER_STRUCT (Entry1, DHCP6_INSTANCE, Link); +@@ -3143,7 +3108,7 @@ ON_CONTINUE: + **/ + BOOLEAN + Dhcp6LinkMovDetect ( +- IN DHCP6_INSTANCE *Instance ++ IN DHCP6_INSTANCE *Instance + ) + { + UINT32 InterruptStatus; +@@ -3152,7 +3117,7 @@ Dhcp6LinkMovDetect ( + EFI_SIMPLE_NETWORK_PROTOCOL *Snp; + + ASSERT (Instance != NULL); +- Snp = Instance->Service->Snp; ++ Snp = Instance->Service->Snp; + MediaPresent = Instance->MediaPresent; + + // +@@ -3177,10 +3142,10 @@ Dhcp6LinkMovDetect ( + if (!MediaPresent && Instance->MediaPresent) { + return TRUE; + } ++ + return FALSE; + } + +- + /** + The timer routine of the Dhcp6 instance for each second. + +@@ -3191,28 +3156,27 @@ Dhcp6LinkMovDetect ( + VOID + EFIAPI + Dhcp6OnTimerTick ( +- IN EFI_EVENT Event, +- IN VOID *Context ++ IN EFI_EVENT Event, ++ IN VOID *Context + ) + { +- LIST_ENTRY *Entry; +- LIST_ENTRY *NextEntry; +- DHCP6_INSTANCE *Instance; +- DHCP6_TX_CB *TxCb; +- DHCP6_IA_CB *IaCb; +- UINT32 LossTime; +- EFI_STATUS Status; ++ LIST_ENTRY *Entry; ++ LIST_ENTRY *NextEntry; ++ DHCP6_INSTANCE *Instance; ++ DHCP6_TX_CB *TxCb; ++ DHCP6_IA_CB *IaCb; ++ UINT32 LossTime; ++ EFI_STATUS Status; + + ASSERT (Context != NULL); + +- Instance = (DHCP6_INSTANCE *) Context; ++ Instance = (DHCP6_INSTANCE *)Context; + + // + // 1. Loop the tx list, count live time of every tx packet to check whether + // need re-transmit or not. + // + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->TxList) { +- + TxCb = NET_LIST_USER_STRUCT (Entry, DHCP6_TX_CB, Link); + + TxCb->TickTime++; +@@ -3221,7 +3185,7 @@ Dhcp6OnTimerTick ( + // + // Handle the first rt in the transmission of solicit specially. + // +- if ((TxCb->RetryCnt == 0 || TxCb->SolicitRetry) && TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) { ++ if (((TxCb->RetryCnt == 0) || TxCb->SolicitRetry) && (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit)) { + if (Instance->AdSelect == NULL) { + // + // Set adpref as 0xff here to indicate select any advertisement +@@ -3238,9 +3202,11 @@ Dhcp6OnTimerTick ( + } else if (EFI_ERROR (Status)) { + TxCb->RetryCnt++; + } ++ + return; + } + } ++ + // + // Increase the retry count for the packet and add up the total loss time. + // +@@ -3250,7 +3216,7 @@ Dhcp6OnTimerTick ( + // + // Check whether overflow the max retry count limit for this packet + // +- if (TxCb->RetryCtl.Mrc != 0 && TxCb->RetryCtl.Mrc < TxCb->RetryCnt) { ++ if ((TxCb->RetryCtl.Mrc != 0) && (TxCb->RetryCtl.Mrc < TxCb->RetryCnt)) { + Status = EFI_NO_RESPONSE; + goto ON_CLOSE; + } +@@ -3258,7 +3224,7 @@ Dhcp6OnTimerTick ( + // + // Check whether overflow the max retry duration for this packet + // +- if (TxCb->RetryCtl.Mrd != 0 && TxCb->RetryCtl.Mrd <= TxCb->RetryLos) { ++ if ((TxCb->RetryCtl.Mrd != 0) && (TxCb->RetryCtl.Mrd <= TxCb->RetryLos)) { + Status = EFI_NO_RESPONSE; + goto ON_CLOSE; + } +@@ -3275,7 +3241,7 @@ Dhcp6OnTimerTick ( + TRUE + ); + +- if (TxCb->RetryCtl.Mrt != 0 && TxCb->RetryCtl.Mrt < TxCb->RetryExp) { ++ if ((TxCb->RetryCtl.Mrt != 0) && (TxCb->RetryCtl.Mrt < TxCb->RetryExp)) { + TxCb->RetryExp = Dhcp6CalculateExpireTime ( + TxCb->RetryCtl.Mrt, + TRUE, +@@ -3288,7 +3254,7 @@ Dhcp6OnTimerTick ( + // duration time. + // + LossTime = TxCb->RetryLos + TxCb->RetryExp; +- if (TxCb->RetryCtl.Mrd != 0 && TxCb->RetryCtl.Mrd < LossTime) { ++ if ((TxCb->RetryCtl.Mrd != 0) && (TxCb->RetryCtl.Mrd < LossTime)) { + TxCb->RetryExp = TxCb->RetryCtl.Mrd - TxCb->RetryLos; + } + +@@ -3314,22 +3280,19 @@ Dhcp6OnTimerTick ( + // + IaCb = &Instance->IaCb; + +- if (Instance->Config == NULL || IaCb->Ia == NULL) { ++ if ((Instance->Config == NULL) || (IaCb->Ia == NULL)) { + return; + } + +- if (IaCb->Ia->State == Dhcp6Bound || IaCb->Ia->State == Dhcp6Renewing || IaCb->Ia->State == Dhcp6Rebinding) { +- ++ if ((IaCb->Ia->State == Dhcp6Bound) || (IaCb->Ia->State == Dhcp6Renewing) || (IaCb->Ia->State == Dhcp6Rebinding)) { + IaCb->LeaseTime++; + +- if (IaCb->LeaseTime > IaCb->T2 && IaCb->Ia->State == Dhcp6Bound) { ++ if ((IaCb->LeaseTime > IaCb->T2) && (IaCb->Ia->State == Dhcp6Bound)) { + // + // Exceed t2, send rebind packet to extend the Ia lease. + // + Dhcp6SendRenewRebindMsg (Instance, TRUE); +- +- } else if (IaCb->LeaseTime > IaCb->T1 && IaCb->Ia->State == Dhcp6Bound) { +- ++ } else if ((IaCb->LeaseTime > IaCb->T1) && (IaCb->Ia->State == Dhcp6Bound)) { + // + // Exceed t1, send renew packet to extend the Ia lease. + // +@@ -3347,28 +3310,32 @@ Dhcp6OnTimerTick ( + + return; + +- ON_CLOSE: ++ON_CLOSE: + + if (Dhcp6IsValidTxCb (Instance, TxCb) && +- TxCb->TxPacket != NULL && +- (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest || +- TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgRenew || +- TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgConfirm) +- ) { ++ (TxCb->TxPacket != NULL) && ++ ((TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) || ++ (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgRenew) || ++ (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgConfirm)) ++ ) ++ { + // + // The failure of renew/Confirm will still switch to the bound state. + // + if ((TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgRenew) || +- (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgConfirm)) { ++ (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgConfirm)) ++ { + ASSERT (Instance->IaCb.Ia); + Instance->IaCb.Ia->State = Dhcp6Bound; + } ++ + // + // The failure of info-request will return no response. + // + if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgInfoRequest) { + Instance->UdpSts = EFI_NO_RESPONSE; + } ++ + Dhcp6DequeueRetry ( + Instance, + TxCb->Xid, +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Apply-uncrustify-changes.patch b/edk2-NetworkPkg-Apply-uncrustify-changes.patch new file mode 100644 index 0000000..2bf3ddf --- /dev/null +++ b/edk2-NetworkPkg-Apply-uncrustify-changes.patch @@ -0,0 +1,1937 @@ +From daa72dcc870f9488f2afccdaa2341f24b1269abc Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 15:22:22 -0500 +Subject: [PATCH 06/15] NetworkPkg: Apply uncrustify changes + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [6/15] 823604dd0cad46a8ae5796cde6d1683aa23f1be5 + +JIRA: https://issues.redhat.com/browse/RHEL-21850 +CVE: CVE-2022-45234 +Upstream: Merged +Conflicts: This patch is too intrusive to apply at once in its entirety, + but we can apply a subset touching only the file being + targeted in the next commit in this series. + This way, that commit applies cleanly. + +commit d1050b9dff1cace252aff86630bfdb59dff5f507 +Author: Michael Kubacki +Date: Sun Dec 5 14:54:07 2021 -0800 + + NetworkPkg: Apply uncrustify changes + + REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 + + Apply uncrustify changes to .c/.h files in the NetworkPkg package + + Cc: Andrew Fish + Cc: Leif Lindholm + Cc: Michael D Kinney + Signed-off-by: Michael Kubacki + Reviewed-by: Maciej Rabeda + +Signed-off-by: Jon Maloy +--- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 973 ++++++++++++++------------- + 1 file changed, 498 insertions(+), 475 deletions(-) + +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +index 8d71143b79..425e0cf806 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +@@ -15,7 +15,9 @@ + // + // ALL_DHCP_Relay_Agents_and_Servers address: FF02::1:2 + // +-EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = {{0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2}}; ++EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = { ++ { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 } ++}; + + /** + Parse out a DHCPv6 option by OptTag, and find the position in buffer. +@@ -30,35 +32,32 @@ EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = {{0xFF, 2, 0, 0, 0, 0, 0, 0, + **/ + EFI_DHCP6_PACKET_OPTION * + PxeBcParseDhcp6Options ( +- IN UINT8 *Buffer, +- IN UINT32 Length, +- IN UINT16 OptTag ++ IN UINT8 *Buffer, ++ IN UINT32 Length, ++ IN UINT16 OptTag + ) + { +- EFI_DHCP6_PACKET_OPTION *Option; +- UINT32 Offset; ++ EFI_DHCP6_PACKET_OPTION *Option; ++ UINT32 Offset; + +- Option = (EFI_DHCP6_PACKET_OPTION *) Buffer; +- Offset = 0; ++ Option = (EFI_DHCP6_PACKET_OPTION *)Buffer; ++ Offset = 0; + + // + // OpLen and OpCode here are both stored in network order. + // + while (Offset < Length) { +- + if (NTOHS (Option->OpCode) == OptTag) { +- + return Option; + } + +- Offset += (NTOHS(Option->OpLen) + 4); +- Option = (EFI_DHCP6_PACKET_OPTION *) (Buffer + Offset); ++ Offset += (NTOHS (Option->OpLen) + 4); ++ Option = (EFI_DHCP6_PACKET_OPTION *)(Buffer + Offset); + } + + return NULL; + } + +- + /** + Build the options buffer for the DHCPv6 request packet. + +@@ -71,70 +70,70 @@ PxeBcParseDhcp6Options ( + **/ + UINT32 + PxeBcBuildDhcp6Options ( +- IN PXEBC_PRIVATE_DATA *Private, +- OUT EFI_DHCP6_PACKET_OPTION **OptList, +- IN UINT8 *Buffer ++ IN PXEBC_PRIVATE_DATA *Private, ++ OUT EFI_DHCP6_PACKET_OPTION **OptList, ++ IN UINT8 *Buffer + ) + { +- PXEBC_DHCP6_OPTION_ENTRY OptEnt; +- UINT32 Index; +- UINT16 Value; ++ PXEBC_DHCP6_OPTION_ENTRY OptEnt; ++ UINT32 Index; ++ UINT16 Value; + +- Index = 0; +- OptList[0] = (EFI_DHCP6_PACKET_OPTION *) Buffer; ++ Index = 0; ++ OptList[0] = (EFI_DHCP6_PACKET_OPTION *)Buffer; + + // + // Append client option request option + // +- OptList[Index]->OpCode = HTONS (DHCP6_OPT_ORO); +- OptList[Index]->OpLen = HTONS (8); +- OptEnt.Oro = (PXEBC_DHCP6_OPTION_ORO *) OptList[Index]->Data; +- OptEnt.Oro->OpCode[0] = HTONS(DHCP6_OPT_BOOT_FILE_URL); +- OptEnt.Oro->OpCode[1] = HTONS(DHCP6_OPT_BOOT_FILE_PARAM); +- OptEnt.Oro->OpCode[2] = HTONS(DHCP6_OPT_DNS_SERVERS); +- OptEnt.Oro->OpCode[3] = HTONS(DHCP6_OPT_VENDOR_CLASS); ++ OptList[Index]->OpCode = HTONS (DHCP6_OPT_ORO); ++ OptList[Index]->OpLen = HTONS (8); ++ OptEnt.Oro = (PXEBC_DHCP6_OPTION_ORO *)OptList[Index]->Data; ++ OptEnt.Oro->OpCode[0] = HTONS (DHCP6_OPT_BOOT_FILE_URL); ++ OptEnt.Oro->OpCode[1] = HTONS (DHCP6_OPT_BOOT_FILE_PARAM); ++ OptEnt.Oro->OpCode[2] = HTONS (DHCP6_OPT_DNS_SERVERS); ++ OptEnt.Oro->OpCode[3] = HTONS (DHCP6_OPT_VENDOR_CLASS); + Index++; +- OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]); ++ OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]); + + // + // Append client network device interface option + // +- OptList[Index]->OpCode = HTONS (DHCP6_OPT_UNDI); +- OptList[Index]->OpLen = HTONS ((UINT16)3); +- OptEnt.Undi = (PXEBC_DHCP6_OPTION_UNDI *) OptList[Index]->Data; ++ OptList[Index]->OpCode = HTONS (DHCP6_OPT_UNDI); ++ OptList[Index]->OpLen = HTONS ((UINT16)3); ++ OptEnt.Undi = (PXEBC_DHCP6_OPTION_UNDI *)OptList[Index]->Data; + + if (Private->Nii != NULL) { +- OptEnt.Undi->Type = Private->Nii->Type; +- OptEnt.Undi->MajorVer = Private->Nii->MajorVer; +- OptEnt.Undi->MinorVer = Private->Nii->MinorVer; ++ OptEnt.Undi->Type = Private->Nii->Type; ++ OptEnt.Undi->MajorVer = Private->Nii->MajorVer; ++ OptEnt.Undi->MinorVer = Private->Nii->MinorVer; + } else { +- OptEnt.Undi->Type = DEFAULT_UNDI_TYPE; +- OptEnt.Undi->MajorVer = DEFAULT_UNDI_MAJOR; +- OptEnt.Undi->MinorVer = DEFAULT_UNDI_MINOR; ++ OptEnt.Undi->Type = DEFAULT_UNDI_TYPE; ++ OptEnt.Undi->MajorVer = DEFAULT_UNDI_MAJOR; ++ OptEnt.Undi->MinorVer = DEFAULT_UNDI_MINOR; + } + + Index++; +- OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]); ++ OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]); + + // + // Append client system architecture option + // +- OptList[Index]->OpCode = HTONS (DHCP6_OPT_ARCH); +- OptList[Index]->OpLen = HTONS ((UINT16) sizeof (PXEBC_DHCP6_OPTION_ARCH)); +- OptEnt.Arch = (PXEBC_DHCP6_OPTION_ARCH *) OptList[Index]->Data; +- Value = HTONS (EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE); ++ OptList[Index]->OpCode = HTONS (DHCP6_OPT_ARCH); ++ OptList[Index]->OpLen = HTONS ((UINT16)sizeof (PXEBC_DHCP6_OPTION_ARCH)); ++ OptEnt.Arch = (PXEBC_DHCP6_OPTION_ARCH *)OptList[Index]->Data; ++ Value = HTONS (EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE); + CopyMem (&OptEnt.Arch->Type, &Value, sizeof (UINT16)); + Index++; +- OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]); ++ OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]); + + // + // Append vendor class option to store the PXE class identifier. + // + OptList[Index]->OpCode = HTONS (DHCP6_OPT_VENDOR_CLASS); +- OptList[Index]->OpLen = HTONS ((UINT16) sizeof (PXEBC_DHCP6_OPTION_VENDOR_CLASS)); +- OptEnt.VendorClass = (PXEBC_DHCP6_OPTION_VENDOR_CLASS *) OptList[Index]->Data; ++ OptList[Index]->OpLen = HTONS ((UINT16)sizeof (PXEBC_DHCP6_OPTION_VENDOR_CLASS)); ++ OptEnt.VendorClass = (PXEBC_DHCP6_OPTION_VENDOR_CLASS *)OptList[Index]->Data; + OptEnt.VendorClass->Vendor = HTONL (PXEBC_DHCP6_ENTERPRISE_NUM); +- OptEnt.VendorClass->ClassLen = HTONS ((UINT16) sizeof (PXEBC_CLASS_ID)); ++ OptEnt.VendorClass->ClassLen = HTONS ((UINT16)sizeof (PXEBC_CLASS_ID)); + CopyMem ( + &OptEnt.VendorClass->ClassId, + DEFAULT_CLASS_ID_DATA, +@@ -169,7 +168,6 @@ PxeBcBuildDhcp6Options ( + return Index; + } + +- + /** + Cache the DHCPv6 packet. + +@@ -182,8 +180,8 @@ PxeBcBuildDhcp6Options ( + **/ + EFI_STATUS + PxeBcCacheDhcp6Packet ( +- IN EFI_DHCP6_PACKET *Dst, +- IN EFI_DHCP6_PACKET *Src ++ IN EFI_DHCP6_PACKET *Dst, ++ IN EFI_DHCP6_PACKET *Src + ) + { + if (Dst->Size < Src->Length) { +@@ -211,22 +209,22 @@ PxeBcCacheDhcp6Packet ( + **/ + EFI_STATUS + PxeBcDns6 ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN CHAR16 *HostName, +- OUT EFI_IPv6_ADDRESS *IpAddress ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN CHAR16 *HostName, ++ OUT EFI_IPv6_ADDRESS *IpAddress + ) + { +- EFI_STATUS Status; +- EFI_DNS6_PROTOCOL *Dns6; +- EFI_DNS6_CONFIG_DATA Dns6ConfigData; +- EFI_DNS6_COMPLETION_TOKEN Token; +- EFI_HANDLE Dns6Handle; +- EFI_IPv6_ADDRESS *DnsServerList; +- BOOLEAN IsDone; +- +- Dns6 = NULL; +- Dns6Handle = NULL; +- DnsServerList = Private->DnsServer; ++ EFI_STATUS Status; ++ EFI_DNS6_PROTOCOL *Dns6; ++ EFI_DNS6_CONFIG_DATA Dns6ConfigData; ++ EFI_DNS6_COMPLETION_TOKEN Token; ++ EFI_HANDLE Dns6Handle; ++ EFI_IPv6_ADDRESS *DnsServerList; ++ BOOLEAN IsDone; ++ ++ Dns6 = NULL; ++ Dns6Handle = NULL; ++ DnsServerList = Private->DnsServer; + ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN)); + + // +@@ -245,7 +243,7 @@ PxeBcDns6 ( + Status = gBS->OpenProtocol ( + Dns6Handle, + &gEfiDns6ProtocolGuid, +- (VOID **) &Dns6, ++ (VOID **)&Dns6, + Private->Image, + Private->Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER +@@ -308,10 +306,12 @@ PxeBcDns6 ( + Status = EFI_DEVICE_ERROR; + goto Exit; + } +- if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) { ++ ++ if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) { + Status = EFI_DEVICE_ERROR; + goto Exit; + } ++ + // + // We just return the first IPv6 address from DNS protocol. + // +@@ -325,10 +325,12 @@ Exit: + if (Token.Event != NULL) { + gBS->CloseEvent (Token.Event); + } ++ + if (Token.RspData.H2AData != NULL) { + if (Token.RspData.H2AData->IpList != NULL) { + FreePool (Token.RspData.H2AData->IpList); + } ++ + FreePool (Token.RspData.H2AData); + } + +@@ -375,26 +377,26 @@ Exit: + **/ + EFI_STATUS + PxeBcExtractBootFileUrl ( +- IN PXEBC_PRIVATE_DATA *Private, +- OUT UINT8 **FileName, +- IN OUT EFI_IPv6_ADDRESS *SrvAddr, +- IN CHAR8 *BootFile, +- IN UINT16 Length ++ IN PXEBC_PRIVATE_DATA *Private, ++ OUT UINT8 **FileName, ++ IN OUT EFI_IPv6_ADDRESS *SrvAddr, ++ IN CHAR8 *BootFile, ++ IN UINT16 Length + ) + { +- UINT16 PrefixLen; +- CHAR8 *BootFileNamePtr; +- CHAR8 *BootFileName; +- UINT16 BootFileNameLen; +- CHAR8 *TmpStr; +- CHAR8 TmpChar; +- CHAR8 *ServerAddressOption; +- CHAR8 *ServerAddress; +- CHAR8 *ModeStr; +- CHAR16 *HostName; +- BOOLEAN IpExpressedUrl; +- UINTN Len; +- EFI_STATUS Status; ++ UINT16 PrefixLen; ++ CHAR8 *BootFileNamePtr; ++ CHAR8 *BootFileName; ++ UINT16 BootFileNameLen; ++ CHAR8 *TmpStr; ++ CHAR8 TmpChar; ++ CHAR8 *ServerAddressOption; ++ CHAR8 *ServerAddress; ++ CHAR8 *ModeStr; ++ CHAR16 *HostName; ++ BOOLEAN IpExpressedUrl; ++ UINTN Len; ++ EFI_STATUS Status; + + IpExpressedUrl = TRUE; + // +@@ -417,17 +419,18 @@ PxeBcExtractBootFileUrl ( + // As an example where the BOOTFILE_NAME is the EFI loader and + // SERVER_ADDRESS is the ASCII encoding of an IPV6 address. + // +- PrefixLen = (UINT16) AsciiStrLen (PXEBC_DHCP6_BOOT_FILE_URL_PREFIX); ++ PrefixLen = (UINT16)AsciiStrLen (PXEBC_DHCP6_BOOT_FILE_URL_PREFIX); + +- if (Length <= PrefixLen || +- CompareMem (BootFile, PXEBC_DHCP6_BOOT_FILE_URL_PREFIX, PrefixLen) != 0) { ++ if ((Length <= PrefixLen) || ++ (CompareMem (BootFile, PXEBC_DHCP6_BOOT_FILE_URL_PREFIX, PrefixLen) != 0)) ++ { + return EFI_NOT_FOUND; + } + + BootFile = BootFile + PrefixLen; +- Length = (UINT16) (Length - PrefixLen); ++ Length = (UINT16)(Length - PrefixLen); + +- TmpStr = (CHAR8 *) AllocateZeroPool (Length + 1); ++ TmpStr = (CHAR8 *)AllocateZeroPool (Length + 1); + if (TmpStr == NULL) { + return EFI_OUT_OF_RESOURCES; + } +@@ -440,7 +443,7 @@ PxeBcExtractBootFileUrl ( + // + ServerAddressOption = TmpStr; + if (*ServerAddressOption == PXEBC_ADDR_START_DELIMITER) { +- ServerAddressOption ++; ++ ServerAddressOption++; + ServerAddress = ServerAddressOption; + while (*ServerAddress != '\0' && *ServerAddress != PXEBC_ADDR_END_DELIMITER) { + ServerAddress++; +@@ -461,10 +464,9 @@ PxeBcExtractBootFileUrl ( + FreePool (TmpStr); + return Status; + } +- + } else { + IpExpressedUrl = FALSE; +- ServerAddress = ServerAddressOption; ++ ServerAddress = ServerAddressOption; + while (*ServerAddress != '\0' && *ServerAddress != PXEBC_TFTP_URL_SEPARATOR) { + ServerAddress++; + } +@@ -473,14 +475,16 @@ PxeBcExtractBootFileUrl ( + FreePool (TmpStr); + return EFI_INVALID_PARAMETER; + } ++ + *ServerAddress = '\0'; + +- Len = AsciiStrSize (ServerAddressOption); ++ Len = AsciiStrSize (ServerAddressOption); + HostName = AllocateZeroPool (Len * sizeof (CHAR16)); + if (HostName == NULL) { + FreePool (TmpStr); + return EFI_OUT_OF_RESOURCES; + } ++ + AsciiStrToUnicodeStrS ( + ServerAddressOption, + HostName, +@@ -490,7 +494,7 @@ PxeBcExtractBootFileUrl ( + // + // Perform DNS resolution. + // +- Status = PxeBcDns6 (Private,HostName, SrvAddr); ++ Status = PxeBcDns6 (Private, HostName, SrvAddr); + if (EFI_ERROR (Status)) { + FreePool (TmpStr); + return Status; +@@ -500,23 +504,24 @@ PxeBcExtractBootFileUrl ( + // + // Get the part of BOOTFILE_NAME string. + // +- BootFileNamePtr = (CHAR8*)((UINTN)ServerAddress + 1); ++ BootFileNamePtr = (CHAR8 *)((UINTN)ServerAddress + 1); + if (IpExpressedUrl) { + if (*BootFileNamePtr != PXEBC_TFTP_URL_SEPARATOR) { + FreePool (TmpStr); + return EFI_INVALID_PARAMETER; + } ++ + ++BootFileNamePtr; + } + +- BootFileNameLen = (UINT16)(Length - (UINT16) ((UINTN)BootFileNamePtr - (UINTN)TmpStr) + 1); +- if (BootFileNameLen != 0 || FileName != NULL) { ++ BootFileNameLen = (UINT16)(Length - (UINT16)((UINTN)BootFileNamePtr - (UINTN)TmpStr) + 1); ++ if ((BootFileNameLen != 0) || (FileName != NULL)) { + // + // Remove trailing mode=octet if present and ignore. All other modes are + // invalid for netboot6, so reject them. + // + ModeStr = AsciiStrStr (BootFileNamePtr, ";mode=octet"); +- if (ModeStr != NULL && *(ModeStr + AsciiStrLen (";mode=octet")) == '\0') { ++ if ((ModeStr != NULL) && (*(ModeStr + AsciiStrLen (";mode=octet")) == '\0')) { + *ModeStr = '\0'; + } else if (AsciiStrStr (BootFileNamePtr, ";mode=") != NULL) { + FreePool (TmpStr); +@@ -526,30 +531,32 @@ PxeBcExtractBootFileUrl ( + // + // Extract boot file name from URL. + // +- BootFileName = (CHAR8 *) AllocateZeroPool (BootFileNameLen); ++ BootFileName = (CHAR8 *)AllocateZeroPool (BootFileNameLen); + if (BootFileName == NULL) { + FreePool (TmpStr); + return EFI_OUT_OF_RESOURCES; + } +- *FileName = (UINT8*) BootFileName; ++ ++ *FileName = (UINT8 *)BootFileName; + + // + // Decode percent-encoding in boot file name. + // + while (*BootFileNamePtr != '\0') { + if (*BootFileNamePtr == '%') { +- TmpChar = *(BootFileNamePtr+ 3); ++ TmpChar = *(BootFileNamePtr+ 3); + *(BootFileNamePtr+ 3) = '\0'; +- *BootFileName = (UINT8) AsciiStrHexToUintn ((CHAR8*)(BootFileNamePtr + 1)); ++ *BootFileName = (UINT8)AsciiStrHexToUintn ((CHAR8 *)(BootFileNamePtr + 1)); + BootFileName++; + *(BootFileNamePtr+ 3) = TmpChar; +- BootFileNamePtr += 3; ++ BootFileNamePtr += 3; + } else { + *BootFileName = *BootFileNamePtr; + BootFileName++; + BootFileNamePtr++; + } + } ++ + *BootFileName = '\0'; + } + +@@ -558,7 +565,6 @@ PxeBcExtractBootFileUrl ( + return EFI_SUCCESS; + } + +- + /** + Parse the Boot File Parameter option. + +@@ -571,14 +577,14 @@ PxeBcExtractBootFileUrl ( + **/ + EFI_STATUS + PxeBcExtractBootFileParam ( +- IN CHAR8 *BootFilePara, +- OUT UINT16 *BootFileSize ++ IN CHAR8 *BootFilePara, ++ OUT UINT16 *BootFileSize + ) + { +- UINT16 Length; +- UINT8 Index; +- UINT8 Digit; +- UINT32 Size; ++ UINT16 Length; ++ UINT8 Index; ++ UINT8 Digit; ++ UINT32 Size; + + CopyMem (&Length, BootFilePara, sizeof (UINT16)); + Length = NTOHS (Length); +@@ -586,7 +592,7 @@ PxeBcExtractBootFileParam ( + // + // The BootFile Size should be 1~5 byte ASCII strings + // +- if (Length < 1 || Length > 5) { ++ if ((Length < 1) || (Length > 5)) { + return EFI_NOT_FOUND; + } + +@@ -608,11 +614,10 @@ PxeBcExtractBootFileParam ( + return EFI_NOT_FOUND; + } + +- *BootFileSize = (UINT16) Size; ++ *BootFileSize = (UINT16)Size; + return EFI_SUCCESS; + } + +- + /** + Parse the cached DHCPv6 packet, including all the options. + +@@ -627,15 +632,15 @@ PxeBcParseDhcp6Packet ( + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 + ) + { +- EFI_DHCP6_PACKET *Offer; +- EFI_DHCP6_PACKET_OPTION **Options; +- EFI_DHCP6_PACKET_OPTION *Option; +- PXEBC_OFFER_TYPE OfferType; +- BOOLEAN IsProxyOffer; +- BOOLEAN IsPxeOffer; +- UINT32 Offset; +- UINT32 Length; +- UINT32 EnterpriseNum; ++ EFI_DHCP6_PACKET *Offer; ++ EFI_DHCP6_PACKET_OPTION **Options; ++ EFI_DHCP6_PACKET_OPTION *Option; ++ PXEBC_OFFER_TYPE OfferType; ++ BOOLEAN IsProxyOffer; ++ BOOLEAN IsPxeOffer; ++ UINT32 Offset; ++ UINT32 Length; ++ UINT32 EnterpriseNum; + + IsProxyOffer = TRUE; + IsPxeOffer = FALSE; +@@ -644,15 +649,14 @@ PxeBcParseDhcp6Packet ( + + ZeroMem (Cache6->OptList, sizeof (Cache6->OptList)); + +- Option = (EFI_DHCP6_PACKET_OPTION *) (Offer->Dhcp6.Option); +- Offset = 0; +- Length = GET_DHCP6_OPTION_SIZE (Offer); ++ Option = (EFI_DHCP6_PACKET_OPTION *)(Offer->Dhcp6.Option); ++ Offset = 0; ++ Length = GET_DHCP6_OPTION_SIZE (Offer); + + // + // OpLen and OpCode here are both stored in network order, since they are from original packet. + // + while (Offset < Length) { +- + if (NTOHS (Option->OpCode) == DHCP6_OPT_IA_NA) { + Options[PXEBC_DHCP6_IDX_IA_NA] = Option; + } else if (NTOHS (Option->OpCode) == DHCP6_OPT_BOOT_FILE_URL) { +@@ -669,7 +673,7 @@ PxeBcParseDhcp6Packet ( + } + + Offset += (NTOHS (Option->OpLen) + 4); +- Option = (EFI_DHCP6_PACKET_OPTION *) (Offer->Dhcp6.Option + Offset); ++ Option = (EFI_DHCP6_PACKET_OPTION *)(Offer->Dhcp6.Option + Offset); + } + + // +@@ -683,7 +687,7 @@ PxeBcParseDhcp6Packet ( + NTOHS (Option->OpLen), + DHCP6_OPT_STATUS_CODE + ); +- if ((Option != NULL && Option->Data[0] == 0) || (Option == NULL)) { ++ if (((Option != NULL) && (Option->Data[0] == 0)) || (Option == NULL)) { + IsProxyOffer = FALSE; + } + } +@@ -692,12 +696,13 @@ PxeBcParseDhcp6Packet ( + // The offer with "PXEClient" is a pxe offer. + // + Option = Options[PXEBC_DHCP6_IDX_VENDOR_CLASS]; +- EnterpriseNum = HTONL(PXEBC_DHCP6_ENTERPRISE_NUM); ++ EnterpriseNum = HTONL (PXEBC_DHCP6_ENTERPRISE_NUM); + +- if (Option != NULL && +- NTOHS(Option->OpLen) >= 13 && +- CompareMem (Option->Data, &EnterpriseNum, sizeof (UINT32)) == 0 && +- CompareMem (&Option->Data[6], DEFAULT_CLASS_ID_DATA, 9) == 0) { ++ if ((Option != NULL) && ++ (NTOHS (Option->OpLen) >= 13) && ++ (CompareMem (Option->Data, &EnterpriseNum, sizeof (UINT32)) == 0) && ++ (CompareMem (&Option->Data[6], DEFAULT_CLASS_ID_DATA, 9) == 0)) ++ { + IsPxeOffer = TRUE; + } + +@@ -721,7 +726,6 @@ PxeBcParseDhcp6Packet ( + return EFI_SUCCESS; + } + +- + /** + Cache the DHCPv6 ack packet, and parse it on demand. + +@@ -735,9 +739,9 @@ PxeBcParseDhcp6Packet ( + **/ + EFI_STATUS + PxeBcCopyDhcp6Ack ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN EFI_DHCP6_PACKET *Ack, +- IN BOOLEAN Verified ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN EFI_DHCP6_PACKET *Ack, ++ IN BOOLEAN Verified + ) + { + EFI_PXE_BASE_CODE_MODE *Mode; +@@ -762,7 +766,6 @@ PxeBcCopyDhcp6Ack ( + return EFI_SUCCESS; + } + +- + /** + Cache the DHCPv6 proxy offer packet according to the received order. + +@@ -775,12 +778,12 @@ PxeBcCopyDhcp6Ack ( + **/ + EFI_STATUS + PxeBcCopyDhcp6Proxy ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN UINT32 OfferIndex ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN UINT32 OfferIndex + ) + { +- EFI_PXE_BASE_CODE_MODE *Mode; +- EFI_DHCP6_PACKET *Offer; ++ EFI_PXE_BASE_CODE_MODE *Mode; ++ EFI_DHCP6_PACKET *Offer; + EFI_STATUS Status; + + ASSERT (OfferIndex < Private->OfferNum); +@@ -793,9 +796,10 @@ PxeBcCopyDhcp6Proxy ( + // Cache the proxy offer packet and parse it. + // + Status = PxeBcCacheDhcp6Packet (&Private->ProxyOffer.Dhcp6.Packet.Offer, Offer); +- if (EFI_ERROR(Status)) { ++ if (EFI_ERROR (Status)) { + return Status; + } ++ + PxeBcParseDhcp6Packet (&Private->ProxyOffer.Dhcp6); + + // +@@ -820,33 +824,33 @@ PxeBcCopyDhcp6Proxy ( + **/ + UINT8 * + PxeBcDhcp6SeekOption ( +- IN UINT8 *Buf, +- IN UINT32 SeekLen, +- IN UINT16 OptType ++ IN UINT8 *Buf, ++ IN UINT32 SeekLen, ++ IN UINT16 OptType + ) + { +- UINT8 *Cursor; +- UINT8 *Option; +- UINT16 DataLen; +- UINT16 OpCode; ++ UINT8 *Cursor; ++ UINT8 *Option; ++ UINT16 DataLen; ++ UINT16 OpCode; + + Option = NULL; + Cursor = Buf; + + while (Cursor < Buf + SeekLen) { +- OpCode = ReadUnaligned16 ((UINT16 *) Cursor); ++ OpCode = ReadUnaligned16 ((UINT16 *)Cursor); + if (OpCode == HTONS (OptType)) { + Option = Cursor; + break; + } +- DataLen = NTOHS (ReadUnaligned16 ((UINT16 *) (Cursor + 2))); ++ ++ DataLen = NTOHS (ReadUnaligned16 ((UINT16 *)(Cursor + 2))); + Cursor += (DataLen + 4); + } + + return Option; + } + +- + /** + Build and send out the request packet for the bootfile, and parse the reply. + +@@ -861,34 +865,34 @@ PxeBcDhcp6SeekOption ( + **/ + EFI_STATUS + PxeBcRequestBootService ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN UINT32 Index ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN UINT32 Index + ) + { +- EFI_PXE_BASE_CODE_UDP_PORT SrcPort; +- EFI_PXE_BASE_CODE_UDP_PORT DestPort; +- EFI_PXE_BASE_CODE_PROTOCOL *PxeBc; +- EFI_PXE_BASE_CODE_DHCPV6_PACKET *Discover; +- UINTN DiscoverLen; +- EFI_DHCP6_PACKET *Request; +- UINTN RequestLen; +- EFI_DHCP6_PACKET *Reply; +- UINT8 *RequestOpt; +- UINT8 *DiscoverOpt; +- UINTN ReadSize; +- UINT16 OpFlags; +- UINT16 OpCode; +- UINT16 OpLen; +- EFI_STATUS Status; +- EFI_DHCP6_PACKET *IndexOffer; +- UINT8 *Option; +- +- PxeBc = &Private->PxeBc; +- Request = Private->Dhcp6Request; +- IndexOffer = &Private->OfferBuffer[Index].Dhcp6.Packet.Offer; +- SrcPort = PXEBC_BS_DISCOVER_PORT; +- DestPort = PXEBC_BS_DISCOVER_PORT; +- OpFlags = 0; ++ EFI_PXE_BASE_CODE_UDP_PORT SrcPort; ++ EFI_PXE_BASE_CODE_UDP_PORT DestPort; ++ EFI_PXE_BASE_CODE_PROTOCOL *PxeBc; ++ EFI_PXE_BASE_CODE_DHCPV6_PACKET *Discover; ++ UINTN DiscoverLen; ++ EFI_DHCP6_PACKET *Request; ++ UINTN RequestLen; ++ EFI_DHCP6_PACKET *Reply; ++ UINT8 *RequestOpt; ++ UINT8 *DiscoverOpt; ++ UINTN ReadSize; ++ UINT16 OpFlags; ++ UINT16 OpCode; ++ UINT16 OpLen; ++ EFI_STATUS Status; ++ EFI_DHCP6_PACKET *IndexOffer; ++ UINT8 *Option; ++ ++ PxeBc = &Private->PxeBc; ++ Request = Private->Dhcp6Request; ++ IndexOffer = &Private->OfferBuffer[Index].Dhcp6.Packet.Offer; ++ SrcPort = PXEBC_BS_DISCOVER_PORT; ++ DestPort = PXEBC_BS_DISCOVER_PORT; ++ OpFlags = 0; + + if (Request == NULL) { + return EFI_DEVICE_ERROR; +@@ -925,19 +929,20 @@ PxeBcRequestBootService ( + // + // Add Server ID Option. + // +- OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *) Option)->OpLen); ++ OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *)Option)->OpLen); + CopyMem (DiscoverOpt, Option, OpLen + 4); + DiscoverOpt += (OpLen + 4); + DiscoverLen += (OpLen + 4); + } + + 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 && +- OpCode != DHCP6_OPT_SERVER_ID +- ) { ++ 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) && ++ (OpCode != DHCP6_OPT_SERVER_ID) ++ ) ++ { + // + // Copy all the options except IA option and Server ID + // +@@ -945,6 +950,7 @@ PxeBcRequestBootService ( + DiscoverOpt += (OpLen + 4); + DiscoverLen += (OpLen + 4); + } ++ + RequestOpt += (OpLen + 4); + RequestLen += (OpLen + 4); + } +@@ -959,7 +965,7 @@ PxeBcRequestBootService ( + ); + if (Option != NULL) { + CalcElapsedTime (Private); +- WriteUnaligned16 ((UINT16*)(Option + 4), HTONS((UINT16) Private->ElapsedTime)); ++ WriteUnaligned16 ((UINT16 *)(Option + 4), HTONS ((UINT16)Private->ElapsedTime)); + } + + Status = PxeBc->UdpWrite ( +@@ -973,7 +979,7 @@ PxeBcRequestBootService ( + NULL, + NULL, + &DiscoverLen, +- (VOID *) Discover ++ (VOID *)Discover + ); + + if (EFI_ERROR (Status)) { +@@ -984,8 +990,8 @@ PxeBcRequestBootService ( + // Cache the right PXE reply packet here, set valid flag later. + // Especially for PXE discover packet, store it into mode data here. + // +- Reply = &Private->ProxyOffer.Dhcp6.Packet.Offer; +- ReadSize = (UINTN) Reply->Size; ++ Reply = &Private->ProxyOffer.Dhcp6.Packet.Offer; ++ ReadSize = (UINTN)Reply->Size; + + // + // Start Udp6Read instance +@@ -1005,7 +1011,7 @@ PxeBcRequestBootService ( + NULL, + NULL, + &ReadSize, +- (VOID *) &Reply->Dhcp6 ++ (VOID *)&Reply->Dhcp6 + ); + // + // Stop Udp6Read instance +@@ -1019,7 +1025,7 @@ PxeBcRequestBootService ( + // + // Update length + // +- Reply->Length = (UINT32) ReadSize; ++ Reply->Length = (UINT32)ReadSize; + + return EFI_SUCCESS; + +@@ -1031,7 +1037,6 @@ ON_ERROR: + return Status; + } + +- + /** + Retry to request bootfile name by the BINL offer. + +@@ -1054,8 +1059,10 @@ PxeBcRetryDhcp6Binl ( + EFI_STATUS Status; + + ASSERT (Index < PXEBC_OFFER_MAX_NUM); +- ASSERT (Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeDhcpBinl || +- Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeProxyBinl); ++ ASSERT ( ++ Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeDhcpBinl || ++ Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeProxyBinl ++ ); + + Mode = Private->PxeBc.Mode; + Private->IsDoDiscover = FALSE; +@@ -1078,7 +1085,7 @@ PxeBcRetryDhcp6Binl ( + Private, + &Private->BootFileName, + &Private->ServerIp.v6, +- (CHAR8 *) (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->Data), ++ (CHAR8 *)(Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->Data), + NTOHS (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->OpLen) + ); + if (EFI_ERROR (Status)) { +@@ -1101,9 +1108,10 @@ PxeBcRetryDhcp6Binl ( + return Status; + } + +- if (Cache6->OfferType != PxeOfferTypeProxyPxe10 && +- Cache6->OfferType != PxeOfferTypeProxyWfm11a && +- Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] == NULL) { ++ if ((Cache6->OfferType != PxeOfferTypeProxyPxe10) && ++ (Cache6->OfferType != PxeOfferTypeProxyWfm11a) && ++ (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] == NULL)) ++ { + // + // This BINL ack doesn't have discovery option set or multicast option set + // or bootfile name specified. +@@ -1121,7 +1129,6 @@ PxeBcRetryDhcp6Binl ( + return EFI_SUCCESS; + } + +- + /** + Cache all the received DHCPv6 offers, and set OfferIndex and OfferCount. + +@@ -1133,8 +1140,8 @@ PxeBcRetryDhcp6Binl ( + **/ + EFI_STATUS + PxeBcCacheDhcp6Offer ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN EFI_DHCP6_PACKET *RcvdOffer ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN EFI_DHCP6_PACKET *RcvdOffer + ) + { + PXEBC_DHCP6_PACKET_CACHE *Cache6; +@@ -1179,8 +1186,9 @@ PxeBcCacheDhcp6Offer ( + // + Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum; + Private->OfferCount[OfferType]++; +- } else if ((OfferType == PxeOfferTypeProxyPxe10 || OfferType == PxeOfferTypeProxyWfm11a) && +- Private->OfferCount[OfferType] < 1) { ++ } else if (((OfferType == PxeOfferTypeProxyPxe10) || (OfferType == PxeOfferTypeProxyWfm11a)) && ++ (Private->OfferCount[OfferType] < 1)) ++ { + // + // Only cache the first PXE10/WFM11a offer, and discard the others. + // +@@ -1202,7 +1210,6 @@ PxeBcCacheDhcp6Offer ( + return EFI_SUCCESS; + } + +- + /** + Select an DHCPv6 offer, and record SelectIndex and SelectProxyType. + +@@ -1211,12 +1218,12 @@ PxeBcCacheDhcp6Offer ( + **/ + VOID + PxeBcSelectDhcp6Offer ( +- IN PXEBC_PRIVATE_DATA *Private ++ IN PXEBC_PRIVATE_DATA *Private + ) + { +- UINT32 Index; +- UINT32 OfferIndex; +- PXEBC_OFFER_TYPE OfferType; ++ UINT32 Index; ++ UINT32 OfferIndex; ++ PXEBC_OFFER_TYPE OfferType; + + Private->SelectIndex = 0; + +@@ -1229,43 +1236,40 @@ PxeBcSelectDhcp6Offer ( + // 1. DhcpPxe10 offer + // + Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpPxe10][0] + 1; +- + } else if (Private->OfferCount[PxeOfferTypeDhcpWfm11a] > 0) { + // + // 2. DhcpWfm11a offer + // + Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpWfm11a][0] + 1; +- +- } else if (Private->OfferCount[PxeOfferTypeDhcpOnly] > 0 && +- Private->OfferCount[PxeOfferTypeProxyPxe10] > 0) { ++ } else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) && ++ (Private->OfferCount[PxeOfferTypeProxyPxe10] > 0)) ++ { + // + // 3. DhcpOnly offer and ProxyPxe10 offer. + // + Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1; + Private->SelectProxyType = PxeOfferTypeProxyPxe10; +- +- } else if (Private->OfferCount[PxeOfferTypeDhcpOnly] > 0 && +- Private->OfferCount[PxeOfferTypeProxyWfm11a] > 0) { ++ } else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) && ++ (Private->OfferCount[PxeOfferTypeProxyWfm11a] > 0)) ++ { + // + // 4. DhcpOnly offer and ProxyWfm11a offer. + // + Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1; + Private->SelectProxyType = PxeOfferTypeProxyWfm11a; +- + } else if (Private->OfferCount[PxeOfferTypeDhcpBinl] > 0) { + // + // 5. DhcpBinl offer. + // + Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpBinl][0] + 1; +- +- } else if (Private->OfferCount[PxeOfferTypeDhcpOnly] > 0 && +- Private->OfferCount[PxeOfferTypeProxyBinl] > 0) { ++ } else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) && ++ (Private->OfferCount[PxeOfferTypeProxyBinl] > 0)) ++ { + // + // 6. DhcpOnly offer and ProxyBinl offer. + // + Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1; + Private->SelectProxyType = PxeOfferTypeProxyBinl; +- + } else { + // + // 7. DhcpOnly offer with bootfilename. +@@ -1283,7 +1287,6 @@ PxeBcSelectDhcp6Offer ( + // Select offer by received order. + // + for (Index = 0; Index < Private->OfferNum; Index++) { +- + OfferType = Private->OfferBuffer[Index].Dhcp6.OfferType; + + if (IS_PROXY_OFFER (OfferType)) { +@@ -1294,8 +1297,9 @@ PxeBcSelectDhcp6Offer ( + } + + if (!Private->IsProxyRecved && +- OfferType == PxeOfferTypeDhcpOnly && +- Private->OfferBuffer[Index].Dhcp6.OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] == NULL) { ++ (OfferType == PxeOfferTypeDhcpOnly) && ++ (Private->OfferBuffer[Index].Dhcp6.OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] == NULL)) ++ { + // + // Skip if DhcpOnly offer without any other proxy offers or bootfilename. + // +@@ -1308,7 +1312,6 @@ PxeBcSelectDhcp6Offer ( + } + } + +- + /** + Handle the DHCPv6 offer packet. + +@@ -1322,21 +1325,21 @@ PxeBcSelectDhcp6Offer ( + **/ + EFI_STATUS + PxeBcHandleDhcp6Offer ( +- IN PXEBC_PRIVATE_DATA *Private ++ IN PXEBC_PRIVATE_DATA *Private + ) + { +- PXEBC_DHCP6_PACKET_CACHE *Cache6; +- EFI_STATUS Status; +- PXEBC_OFFER_TYPE OfferType; +- UINT32 ProxyIndex; +- UINT32 SelectIndex; +- UINT32 Index; ++ PXEBC_DHCP6_PACKET_CACHE *Cache6; ++ EFI_STATUS Status; ++ PXEBC_OFFER_TYPE OfferType; ++ UINT32 ProxyIndex; ++ UINT32 SelectIndex; ++ UINT32 Index; + + ASSERT (Private->SelectIndex > 0); +- SelectIndex = (UINT32) (Private->SelectIndex - 1); ++ SelectIndex = (UINT32)(Private->SelectIndex - 1); + ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM); +- Cache6 = &Private->OfferBuffer[SelectIndex].Dhcp6; +- Status = EFI_SUCCESS; ++ Cache6 = &Private->OfferBuffer[SelectIndex].Dhcp6; ++ Status = EFI_SUCCESS; + + // + // First try to cache DNS server address if DHCP6 offer provides. +@@ -1346,6 +1349,7 @@ PxeBcHandleDhcp6Offer ( + if (Private->DnsServer == NULL) { + return EFI_OUT_OF_RESOURCES; + } ++ + CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS)); + } + +@@ -1357,7 +1361,6 @@ PxeBcHandleDhcp6Offer ( + Status = EFI_NO_RESPONSE; + } + } else if (Cache6->OfferType == PxeOfferTypeDhcpOnly) { +- + if (Private->IsProxyRecved) { + // + // DhcpOnly offer is selected, so need try to request bootfilename. +@@ -1375,12 +1378,12 @@ PxeBcHandleDhcp6Offer ( + // Try all the cached ProxyBinl offer one by one to request bootfilename. + // + for (Index = 0; Index < Private->OfferCount[Private->SelectProxyType]; Index++) { +- + ProxyIndex = Private->OfferIndex[Private->SelectProxyType][Index]; + if (!EFI_ERROR (PxeBcRetryDhcp6Binl (Private, ProxyIndex))) { + break; + } + } ++ + if (Index == Private->OfferCount[Private->SelectProxyType]) { + Status = EFI_NO_RESPONSE; + } +@@ -1397,7 +1400,6 @@ PxeBcHandleDhcp6Offer ( + Status = EFI_NO_RESPONSE; + + for (Index = 0; Index < Private->OfferNum; Index++) { +- + OfferType = Private->OfferBuffer[Index].Dhcp6.OfferType; + + if (!IS_PROXY_OFFER (OfferType)) { +@@ -1423,7 +1425,7 @@ PxeBcHandleDhcp6Offer ( + } + } + +- if (!EFI_ERROR (Status) && Private->SelectProxyType != PxeOfferTypeProxyBinl) { ++ if (!EFI_ERROR (Status) && (Private->SelectProxyType != PxeOfferTypeProxyBinl)) { + // + // Success to try to request by a ProxyPxe10 or ProxyWfm11a offer, copy and parse it. + // +@@ -1441,14 +1443,13 @@ PxeBcHandleDhcp6Offer ( + // + // All PXE boot information is ready by now. + // +- Status = PxeBcCopyDhcp6Ack (Private, &Private->DhcpAck.Dhcp6.Packet.Ack, TRUE); ++ Status = PxeBcCopyDhcp6Ack (Private, &Private->DhcpAck.Dhcp6.Packet.Ack, TRUE); + Private->PxeBc.Mode->DhcpDiscoverValid = TRUE; + } + + return Status; + } + +- + /** + Unregister the address by Ip6Config protocol. + +@@ -1457,7 +1458,7 @@ PxeBcHandleDhcp6Offer ( + **/ + VOID + PxeBcUnregisterIp6Address ( +- IN PXEBC_PRIVATE_DATA *Private ++ IN PXEBC_PRIVATE_DATA *Private + ) + { + if (Private->Ip6Policy != PXEBC_IP6_POLICY_MAX) { +@@ -1485,18 +1486,18 @@ PxeBcUnregisterIp6Address ( + **/ + EFI_STATUS + PxeBcCheckRouteTable ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN UINTN TimeOutInSecond, +- OUT EFI_IPv6_ADDRESS *GatewayAddr ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN UINTN TimeOutInSecond, ++ OUT EFI_IPv6_ADDRESS *GatewayAddr + ) + { +- EFI_STATUS Status; +- EFI_IP6_PROTOCOL *Ip6; +- EFI_IP6_MODE_DATA Ip6ModeData; +- UINTN Index; +- EFI_EVENT TimeOutEvt; +- UINTN RetryCount; +- BOOLEAN GatewayIsFound; ++ EFI_STATUS Status; ++ EFI_IP6_PROTOCOL *Ip6; ++ EFI_IP6_MODE_DATA Ip6ModeData; ++ UINTN Index; ++ EFI_EVENT TimeOutEvt; ++ UINTN RetryCount; ++ BOOLEAN GatewayIsFound; + + ASSERT (GatewayAddr != NULL); + ASSERT (Private != NULL); +@@ -1527,23 +1528,28 @@ PxeBcCheckRouteTable ( + if (Ip6ModeData.AddressList != NULL) { + FreePool (Ip6ModeData.AddressList); + } ++ + if (Ip6ModeData.GroupTable != NULL) { + FreePool (Ip6ModeData.GroupTable); + } ++ + if (Ip6ModeData.RouteTable != NULL) { + FreePool (Ip6ModeData.RouteTable); + } ++ + if (Ip6ModeData.NeighborCache != NULL) { + FreePool (Ip6ModeData.NeighborCache); + } ++ + if (Ip6ModeData.PrefixTable != NULL) { + FreePool (Ip6ModeData.PrefixTable); + } ++ + if (Ip6ModeData.IcmpTypeList != NULL) { + FreePool (Ip6ModeData.IcmpTypeList); + } + +- if (GatewayIsFound || RetryCount == TimeOutInSecond) { ++ if (GatewayIsFound || (RetryCount == TimeOutInSecond)) { + break; + } + +@@ -1569,6 +1575,7 @@ PxeBcCheckRouteTable ( + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } ++ + while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) { + Ip6->Poll (Ip6); + } +@@ -1600,29 +1607,29 @@ ON_EXIT: + **/ + EFI_STATUS + PxeBcRegisterIp6Address ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN EFI_IPv6_ADDRESS *Address ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN EFI_IPv6_ADDRESS *Address + ) + { +- EFI_IP6_PROTOCOL *Ip6; +- EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; +- EFI_IP6_CONFIG_POLICY Policy; +- EFI_IP6_CONFIG_MANUAL_ADDRESS CfgAddr; +- EFI_IPv6_ADDRESS GatewayAddr; +- UINTN DataSize; +- EFI_EVENT MappedEvt; +- EFI_STATUS Status; +- BOOLEAN NoGateway; +- EFI_IPv6_ADDRESS *Ip6Addr; +- UINTN Index; +- +- Status = EFI_SUCCESS; +- MappedEvt = NULL; +- Ip6Addr = NULL; +- DataSize = sizeof (EFI_IP6_CONFIG_POLICY); +- Ip6Cfg = Private->Ip6Cfg; +- Ip6 = Private->Ip6; +- NoGateway = FALSE; ++ EFI_IP6_PROTOCOL *Ip6; ++ EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; ++ EFI_IP6_CONFIG_POLICY Policy; ++ EFI_IP6_CONFIG_MANUAL_ADDRESS CfgAddr; ++ EFI_IPv6_ADDRESS GatewayAddr; ++ UINTN DataSize; ++ EFI_EVENT MappedEvt; ++ EFI_STATUS Status; ++ BOOLEAN NoGateway; ++ EFI_IPv6_ADDRESS *Ip6Addr; ++ UINTN Index; ++ ++ Status = EFI_SUCCESS; ++ MappedEvt = NULL; ++ Ip6Addr = NULL; ++ DataSize = sizeof (EFI_IP6_CONFIG_POLICY); ++ Ip6Cfg = Private->Ip6Cfg; ++ Ip6 = Private->Ip6; ++ NoGateway = FALSE; + + ZeroMem (&CfgAddr, sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); + CopyMem (&CfgAddr.Address, Address, sizeof (EFI_IPv6_ADDRESS)); +@@ -1648,7 +1655,7 @@ PxeBcRegisterIp6Address ( + Status = Ip6Cfg->SetData ( + Ip6Cfg, + Ip6ConfigDataTypePolicy, +- sizeof(EFI_IP6_CONFIG_POLICY), ++ sizeof (EFI_IP6_CONFIG_POLICY), + &Policy + ); + if (EFI_ERROR (Status)) { +@@ -1674,22 +1681,22 @@ PxeBcRegisterIp6Address ( + } + + Private->IsAddressOk = FALSE; +- Status = Ip6Cfg->RegisterDataNotify ( +- Ip6Cfg, +- Ip6ConfigDataTypeManualAddress, +- MappedEvt +- ); +- if (EFI_ERROR(Status)) { ++ Status = Ip6Cfg->RegisterDataNotify ( ++ Ip6Cfg, ++ Ip6ConfigDataTypeManualAddress, ++ MappedEvt ++ ); ++ if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = Ip6Cfg->SetData ( + Ip6Cfg, + Ip6ConfigDataTypeManualAddress, +- sizeof(EFI_IP6_CONFIG_MANUAL_ADDRESS), ++ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS), + &CfgAddr + ); +- if (EFI_ERROR(Status) && Status != EFI_NOT_READY) { ++ if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) { + goto ON_EXIT; + } else if (Status == EFI_NOT_READY) { + // +@@ -1698,17 +1705,18 @@ PxeBcRegisterIp6Address ( + while (!Private->IsAddressOk) { + Ip6->Poll (Ip6); + } ++ + // + // Check whether the IP6 address setting is successed. + // + DataSize = 0; +- Status = Ip6Cfg->GetData ( +- Ip6Cfg, +- Ip6ConfigDataTypeManualAddress, +- &DataSize, +- NULL +- ); +- if (Status != EFI_BUFFER_TOO_SMALL || DataSize == 0) { ++ Status = Ip6Cfg->GetData ( ++ Ip6Cfg, ++ Ip6ConfigDataTypeManualAddress, ++ &DataSize, ++ NULL ++ ); ++ if ((Status != EFI_BUFFER_TOO_SMALL) || (DataSize == 0)) { + Status = EFI_DEVICE_ERROR; + goto ON_EXIT; + } +@@ -1717,11 +1725,12 @@ PxeBcRegisterIp6Address ( + if (Ip6Addr == NULL) { + return EFI_OUT_OF_RESOURCES; + } ++ + Status = Ip6Cfg->GetData ( + Ip6Cfg, + Ip6ConfigDataTypeManualAddress, + &DataSize, +- (VOID*) Ip6Addr ++ (VOID *)Ip6Addr + ); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; +@@ -1733,6 +1742,7 @@ PxeBcRegisterIp6Address ( + break; + } + } ++ + if (Index == DataSize / sizeof (EFI_IPv6_ADDRESS)) { + Status = EFI_ABORTED; + goto ON_EXIT; +@@ -1763,9 +1773,11 @@ ON_EXIT: + ); + gBS->CloseEvent (MappedEvt); + } ++ + if (Ip6Addr != NULL) { + FreePool (Ip6Addr); + } ++ + return Status; + } + +@@ -1780,16 +1792,16 @@ ON_EXIT: + **/ + EFI_STATUS + PxeBcSetIp6Policy ( +- IN PXEBC_PRIVATE_DATA *Private ++ IN PXEBC_PRIVATE_DATA *Private + ) + { +- EFI_IP6_CONFIG_POLICY Policy; +- EFI_STATUS Status; +- EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; +- UINTN DataSize; ++ EFI_IP6_CONFIG_POLICY Policy; ++ EFI_STATUS Status; ++ EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; ++ UINTN DataSize; + +- Ip6Cfg = Private->Ip6Cfg; +- DataSize = sizeof (EFI_IP6_CONFIG_POLICY); ++ Ip6Cfg = Private->Ip6Cfg; ++ DataSize = sizeof (EFI_IP6_CONFIG_POLICY); + + // + // Get and store the current policy of IP6 driver. +@@ -1809,7 +1821,7 @@ PxeBcSetIp6Policy ( + Status = Ip6Cfg->SetData ( + Ip6Cfg, + Ip6ConfigDataTypePolicy, +- sizeof(EFI_IP6_CONFIG_POLICY), ++ sizeof (EFI_IP6_CONFIG_POLICY), + &Policy + ); + if (EFI_ERROR (Status)) { +@@ -1834,11 +1846,11 @@ PxeBcSetIp6Policy ( + **/ + EFI_STATUS + PxeBcSetIp6Address ( +- IN PXEBC_PRIVATE_DATA *Private ++ IN PXEBC_PRIVATE_DATA *Private + ) + { +- EFI_STATUS Status; +- EFI_DHCP6_PROTOCOL *Dhcp6; ++ EFI_STATUS Status; ++ EFI_DHCP6_PROTOCOL *Dhcp6; + + Dhcp6 = Private->Dhcp6; + +@@ -1885,47 +1897,48 @@ PxeBcSetIp6Address ( + EFI_STATUS + EFIAPI + PxeBcDhcp6CallBack ( +- IN EFI_DHCP6_PROTOCOL *This, +- IN VOID *Context, +- IN EFI_DHCP6_STATE CurrentState, +- IN EFI_DHCP6_EVENT Dhcp6Event, +- IN EFI_DHCP6_PACKET *Packet, +- OUT EFI_DHCP6_PACKET **NewPacket OPTIONAL ++ IN EFI_DHCP6_PROTOCOL *This, ++ IN VOID *Context, ++ IN EFI_DHCP6_STATE CurrentState, ++ IN EFI_DHCP6_EVENT Dhcp6Event, ++ IN EFI_DHCP6_PACKET *Packet, ++ OUT EFI_DHCP6_PACKET **NewPacket OPTIONAL + ) + { +- PXEBC_PRIVATE_DATA *Private; +- EFI_PXE_BASE_CODE_MODE *Mode; +- EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback; +- EFI_DHCP6_PACKET *SelectAd; +- EFI_STATUS Status; +- BOOLEAN Received; ++ PXEBC_PRIVATE_DATA *Private; ++ EFI_PXE_BASE_CODE_MODE *Mode; ++ EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback; ++ EFI_DHCP6_PACKET *SelectAd; ++ EFI_STATUS Status; ++ BOOLEAN Received; + + if ((Dhcp6Event != Dhcp6RcvdAdvertise) && + (Dhcp6Event != Dhcp6SelectAdvertise) && + (Dhcp6Event != Dhcp6SendSolicit) && + (Dhcp6Event != Dhcp6SendRequest) && +- (Dhcp6Event != Dhcp6RcvdReply)) { ++ (Dhcp6Event != Dhcp6RcvdReply)) ++ { + return EFI_SUCCESS; + } + + ASSERT (Packet != NULL); + +- Private = (PXEBC_PRIVATE_DATA *) Context; +- Mode = Private->PxeBc.Mode; +- Callback = Private->PxeBcCallback; ++ Private = (PXEBC_PRIVATE_DATA *)Context; ++ Mode = Private->PxeBc.Mode; ++ Callback = Private->PxeBcCallback; + + // + // Callback to user when any traffic occurred if has. + // +- if (Dhcp6Event != Dhcp6SelectAdvertise && Callback != NULL) { +- Received = (BOOLEAN) (Dhcp6Event == Dhcp6RcvdAdvertise || Dhcp6Event == Dhcp6RcvdReply); +- Status = Callback->Callback ( +- Callback, +- Private->Function, +- Received, +- Packet->Length, +- (EFI_PXE_BASE_CODE_PACKET *) &Packet->Dhcp6 +- ); ++ if ((Dhcp6Event != Dhcp6SelectAdvertise) && (Callback != NULL)) { ++ Received = (BOOLEAN)(Dhcp6Event == Dhcp6RcvdAdvertise || Dhcp6Event == Dhcp6RcvdReply); ++ Status = Callback->Callback ( ++ Callback, ++ Private->Function, ++ Received, ++ Packet->Length, ++ (EFI_PXE_BASE_CODE_PACKET *)&Packet->Dhcp6 ++ ); + if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) { + return EFI_ABORTED; + } +@@ -1934,108 +1947,114 @@ PxeBcDhcp6CallBack ( + Status = EFI_SUCCESS; + + switch (Dhcp6Event) { ++ case Dhcp6SendSolicit: ++ if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { ++ // ++ // If the to be sent packet exceeds the maximum length, abort the DHCP process. ++ // ++ Status = EFI_ABORTED; ++ break; ++ } + +- case Dhcp6SendSolicit: +- if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { + // +- // If the to be sent packet exceeds the maximum length, abort the DHCP process. ++ // Record the first Solicate msg time + // +- Status = EFI_ABORTED; +- break; +- } +- +- // +- // Record the first Solicate msg time +- // +- if (Private->SolicitTimes == 0) { +- CalcElapsedTime (Private); +- Private->SolicitTimes++; +- } +- // +- // Cache the dhcp discover packet to mode data directly. +- // +- CopyMem (&Mode->DhcpDiscover.Dhcpv4, &Packet->Dhcp6, Packet->Length); +- break; ++ if (Private->SolicitTimes == 0) { ++ CalcElapsedTime (Private); ++ Private->SolicitTimes++; ++ } + +- case Dhcp6RcvdAdvertise: +- Status = EFI_NOT_READY; +- if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { + // +- // Ignore the incoming packets which exceed the maximum length. ++ // Cache the dhcp discover packet to mode data directly. + // ++ CopyMem (&Mode->DhcpDiscover.Dhcpv4, &Packet->Dhcp6, Packet->Length); + break; +- } +- if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) { ++ ++ case Dhcp6RcvdAdvertise: ++ Status = EFI_NOT_READY; ++ if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { ++ // ++ // Ignore the incoming packets which exceed the maximum length. ++ // ++ break; ++ } ++ ++ if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) { ++ // ++ // Cache the dhcp offers to OfferBuffer[] for select later, and record ++ // the OfferIndex and OfferCount. ++ // ++ PxeBcCacheDhcp6Offer (Private, Packet); ++ } ++ ++ break; ++ ++ case Dhcp6SendRequest: ++ if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { ++ // ++ // If the to be sent packet exceeds the maximum length, abort the DHCP process. ++ // ++ Status = EFI_ABORTED; ++ break; ++ } ++ + // +- // Cache the dhcp offers to OfferBuffer[] for select later, and record +- // the OfferIndex and OfferCount. ++ // Store the request packet as seed packet for discover. + // +- PxeBcCacheDhcp6Offer (Private, Packet); +- } +- break; ++ if (Private->Dhcp6Request != NULL) { ++ FreePool (Private->Dhcp6Request); ++ } ++ ++ Private->Dhcp6Request = AllocateZeroPool (Packet->Size); ++ if (Private->Dhcp6Request != NULL) { ++ CopyMem (Private->Dhcp6Request, Packet, Packet->Size); ++ } ++ ++ break; + +- case Dhcp6SendRequest: +- if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { ++ case Dhcp6SelectAdvertise: + // +- // If the to be sent packet exceeds the maximum length, abort the DHCP process. ++ // Select offer by the default policy or by order, and record the SelectIndex ++ // and SelectProxyType. + // +- Status = EFI_ABORTED; +- break; +- } ++ PxeBcSelectDhcp6Offer (Private); + +- // +- // Store the request packet as seed packet for discover. +- // +- if (Private->Dhcp6Request != NULL) { +- FreePool (Private->Dhcp6Request); +- } +- Private->Dhcp6Request = AllocateZeroPool (Packet->Size); +- if (Private->Dhcp6Request != NULL) { +- CopyMem (Private->Dhcp6Request, Packet, Packet->Size); +- } +- break; ++ if (Private->SelectIndex == 0) { ++ Status = EFI_ABORTED; ++ } else { ++ ASSERT (NewPacket != NULL); ++ SelectAd = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp6.Packet.Offer; ++ *NewPacket = AllocateZeroPool (SelectAd->Size); ++ ASSERT (*NewPacket != NULL); ++ if (*NewPacket == NULL) { ++ return EFI_ABORTED; ++ } + +- case Dhcp6SelectAdvertise: +- // +- // Select offer by the default policy or by order, and record the SelectIndex +- // and SelectProxyType. +- // +- PxeBcSelectDhcp6Offer (Private); ++ CopyMem (*NewPacket, SelectAd, SelectAd->Size); ++ } + +- if (Private->SelectIndex == 0) { +- Status = EFI_ABORTED; +- } else { +- ASSERT (NewPacket != NULL); +- SelectAd = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp6.Packet.Offer; +- *NewPacket = AllocateZeroPool (SelectAd->Size); +- ASSERT (*NewPacket != NULL); +- if (*NewPacket == NULL) { +- return EFI_ABORTED; ++ break; ++ ++ case Dhcp6RcvdReply: ++ // ++ // Cache the dhcp ack to Private->Dhcp6Ack, but it's not the final ack in mode data ++ // without verification. ++ // ++ ASSERT (Private->SelectIndex != 0); ++ Status = PxeBcCopyDhcp6Ack (Private, Packet, FALSE); ++ if (EFI_ERROR (Status)) { ++ Status = EFI_ABORTED; + } +- CopyMem (*NewPacket, SelectAd, SelectAd->Size); +- } +- break; + +- case Dhcp6RcvdReply: +- // +- // Cache the dhcp ack to Private->Dhcp6Ack, but it's not the final ack in mode data +- // without verification. +- // +- ASSERT (Private->SelectIndex != 0); +- Status = PxeBcCopyDhcp6Ack (Private, Packet, FALSE); +- if (EFI_ERROR (Status)) { +- Status = EFI_ABORTED; +- } +- break; ++ break; + +- default: +- ASSERT (0); ++ default: ++ ASSERT (0); + } + + return Status; + } + +- + /** + Build and send out the request packet for the bootfile, and parse the reply. + +@@ -2053,37 +2072,37 @@ PxeBcDhcp6CallBack ( + **/ + EFI_STATUS + PxeBcDhcp6Discover ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN UINT16 Type, +- IN UINT16 *Layer, +- IN BOOLEAN UseBis, +- IN EFI_IP_ADDRESS *DestIp ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN UINT16 Type, ++ IN UINT16 *Layer, ++ IN BOOLEAN UseBis, ++ IN EFI_IP_ADDRESS *DestIp + ) + { +- EFI_PXE_BASE_CODE_UDP_PORT SrcPort; +- EFI_PXE_BASE_CODE_UDP_PORT DestPort; +- EFI_PXE_BASE_CODE_MODE *Mode; +- EFI_PXE_BASE_CODE_PROTOCOL *PxeBc; +- EFI_PXE_BASE_CODE_DHCPV6_PACKET *Discover; +- UINTN DiscoverLen; +- EFI_DHCP6_PACKET *Request; +- UINTN RequestLen; +- EFI_DHCP6_PACKET *Reply; +- UINT8 *RequestOpt; +- UINT8 *DiscoverOpt; +- UINTN ReadSize; +- UINT16 OpCode; +- UINT16 OpLen; +- UINT32 Xid; +- EFI_STATUS Status; +- +- PxeBc = &Private->PxeBc; +- Mode = PxeBc->Mode; +- Request = Private->Dhcp6Request; +- SrcPort = PXEBC_BS_DISCOVER_PORT; +- DestPort = PXEBC_BS_DISCOVER_PORT; +- +- if (!UseBis && Layer != NULL) { ++ EFI_PXE_BASE_CODE_UDP_PORT SrcPort; ++ EFI_PXE_BASE_CODE_UDP_PORT DestPort; ++ EFI_PXE_BASE_CODE_MODE *Mode; ++ EFI_PXE_BASE_CODE_PROTOCOL *PxeBc; ++ EFI_PXE_BASE_CODE_DHCPV6_PACKET *Discover; ++ UINTN DiscoverLen; ++ EFI_DHCP6_PACKET *Request; ++ UINTN RequestLen; ++ EFI_DHCP6_PACKET *Reply; ++ UINT8 *RequestOpt; ++ UINT8 *DiscoverOpt; ++ UINTN ReadSize; ++ UINT16 OpCode; ++ UINT16 OpLen; ++ UINT32 Xid; ++ EFI_STATUS Status; ++ ++ PxeBc = &Private->PxeBc; ++ Mode = PxeBc->Mode; ++ Request = Private->Dhcp6Request; ++ SrcPort = PXEBC_BS_DISCOVER_PORT; ++ DestPort = PXEBC_BS_DISCOVER_PORT; ++ ++ if (!UseBis && (Layer != NULL)) { + *Layer &= EFI_PXE_BASE_CODE_BOOT_LAYER_MASK; + } + +@@ -2108,10 +2127,11 @@ PxeBcDhcp6Discover ( + RequestLen = DiscoverLen; + + 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) { ++ 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)) ++ { + // + // Copy all the options except IA option. + // +@@ -2119,6 +2139,7 @@ PxeBcDhcp6Discover ( + DiscoverOpt += (OpLen + 4); + DiscoverLen += (OpLen + 4); + } ++ + RequestOpt += (OpLen + 4); + RequestLen += (OpLen + 4); + } +@@ -2134,7 +2155,7 @@ PxeBcDhcp6Discover ( + NULL, + NULL, + &DiscoverLen, +- (VOID *) Discover ++ (VOID *)Discover + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; +@@ -2150,7 +2171,8 @@ PxeBcDhcp6Discover ( + } else { + Reply = &Private->ProxyOffer.Dhcp6.Packet.Offer; + } +- ReadSize = (UINTN) Reply->Size; ++ ++ ReadSize = (UINTN)Reply->Size; + + // + // Start Udp6Read instance +@@ -2170,7 +2192,7 @@ PxeBcDhcp6Discover ( + NULL, + NULL, + &ReadSize, +- (VOID *) &Reply->Dhcp6 ++ (VOID *)&Reply->Dhcp6 + ); + // + // Stop Udp6Read instance +@@ -2190,7 +2212,6 @@ ON_ERROR: + return Status; + } + +- + /** + Start the DHCPv6 S.A.R.R. process to acquire the IPv6 address and other PXE boot information. + +@@ -2203,35 +2224,35 @@ ON_ERROR: + **/ + EFI_STATUS + PxeBcDhcp6Sarr ( +- IN PXEBC_PRIVATE_DATA *Private, +- IN EFI_DHCP6_PROTOCOL *Dhcp6 ++ IN PXEBC_PRIVATE_DATA *Private, ++ IN EFI_DHCP6_PROTOCOL *Dhcp6 + ) + { +- EFI_PXE_BASE_CODE_MODE *PxeMode; +- EFI_DHCP6_CONFIG_DATA Config; +- EFI_DHCP6_MODE_DATA Mode; +- EFI_DHCP6_RETRANSMISSION *Retransmit; +- EFI_DHCP6_PACKET_OPTION *OptList[PXEBC_DHCP6_OPTION_MAX_NUM]; +- UINT8 Buffer[PXEBC_DHCP6_OPTION_MAX_SIZE]; +- UINT32 OptCount; +- EFI_STATUS Status; +- EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; +- EFI_STATUS TimerStatus; +- EFI_EVENT Timer; +- UINT64 GetMappingTimeOut; +- UINTN DataSize; +- EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits; +- +- Status = EFI_SUCCESS; +- PxeMode = Private->PxeBc.Mode; +- Ip6Cfg = Private->Ip6Cfg; +- Timer = NULL; ++ EFI_PXE_BASE_CODE_MODE *PxeMode; ++ EFI_DHCP6_CONFIG_DATA Config; ++ EFI_DHCP6_MODE_DATA Mode; ++ EFI_DHCP6_RETRANSMISSION *Retransmit; ++ EFI_DHCP6_PACKET_OPTION *OptList[PXEBC_DHCP6_OPTION_MAX_NUM]; ++ UINT8 Buffer[PXEBC_DHCP6_OPTION_MAX_SIZE]; ++ UINT32 OptCount; ++ EFI_STATUS Status; ++ EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; ++ EFI_STATUS TimerStatus; ++ EFI_EVENT Timer; ++ UINT64 GetMappingTimeOut; ++ UINTN DataSize; ++ EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits; ++ ++ Status = EFI_SUCCESS; ++ PxeMode = Private->PxeBc.Mode; ++ Ip6Cfg = Private->Ip6Cfg; ++ Timer = NULL; + + // + // Build option list for the request packet. + // +- OptCount = PxeBcBuildDhcp6Options (Private, OptList, Buffer); +- ASSERT (OptCount> 0); ++ OptCount = PxeBcBuildDhcp6Options (Private, OptList, Buffer); ++ ASSERT (OptCount > 0); + + Retransmit = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION)); + if (Retransmit == NULL) { +@@ -2274,7 +2295,6 @@ PxeBcDhcp6Sarr ( + ZeroMem (Private->OfferCount, sizeof (Private->OfferCount)); + ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex)); + +- + // + // Start DHCPv6 S.A.R.R. process to acquire IPv6 address. + // +@@ -2290,12 +2310,12 @@ PxeBcDhcp6Sarr ( + // Get Duplicate Address Detection Transmits count. + // + DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS); +- Status = Ip6Cfg->GetData ( +- Ip6Cfg, +- Ip6ConfigDataTypeDupAddrDetectTransmits, +- &DataSize, +- &DadXmits +- ); ++ Status = Ip6Cfg->GetData ( ++ Ip6Cfg, ++ Ip6ConfigDataTypeDupAddrDetectTransmits, ++ &DataSize, ++ &DadXmits ++ ); + if (EFI_ERROR (Status)) { + Dhcp6->Configure (Dhcp6, NULL); + return Status; +@@ -2308,7 +2328,7 @@ PxeBcDhcp6Sarr ( + } + + GetMappingTimeOut = TICKS_PER_SECOND * DadXmits.DupAddrDetectTransmits + PXEBC_DAD_ADDITIONAL_DELAY; +- Status = gBS->SetTimer (Timer, TimerRelative, GetMappingTimeOut); ++ Status = gBS->SetTimer (Timer, TimerRelative, GetMappingTimeOut); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (Timer); + Dhcp6->Configure (Dhcp6, NULL); +@@ -2316,7 +2336,6 @@ PxeBcDhcp6Sarr ( + } + + do { +- + TimerStatus = gBS->CheckEvent (Timer); + if (!EFI_ERROR (TimerStatus)) { + Status = Dhcp6->Start (Dhcp6); +@@ -2325,10 +2344,12 @@ PxeBcDhcp6Sarr ( + + gBS->CloseEvent (Timer); + } ++ + if (EFI_ERROR (Status)) { + if (Status == EFI_ICMP_ERROR) { + PxeMode->IcmpErrorReceived = TRUE; + } ++ + Dhcp6->Configure (Dhcp6, NULL); + return Status; + } +@@ -2354,9 +2375,11 @@ PxeBcDhcp6Sarr ( + if (Mode.ClientId != NULL) { + FreePool (Mode.ClientId); + } ++ + if (Mode.Ia != NULL) { + FreePool (Mode.Ia); + } ++ + // + // Check the selected offer whether BINL retry is needed. + // +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch b/edk2-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch new file mode 100644 index 0000000..e37b524 --- /dev/null +++ b/edk2-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch @@ -0,0 +1,69 @@ +From 649fe647114ca5dee84b0c55106ee58a9703984f Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 15/15] NetworkPkg: Dhcp6Dxe: Packet-Length is not updated + before appending + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [15/15] bc7ef287311bb3f757bc26f8921875566bcb5917 + +JIRA: https://issues.redhat.com/browse/RHEL-21840 +CVE: CVE-2023-45229 +Upstream: Merged + +commit 75deaf5c3c0d164c61653258c331151241bb69d8 +Author: Doug Flick +Date: Tue Feb 13 10:46:02 2024 -0800 + + NetworkPkg: Dhcp6Dxe: Packet-Length is not updated before appending + + In order for Dhcp6AppendIaAddrOption (..) to safely append the IA + Address option, the Packet-Length field must be updated before appending + the option. + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + Reviewed-by: Leif Lindholm + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +index e172ffc2a2..c23eff8766 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +@@ -948,6 +948,11 @@ Dhcp6AppendIaOption ( + *PacketCursor += sizeof (T2); + } + ++ // ++ // Update the packet length ++ // ++ Packet->Length += BytesNeeded; ++ + // + // Fill all the addresses belong to the Ia + // +@@ -959,11 +964,6 @@ Dhcp6AppendIaOption ( + } + } + +- // +- // Update the packet length +- // +- Packet->Length += BytesNeeded; +- + // + // Fill the value of Ia option length + // +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch b/edk2-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch new file mode 100644 index 0000000..a928fa2 --- /dev/null +++ b/edk2-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch @@ -0,0 +1,161 @@ +From 4bf844922a963cb20fb1e72ca11a65a673992ca2 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 14/15] NetworkPkg: Dhcp6Dxe: Removes duplicate check and + replaces with macro + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [14/15] a943400f9267b219bf1fd202534500f82a2a4c56 + +JIRA: https://issues.redhat.com/browse/RHEL-21840 +CVE: CVE-2023-45229 +Upstream: Merged + +commit af3fad99d6088881562e50149f414f76a5be0140 +Author: Doug Flick +Date: Tue Feb 13 10:46:01 2024 -0800 + + NetworkPkg: Dhcp6Dxe: Removes duplicate check and replaces with macro + + Removes duplicate check after merge + + > + > // + > // 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; + > } + > + + Converts the check to a macro and replaces all instances of the check + with the macro + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + Reviewed-by: Leif Lindholm + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 43 +++++++++++++----------------- + 1 file changed, 18 insertions(+), 25 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +index 484c360a96..e172ffc2a2 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +@@ -10,6 +10,15 @@ + + #include "Dhcp6Impl.h" + ++// ++// Verifies the packet cursor is within the packet ++// otherwise it is invalid ++// ++#define IS_INVALID_PACKET_CURSOR(PacketCursor, Packet) \ ++ (((*PacketCursor) < (Packet)->Dhcp6.Option) || \ ++ ((*PacketCursor) >= (Packet)->Dhcp6.Option + ((Packet)->Size - sizeof(EFI_DHCP6_HEADER))) \ ++ ) \ ++ + + /** + Generate client Duid in the format of Duid-llt. +@@ -662,9 +671,7 @@ Dhcp6AppendOption ( + // + // Verify the PacketCursor is within the packet + // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { + return EFI_INVALID_PARAMETER; + } + +@@ -681,15 +688,6 @@ Dhcp6AppendOption ( + 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); +@@ -768,9 +766,7 @@ Dhcp6AppendIaAddrOption ( + // + // Verify the PacketCursor is within the packet + // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { + return EFI_INVALID_PARAMETER; + } + +@@ -902,9 +898,7 @@ Dhcp6AppendIaOption ( + // + // Verify the PacketCursor is within the packet + // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { + return EFI_INVALID_PARAMETER; + } + +@@ -966,14 +960,14 @@ Dhcp6AppendIaOption ( + } + + // +- // Fill the value of Ia option length ++ // Update the packet length + // +- *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); ++ Packet->Length += BytesNeeded; + + // +- // Update the packet length ++ // Fill the value of Ia option length + // +- Packet->Length += BytesNeeded; ++ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); + + return EFI_SUCCESS; + } +@@ -982,6 +976,7 @@ Dhcp6AppendIaOption ( + Append the appointed Elapsed time option to Buf, and move Buf to the end. + + @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] Instance The pointer to the Dhcp6 instance. +@@ -1037,9 +1032,7 @@ Dhcp6AppendETOption ( + // + // Verify the PacketCursor is within the packet + // +- if ( (*PacketCursor < Packet->Dhcp6.Option) +- || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) +- { ++ if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) { + return EFI_INVALID_PARAMETER; + } + +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch b/edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch new file mode 100644 index 0000000..ea1b84f --- /dev/null +++ b/edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch @@ -0,0 +1,257 @@ +From 1b58858f28a364a8f8fa897a78db7ced068719dd Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 13/15] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 + Related Patch + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [13/15] 904fd82592208d0ca42bbb64f437691a5bdfd0b6 + +JIRA: https://issues.redhat.com/browse/RHEL-21840 +CVE: CVE-2023-45229 +Upstream: Merged + +commit 1c440a5eceedc64e892877eeac0f1a4938f5abbb +Author: Doug Flick +Date: Tue Feb 13 10:46:00 2024 -0800 + + NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Related Patch + + REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4673 + REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534 + + This was not part of the Quarkslab bugs however the same pattern + as CVE-2023-45229 exists in Dhcp6UpdateIaInfo. + + This patch replaces the code in question with the safe function + created to patch CVE-2023-45229 + + > + > if (EFI_ERROR ( + > Dhcp6SeekInnerOptionSafe ( + > Instance->Config->IaDescriptor.Type, + > Option, + > OptionLen, + > &IaInnerOpt, + > &IaInnerLen + > ) + > )) + > { + > return EFI_DEVICE_ERROR; + > } + > + + Additionally corrects incorrect usage of macro to read the status + + > - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN + (Option))); + > + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *) + DHCP6_OFFSET_OF_STATUS_CODE (Option)); + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + Reviewed-by: Leif Lindholm + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 70 ++++++++++++++++++++++++++--------- + NetworkPkg/Dhcp6Dxe/Dhcp6Io.h | 22 +++++++++++ + 2 files changed, 75 insertions(+), 17 deletions(-) + +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +index 3b8feb4a20..a9bffae353 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +@@ -528,13 +528,23 @@ Dhcp6UpdateIaInfo ( + { + EFI_STATUS Status; + UINT8 *Option; ++ UINT32 OptionLen; + UINT8 *IaInnerOpt; + UINT16 IaInnerLen; + UINT16 StsCode; + UINT32 T1; + UINT32 T2; + ++ T1 = 0; ++ T2 = 0; ++ + ASSERT (Instance->Config != NULL); ++ ++ // OptionLen is the length of the Options excluding the DHCP header. ++ // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last ++ // byte of the Option[] field. ++ OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header); ++ + // + // If the reply was received in response to a solicit with rapid commit option, + // request, renew or rebind message, the client updates the information it has +@@ -549,13 +559,29 @@ Dhcp6UpdateIaInfo ( + // + Option = Dhcp6SeekIaOption ( + Packet->Dhcp6.Option, +- Packet->Length - sizeof (EFI_DHCP6_HEADER), ++ OptionLen, + &Instance->Config->IaDescriptor + ); + if (Option == NULL) { + return EFI_DEVICE_ERROR; + } + ++ // ++ // Calculate the distance from Packet->Dhcp6.Option to the IA option. ++ // ++ // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is ++ // the size of the whole packet, including the DHCP header, and Packet->Length ++ // is the length of the DHCP message body, excluding the DHCP header. ++ // ++ // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of ++ // DHCP6 option area to the start of the IA option. ++ // ++ // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the ++ // IA option to the end of the DHCP6 option area, thus subtract the space ++ // up until this option ++ // ++ OptionLen = OptionLen - (UINT32)(Option - Packet->Dhcp6.Option); ++ + // + // The format of the IA_NA option is: + // +@@ -591,32 +617,32 @@ Dhcp6UpdateIaInfo ( + // + + // +- // sizeof (option-code + option-len + IaId) = 8 +- // sizeof (option-code + option-len + IaId + T1) = 12 +- // sizeof (option-code + option-len + IaId + T1 + T2) = 16 +- // +- // The inner options still start with 2 bytes option-code and 2 bytes option-len. ++ // Seek the inner option + // ++ if (EFI_ERROR ( ++ Dhcp6SeekInnerOptionSafe ( ++ Instance->Config->IaDescriptor.Type, ++ Option, ++ OptionLen, ++ &IaInnerOpt, ++ &IaInnerLen ++ ) ++ )) ++ { ++ return EFI_DEVICE_ERROR; ++ } ++ + if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) { + T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option)))); + T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option)))); + // + // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2, + // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes +- // the remainder of the message as though the server had not included the invalid IA_NA option. ++ // the remainder of the message as though the server had not included the invalid IA_NA option. + // + if ((T1 > T2) && (T2 > 0)) { + return EFI_DEVICE_ERROR; + } +- +- IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); +- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2); +- } else { +- T1 = 0; +- T2 = 0; +- +- IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option); +- IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID); + } + + // +@@ -642,7 +668,7 @@ Dhcp6UpdateIaInfo ( + Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode); + + if (Option != NULL) { +- StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))); ++ StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (Option)))); + if (StsCode != Dhcp6StsSuccess) { + return EFI_DEVICE_ERROR; + } +@@ -703,15 +729,21 @@ Dhcp6SeekInnerOptionSafe ( + } + + if (IaType == Dhcp6OptIana) { ++ // + // Verify we have a fully formed IA_NA ++ // + if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) { + return EFI_DEVICE_ERROR; + } + ++ // ++ // Get the IA Inner Option and Length + // + IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option); + ++ // + // Verify the IaInnerLen is valid. ++ // + IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option))); + if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) { + return EFI_DEVICE_ERROR; +@@ -719,14 +751,18 @@ Dhcp6SeekInnerOptionSafe ( + + 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; +diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h +index 554f0f5e5d..8c0d282bca 100644 +--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h ++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h +@@ -218,4 +218,26 @@ Dhcp6OnTimerTick ( + IN VOID *Context + ); + ++/** ++ Seeks the Inner Options from a DHCP6 Option ++ ++ @param[in] IaType The type of the IA option. ++ @param[in] Option The pointer to the DHCP6 Option. ++ @param[in] OptionLen The length of the DHCP6 Option. ++ @param[out] IaInnerOpt The pointer to the IA inner option. ++ @param[out] IaInnerLen The length of the IA inner option. ++ ++ @retval EFI_SUCCESS Seek the inner option successfully. ++ @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, ++ the pointers are not modified ++**/ ++EFI_STATUS ++Dhcp6SeekInnerOptionSafe ( ++ IN UINT16 IaType, ++ IN UINT8 *Option, ++ IN UINT32 OptionLen, ++ OUT UINT8 **IaInnerOpt, ++ OUT UINT16 *IaInnerLen ++ ); ++ + #endif +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch new file mode 100644 index 0000000..b87ded2 --- /dev/null +++ b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch @@ -0,0 +1,78 @@ +From e3f153773bd2ca13ee4869187f1711840fc8afc9 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 15 Feb 2024 11:51:09 -0500 +Subject: [PATCH 02/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Patch + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [2/15] 61eaf6aac61b774c3a8ace54af8abd607651d2db + +JIRA: https://issues.redhat.com/browse/RHEL-21844 +CVE: CVE-2022-45231 +Upstream: Merged + +commit bbfee34f4188ac00371abe1389ae9c9fb989a0cd +Author: Doug Flick +Date: Fri Jan 26 05:54:48 2024 +0800 + + NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Patch + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4536 + + Bug Overview: + PixieFail Bug #3 + 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 + + Out-of-bounds read when handling a ND Redirect message with truncated + options + + Change Overview: + + Adds a check to prevent truncated options from being parsed + + // + + // 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; + + } + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Ip6Dxe/Ip6Option.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c +index 199eea124d..8718d5d875 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.39.3 + diff --git a/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch new file mode 100644 index 0000000..35eaa36 --- /dev/null +++ b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch @@ -0,0 +1,277 @@ +From e8200dda7752d21794b2268efe9e957958ffef29 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Wed, 14 Feb 2024 12:24:44 -0500 +Subject: [PATCH 03/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Unit + Tests + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [3/15] ca554677a3397423073d3bb4774f856b2329ae9c + +JIRA: https://issues.redhat.com/browse/RHEL-21844 +CVE: CVE-2022-45231 +Upstream: Merged + +commit 6f77463d72807ec7f4ed6518c3dac29a1040df9f +Author: Doug Flick +Date: Fri Jan 26 05:54:49 2024 +0800 + + NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45231 Unit Tests + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4536 + + Validates that the patch for... + + Out-of-bounds read when handling a ND Redirect message with truncated + options + + .. has been fixed + + Tests the following function to ensure that an out of bounds read does + not occur + Ip6OptionValidation + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp | 20 +++ + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 42 ++++++ + .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 129 ++++++++++++++++++ + NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + + 4 files changed, 192 insertions(+) + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf + create mode 100644 NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp + +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.cpp +new file mode 100644 +index 0000000000..6ebfd5fdfb +--- /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 ++ ++//////////////////////////////////////////////////////////////////////////////// ++// Run the tests ++//////////////////////////////////////////////////////////////////////////////// ++int ++main ( ++ int argc, ++ char *argv[] ++ ) ++{ ++ testing::InitGoogleTest (&argc, argv); ++ return RUN_ALL_TESTS (); ++} +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf +new file mode 100644 +index 0000000000..6e4de0745f +--- /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.
++# 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/Ip6OptionGoogleTest.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +new file mode 100644 +index 0000000000..f2cd90e1a9 +--- /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 ++ ++extern "C" { ++ #include ++ #include ++ #include ++ #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)); ++} +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +index 20bc90b172..ab7c2857b6 100644 +--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -25,6 +25,7 @@ + # 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] +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch new file mode 100644 index 0000000..a7b6eb8 --- /dev/null +++ b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch @@ -0,0 +1,377 @@ +From 23b31a16bbb789f4c251b1d2f23334210a9fb545 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Thu, 15 Feb 2024 11:51:09 -0500 +Subject: [PATCH 04/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [4/15] 48c273e43a6275c7eae3223c4ffa433f4d6531a4 + +JIRA: https://issues.redhat.com/browse/RHEL-21846 +CVE: CVE-2022-45232 +Upstream: Merged + +JIRA: https://issues.redhat.com/browse/RHEL-21848 +CVE: CVE-2022-45233 +Upstream: Merged + +commit 4df0229ef992d4f2721a8508787ebf9dc81fbd6e +Author: Doug Flick +Date: Fri Jan 26 05:54:50 2024 +0800 + + NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537 + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538 + + Bug Details: + PixieFail Bug #4 + 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') + + Infinite loop when parsing unknown options in the Destination Options + header + + PixieFail Bug #5 + 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') + + Infinite loop when parsing a PadN option in the Destination Options + header + + Change Overview: + + Most importantly this change corrects the following incorrect math + and cleans up the code. + + > // It is a PadN option + > // + > - Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); + > + OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; + > + Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + + > case Ip6OptionSkip: + > - Offset = (UINT8)(Offset + *(Option + Offset + 1)); + > OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; + > Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); + + Additionally, this change also corrects incorrect math where the calling + function was calculating the HDR EXT optionLen as a uint8 instead of a + uint16 + + > - OptionLen = (UINT8)((*Option + 1) * 8 - 2); + > + OptionLen = IP6_HDR_EXT_LEN (*Option) - + IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN; + + Additionally this check adds additional logic to santize the incoming + data + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Ip6Dxe/Ip6Nd.h | 35 ++++++++++++++++ + NetworkPkg/Ip6Dxe/Ip6Option.c | 76 ++++++++++++++++++++++++++++++----- + NetworkPkg/Ip6Dxe/Ip6Option.h | 71 ++++++++++++++++++++++++++++++++ + 3 files changed, 171 insertions(+), 11 deletions(-) + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h +index 860934a167..bf64e9114e 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Nd.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h +@@ -56,13 +56,48 @@ VOID + VOID *Context + ); + ++// ++// 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. ++// + typedef struct _IP6_OPTION_HEADER { ++ /// ++ /// identifier of the type of option. ++ /// + UINT8 Type; ++ /// ++ /// Length of the Option Data field of this option, in octets. ++ /// + UINT8 Length; ++ /// ++ /// Option-Type-specific data. ++ /// + } IP6_OPTION_HEADER; + + STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) == 2, "IP6_OPTION_HEADER is expected to be exactly 2 bytes long."); + ++#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + sizeof(IP6_OPTION_HEADER) + length) ++STATIC_ASSERT ( ++ IP6_NEXT_OPTION_OFFSET (0, 0) == 2, ++ "The next option is minimally the combined size of the option tag and length" ++ ); ++ + typedef struct _IP6_ETHE_ADDR_OPTION { + UINT8 Type; + UINT8 Length; +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c +index 8718d5d875..fd97ce116f 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_OPTION_HEADER *)(Option + Offset))->Length; ++ 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_OPTION_HEADER *)(Option + Offset))->Length; ++ 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) - sizeof (IP6_EXT_HDR); + 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 + sizeof (IP6_EXT_HDR) + 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; + +diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.h b/NetworkPkg/Ip6Dxe/Ip6Option.h +index bd8e223c8a..fb07c28f5a 100644 +--- a/NetworkPkg/Ip6Dxe/Ip6Option.h ++++ b/NetworkPkg/Ip6Dxe/Ip6Option.h +@@ -12,6 +12,77 @@ + + #define IP6_FRAGMENT_OFFSET_MASK (~0x3) + ++// ++// 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 ++// ++typedef struct _IP6_EXT_HDR { ++ /// ++ /// The Next Header field identifies the type of header immediately ++ /// ++ UINT8 NextHeader; ++ /// ++ /// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options ++ /// ++ UINT8 HdrExtLen; ++ /// ++ /// Header-Specific Data ++ /// ++} IP6_EXT_HDR; ++ ++STATIC_ASSERT ( ++ sizeof (IP6_EXT_HDR) == 2, ++ "The combined size of Next Header and Len is two 8 bit fields" ++ ); ++ ++// ++// IPv6 extension headers contain an 8-bit length field which describes the size of ++// the header. However, the length field only includes the size of the extension ++// header options, not the size of the first 8 bytes of the header. Therefore, in ++// order to calculate the full size of the extension header, we add 1 (to account ++// for the first 8 bytes omitted by the length field reporting) and then multiply ++// by 8 (since the size is represented in 8-byte units). ++// ++// a is the length field of the extension header (UINT8) ++// The result may be up to 2046 octets (UINT16) ++// ++#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) - sizeof(IP6_EXT_HDR)) ++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; +-- +2.39.3 + diff --git a/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch new file mode 100644 index 0000000..1add20a --- /dev/null +++ b/edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch @@ -0,0 +1,430 @@ +From 2bd8bc051f6394f2ab3c22649c54ecbed5d636cd Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Wed, 14 Feb 2024 20:25:29 -0500 +Subject: [PATCH 05/15] NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit + Tests + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [5/15] 624365d403df25927ab0514b0e25faea7376def8 + +JIRA: https://issues.redhat.com/browse/RHEL-21846 +CVE: CVE-2022-45232 +Upstream: Merged + +commit c9c87f08dd6ace36fa843424522c3558a8374cac +Author: Doug Flick +Date: Fri Jan 26 05:54:51 2024 +0800 + + NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537 + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538 + + Unit tests to confirm that.. + Infinite loop when parsing unknown options in the Destination Options + header + + and + + Infinite loop when parsing a PadN option in the Destination Options + header + + ... have been patched + + This patch tests the following functions: + Ip6IsOptionValid + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + .../Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf | 10 +- + .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp | 278 ++++++++++++++++++ + .../Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h | 40 +++ + 3 files changed, 324 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 6e4de0745f..ba29dbabad 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.
+ # 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 @@ + # 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.cpp b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +index f2cd90e1a9..29f8a4a96e 100644 +--- a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp ++++ b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.cpp +@@ -12,6 +12,7 @@ extern "C" { + #include + #include "../Ip6Impl.h" + #include "../Ip6Option.h" ++ #include "Ip6OptionGoogleTest.h" + } + + ///////////////////////////////////////////////////////////////////////// +@@ -127,3 +128,280 @@ 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 ++ } ++}; ++ ++// 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 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 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 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)); ++} +diff --git a/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h b/NetworkPkg/Ip6Dxe/GoogleTest/Ip6OptionGoogleTest.h +new file mode 100644 +index 0000000000..0509b6ae30 +--- /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 IP6_OPTION_HEADER_GOOGLE_TEST_H_ ++#define IP6_OPTION_HEADER_GOOGLE_TEST_H_ ++ ++#include ++#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 // __IP6_OPTION_HEADER_GOOGLE_TEST_H__ +-- +2.39.3 + diff --git a/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch new file mode 100644 index 0000000..8e6f603 --- /dev/null +++ b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch @@ -0,0 +1,168 @@ +From 38baf93892ec464490b6fe611c23b014f574344b Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 07/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 + Patch + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [7/15] c1baa0b2facbf0b63a90a0bfd55264af9f893098 + +JIRA: https://issues.redhat.com/browse/RHEL-21850 +CVE: CVE-2022-45234 +Upstream: Merged + +commit 1b53515d53d303166b2bbd31e2cc7f16fd0aecd7 +Author: Doug Flick +Date: Fri Jan 26 05:54:52 2024 +0800 + + NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Patch + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539 + + Bug Details: + PixieFail Bug #6 + 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 + + Buffer overflow when processing DNS Servers option in a DHCPv6 + Advertise message + + Change Overview: + + Introduces a function to cache the Dns Server and perform sanitizing + on the incoming DnsServerLen to ensure that the length is valid + + > + EFI_STATUS + > + PxeBcCacheDnsServerAddresses ( + > + IN PXEBC_PRIVATE_DATA *Private, + > + IN PXEBC_DHCP6_PACKET_CACHE *Cache6 + > + ) + + Additional code cleanup + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + 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 425e0cf806..2b2d372889 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +@@ -3,6 +3,7 @@ + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
++ 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.39.3 + diff --git a/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch new file mode 100644 index 0000000..aac0738 --- /dev/null +++ b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch @@ -0,0 +1,511 @@ +From fd1bc6ff10a45123b0ec7f9ae3354ad3713bc532 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 08/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 + Unit Tests + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [8/15] f88ebc7fa79ce4fe615dd79c42fedee0a0da7a0b + +JIRA: https://issues.redhat.com/browse/RHEL-21850 +CVE: CVE-2022-45234 +Upstream: Merged + +commit 458c582685fc0e8057d2511c5a0394078d988c17 +Author: Doug Flick +Date: Fri Jan 26 05:54:53 2024 +0800 + + NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45234 Unit Tests + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4539 + + Unit tests to that the bug.. + + Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise + message + + ..has been patched + + This contains tests for the following functions: + PxeBcHandleDhcp6Offer + PxeBcCacheDnsServerAddresses + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Test/NetworkPkgHostTest.dsc | 1 + + .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 300 ++++++++++++++++++ + .../GoogleTest/PxeBcDhcp6GoogleTest.h | 50 +++ + .../GoogleTest/UefiPxeBcDxeGoogleTest.cpp | 19 ++ + .../GoogleTest/UefiPxeBcDxeGoogleTest.inf | 48 +++ + 5 files changed, 418 insertions(+) + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp + create mode 100644 NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf + +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +index ab7c2857b6..c8a991e5c1 100644 +--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -26,6 +26,7 @@ + # + 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/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +new file mode 100644 +index 0000000000..8260eeee50 +--- /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 ++ ++extern "C" { ++ #include ++ #include ++ #include ++ #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/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h +new file mode 100644 +index 0000000000..b17c314791 +--- /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.
++ 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 ++#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/UefiPxeBcDxeGoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.cpp +new file mode 100644 +index 0000000000..cc4fdf525b +--- /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 ++ ++//////////////////////////////////////////////////////////////////////////////// ++// Run the tests ++//////////////////////////////////////////////////////////////////////////////// ++int ++main ( ++ int argc, ++ char *argv[] ++ ) ++{ ++ testing::InitGoogleTest (&argc, argv); ++ return RUN_ALL_TESTS (); ++} +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf b/NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf +new file mode 100644 +index 0000000000..301dcdf611 +--- /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.
++# 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 +-- +2.39.3 + diff --git a/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch new file mode 100644 index 0000000..beaa36f --- /dev/null +++ b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch @@ -0,0 +1,257 @@ +From 0016db53099ba979617f376fe1104fefada4fa29 Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 09/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 + Patch + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [9/15] c48c060b87761537ee526e1f8a9e5993eb1a0381 + +JIRA: https://issues.redhat.com/browse/RHEL-21852 +CVE: CVE-2022-45235 +Upstream: Merged + +commit fac297724e6cc343430cd0104e55cd7a96d1151e +Author: Doug Flick +Date: Fri Jan 26 05:54:55 2024 +0800 + + NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Patch + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540 + + Bug Details: + PixieFail Bug #7 + 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 + + Buffer overflow when handling Server ID option from a DHCPv6 proxy + Advertise message + + Change Overview: + + Performs two checks + + 1. Checks that the length of the duid is accurate + > + // + > + // 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; + > + } + + 2. Ensures that the amount of data written to the buffer is tracked and + never exceeds that + > + // + > + // 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; + > + } + + Additional code clean up and fix for memory leak in case Option was NULL + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 77 ++++++++++++++++++++++------ + NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 17 ++++++ + 2 files changed, 78 insertions(+), 16 deletions(-) + +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +index 2b2d372889..7fd1281c11 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 ( +diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +index ae4be775e8..47eb8cc0c0 100644 +--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h ++++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +@@ -35,6 +35,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) +-- +2.39.3 + diff --git a/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch new file mode 100644 index 0000000..8380050 --- /dev/null +++ b/edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch @@ -0,0 +1,409 @@ +From 80b34c0f56228353c174f9ff739d0755c62d76cf Mon Sep 17 00:00:00 2001 +From: Jon Maloy +Date: Fri, 16 Feb 2024 10:48:05 -0500 +Subject: [PATCH 10/15] NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 + Unit Tests + +RH-Author: Jon Maloy +RH-MergeRequest: 56: Pixiefail issues in NetworkPkg package +RH-Jira: RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852 +RH-Acked-by: Gerd Hoffmann +RH-Acked-by: Oliver Steffen +RH-Commit: [10/15] 5dbf3f771506ff9a0c28827c568d04e825572658 + +JIRA: https://issues.redhat.com/browse/RHEL-21852 +CVE: CVE-2022-45235 +Upstream: Merged + +commit ff2986358f75d8f58ef08a66fe673539c9c48f41 +Author: Doug Flick +Date: Fri Jan 26 05:54:56 2024 +0800 + + NetworkPkg: UefiPxeBcDxe: SECURITY PATCH CVE-2023-45235 Unit Tests + + REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4540 + + Unit tests to confirm that the bug.. + + Buffer overflow when handling Server ID option from a DHCPv6 proxy + Advertise message + + ..has been patched. + + This patch contains unit tests for the following functions: + PxeBcRequestBootService + PxeBcDhcp6Discover + + Cc: Saloni Kasbekar + Cc: Zachary Clark-williams + + Signed-off-by: Doug Flick [MSFT] + Reviewed-by: Saloni Kasbekar + +Signed-off-by: Jon Maloy +--- + NetworkPkg/Test/NetworkPkgHostTest.dsc | 5 +- + .../GoogleTest/PxeBcDhcp6GoogleTest.cpp | 278 +++++++++++++++++- + .../GoogleTest/PxeBcDhcp6GoogleTest.h | 18 ++ + 3 files changed, 298 insertions(+), 3 deletions(-) + +diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc +index c8a991e5c1..1010a80a15 100644 +--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc ++++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc +@@ -26,7 +26,10 @@ + # + NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf + NetworkPkg/Ip6Dxe/GoogleTest/Ip6DxeGoogleTest.inf +- NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf ++ NetworkPkg/UefiPxeBcDxe/GoogleTest/UefiPxeBcDxeGoogleTest.inf { ++ ++ 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.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp +index 8260eeee50..bd423ebadf 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 ++#include ++#include ++#include + + extern "C" { + #include +@@ -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 ++ ); ++} +diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.h +index b17c314791..0d825e4425 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_ +-- +2.39.3 + diff --git a/edk2.spec b/edk2.spec index 52eaa1f..e323461 100644 --- a/edk2.spec +++ b/edk2.spec @@ -7,7 +7,7 @@ ExclusiveArch: x86_64 aarch64 Name: edk2 Version: %{GITDATE}git%{GITCOMMIT} -Release: 11%{?dist} +Release: 12%{?dist} Summary: UEFI firmware for 64-bit virtual machines Group: Applications/Emulators License: BSD-2-Clause-Patent and OpenSSL and MIT @@ -151,6 +151,111 @@ Patch66: edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45230-Un.patch # For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] # For RHEL-21842 - CVE-2023-45230 edk2: Buffer overflow in the DHCPv6 client via a long Server ID option [rhel-8] Patch67: edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Pa.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch68: edk2-Apply-uncrustify-changes-to-.c-.h-files-in-the-Netwo.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch69: edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch70: edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch71: edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch72: edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch73: edk2-NetworkPkg-Apply-uncrustify-changes.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch74: edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch75: edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch76: edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch77: edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch78: edk2-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch79: edk2-NetworkPkg-Apply-uncrustify-changes-p2.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch80: edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch81: edk2-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch +# For RHEL-21840 - CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21844 - CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8] +# For RHEL-21846 - CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8] +# For RHEL-21848 - CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8] +# For RHEL-21850 - CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8] +# For RHEL-21852 - CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8] +Patch82: edk2-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch # python3-devel and libuuid-devel are required for building tools. @@ -297,6 +402,8 @@ sed \ %{SOURCE5} \ > PkKek1.oemstr +# Hack to ensure git lock is removed before chmod starts to not fail +sleep 5 # Done by %setup, but we do not use it for the auxiliary tarballs chmod -Rf a+rX,u+w,g-w,o-w . @@ -595,6 +702,35 @@ true %endif %changelog +* Tue Feb 27 2024 Miroslav Rezanina - 20220126gitbb1bba3d77-12 +- edk2-Apply-uncrustify-changes-to-.c-.h-files-in-the-Netwo.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Patc.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45231-Unit.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Patc.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Ip6Dxe-SECURITY-PATCH-CVE-2023-45232-Unit.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Apply-uncrustify-changes.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p2.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p3.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-UefiPxeBcDxe-SECURITY-PATCH-CVE-2023-4523p4.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Adds-a-SecurityFix.yaml-file.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Apply-uncrustify-changes-p2.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- edk2-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch [RHEL-21840 RHEL-21844 RHEL-21846 RHEL-21848 RHEL-21850 RHEL-21852] +- Resolves: RHEL-21840 + (CVE-2023-45229 edk2: Integer underflow when processing IA_NA/IA_TA options in a DHCPv6 Advertise message [rhel-8]) +- Resolves: RHEL-21844 + (CVE-2023-45231 edk2: Out of Bounds read when handling a ND Redirect message with truncated options [rhel-8]) +- Resolves: RHEL-21846 + (CVE-2023-45232 edk2: Infinite loop when parsing unknown options in the Destination Options header [rhel-8]) +- Resolves: RHEL-21848 + (CVE-2023-45233 edk2: Infinite loop when parsing a PadN option in the Destination Options header [rhel-8]) +- Resolves: RHEL-21850 + (CVE-2023-45234 edk2: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message [rhel-8]) +- Resolves: RHEL-21852 + (CVE-2023-45235 edk2: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message [rhel-8]) + * Wed Feb 14 2024 Jon Maloy - 20220126gitbb1bba3d77-11 - edk2-SecurityPkg-Change-use-of-EFI_D_-to-DEBUG_.patch [RHEL-21154 RHEL-21156] - edk2-SecurityPkg-Change-OPTIONAL-keyword-usage-style.patch [RHEL-21154 RHEL-21156]