]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
ovmf: Fix CVE-2023-45229
authorSoumya Sambu <soumya.sambu@windriver.com>
Fri, 28 Jun 2024 09:42:17 +0000 (09:42 +0000)
committerHongxu Jia <hongxu.jia@windriver.com>
Wed, 4 Dec 2024 03:30:12 +0000 (11:30 +0800)
EDK2's Network Package is susceptible to an out-of-bounds read
vulnerability when processing the IA_NA or IA_TA option in a DHCPv6
Advertise message. This vulnerability can be exploited by an attacker
to gain unauthorized access and potentially lead to a loss of
Confidentiality.

References:
https://nvd.nist.gov/vuln/detail/CVE-2023-45229

Upstream-patches:
https://github.com/tianocore/edk2/commit/1dbb10cc52dc8ef49bb700daa1cefc76b26d52e0
https://github.com/tianocore/edk2/commit/07362769ab7a7d74dbea1c7a7a3662c7b5d1f097
https://github.com/tianocore/edk2/commit/1c440a5eceedc64e892877eeac0f1a4938f5abbb
https://github.com/tianocore/edk2/commit/1d0b95f6457d225c5108302a9da74b4ed7aa5a38

Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0001.patch [new file with mode: 0644]
meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0002.patch [new file with mode: 0644]
meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0003.patch [new file with mode: 0644]
meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0004.patch [new file with mode: 0644]
meta/recipes-core/ovmf/ovmf_git.bb

diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0001.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0001.patch
new file mode 100644 (file)
index 0000000..9d8549b
--- /dev/null
@@ -0,0 +1,604 @@
+From 1dbb10cc52dc8ef49bb700daa1cefc76b26d52e0 Mon Sep 17 00:00:00 2001
+From: "Doug Flick via groups.io" <dougflick=microsoft.com@groups.io>
+Date: Fri, 26 Jan 2024 05:54:46 +0800
+Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch
+
+REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534
+
+Bug Details:
+PixieFail Bug #1
+CVE-2023-45229
+CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
+CWE-125 Out-of-bounds Read
+
+Change Overview:
+
+Introduce Dhcp6SeekInnerOptionSafe which performs checks before seeking
+the Inner Option from a DHCP6 Option.
+
+>
+> EFI_STATUS
+> Dhcp6SeekInnerOptionSafe (
+>  IN  UINT16  IaType,
+>  IN  UINT8   *Option,
+>  IN  UINT32  OptionLen,
+>  OUT UINT8   **IaInnerOpt,
+>  OUT UINT16  *IaInnerLen
+>  );
+>
+
+Lots of code cleanup to improve code readability.
+
+Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
+Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
+
+Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
+Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
+
+CVE: CVE-2023-45229
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1dbb10cc52dc8ef49bb700daa1cefc76b26d52e0]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 138 +++++++++++++++++++---
+ NetworkPkg/Dhcp6Dxe/Dhcp6Io.c   | 203 +++++++++++++++++++++-----------
+ 2 files changed, 256 insertions(+), 85 deletions(-)
+
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+index f2422c2f28..220e7c68f1 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+@@ -45,6 +45,20 @@ typedef struct _DHCP6_INSTANCE  DHCP6_INSTANCE;
+ #define DHCP6_SERVICE_SIGNATURE   SIGNATURE_32 ('D', 'H', '6', 'S')\r
+ #define DHCP6_INSTANCE_SIGNATURE  SIGNATURE_32 ('D', 'H', '6', 'I')\r
\r
++#define DHCP6_PACKET_ALL        0\r
++#define DHCP6_PACKET_STATEFUL   1\r
++#define DHCP6_PACKET_STATELESS  2\r
++\r
++#define DHCP6_BASE_PACKET_SIZE  1024\r
++\r
++#define DHCP6_PORT_CLIENT  546\r
++#define DHCP6_PORT_SERVER  547\r
++\r
++#define DHCP_CHECK_MEDIA_WAITING_TIME  EFI_TIMER_PERIOD_SECONDS(20)\r
++\r
++#define DHCP6_INSTANCE_FROM_THIS(Instance)  CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE)\r
++#define DHCP6_SERVICE_FROM_THIS(Service)    CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE)\r
++\r
+ //\r
+ // For more information on DHCP options see RFC 8415, Section 21.1\r
+ //\r
+@@ -59,12 +73,10 @@ typedef struct _DHCP6_INSTANCE  DHCP6_INSTANCE;
+ //    |                      (option-len octets)                      |\r
+ //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+ //\r
+-#define DHCP6_SIZE_OF_OPT_CODE  (sizeof(UINT16))\r
+-#define DHCP6_SIZE_OF_OPT_LEN   (sizeof(UINT16))\r
++#define DHCP6_SIZE_OF_OPT_CODE  (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode))\r
++#define DHCP6_SIZE_OF_OPT_LEN   (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen))\r
\r
+-//\r
+ // Combined size of Code and Length\r
+-//\r
+ #define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN  (DHCP6_SIZE_OF_OPT_CODE + \\r
+                                               DHCP6_SIZE_OF_OPT_LEN)\r
\r
+@@ -73,34 +85,122 @@ STATIC_ASSERT (
+   "Combined size of Code and Length must be 4 per RFC 8415"\r
+   );\r
\r
+-//\r
+ // Offset to the length is just past the code\r
+-//\r
+-#define DHCP6_OPT_LEN_OFFSET(a)  (a + DHCP6_SIZE_OF_OPT_CODE)\r
++#define DHCP6_OFFSET_OF_OPT_LEN(a)  (a + DHCP6_SIZE_OF_OPT_CODE)\r
+ STATIC_ASSERT (\r
+-  DHCP6_OPT_LEN_OFFSET (0) == 2,\r
++  DHCP6_OFFSET_OF_OPT_LEN (0) == 2,\r
+   "Offset of length is + 2 past start of option"\r
+   );\r
\r
+-#define DHCP6_OPT_DATA_OFFSET(a)  (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN)\r
++#define DHCP6_OFFSET_OF_OPT_DATA(a)  (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN)\r
+ STATIC_ASSERT (\r
+-  DHCP6_OPT_DATA_OFFSET (0) == 4,\r
++  DHCP6_OFFSET_OF_OPT_DATA (0) == 4,\r
+   "Offset to option data should be +4 from start of option"\r
+   );\r
++//\r
++// Identity Association options (both NA (Non-Temporary) and TA (Temporary Association))\r
++// are defined in RFC 8415 and are a deriviation of a TLV stucture\r
++// For more information on IA_NA see Section 21.4\r
++// For more information on IA_TA see Section 21.5\r
++//\r
++//\r
++//  The format of IA_NA and IA_TA option:\r
++//\r
++//     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//    |          OPTION_IA_NA         |          option-len           |\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//    |                        IAID (4 octets)                        |\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//    |                        T1 (only for IA_NA)                    |\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//    |                        T2 (only for IA_NA)                    |\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//    |                                                               |\r
++//    .                  IA_NA-options/IA_TA-options                  .\r
++//    .                                                               .\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//\r
++#define DHCP6_SIZE_OF_IAID           (sizeof(UINT32))\r
++#define DHCP6_SIZE_OF_TIME_INTERVAL  (sizeof(UINT32))\r
\r
+-#define DHCP6_PACKET_ALL        0\r
+-#define DHCP6_PACKET_STATEFUL   1\r
+-#define DHCP6_PACKET_STATELESS  2\r
++// Combined size of IAID, T1, and T2\r
++#define DHCP6_SIZE_OF_COMBINED_IAID_T1_T2  (DHCP6_SIZE_OF_IAID +  \\r
++                                            DHCP6_SIZE_OF_TIME_INTERVAL + \\r
++                                            DHCP6_SIZE_OF_TIME_INTERVAL)\r
++STATIC_ASSERT (\r
++  DHCP6_SIZE_OF_COMBINED_IAID_T1_T2 == 12,\r
++  "Combined size of IAID, T1, T2 must be 12 per RFC 8415"\r
++  );\r
\r
+-#define DHCP6_BASE_PACKET_SIZE  1024\r
++// This is the size of IA_TA without options\r
++#define DHCP6_MIN_SIZE_OF_IA_TA  (DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \\r
++                                  DHCP6_SIZE_OF_IAID)\r
++STATIC_ASSERT (\r
++  DHCP6_MIN_SIZE_OF_IA_TA == 8,\r
++  "Minimum combined size of IA_TA per RFC 8415"\r
++  );\r
\r
+-#define DHCP6_PORT_CLIENT  546\r
+-#define DHCP6_PORT_SERVER  547\r
++// Offset to a IA_TA inner option\r
++#define DHCP6_OFFSET_OF_IA_TA_INNER_OPT(a)  (a + DHCP6_MIN_SIZE_OF_IA_TA)\r
++STATIC_ASSERT (\r
++  DHCP6_OFFSET_OF_IA_TA_INNER_OPT (0) == 8,\r
++  "Offset of IA_TA Inner option is + 8 past start of option"\r
++  );\r
\r
+-#define DHCP_CHECK_MEDIA_WAITING_TIME  EFI_TIMER_PERIOD_SECONDS(20)\r
++// This is the size of IA_NA without options (16)\r
++#define DHCP6_MIN_SIZE_OF_IA_NA  DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \\r
++                                 DHCP6_SIZE_OF_COMBINED_IAID_T1_T2\r
++STATIC_ASSERT (\r
++  DHCP6_MIN_SIZE_OF_IA_NA == 16,\r
++  "Minimum combined size of IA_TA per RFC 8415"\r
++  );\r
\r
+-#define DHCP6_INSTANCE_FROM_THIS(Instance)  CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE)\r
+-#define DHCP6_SERVICE_FROM_THIS(Service)    CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE)\r
++#define DHCP6_OFFSET_OF_IA_NA_INNER_OPT(a)  (a + DHCP6_MIN_SIZE_OF_IA_NA)\r
++STATIC_ASSERT (\r
++  DHCP6_OFFSET_OF_IA_NA_INNER_OPT (0) == 16,\r
++  "Offset of IA_NA Inner option is + 16 past start of option"\r
++  );\r
++\r
++#define DHCP6_OFFSET_OF_IA_NA_T1(a)  (a + \\r
++                                   DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + \\r
++                                   DHCP6_SIZE_OF_IAID)\r
++STATIC_ASSERT (\r
++  DHCP6_OFFSET_OF_IA_NA_T1 (0) == 8,\r
++  "Offset of IA_NA Inner option is + 8 past start of option"\r
++  );\r
++\r
++#define DHCP6_OFFSET_OF_IA_NA_T2(a)  (a + \\r
++                                   DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN +\\r
++                                   DHCP6_SIZE_OF_IAID + \\r
++                                   DHCP6_SIZE_OF_TIME_INTERVAL)\r
++STATIC_ASSERT (\r
++  DHCP6_OFFSET_OF_IA_NA_T2 (0) == 12,\r
++  "Offset of IA_NA Inner option is + 12 past start of option"\r
++  );\r
++\r
++//\r
++// For more information see RFC 8415 Section 21.13\r
++//\r
++// The format of the Status Code Option:\r
++//\r
++//     0                   1                   2                   3\r
++//     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//    |       OPTION_STATUS_CODE      |         option-len            |\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//    |          status-code          |                               |\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |\r
++//    .                                                               .\r
++//    .                        status-message                         .\r
++//    .                                                               .\r
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++//\r
++#define DHCP6_OFFSET_OF_STATUS_CODE(a)  (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN)\r
++STATIC_ASSERT (\r
++  DHCP6_OFFSET_OF_STATUS_CODE (0) == 4,\r
++  "Offset of status is + 4 past start of option"\r
++  );\r
\r
+ extern EFI_IPv6_ADDRESS    mAllDhcpRelayAndServersAddress;\r
+ extern EFI_DHCP6_PROTOCOL  gDhcp6ProtocolTemplate;\r
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+index bf5aa7a769..89d16484a5 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+@@ -598,8 +598,8 @@ Dhcp6UpdateIaInfo (
+   // The inner options still start with 2 bytes option-code and 2 bytes option-len.\r
+   //\r
+   if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {\r
+-    T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 8)));\r
+-    T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(Option + 12)));\r
++    T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option))));\r
++    T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option))));\r
+     //\r
+     // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2,\r
+     // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes\r
+@@ -609,13 +609,14 @@ Dhcp6UpdateIaInfo (
+       return EFI_DEVICE_ERROR;\r
+     }\r
\r
+-    IaInnerOpt = Option + 16;\r
+-    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2))) - 12);\r
++    IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);\r
++    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2);\r
+   } else {\r
+-    T1         = 0;\r
+-    T2         = 0;\r
+-    IaInnerOpt = Option + 8;\r
+-    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 2))) - 4);\r
++    T1 = 0;\r
++    T2 = 0;\r
++\r
++    IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);\r
++    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID);\r
+   }\r
\r
+   //\r
+@@ -641,7 +642,7 @@ Dhcp6UpdateIaInfo (
+   Option  = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);\r
\r
+   if (Option != NULL) {\r
+-    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4)));\r
++    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option))));\r
+     if (StsCode != Dhcp6StsSuccess) {\r
+       return EFI_DEVICE_ERROR;\r
+     }\r
+@@ -661,6 +662,87 @@ Dhcp6UpdateIaInfo (
+   return Status;\r
+ }\r
\r
++/**\r
++  Seeks the Inner Options from a DHCP6 Option\r
++\r
++  @param[in]  IaType          The type of the IA option.\r
++  @param[in]  Option          The pointer to the DHCP6 Option.\r
++  @param[in]  OptionLen       The length of the DHCP6 Option.\r
++  @param[out] IaInnerOpt      The pointer to the IA inner option.\r
++  @param[out] IaInnerLen      The length of the IA inner option.\r
++\r
++  @retval EFI_SUCCESS         Seek the inner option successfully.\r
++  @retval EFI_DEVICE_ERROR    The OptionLen is invalid. On Error,\r
++                              the pointers are not modified\r
++**/\r
++EFI_STATUS\r
++Dhcp6SeekInnerOptionSafe (\r
++  IN  UINT16  IaType,\r
++  IN  UINT8   *Option,\r
++  IN  UINT32  OptionLen,\r
++  OUT UINT8   **IaInnerOpt,\r
++  OUT UINT16  *IaInnerLen\r
++  )\r
++{\r
++  UINT16  IaInnerLenTmp;\r
++  UINT8   *IaInnerOptTmp;\r
++\r
++  if (Option == NULL) {\r
++    ASSERT (Option != NULL);\r
++    return EFI_DEVICE_ERROR;\r
++  }\r
++\r
++  if (IaInnerOpt == NULL) {\r
++    ASSERT (IaInnerOpt != NULL);\r
++    return EFI_DEVICE_ERROR;\r
++  }\r
++\r
++  if (IaInnerLen == NULL) {\r
++    ASSERT (IaInnerLen != NULL);\r
++    return EFI_DEVICE_ERROR;\r
++  }\r
++\r
++  if (IaType == Dhcp6OptIana) {\r
++    // Verify we have a fully formed IA_NA\r
++    if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) {\r
++      return EFI_DEVICE_ERROR;\r
++    }\r
++\r
++    //\r
++    IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);\r
++\r
++    // Verify the IaInnerLen is valid.\r
++    IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option)));\r
++    if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) {\r
++      return EFI_DEVICE_ERROR;\r
++    }\r
++\r
++    IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2;\r
++  } else if (IaType == Dhcp6OptIata) {\r
++    // Verify the OptionLen is valid.\r
++    if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) {\r
++      return EFI_DEVICE_ERROR;\r
++    }\r
++\r
++    IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);\r
++\r
++    // Verify the IaInnerLen is valid.\r
++    IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option))));\r
++    if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) {\r
++      return EFI_DEVICE_ERROR;\r
++    }\r
++\r
++    IaInnerLenTmp -= DHCP6_SIZE_OF_IAID;\r
++  } else {\r
++    return EFI_DEVICE_ERROR;\r
++  }\r
++\r
++  *IaInnerOpt = IaInnerOptTmp;\r
++  *IaInnerLen = IaInnerLenTmp;\r
++\r
++  return EFI_SUCCESS;\r
++}\r
++\r
+ /**\r
+   Seek StatusCode Option in package. A Status Code option may appear in the\r
+   options field of a DHCP message and/or in the options field of another option.\r
+@@ -684,6 +766,12 @@ Dhcp6SeekStsOption (
+   UINT8   *IaInnerOpt;\r
+   UINT16  IaInnerLen;\r
+   UINT16  StsCode;\r
++  UINT32  OptionLen;\r
++\r
++  // OptionLen is the length of the Options excluding the DHCP header.\r
++  // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last\r
++  // byte of the Option[] field.\r
++  OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header);\r
\r
+   //\r
+   // Seek StatusCode option directly in DHCP message body. That is, search in\r
+@@ -691,12 +779,12 @@ Dhcp6SeekStsOption (
+   //\r
+   *Option = Dhcp6SeekOption (\r
+               Packet->Dhcp6.Option,\r
+-              Packet->Length - 4,\r
++              OptionLen,\r
+               Dhcp6OptStatusCode\r
+               );\r
\r
+   if (*Option != NULL) {\r
+-    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4)));\r
++    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (*Option))));\r
+     if (StsCode != Dhcp6StsSuccess) {\r
+       return EFI_DEVICE_ERROR;\r
+     }\r
+@@ -707,7 +795,7 @@ Dhcp6SeekStsOption (
+   //\r
+   *Option = Dhcp6SeekIaOption (\r
+               Packet->Dhcp6.Option,\r
+-              Packet->Length - sizeof (EFI_DHCP6_HEADER),\r
++              OptionLen,\r
+               &Instance->Config->IaDescriptor\r
+               );\r
+   if (*Option == NULL) {\r
+@@ -715,52 +803,35 @@ Dhcp6SeekStsOption (
+   }\r
\r
+   //\r
+-  // The format of the IA_NA option is:\r
++  // Calculate the distance from Packet->Dhcp6.Option to the IA option.\r
+   //\r
+-  //     0                   1                   2                   3\r
+-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |          OPTION_IA_NA         |          option-len           |\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |                        IAID (4 octets)                        |\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |                              T1                               |\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |                              T2                               |\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |                                                               |\r
+-  //    .                         IA_NA-options                         .\r
+-  //    .                                                               .\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++  // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is\r
++  // the size of the whole packet, including the DHCP header, and Packet->Length\r
++  // is the length of the DHCP message body, excluding the DHCP header.\r
+   //\r
+-  // The format of the IA_TA option is:\r
++  // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of\r
++  // DHCP6 option area to the start of the IA option.\r
+   //\r
+-  //     0                   1                   2                   3\r
+-  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |         OPTION_IA_TA          |          option-len           |\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |                        IAID (4 octets)                        |\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+-  //    |                                                               |\r
+-  //    .                         IA_TA-options                         .\r
+-  //    .                                                               .\r
+-  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
++  // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the\r
++  // IA option to the end of the DHCP6 option area, thus subtract the space\r
++  // up until this option\r
+   //\r
++  OptionLen = OptionLen - (*Option - Packet->Dhcp6.Option);\r
\r
+   //\r
+-  // sizeof (option-code + option-len + IaId)           = 8\r
+-  // sizeof (option-code + option-len + IaId + T1)      = 12\r
+-  // sizeof (option-code + option-len + IaId + T1 + T2) = 16\r
+-  //\r
+-  // The inner options still start with 2 bytes option-code and 2 bytes option-len.\r
++  // Seek the inner option\r
+   //\r
+-  if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {\r
+-    IaInnerOpt = *Option + 16;\r
+-    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2))) - 12);\r
+-  } else {\r
+-    IaInnerOpt = *Option + 8;\r
+-    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 2))) - 4);\r
++  if (EFI_ERROR (\r
++        Dhcp6SeekInnerOptionSafe (\r
++          Instance->Config->IaDescriptor.Type,\r
++          *Option,\r
++          OptionLen,\r
++          &IaInnerOpt,\r
++          &IaInnerLen\r
++          )\r
++        ))\r
++  {\r
++    return EFI_DEVICE_ERROR;\r
+   }\r
\r
+   //\r
+@@ -784,7 +855,7 @@ Dhcp6SeekStsOption (
+   //\r
+   *Option = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);\r
+   if (*Option != NULL) {\r
+-    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(*Option + 4)));\r
++    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (*Option)))));\r
+     if (StsCode != Dhcp6StsSuccess) {\r
+       return EFI_DEVICE_ERROR;\r
+     }\r
+@@ -1105,7 +1176,7 @@ Dhcp6SendRequestMsg (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              Instance->AdSelect->Dhcp6.Option,\r
+-             Instance->AdSelect->Length - 4,\r
++             Instance->AdSelect->Length - sizeof (EFI_DHCP6_HEADER),\r
+              Dhcp6OptServerId\r
+              );\r
+   if (Option == NULL) {\r
+@@ -1289,7 +1360,7 @@ Dhcp6SendDeclineMsg (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              LastReply->Dhcp6.Option,\r
+-             LastReply->Length - 4,\r
++             LastReply->Length - sizeof (EFI_DHCP6_HEADER),\r
+              Dhcp6OptServerId\r
+              );\r
+   if (Option == NULL) {\r
+@@ -1448,7 +1519,7 @@ Dhcp6SendReleaseMsg (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              LastReply->Dhcp6.Option,\r
+-             LastReply->Length - 4,\r
++             LastReply->Length - sizeof (EFI_DHCP6_HEADER),\r
+              Dhcp6OptServerId\r
+              );\r
+   if (Option == NULL) {\r
+@@ -1673,7 +1744,7 @@ Dhcp6SendRenewRebindMsg (
\r
+     Option = Dhcp6SeekOption (\r
+                LastReply->Dhcp6.Option,\r
+-               LastReply->Length - 4,\r
++               LastReply->Length - sizeof (EFI_DHCP6_HEADER),\r
+                Dhcp6OptServerId\r
+                );\r
+     if (Option == NULL) {\r
+@@ -2208,7 +2279,7 @@ Dhcp6HandleReplyMsg (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              Packet->Dhcp6.Option,\r
+-             Packet->Length - 4,\r
++             Packet->Length - sizeof (EFI_DHCP6_HEADER),\r
+              Dhcp6OptRapidCommit\r
+              );\r
\r
+@@ -2354,7 +2425,7 @@ Dhcp6HandleReplyMsg (
+     //\r
+     // Any error status code option is found.\r
+     //\r
+-    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(Option + 4)));\r
++    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)((DHCP6_OFFSET_OF_STATUS_CODE (Option)))));\r
+     switch (StsCode) {\r
+       case Dhcp6StsUnspecFail:\r
+         //\r
+@@ -2487,7 +2558,7 @@ Dhcp6SelectAdvertiseMsg (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              AdSelect->Dhcp6.Option,\r
+-             AdSelect->Length - 4,\r
++             AdSelect->Length - sizeof (EFI_DHCP6_HEADER),\r
+              Dhcp6OptServerUnicast\r
+              );\r
\r
+@@ -2498,7 +2569,7 @@ Dhcp6SelectAdvertiseMsg (
+       return EFI_OUT_OF_RESOURCES;\r
+     }\r
\r
+-    CopyMem (Instance->Unicast, Option + 4, sizeof (EFI_IPv6_ADDRESS));\r
++    CopyMem (Instance->Unicast, DHCP6_OFFSET_OF_OPT_DATA (Option), sizeof (EFI_IPv6_ADDRESS));\r
+   }\r
\r
+   //\r
+@@ -2551,7 +2622,7 @@ Dhcp6HandleAdvertiseMsg (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              Packet->Dhcp6.Option,\r
+-             Packet->Length - 4,\r
++             Packet->Length - sizeof (EFI_DHCP6_HEADER),\r
+              Dhcp6OptRapidCommit\r
+              );\r
\r
+@@ -2645,7 +2716,7 @@ Dhcp6HandleAdvertiseMsg (
+       CopyMem (Instance->AdSelect, Packet, Packet->Size);\r
\r
+       if (Option != NULL) {\r
+-        Instance->AdPref = *(Option + 4);\r
++        Instance->AdPref = *(DHCP6_OFFSET_OF_OPT_DATA (Option));\r
+       }\r
+     } else {\r
+       //\r
+@@ -2714,11 +2785,11 @@ Dhcp6HandleStateful (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              Packet->Dhcp6.Option,\r
+-             Packet->Length - 4,\r
++             Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN,\r
+              Dhcp6OptClientId\r
+              );\r
\r
+-  if ((Option == NULL) || (CompareMem (Option + 4, ClientId->Duid, ClientId->Length) != 0)) {\r
++  if ((Option == NULL) || (CompareMem (DHCP6_OFFSET_OF_OPT_DATA (Option), ClientId->Duid, ClientId->Length) != 0)) {\r
+     goto ON_CONTINUE;\r
+   }\r
\r
+@@ -2727,7 +2798,7 @@ Dhcp6HandleStateful (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              Packet->Dhcp6.Option,\r
+-             Packet->Length - 4,\r
++             Packet->Length - DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN,\r
+              Dhcp6OptServerId\r
+              );\r
\r
+@@ -2832,7 +2903,7 @@ Dhcp6HandleStateless (
+   //\r
+   Option = Dhcp6SeekOption (\r
+              Packet->Dhcp6.Option,\r
+-             Packet->Length - 4,\r
++             Packet->Length - sizeof (EFI_DHCP6_HEADER),\r
+              Dhcp6OptServerId\r
+              );\r
\r
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0002.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0002.patch
new file mode 100644 (file)
index 0000000..7ce5c98
--- /dev/null
@@ -0,0 +1,539 @@
+From 07362769ab7a7d74dbea1c7a7a3662c7b5d1f097 Mon Sep 17 00:00:00 2001
+From: "Doug Flick via groups.io" <dougflick=microsoft.com@groups.io>
+Date: Fri, 26 Jan 2024 05:54:47 +0800
+Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit 
+ Tests
+
+REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534
+
+These tests confirm that the report bug...
+
+"Out-of-bounds read when processing IA_NA/IA_TA options in a
+DHCPv6 Advertise message"
+
+..has been patched.
+
+The following functions are tested to confirm an out of bounds read is
+patched and that the correct statuses are returned:
+
+Dhcp6SeekInnerOptionSafe
+Dhcp6SeekStsOption
+
+TCBZ4534
+CVE-2023-45229
+CVSS 6.5 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
+CWE-125 Out-of-bounds Read
+
+Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
+Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
+
+Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
+Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
+
+CVE: CVE-2023-45229
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/07362769ab7a7d74dbea1c7a7a3662c7b5d1f097]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ NetworkPkg/Dhcp6Dxe/Dhcp6Io.c                 |   2 +-
+ .../GoogleTest/Dhcp6DxeGoogleTest.inf         |   1 +
+ .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 365 +++++++++++++++++-
+ .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h   |  58 +++
+ 4 files changed, 423 insertions(+), 3 deletions(-)
+ create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h
+
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+index 89d16484a5..3b8feb4a20 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+@@ -816,7 +816,7 @@ Dhcp6SeekStsOption (
+   // IA option to the end of the DHCP6 option area, thus subtract the space\r
+   // up until this option\r
+   //\r
+-  OptionLen = OptionLen - (*Option - Packet->Dhcp6.Option);\r
++  OptionLen = OptionLen - (UINT32)(*Option - Packet->Dhcp6.Option);\r
\r
+   //\r
+   // Seek the inner option\r
+diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+index 8e9119a371..12532ed30c 100644
+--- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+@@ -18,6 +18,7 @@
+ [Sources]\r
+   Dhcp6DxeGoogleTest.cpp\r
+   Dhcp6IoGoogleTest.cpp\r
++  Dhcp6IoGoogleTest.h\r
+   ../Dhcp6Io.c\r
+   ../Dhcp6Utility.c\r
\r
+diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
+index 7ee40e4af4..7db253a7b8 100644
+--- a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
+@@ -13,6 +13,7 @@ extern "C" {
+   #include <Library/BaseMemoryLib.h>\r
+   #include "../Dhcp6Impl.h"\r
+   #include "../Dhcp6Utility.h"\r
++  #include "Dhcp6IoGoogleTest.h"\r
+ }\r
\r
+ ////////////////////////////////////////////////////////////////////////\r
+@@ -21,7 +22,35 @@ extern "C" {
\r
+ #define DHCP6_PACKET_MAX_LEN  1500\r
\r
++// This definition is used by this test but is also required to compile\r
++// by Dhcp6Io.c\r
++#define DHCPV6_OPTION_IA_NA  3\r
++#define DHCPV6_OPTION_IA_TA  4\r
++\r
++#define SEARCH_PATTERN      0xDEADC0DE\r
++#define SEARCH_PATTERN_LEN  sizeof(SEARCH_PATTERN)\r
++\r
+ ////////////////////////////////////////////////////////////////////////\r
++// Test structures for IA_NA and IA_TA options\r
++////////////////////////////////////////////////////////////////////////\r
++typedef struct {\r
++  UINT16    Code;\r
++  UINT16    Len;\r
++  UINT32    IAID;\r
++} DHCPv6_OPTION;\r
++\r
++typedef struct {\r
++  DHCPv6_OPTION    Header;\r
++  UINT32           T1;\r
++  UINT32           T2;\r
++  UINT8            InnerOptions[0];\r
++} DHCPv6_OPTION_IA_NA;\r
++\r
++typedef struct {\r
++  DHCPv6_OPTION    Header;\r
++  UINT8            InnerOptions[0];\r
++} DHCPv6_OPTION_IA_TA;\r
++\r
+ ////////////////////////////////////////////////////////////////////////\r
+ // Symbol Definitions\r
+ // These functions are not directly under test - but required to compile\r
+@@ -210,7 +239,7 @@ TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) {
+   Status = Dhcp6AppendETOption (\r
+              Dhcp6AppendETOptionTest::Packet,\r
+              &Cursor,\r
+-             &Instance, // Instance is not used in this function\r
++             &Instance,                    // Instance is not used in this function\r
+              &ElapsedTime\r
+              );\r
\r
+@@ -240,7 +269,7 @@ TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) {
+   Status = Dhcp6AppendETOption (\r
+              Dhcp6AppendETOptionTest::Packet,\r
+              &Cursor,\r
+-             &Instance, // Instance is not used in this function\r
++             &Instance,                    // Instance is not used in this function\r
+              &ElapsedTime\r
+              );\r
\r
+@@ -476,3 +505,335 @@ TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) {
+   // verify that the status is EFI_SUCCESS\r
+   ASSERT_EQ (Status, EFI_SUCCESS);\r
+ }\r
++\r
++////////////////////////////////////////////////////////////////////////\r
++// Dhcp6SeekInnerOptionSafe Tests\r
++////////////////////////////////////////////////////////////////////////\r
++\r
++// Define a fixture for your tests if needed\r
++class Dhcp6SeekInnerOptionSafeTest : public ::testing::Test {\r
++protected:\r
++  // Add any setup code if needed\r
++  virtual void\r
++  SetUp (\r
++    )\r
++  {\r
++    // Initialize any resources or variables\r
++  }\r
++\r
++  // Add any cleanup code if needed\r
++  virtual void\r
++  TearDown (\r
++    )\r
++  {\r
++    // Clean up any resources or variables\r
++  }\r
++};\r
++\r
++// Test Description:\r
++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IANA option is found.\r
++TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAValidOptionExpectSuccess) {\r
++  EFI_STATUS           Result;\r
++  UINT8                Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 };\r
++  UINT32               OptionLength                                              = sizeof (Option);\r
++  DHCPv6_OPTION_IA_NA  *OptionPtr                                                = (DHCPv6_OPTION_IA_NA *)Option;\r
++  UINT32               SearchPattern                                             = SEARCH_PATTERN;\r
++\r
++  UINTN   SearchPatternLength = SEARCH_PATTERN_LEN;\r
++  UINT8   *InnerOptionPtr     = NULL;\r
++  UINT16  InnerOptionLength   = 0;\r
++\r
++  OptionPtr->Header.Code = Dhcp6OptIana;\r
++  OptionPtr->Header.Len  = HTONS (4 + 12); // Valid length has to be more than 12\r
++  OptionPtr->Header.IAID = 0x12345678;\r
++  OptionPtr->T1          = 0x11111111;\r
++  OptionPtr->T2          = 0x22222222;\r
++  CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);\r
++\r
++  Result = Dhcp6SeekInnerOptionSafe (\r
++             Dhcp6OptIana,\r
++             Option,\r
++             OptionLength,\r
++             &InnerOptionPtr,\r
++             &InnerOptionLength\r
++             );\r
++  ASSERT_EQ (Result, EFI_SUCCESS);\r
++  ASSERT_EQ (InnerOptionLength, 4);\r
++  ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0);\r
++}\r
++\r
++// Test Description:\r
++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_DEIVCE_ERROR when the IANA option size is invalid.\r
++TEST_F (Dhcp6SeekInnerOptionSafeTest, IANAInvalidSizeExpectFail) {\r
++  // Lets add an inner option of bytes we expect to find\r
++  EFI_STATUS           Status;\r
++  UINT8                Option[sizeof (DHCPv6_OPTION_IA_NA) + SEARCH_PATTERN_LEN] = { 0 };\r
++  UINT32               OptionLength                                              = sizeof (Option);\r
++  DHCPv6_OPTION_IA_NA  *OptionPtr                                                = (DHCPv6_OPTION_IA_NA *)Option;\r
++  UINT32               SearchPattern                                             = SEARCH_PATTERN;\r
++\r
++  UINTN   SearchPatternLength = SEARCH_PATTERN_LEN;\r
++  UINT8   *InnerOptionPtr     = NULL;\r
++  UINT16  InnerOptionLength   = 0;\r
++\r
++  OptionPtr->Header.Code = Dhcp6OptIana;\r
++  OptionPtr->Header.Len  = HTONS (4); // Set the length to lower than expected (12)\r
++  OptionPtr->Header.IAID = 0x12345678;\r
++  OptionPtr->T1          = 0x11111111;\r
++  OptionPtr->T2          = 0x22222222;\r
++  CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);\r
++\r
++  // Set the InnerOptionLength to be less than the size of the option\r
++  Status = Dhcp6SeekInnerOptionSafe (\r
++             Dhcp6OptIana,\r
++             Option,\r
++             OptionLength,\r
++             &InnerOptionPtr,\r
++             &InnerOptionLength\r
++             );\r
++  ASSERT_EQ (Status, EFI_DEVICE_ERROR);\r
++\r
++  // Now set the OptionLength to be less than the size of the option\r
++  OptionLength = sizeof (DHCPv6_OPTION_IA_NA) - 1;\r
++  Status       = Dhcp6SeekInnerOptionSafe (\r
++                   Dhcp6OptIana,\r
++                   Option,\r
++                   OptionLength,\r
++                   &InnerOptionPtr,\r
++                   &InnerOptionLength\r
++                   );\r
++  ASSERT_EQ (Status, EFI_DEVICE_ERROR);\r
++}\r
++\r
++// Test Description:\r
++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option is found\r
++TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAValidOptionExpectSuccess) {\r
++  // Lets add an inner option of bytes we expect to find\r
++  EFI_STATUS           Status;\r
++  UINT8                Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 };\r
++  UINT32               OptionLength                                              = sizeof (Option);\r
++  DHCPv6_OPTION_IA_TA  *OptionPtr                                                = (DHCPv6_OPTION_IA_TA *)Option;\r
++  UINT32               SearchPattern                                             = SEARCH_PATTERN;\r
++\r
++  UINTN   SearchPatternLength = SEARCH_PATTERN_LEN;\r
++  UINT8   *InnerOptionPtr     = NULL;\r
++  UINT16  InnerOptionLength   = 0;\r
++\r
++  OptionPtr->Header.Code = Dhcp6OptIata;\r
++  OptionPtr->Header.Len  = HTONS (4 + 4); // Valid length has to be more than 4\r
++  OptionPtr->Header.IAID = 0x12345678;\r
++  CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);\r
++\r
++  Status = Dhcp6SeekInnerOptionSafe (\r
++             Dhcp6OptIata,\r
++             Option,\r
++             OptionLength,\r
++             &InnerOptionPtr,\r
++             &InnerOptionLength\r
++             );\r
++  ASSERT_EQ (Status, EFI_SUCCESS);\r
++  ASSERT_EQ (InnerOptionLength, 4);\r
++  ASSERT_EQ (CompareMem (InnerOptionPtr, &SearchPattern, SearchPatternLength), 0);\r
++}\r
++\r
++// Test Description:\r
++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid.\r
++TEST_F (Dhcp6SeekInnerOptionSafeTest, IATAInvalidSizeExpectFail) {\r
++  // Lets add an inner option of bytes we expect to find\r
++  EFI_STATUS           Status;\r
++  UINT8                Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 };\r
++  UINT32               OptionLength                                              = sizeof (Option);\r
++  DHCPv6_OPTION_IA_TA  *OptionPtr                                                = (DHCPv6_OPTION_IA_TA *)Option;\r
++  UINT32               SearchPattern                                             = SEARCH_PATTERN;\r
++\r
++  UINTN   SearchPatternLength = SEARCH_PATTERN_LEN;\r
++  UINT8   *InnerOptionPtr     = NULL;\r
++  UINT16  InnerOptionLength   = 0;\r
++\r
++  OptionPtr->Header.Code = Dhcp6OptIata;\r
++  OptionPtr->Header.Len  = HTONS (2); // Set the length to lower than expected (4)\r
++  OptionPtr->Header.IAID = 0x12345678;\r
++  CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);\r
++\r
++  Status = Dhcp6SeekInnerOptionSafe (\r
++             Dhcp6OptIata,\r
++             Option,\r
++             OptionLength,\r
++             &InnerOptionPtr,\r
++             &InnerOptionLength\r
++             );\r
++  ASSERT_EQ (Status, EFI_DEVICE_ERROR);\r
++\r
++  // Now lets try modifying the OptionLength to be less than the size of the option\r
++  OptionLength = sizeof (DHCPv6_OPTION_IA_TA) - 1;\r
++  Status       = Dhcp6SeekInnerOptionSafe (\r
++                   Dhcp6OptIata,\r
++                   Option,\r
++                   OptionLength,\r
++                   &InnerOptionPtr,\r
++                   &InnerOptionLength\r
++                   );\r
++  ASSERT_EQ (Status, EFI_DEVICE_ERROR);\r
++}\r
++\r
++// Test Description:\r
++// This test verifies that any other Option Type fails\r
++TEST_F (Dhcp6SeekInnerOptionSafeTest, InvalidOption) {\r
++  // Lets add an inner option of bytes we expect to find\r
++  EFI_STATUS           Result;\r
++  UINT8                Option[sizeof (DHCPv6_OPTION_IA_TA) + SEARCH_PATTERN_LEN] = { 0 };\r
++  UINT32               OptionLength                                              = sizeof (Option);\r
++  DHCPv6_OPTION_IA_TA  *OptionPtr                                                = (DHCPv6_OPTION_IA_TA *)Option;\r
++  UINT32               SearchPattern                                             = SEARCH_PATTERN;\r
++\r
++  UINTN   SearchPatternLength = SEARCH_PATTERN_LEN;\r
++  UINT8   *InnerOptionPtr     = NULL;\r
++  UINT16  InnerOptionLength   = 0;\r
++\r
++  OptionPtr->Header.Code = 0xC0DE;\r
++  OptionPtr->Header.Len  = HTONS (2); // Set the length to lower than expected (4)\r
++  OptionPtr->Header.IAID = 0x12345678;\r
++  CopyMem (OptionPtr->InnerOptions, &SearchPattern, SearchPatternLength);\r
++\r
++  Result = Dhcp6SeekInnerOptionSafe (0xC0DE, Option, OptionLength, &InnerOptionPtr, &InnerOptionLength);\r
++  ASSERT_EQ (Result, EFI_DEVICE_ERROR);\r
++}\r
++\r
++////////////////////////////////////////////////////////////////////////\r
++// Dhcp6SeekStsOption Tests\r
++////////////////////////////////////////////////////////////////////////\r
++\r
++#define PACKET_SIZE  (1500)\r
++\r
++class Dhcp6SeekStsOptionTest : public ::testing::Test {\r
++public:\r
++  DHCP6_INSTANCE Instance      = { 0 };\r
++  EFI_DHCP6_PACKET *Packet     = NULL;\r
++  EFI_DHCP6_CONFIG_DATA Config = { 0 };\r
++\r
++protected:\r
++  // Add any setup code if needed\r
++  virtual void\r
++  SetUp (\r
++    )\r
++  {\r
++    // Allocate a packet\r
++    Packet = (EFI_DHCP6_PACKET *)AllocateZeroPool (PACKET_SIZE);\r
++    ASSERT_NE (Packet, nullptr);\r
++\r
++    // Initialize the packet\r
++    Packet->Size = PACKET_SIZE;\r
++\r
++    Instance.Config = &Config;\r
++  }\r
++\r
++  // Add any cleanup code if needed\r
++  virtual void\r
++  TearDown (\r
++    )\r
++  {\r
++    // Clean up any resources or variables\r
++    FreePool (Packet);\r
++  }\r
++};\r
++\r
++// Test Description:\r
++// This test verifies that Dhcp6SeekStsOption returns EFI_DEVICE_ERROR when the option is invalid\r
++// This verifies that the calling function is working as expected\r
++TEST_F (Dhcp6SeekStsOptionTest, SeekIATAOptionExpectFail) {\r
++  EFI_STATUS    Status;\r
++  UINT8         *Option             = NULL;\r
++  UINT32        SearchPattern       = SEARCH_PATTERN;\r
++  UINT16        SearchPatternLength = SEARCH_PATTERN_LEN;\r
++  UINT16        *Len                = NULL;\r
++  EFI_DHCP6_IA  Ia                  = { 0 };\r
++\r
++  Ia.Descriptor.Type                = DHCPV6_OPTION_IA_TA;\r
++  Ia.IaAddressCount                 = 1;\r
++  Ia.IaAddress[0].PreferredLifetime = 0xDEADBEEF;\r
++  Ia.IaAddress[0].ValidLifetime     = 0xDEADAAAA;\r
++  Ia.IaAddress[0].IpAddress         = mAllDhcpRelayAndServersAddress;\r
++\r
++  Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
++\r
++  Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option;\r
++\r
++  // Let's append the option to the packet\r
++  Status = Dhcp6AppendOption (\r
++             Dhcp6SeekStsOptionTest::Packet,\r
++             &Option,\r
++             Dhcp6OptStatusCode,\r
++             SearchPatternLength,\r
++             (UINT8 *)&SearchPattern\r
++             );\r
++  ASSERT_EQ (Status, EFI_SUCCESS);\r
++\r
++  // Inner option length - this will be overwritten later\r
++  Len = (UINT16 *)(Option + 2);\r
++\r
++  // Fill in the inner IA option\r
++  Status = Dhcp6AppendIaOption (\r
++             Dhcp6SeekStsOptionTest::Packet,\r
++             &Option,\r
++             &Ia,\r
++             0x12345678,\r
++             0x11111111,\r
++             0x22222222\r
++             );\r
++  ASSERT_EQ (Status, EFI_SUCCESS);\r
++\r
++  // overwrite the len of inner Ia option\r
++  *Len = HTONS (3);\r
++\r
++  Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_TA;\r
++\r
++  Option = NULL;\r
++  Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option);\r
++\r
++  ASSERT_EQ (Status, EFI_DEVICE_ERROR);\r
++}\r
++\r
++// Test Description:\r
++// This test verifies that Dhcp6SeekInnerOptionSafe returns EFI_SUCCESS when the IATA option size is invalid.\r
++TEST_F (Dhcp6SeekStsOptionTest, SeekIANAOptionExpectSuccess) {\r
++  EFI_STATUS    Status              = EFI_NOT_FOUND;\r
++  UINT8         *Option             = NULL;\r
++  UINT32        SearchPattern       = SEARCH_PATTERN;\r
++  UINT16        SearchPatternLength = SEARCH_PATTERN_LEN;\r
++  EFI_DHCP6_IA  Ia                  = { 0 };\r
++\r
++  Ia.Descriptor.Type                = DHCPV6_OPTION_IA_NA;\r
++  Ia.IaAddressCount                 = 1;\r
++  Ia.IaAddress[0].PreferredLifetime = 0x11111111;\r
++  Ia.IaAddress[0].ValidLifetime     = 0x22222222;\r
++  Ia.IaAddress[0].IpAddress         = mAllDhcpRelayAndServersAddress;\r
++  Packet->Length                    = sizeof (EFI_DHCP6_HEADER);\r
++\r
++  Option = Dhcp6SeekStsOptionTest::Packet->Dhcp6.Option;\r
++\r
++  Status = Dhcp6AppendOption (\r
++             Dhcp6SeekStsOptionTest::Packet,\r
++             &Option,\r
++             Dhcp6OptStatusCode,\r
++             SearchPatternLength,\r
++             (UINT8 *)&SearchPattern\r
++             );\r
++  ASSERT_EQ (Status, EFI_SUCCESS);\r
++\r
++  Status = Dhcp6AppendIaOption (\r
++             Dhcp6SeekStsOptionTest::Packet,\r
++             &Option,\r
++             &Ia,\r
++             0x12345678,\r
++             0x11111111,\r
++             0x22222222\r
++             );\r
++  ASSERT_EQ (Status, EFI_SUCCESS);\r
++\r
++  Dhcp6SeekStsOptionTest::Instance.Config->IaDescriptor.Type = DHCPV6_OPTION_IA_NA;\r
++\r
++  Option = NULL;\r
++  Status = Dhcp6SeekStsOption (&(Dhcp6SeekStsOptionTest::Instance), Dhcp6SeekStsOptionTest::Packet, &Option);\r
++\r
++  ASSERT_EQ (Status, EFI_SUCCESS);\r
++}\r
+diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h
+new file mode 100644
+index 0000000000..aed3b89082
+--- /dev/null
++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.h
+@@ -0,0 +1,58 @@
++/** @file\r
++  Acts as header for private functions under test in Dhcp6Io.c\r
++\r
++  Copyright (c) Microsoft Corporation\r
++  SPDX-License-Identifier: BSD-2-Clause-Patent\r
++**/\r
++\r
++#ifndef DHCP6_IO_GOOGLE_TEST_H_\r
++#define DHCP6_IO_GOOGLE_TEST_H_\r
++\r
++////////////////////////////////////////////////////////////////////////////////\r
++// These are the functions that are being unit tested\r
++////////////////////////////////////////////////////////////////////////////////\r
++\r
++#include <Uefi.h>\r
++\r
++/**\r
++  Seeks the Inner Options from a DHCP6 Option\r
++\r
++  @param[in]  IaType          The type of the IA option.\r
++  @param[in]  Option          The pointer to the DHCP6 Option.\r
++  @param[in]  OptionLen       The length of the DHCP6 Option.\r
++  @param[out] IaInnerOpt      The pointer to the IA inner option.\r
++  @param[out] IaInnerLen      The length of the IA inner option.\r
++\r
++  @retval EFI_SUCCESS         Seek the inner option successfully.\r
++  @retval EFI_DEVICE_ERROR    The OptionLen is invalid.\r
++*/\r
++EFI_STATUS\r
++Dhcp6SeekInnerOptionSafe (\r
++  UINT16  IaType,\r
++  UINT8   *Option,\r
++  UINT32  OptionLen,\r
++  UINT8   **IaInnerOpt,\r
++  UINT16  *IaInnerLen\r
++  );\r
++\r
++/**\r
++  Seek StatusCode Option in package. A Status Code option may appear in the\r
++  options field of a DHCP message and/or in the options field of another option.\r
++  See details in section 22.13, RFC3315.\r
++\r
++  @param[in]       Instance        The pointer to the Dhcp6 instance.\r
++  @param[in]       Packet          The pointer to reply messages.\r
++  @param[out]      Option          The pointer to status code option.\r
++\r
++  @retval EFI_SUCCESS              Seek status code option successfully.\r
++  @retval EFI_DEVICE_ERROR         An unexpected error.\r
++\r
++**/\r
++EFI_STATUS\r
++Dhcp6SeekStsOption (\r
++  IN     DHCP6_INSTANCE    *Instance,\r
++  IN     EFI_DHCP6_PACKET  *Packet,\r
++  OUT    UINT8             **Option\r
++  );\r
++\r
++#endif // DHCP6_IO_GOOGLE_TEST_H\r
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0003.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0003.patch
new file mode 100644 (file)
index 0000000..bf4e8ed
--- /dev/null
@@ -0,0 +1,244 @@
+From 1c440a5eceedc64e892877eeac0f1a4938f5abbb Mon Sep 17 00:00:00 2001
+From: Doug Flick <dougflick@microsoft.com>
+Date: Tue, 13 Feb 2024 10:46:00 -0800
+Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Related 
+ Patch
+
+REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4673
+REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4534
+
+This was not part of the Quarkslab bugs however the same pattern
+as CVE-2023-45229 exists in Dhcp6UpdateIaInfo.
+
+This patch replaces the code in question with the safe function
+created to patch CVE-2023-45229
+
+>
+>   if (EFI_ERROR (
+>        Dhcp6SeekInnerOptionSafe (
+>          Instance->Config->IaDescriptor.Type,
+>          Option,
+>          OptionLen,
+>          &IaInnerOpt,
+>          &IaInnerLen
+>          )
+>        ))
+>  {
+>    return EFI_DEVICE_ERROR;
+>  }
+>
+
+Additionally corrects incorrect usage of macro to read the status
+
+> - StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN
+ (Option)));
+> + StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)
+DHCP6_OFFSET_OF_STATUS_CODE (Option));
+
+Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
+Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
+Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
+Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
+Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
+
+CVE: CVE-2023-45229
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1c440a5eceedc64e892877eeac0f1a4938f5abbb]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ 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 (
+ {\r
+   EFI_STATUS  Status;\r
+   UINT8       *Option;\r
++  UINT32      OptionLen;\r
+   UINT8       *IaInnerOpt;\r
+   UINT16      IaInnerLen;\r
+   UINT16      StsCode;\r
+   UINT32      T1;\r
+   UINT32      T2;\r
\r
++  T1 = 0;\r
++  T2 = 0;\r
++\r
+   ASSERT (Instance->Config != NULL);\r
++\r
++  // OptionLen is the length of the Options excluding the DHCP header.\r
++  // Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last\r
++  // byte of the Option[] field.\r
++  OptionLen = Packet->Length - sizeof (Packet->Dhcp6.Header);\r
++\r
+   //\r
+   // If the reply was received in response to a solicit with rapid commit option,\r
+   // request, renew or rebind message, the client updates the information it has\r
+@@ -549,13 +559,29 @@ Dhcp6UpdateIaInfo (
+   //\r
+   Option = Dhcp6SeekIaOption (\r
+              Packet->Dhcp6.Option,\r
+-             Packet->Length - sizeof (EFI_DHCP6_HEADER),\r
++             OptionLen,\r
+              &Instance->Config->IaDescriptor\r
+              );\r
+   if (Option == NULL) {\r
+     return EFI_DEVICE_ERROR;\r
+   }\r
\r
++  //\r
++  // Calculate the distance from Packet->Dhcp6.Option to the IA option.\r
++  //\r
++  // Packet->Size and Packet->Length are both UINT32 type, and Packet->Size is\r
++  // the size of the whole packet, including the DHCP header, and Packet->Length\r
++  // is the length of the DHCP message body, excluding the DHCP header.\r
++  //\r
++  // (*Option - Packet->Dhcp6.Option) is the number of bytes from the start of\r
++  // DHCP6 option area to the start of the IA option.\r
++  //\r
++  // Dhcp6SeekInnerOptionSafe() is searching starting from the start of the\r
++  // IA option to the end of the DHCP6 option area, thus subtract the space\r
++  // up until this option\r
++  //\r
++  OptionLen = OptionLen - (UINT32)(Option - Packet->Dhcp6.Option);\r
++\r
+   //\r
+   // The format of the IA_NA option is:\r
+   //\r
+@@ -591,32 +617,32 @@ Dhcp6UpdateIaInfo (
+   //\r
\r
+   //\r
+-  // sizeof (option-code + option-len + IaId)           = 8\r
+-  // sizeof (option-code + option-len + IaId + T1)      = 12\r
+-  // sizeof (option-code + option-len + IaId + T1 + T2) = 16\r
+-  //\r
+-  // The inner options still start with 2 bytes option-code and 2 bytes option-len.\r
++  // Seek the inner option\r
+   //\r
++  if (EFI_ERROR (\r
++        Dhcp6SeekInnerOptionSafe (\r
++          Instance->Config->IaDescriptor.Type,\r
++          Option,\r
++          OptionLen,\r
++          &IaInnerOpt,\r
++          &IaInnerLen\r
++          )\r
++        ))\r
++  {\r
++    return EFI_DEVICE_ERROR;\r
++  }\r
++\r
+   if (Instance->Config->IaDescriptor.Type == Dhcp6OptIana) {\r
+     T1 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T1 (Option))));\r
+     T2 = NTOHL (ReadUnaligned32 ((UINT32 *)(DHCP6_OFFSET_OF_IA_NA_T2 (Option))));\r
+     //\r
+     // Refer to RFC3155 Chapter 22.4. If a client receives an IA_NA with T1 greater than T2,\r
+     // and both T1 and T2 are greater than 0, the client discards the IA_NA option and processes\r
+-    // the remainder of the message as though the server had not  included the invalid IA_NA option.\r
++    // the remainder of the message as though the server had not included the invalid IA_NA option.\r
+     //\r
+     if ((T1 > T2) && (T2 > 0)) {\r
+       return EFI_DEVICE_ERROR;\r
+     }\r
+-\r
+-    IaInnerOpt = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);\r
+-    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_COMBINED_IAID_T1_T2);\r
+-  } else {\r
+-    T1 = 0;\r
+-    T2 = 0;\r
+-\r
+-    IaInnerOpt = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);\r
+-    IaInnerLen = (UINT16)(NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option)))) - DHCP6_SIZE_OF_IAID);\r
+   }\r
\r
+   //\r
+@@ -642,7 +668,7 @@ Dhcp6UpdateIaInfo (
+   Option  = Dhcp6SeekOption (IaInnerOpt, IaInnerLen, Dhcp6OptStatusCode);\r
\r
+   if (Option != NULL) {\r
+-    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option))));\r
++    StsCode = NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_STATUS_CODE (Option))));\r
+     if (StsCode != Dhcp6StsSuccess) {\r
+       return EFI_DEVICE_ERROR;\r
+     }\r
+@@ -703,15 +729,21 @@ Dhcp6SeekInnerOptionSafe (
+   }\r
\r
+   if (IaType == Dhcp6OptIana) {\r
++    //\r
+     // Verify we have a fully formed IA_NA\r
++    //\r
+     if (OptionLen < DHCP6_MIN_SIZE_OF_IA_NA) {\r
+       return EFI_DEVICE_ERROR;\r
+     }\r
\r
++    //\r
++    // Get the IA Inner Option and Length\r
+     //\r
+     IaInnerOptTmp = DHCP6_OFFSET_OF_IA_NA_INNER_OPT (Option);\r
\r
++    //\r
+     // Verify the IaInnerLen is valid.\r
++    //\r
+     IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)DHCP6_OFFSET_OF_OPT_LEN (Option)));\r
+     if (IaInnerLenTmp < DHCP6_SIZE_OF_COMBINED_IAID_T1_T2) {\r
+       return EFI_DEVICE_ERROR;\r
+@@ -719,14 +751,18 @@ Dhcp6SeekInnerOptionSafe (
\r
+     IaInnerLenTmp -= DHCP6_SIZE_OF_COMBINED_IAID_T1_T2;\r
+   } else if (IaType == Dhcp6OptIata) {\r
++    //\r
+     // Verify the OptionLen is valid.\r
++    //\r
+     if (OptionLen < DHCP6_MIN_SIZE_OF_IA_TA) {\r
+       return EFI_DEVICE_ERROR;\r
+     }\r
\r
+     IaInnerOptTmp = DHCP6_OFFSET_OF_IA_TA_INNER_OPT (Option);\r
\r
++    //\r
+     // Verify the IaInnerLen is valid.\r
++    //\r
+     IaInnerLenTmp = (UINT16)NTOHS (ReadUnaligned16 ((UINT16 *)(DHCP6_OFFSET_OF_OPT_LEN (Option))));\r
+     if (IaInnerLenTmp < DHCP6_SIZE_OF_IAID) {\r
+       return EFI_DEVICE_ERROR;\r
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h
+index 051a652f2b..ab0e1ac27f 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h
+@@ -217,4 +217,26 @@ Dhcp6OnTimerTick (
+   IN VOID       *Context\r
+   );\r
\r
++/**\r
++  Seeks the Inner Options from a DHCP6 Option\r
++\r
++  @param[in]  IaType          The type of the IA option.\r
++  @param[in]  Option          The pointer to the DHCP6 Option.\r
++  @param[in]  OptionLen       The length of the DHCP6 Option.\r
++  @param[out] IaInnerOpt      The pointer to the IA inner option.\r
++  @param[out] IaInnerLen      The length of the IA inner option.\r
++\r
++  @retval EFI_SUCCESS         Seek the inner option successfully.\r
++  @retval EFI_DEVICE_ERROR    The OptionLen is invalid. On Error,\r
++                              the pointers are not modified\r
++**/\r
++EFI_STATUS\r
++Dhcp6SeekInnerOptionSafe (\r
++  IN  UINT16  IaType,\r
++  IN  UINT8   *Option,\r
++  IN  UINT32  OptionLen,\r
++  OUT UINT8   **IaInnerOpt,\r
++  OUT UINT16  *IaInnerLen\r
++  );\r
++\r
+ #endif\r
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0004.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45229-0004.patch
new file mode 100644 (file)
index 0000000..85d2049
--- /dev/null
@@ -0,0 +1,157 @@
+From 1d0b95f6457d225c5108302a9da74b4ed7aa5a38 Mon Sep 17 00:00:00 2001
+From: "Doug Flick via groups.io" <dougflick=microsoft.com@groups.io>
+Date: Fri, 26 Jan 2024 05:54:57 +0800
+Subject: [PATCH] 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 <saloni.kasbekar@intel.com>
+Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
+
+Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
+Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
+
+CVE: CVE_2023_45229
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/1d0b95f6457d225c5108302a9da74b4ed7aa5a38]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ NetworkPkg/SecurityFixes.yaml | 123 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 123 insertions(+)
+ create mode 100644 NetworkPkg/SecurityFixes.yaml
+
+diff --git a/NetworkPkg/SecurityFixes.yaml b/NetworkPkg/SecurityFixes.yaml
+new file mode 100644
+index 0000000000..7e900483fe
+--- /dev/null
++++ b/NetworkPkg/SecurityFixes.yaml
+@@ -0,0 +1,123 @@
++## @file\r
++# Security Fixes for SecurityPkg\r
++#\r
++# Copyright (c) Microsoft Corporation\r
++# SPDX-License-Identifier: BSD-2-Clause-Patent\r
++##\r
++CVE_2023_45229:\r
++  commit_titles:\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Patch"\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45229 Unit Tests"\r
++  cve: CVE-2023-45229\r
++  date_reported: 2023-08-28 13:56 UTC\r
++  description: "Bug 01 - edk2/NetworkPkg: Out-of-bounds read when processing IA_NA/IA_TA options in a DHCPv6 Advertise message"\r
++  note:\r
++  files_impacted:\r
++    - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c\r
++    - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h\r
++  links:\r
++    - https://bugzilla.tianocore.org/show_bug.cgi?id=4534\r
++    - https://nvd.nist.gov/vuln/detail/CVE-2023-45229\r
++    - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++    - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++    - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
++CVE_2023_45230:\r
++  commit_titles:\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch"\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit Tests"\r
++  cve: CVE-2023-45230\r
++  date_reported: 2023-08-28 13:56 UTC\r
++  description: "Bug 02 - edk2/NetworkPkg: Buffer overflow in the DHCPv6 client via a long Server ID option"\r
++  note:\r
++  files_impacted:\r
++    - NetworkPkg\Dhcp6Dxe\Dhcp6Io.c\r
++    - NetworkPkg\Dhcp6Dxe\Dhcp6Impl.h\r
++  links:\r
++    - https://bugzilla.tianocore.org/show_bug.cgi?id=4535\r
++    - https://nvd.nist.gov/vuln/detail/CVE-2023-45230\r
++    - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++    - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++    - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
++CVE_2023_45231:\r
++  commit_titles:\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Patch"\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45231 Unit Tests"\r
++  cve: CVE-2023-45231\r
++  date_reported: 2023-08-28 13:56 UTC\r
++  description: "Bug 03 - edk2/NetworkPkg: Out-of-bounds read when handling a ND Redirect message with truncated options"\r
++  note:\r
++  files_impacted:\r
++    - NetworkPkg/Ip6Dxe/Ip6Option.c\r
++  links:\r
++    - https://bugzilla.tianocore.org/show_bug.cgi?id=4536\r
++    - https://nvd.nist.gov/vuln/detail/CVE-2023-45231\r
++    - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++    - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++    - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
++CVE_2023_45232:\r
++  commit_titles:\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch"\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests"\r
++  cve: CVE-2023-45232\r
++  date_reported: 2023-08-28 13:56 UTC\r
++  description: "Bug 04 - edk2/NetworkPkg: Infinite loop when parsing unknown options in the Destination Options header"\r
++  note:\r
++  files_impacted:\r
++    - NetworkPkg/Ip6Dxe/Ip6Option.c\r
++    - NetworkPkg/Ip6Dxe/Ip6Option.h\r
++  links:\r
++    - https://bugzilla.tianocore.org/show_bug.cgi?id=4537\r
++    - https://nvd.nist.gov/vuln/detail/CVE-2023-45232\r
++    - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++    - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++    - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
++CVE_2023_45233:\r
++  commit_titles:\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Patch"\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45232 Unit Tests"\r
++  cve: CVE-2023-45233\r
++  date_reported: 2023-08-28 13:56 UTC\r
++  description: "Bug 05 - edk2/NetworkPkg: Infinite loop when parsing a PadN option in the Destination Options header "\r
++  note: This was fixed along with CVE-2023-45233\r
++  files_impacted:\r
++    - NetworkPkg/Ip6Dxe/Ip6Option.c\r
++    - NetworkPkg/Ip6Dxe/Ip6Option.h\r
++  links:\r
++    - https://bugzilla.tianocore.org/show_bug.cgi?id=4538\r
++    - https://nvd.nist.gov/vuln/detail/CVE-2023-45233\r
++    - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++    - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++    - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
++CVE_2023_45234:\r
++  commit_titles:\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Patch"\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45234 Unit Tests"\r
++  cve: CVE-2023-45234\r
++  date_reported: 2023-08-28 13:56 UTC\r
++  description: "Bug 06 - edk2/NetworkPkg: Buffer overflow when processing DNS Servers option in a DHCPv6 Advertise message"\r
++  note:\r
++  files_impacted:\r
++    - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c\r
++  links:\r
++    - https://bugzilla.tianocore.org/show_bug.cgi?id=4539\r
++    - https://nvd.nist.gov/vuln/detail/CVE-2023-45234\r
++    - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++    - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++    - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
++CVE_2023_45235:\r
++  commit_titles:\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Patch"\r
++    - "NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45235 Unit Tests"\r
++  cve: CVE-2023-45235\r
++  date_reported: 2023-08-28 13:56 UTC\r
++  description: "Bug 07 - edk2/NetworkPkg: Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message"\r
++  note:\r
++  files_impacted:\r
++    - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c\r
++    - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h\r
++  links:\r
++    - https://bugzilla.tianocore.org/show_bug.cgi?id=4540\r
++    - https://nvd.nist.gov/vuln/detail/CVE-2023-45235\r
++    - http://www.openwall.com/lists/oss-security/2024/01/16/2\r
++    - http://packetstormsecurity.com/files/176574/PixieFail-Proof-Of-Concepts.html\r
++    - https://blog.quarkslab.com/pixiefail-nine-vulnerabilities-in-tianocores-edk-ii-ipv6-network-stack.html\r
+-- 
+2.40.0
+
index ceebb53438bbe4288b8249569dcb3a3cc44c50fa..6ac72772d18dafa0830bcff1808172aa395b0c68 100644 (file)
@@ -43,6 +43,10 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
            file://CVE-2023-45234-0002.patch \
            file://CVE-2023-45235-0001.patch \
            file://CVE-2023-45235-0002.patch \
+           file://CVE-2023-45229-0001.patch \
+           file://CVE-2023-45229-0002.patch \
+           file://CVE-2023-45229-0003.patch \
+           file://CVE-2023-45229-0004.patch \
            "
 
 PV = "edk2-stable202202"