diff mbox series

[kirkstone,V2,03/13] ovmf: Fix CVE-2023-45230

Message ID 20241126022526.3389121-3-hongxu.jia@windriver.com
State New
Headers show
Series [kirkstone,V2,01/13] ovmf: Fix CVE-2022-36763 | expand

Commit Message

Hongxu Jia Nov. 26, 2024, 2:25 a.m. UTC
From: Soumya Sambu <soumya.sambu@windriver.com>

EDK2's Network Package is susceptible to a buffer overflow vulnerability
via a long server ID option in DHCPv6 client. This vulnerability can be
exploited by an attacker to gain unauthorized access and potentially lead
to a loss of Confidentiality, Integrity and/or Availability.

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

Upstream-patches:
https://github.com/tianocore/edk2/commit/f31453e8d6542461d92d835e0b79fec8b039174d
https://github.com/tianocore/edk2/commit/5f3658197bf29c83b3349b0ab1d99cdb0c3814bc

Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
---
 .../ovmf/ovmf/CVE-2023-45230-0001.patch       | 1617 +++++++++++++++++
 .../ovmf/ovmf/CVE-2023-45230-0002.patch       |  604 ++++++
 meta/recipes-core/ovmf/ovmf_git.bb            |    2 +
 3 files changed, 2223 insertions(+)
 create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0001.patch
 create mode 100644 meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0002.patch
diff mbox series

Patch

diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0001.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0001.patch
new file mode 100644
index 0000000000..b0e13c1613
--- /dev/null
+++ b/meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0001.patch
@@ -0,0 +1,1617 @@ 
+From f31453e8d6542461d92d835e0b79fec8b039174d 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:43 +0800
+Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch
+
+REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535
+
+Bug Details:
+PixieFail Bug #2
+CVE-2023-45230
+CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
+CWE-119 Improper Restriction of Operations within the Bounds
+ of a Memory Buffer
+
+Changes Overview:
+> -UINT8 *
+> +EFI_STATUS
+>  Dhcp6AppendOption (
+> -  IN OUT UINT8   *Buf,
+> -  IN     UINT16  OptType,
+> -  IN     UINT16  OptLen,
+> -  IN     UINT8   *Data
+> +  IN OUT EFI_DHCP6_PACKET  *Packet,
+> +  IN OUT UINT8             **PacketCursor,
+> +  IN     UINT16            OptType,
+> +  IN     UINT16            OptLen,
+> +  IN     UINT8             *Data
+>    );
+
+Dhcp6AppendOption() and variants can return errors now.  All callsites
+are adapted accordingly.
+
+It gets passed in EFI_DHCP6_PACKET as additional parameter ...
+
+> +  //
+> +  // Verify the PacketCursor is within the packet
+> +  //
+> +  if (  (*PacketCursor < Packet->Dhcp6.Option)
+> +     || (*PacketCursor >= Packet->Dhcp6.Option +
+ (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
+> +  {
+> +    return EFI_INVALID_PARAMETER;
+> +  }
+
+... so it can look at Packet->Size when checking buffer space.
+Also to allow Packet->Length updates.
+
+Lots of checks added.
+
+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-45230
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/f31453e8d6542461d92d835e0b79fec8b039174d]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h    |  43 +++
+ NetworkPkg/Dhcp6Dxe/Dhcp6Io.c      | 409 +++++++++++++++++++----------
+ NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 373 +++++++++++++++++++++-----
+ NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h |  82 +++---
+ 4 files changed, 668 insertions(+), 239 deletions(-)
+
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+index 0eb9c669b5..f2422c2f28 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+@@ -45,6 +45,49 @@ typedef struct _DHCP6_INSTANCE  DHCP6_INSTANCE;
+ #define DHCP6_SERVICE_SIGNATURE   SIGNATURE_32 ('D', 'H', '6', 'S')
+ #define DHCP6_INSTANCE_SIGNATURE  SIGNATURE_32 ('D', 'H', '6', 'I')
+ 
++//
++// For more information on DHCP options see RFC 8415, Section 21.1
++//
++// The format of DHCP options is:
++//
++//     0                   1                   2                   3
++//     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++//    |          option-code          |           option-len          |
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++//    |                          option-data                          |
++//    |                      (option-len octets)                      |
++//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++//
++#define DHCP6_SIZE_OF_OPT_CODE  (sizeof(UINT16))
++#define DHCP6_SIZE_OF_OPT_LEN   (sizeof(UINT16))
++
++//
++// Combined size of Code and Length
++//
++#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN  (DHCP6_SIZE_OF_OPT_CODE + \
++                                              DHCP6_SIZE_OF_OPT_LEN)
++
++STATIC_ASSERT (
++  DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN == 4,
++  "Combined size of Code and Length must be 4 per RFC 8415"
++  );
++
++//
++// Offset to the length is just past the code
++//
++#define DHCP6_OPT_LEN_OFFSET(a)  (a + DHCP6_SIZE_OF_OPT_CODE)
++STATIC_ASSERT (
++  DHCP6_OPT_LEN_OFFSET (0) == 2,
++  "Offset of length is + 2 past start of option"
++  );
++
++#define DHCP6_OPT_DATA_OFFSET(a)  (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN)
++STATIC_ASSERT (
++  DHCP6_OPT_DATA_OFFSET (0) == 4,
++  "Offset to option data should be +4 from start of option"
++  );
++
+ #define DHCP6_PACKET_ALL        0
+ #define DHCP6_PACKET_STATEFUL   1
+ #define DHCP6_PACKET_STATELESS  2
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+index dcd01e6268..bf5aa7a769 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+@@ -3,9 +3,9 @@
+ 
+   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
+   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
++  Copyright (c) Microsoft Corporation
+ 
+   SPDX-License-Identifier: BSD-2-Clause-Patent
+-
+ **/
+ 
+ #include "Dhcp6Impl.h"
+@@ -930,7 +930,8 @@ Dhcp6SendSolicitMsg   (
+   //
+   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
+   if (Packet == NULL) {
+-    return EFI_OUT_OF_RESOURCES;
++    Status = EFI_OUT_OF_RESOURCES;
++    goto ON_ERROR;
+   }
+ 
+   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
+@@ -944,54 +945,64 @@ Dhcp6SendSolicitMsg   (
+   Cursor = Packet->Dhcp6.Option;
+ 
+   Length = HTONS (ClientId->Length);
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptClientId),
+              Length,
+              ClientId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendETOption (
+-             Cursor,
++  Status = Dhcp6AppendETOption (
++             Packet,
++             &Cursor,
+              Instance,
+              &Elapsed
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendIaOption (
+-             Cursor,
++  Status = Dhcp6AppendIaOption (
++             Packet,
++             &Cursor,
+              Instance->IaCb.Ia,
+              Instance->IaCb.T1,
+              Instance->IaCb.T2,
+              Packet->Dhcp6.Header.MessageType
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+   //
+   // Append user-defined when configurate Dhcp6 service.
+   //
+   for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
+     UserOpt = Instance->Config->OptionList[Index];
+-    Cursor  = Dhcp6AppendOption (
+-                Cursor,
++    Status  = Dhcp6AppendOption (
++                Packet,
++                &Cursor,
+                 UserOpt->OpCode,
+                 UserOpt->OpLen,
+                 UserOpt->Data
+                 );
++    if (EFI_ERROR (Status)) {
++      goto ON_ERROR;
++    }
+   }
+ 
+-  //
+-  // Determine the size/length of packet.
+-  //
+-  Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
+   ASSERT (Packet->Size > Packet->Length + 8);
+ 
+   //
+   // Callback to user with the packet to be sent and check the user's feedback.
+   //
+   Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+@@ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg   (
+   Instance->StartTime = 0;
+ 
+   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+@@ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg   (
+            Elapsed,
+            Instance->Config->SolicitRetransmission
+            );
++
++ON_ERROR:
++
++  if (Packet) {
++    FreePool (Packet);
++  }
++
++  return Status;
+ }
+ 
+ /**
+@@ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg (
+   //
+   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
+   if (Packet == NULL) {
+-    return EFI_OUT_OF_RESOURCES;
++    Status = EFI_OUT_OF_RESOURCES;
++    goto ON_ERROR;
+   }
+ 
+   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
+@@ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg (
+   Cursor = Packet->Dhcp6.Option;
+ 
+   Length = HTONS (ClientId->Length);
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptClientId),
+              Length,
+              ClientId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendETOption (
+-             Cursor,
++  Status = Dhcp6AppendETOption (
++             Packet,
++             &Cursor,
+              Instance,
+              &Elapsed
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptServerId),
+              ServerId->Length,
+              ServerId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendIaOption (
+-             Cursor,
++  Status = Dhcp6AppendIaOption (
++             Packet,
++             &Cursor,
+              Instance->IaCb.Ia,
+              Instance->IaCb.T1,
+              Instance->IaCb.T2,
+              Packet->Dhcp6.Header.MessageType
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+   //
+   // Append user-defined when configurate Dhcp6 service.
+   //
+   for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
+     UserOpt = Instance->Config->OptionList[Index];
+-    Cursor  = Dhcp6AppendOption (
+-                Cursor,
++    Status  = Dhcp6AppendOption (
++                Packet,
++                &Cursor,
+                 UserOpt->OpCode,
+                 UserOpt->OpLen,
+                 UserOpt->Data
+                 );
++    if (EFI_ERROR (Status)) {
++      goto ON_ERROR;
++    }
+   }
+ 
+-  //
+-  // Determine the size/length of packet.
+-  //
+-  Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
+   ASSERT (Packet->Size > Packet->Length + 8);
+ 
+   //
+@@ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg (
+   Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet);
+ 
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+@@ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg (
+   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
+ 
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+   // Enqueue the sent packet for the retransmission in case reply timeout.
+   //
+   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
++
++ON_ERROR:
++
++  if (Packet) {
++    FreePool (Packet);
++  }
++
++  return Status;
+ }
+ 
+ /**
+@@ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg (
+   //
+   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
+   if (Packet == NULL) {
+-    return EFI_OUT_OF_RESOURCES;
++    Status = EFI_OUT_OF_RESOURCES;
++    goto ON_ERROR;
+   }
+ 
+   Packet->Size                       = DHCP6_BASE_PACKET_SIZE;
+@@ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg (
+   Cursor = Packet->Dhcp6.Option;
+ 
+   Length = HTONS (ClientId->Length);
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptClientId),
+              Length,
+              ClientId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendETOption (
+-             Cursor,
++  Status = Dhcp6AppendETOption (
++             Packet,
++             &Cursor,
+              Instance,
+              &Elapsed
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptServerId),
+              ServerId->Length,
+              ServerId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType);
++  Status = Dhcp6AppendIaOption (
++             Packet,
++             &Cursor,
++             DecIa,
++             0,
++             0,
++             Packet->Dhcp6.Header.MessageType
++             );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  //
+-  // Determine the size/length of packet.
+-  //
+-  Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
+   ASSERT (Packet->Size > Packet->Length + 8);
+ 
+   //
+   // Callback to user with the packet to be sent and check the user's feedback.
+   //
+   Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+@@ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg (
+   Instance->StartTime = 0;
+ 
+   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+   // Enqueue the sent packet for the retransmission in case reply timeout.
+   //
+   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
++
++ON_ERROR:
++
++  if (Packet) {
++    FreePool (Packet);
++  }
++
++  return Status;
+ }
+ 
+ /**
+@@ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg (
+   //
+   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
+   if (Packet == NULL) {
+-    return EFI_OUT_OF_RESOURCES;
++    Status = EFI_OUT_OF_RESOURCES;
++    goto ON_ERROR;
+   }
+ 
+   Packet->Size                       = DHCP6_BASE_PACKET_SIZE;
+@@ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg (
+   Cursor = Packet->Dhcp6.Option;
+ 
+   Length = HTONS (ClientId->Length);
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptClientId),
+              Length,
+              ClientId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+   //
+   // ServerId is extracted from packet, it's network order.
+   //
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptServerId),
+              ServerId->Length,
+              ServerId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendETOption (
+-             Cursor,
++  Status = Dhcp6AppendETOption (
++             Packet,
++             &Cursor,
+              Instance,
+              &Elapsed
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType);
++  Status = Dhcp6AppendIaOption (
++             Packet,
++             &Cursor,
++             RelIa,
++             0,
++             0,
++             Packet->Dhcp6.Header.MessageType
++             );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  //
+-  // Determine the size/length of packet
+-  //
+-  Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
+   ASSERT (Packet->Size > Packet->Length + 8);
+ 
+   //
+   // Callback to user with the packet to be sent and check the user's feedback.
+   //
+   Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+@@ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg (
+   Instance->IaCb.Ia->State = Dhcp6Releasing;
+ 
+   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+   // Enqueue the sent packet for the retransmission in case reply timeout.
+   //
+   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
++
++ON_ERROR:
++
++  if (Packet) {
++    FreePool (Packet);
++  }
++
++  return Status;
+ }
+ 
+ /**
+@@ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg (
+   //
+   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
+   if (Packet == NULL) {
+-    return EFI_OUT_OF_RESOURCES;
++    Status = EFI_OUT_OF_RESOURCES;
++    goto ON_ERROR;
+   }
+ 
+   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
+@@ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg (
+   Cursor = Packet->Dhcp6.Option;
+ 
+   Length = HTONS (ClientId->Length);
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptClientId),
+              Length,
+              ClientId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendETOption (
+-             Cursor,
++  Status = Dhcp6AppendETOption (
++             Packet,
++             &Cursor,
+              Instance,
+              &Elapsed
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendIaOption (
+-             Cursor,
++  Status = Dhcp6AppendIaOption (
++             Packet,
++             &Cursor,
+              Instance->IaCb.Ia,
+              Instance->IaCb.T1,
+              Instance->IaCb.T2,
+              Packet->Dhcp6.Header.MessageType
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+   if (!RebindRequest) {
+     //
+@@ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg (
+                Dhcp6OptServerId
+                );
+     if (Option == NULL) {
+-      FreePool (Packet);
+-      return EFI_DEVICE_ERROR;
++      Status = EFI_DEVICE_ERROR;
++      goto ON_ERROR;
+     }
+ 
+     ServerId = (EFI_DHCP6_DUID *)(Option + 2);
+ 
+-    Cursor = Dhcp6AppendOption (
+-               Cursor,
++    Status = Dhcp6AppendOption (
++               Packet,
++               &Cursor,
+                HTONS (Dhcp6OptServerId),
+                ServerId->Length,
+                ServerId->Duid
+                );
++    if (EFI_ERROR (Status)) {
++      goto ON_ERROR;
++    }
+   }
+ 
+   //
+@@ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg (
+   //
+   for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
+     UserOpt = Instance->Config->OptionList[Index];
+-    Cursor  = Dhcp6AppendOption (
+-                Cursor,
++    Status  = Dhcp6AppendOption (
++                Packet,
++                &Cursor,
+                 UserOpt->OpCode,
+                 UserOpt->OpLen,
+                 UserOpt->Data
+                 );
++    if (EFI_ERROR (Status)) {
++      goto ON_ERROR;
++    }
+   }
+ 
+-  //
+-  // Determine the size/length of packet.
+-  //
+-  Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
+   ASSERT (Packet->Size > Packet->Length + 8);
+ 
+   //
+@@ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg (
+   Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing;
+ 
+   Status = Dhcp6CallbackUser (Instance, Event, &Packet);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+@@ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg (
+   Instance->StartTime = 0;
+ 
+   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+   // Enqueue the sent packet for the retransmission in case reply timeout.
+   //
+   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
++
++ON_ERROR:
++
++  if (Packet) {
++    FreePool (Packet);
++  }
++
++  return Status;
+ }
+ 
+ /**
+@@ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg (
+   //
+   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
+   if (Packet == NULL) {
+-    return EFI_OUT_OF_RESOURCES;
++    Status = EFI_OUT_OF_RESOURCES;
++    goto ON_ERROR;
+   }
+ 
+   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
+@@ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg (
+ 
+   if (SendClientId) {
+     Length = HTONS (ClientId->Length);
+-    Cursor = Dhcp6AppendOption (
+-               Cursor,
++    Status = Dhcp6AppendOption (
++               Packet,
++               &Cursor,
+                HTONS (Dhcp6OptClientId),
+                Length,
+                ClientId->Duid
+                );
++    if (EFI_ERROR (Status)) {
++      goto ON_ERROR;
++    }
+   }
+ 
+-  Cursor = Dhcp6AppendETOption (
+-             Cursor,
++  Status = Dhcp6AppendETOption (
++             Packet,
++             &Cursor,
+              Instance,
+              &Elapsed
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              OptionRequest->OpCode,
+              OptionRequest->OpLen,
+              OptionRequest->Data
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+   //
+   // Append user-defined when configurate Dhcp6 service.
+   //
+   for (Index = 0; Index < OptionCount; Index++) {
+     UserOpt = OptionList[Index];
+-    Cursor  = Dhcp6AppendOption (
+-                Cursor,
++    Status  = Dhcp6AppendOption (
++                Packet,
++                &Cursor,
+                 UserOpt->OpCode,
+                 UserOpt->OpLen,
+                 UserOpt->Data
+                 );
++    if (EFI_ERROR (Status)) {
++      goto ON_ERROR;
++    }
+   }
+ 
+-  //
+-  // Determine the size/length of packet.
+-  //
+-  Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
+   ASSERT (Packet->Size > Packet->Length + 8);
+ 
+   //
+@@ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg (
+   // Send info-request packet with no state.
+   //
+   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+   // Enqueue the sent packet for the retransmission in case reply timeout.
+   //
+   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission);
++
++ON_ERROR:
++
++  if (Packet) {
++    FreePool (Packet);
++  }
++
++  return Status;
+ }
+ 
+ /**
+@@ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg (
+   //
+   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
+   if (Packet == NULL) {
+-    return EFI_OUT_OF_RESOURCES;
++    Status = EFI_OUT_OF_RESOURCES;
++    goto ON_ERROR;
+   }
+ 
+   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen;
+@@ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg (
+   Cursor = Packet->Dhcp6.Option;
+ 
+   Length = HTONS (ClientId->Length);
+-  Cursor = Dhcp6AppendOption (
+-             Cursor,
++  Status = Dhcp6AppendOption (
++             Packet,
++             &Cursor,
+              HTONS (Dhcp6OptClientId),
+              Length,
+              ClientId->Duid
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendETOption (
+-             Cursor,
++  Status = Dhcp6AppendETOption (
++             Packet,
++             &Cursor,
+              Instance,
+              &Elapsed
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+-  Cursor = Dhcp6AppendIaOption (
+-             Cursor,
++  Status = Dhcp6AppendIaOption (
++             Packet,
++             &Cursor,
+              Instance->IaCb.Ia,
+              Instance->IaCb.T1,
+              Instance->IaCb.T2,
+              Packet->Dhcp6.Header.MessageType
+              );
++  if (EFI_ERROR (Status)) {
++    goto ON_ERROR;
++  }
+ 
+   //
+   // Append user-defined when configurate Dhcp6 service.
+   //
+   for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
+     UserOpt = Instance->Config->OptionList[Index];
+-    Cursor  = Dhcp6AppendOption (
+-                Cursor,
++    Status  = Dhcp6AppendOption (
++                Packet,
++                &Cursor,
+                 UserOpt->OpCode,
+                 UserOpt->OpLen,
+                 UserOpt->Data
+                 );
++    if (EFI_ERROR (Status)) {
++      goto ON_ERROR;
++    }
+   }
+ 
+-  //
+-  // Determine the size/length of packet.
+-  //
+-  Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
+   ASSERT (Packet->Size > Packet->Length + 8);
+ 
+   //
+   // Callback to user with the packet to be sent and check the user's feedback.
+   //
+   Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+@@ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg (
+   Instance->StartTime = 0;
+ 
+   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
+-
+   if (EFI_ERROR (Status)) {
+-    FreePool (Packet);
+-    return Status;
++    goto ON_ERROR;
+   }
+ 
+   //
+   // Enqueue the sent packet for the retransmission in case reply timeout.
+   //
+   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
++
++ON_ERROR:
++
++  if (Packet) {
++    FreePool (Packet);
++  }
++
++  return Status;
+ }
+ 
+ /**
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
+index e6368b5b1c..705c665c51 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
+@@ -577,24 +577,33 @@ Dhcp6OnTransmitted (
+ }
+ 
+ /**
+-  Append the option to Buf, and move Buf to the end.
++  Append the option to Buf, update the length of packet, and move Buf to the end.
+ 
+-  @param[in, out] Buf           The pointer to the buffer.
+-  @param[in]      OptType       The option type.
+-  @param[in]      OptLen        The length of option contents.
+-  @param[in]      Data          The pointer to the option content.
++  @param[in, out] Packet         A pointer to the packet, on success Packet->Length
++                                 will be updated.
++  @param[in, out] PacketCursor   The pointer in the packet, on success PacketCursor
++                                 will be moved to the end of the option.
++  @param[in]      OptType        The option type.
++  @param[in]      OptLen         The length of option contents.
++  @param[in]      Data           The pointer to the option content.
+ 
+-  @return         Buf           The position to append the next option.
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ 
+ **/
+-UINT8 *
++EFI_STATUS
+ Dhcp6AppendOption (
+-  IN OUT UINT8   *Buf,
+-  IN     UINT16  OptType,
+-  IN     UINT16  OptLen,
+-  IN     UINT8   *Data
++  IN OUT EFI_DHCP6_PACKET  *Packet,
++  IN OUT UINT8             **PacketCursor,
++  IN     UINT16            OptType,
++  IN     UINT16            OptLen,
++  IN     UINT8             *Data
+   )
+ {
++  UINT32  Length;
++  UINT32  BytesNeeded;
++
+   //
+   //  The format of Dhcp6 option:
+   //
+@@ -607,35 +616,95 @@ Dhcp6AppendOption (
+   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   //
+ 
+-  ASSERT (OptLen != 0);
++  //
++  // Verify the arguments are valid
++  //
++  if (Packet == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if (Data == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if (OptLen == 0) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  //
++  // Verify the PacketCursor is within the packet
++  //
++  if (  (*PacketCursor < Packet->Dhcp6.Option)
++     || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
++  {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  //
++  // Calculate the bytes needed for the option
++  //
++  BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen);
++
++  //
++  // Space remaining in the packet
++  //
++  Length = Packet->Size - Packet->Length;
++  if (Length < BytesNeeded) {
++    return EFI_BUFFER_TOO_SMALL;
++  }
++
++  //
++  // Verify the PacketCursor is within the packet
++  //
++  if (  (*PacketCursor < Packet->Dhcp6.Option)
++     || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
++  {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType);
++  *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen);
++  *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
++  CopyMem (*PacketCursor, Data, NTOHS (OptLen));
++  *PacketCursor += NTOHS (OptLen);
+ 
+-  WriteUnaligned16 ((UINT16 *)Buf, OptType);
+-  Buf += 2;
+-  WriteUnaligned16 ((UINT16 *)Buf, OptLen);
+-  Buf += 2;
+-  CopyMem (Buf, Data, NTOHS (OptLen));
+-  Buf += NTOHS (OptLen);
++  // Update the packet length by the length of the option + 4 bytes
++  Packet->Length += BytesNeeded;
+ 
+-  return Buf;
++  return EFI_SUCCESS;
+ }
+ 
+ /**
+   Append the appointed IA Address option to Buf, and move Buf to the end.
+ 
+-  @param[in, out] Buf           The pointer to the position to append.
++  @param[in, out] Packet        A pointer to the packet, on success Packet->Length
++                                will be updated.
++  @param[in, out] PacketCursor  The pointer in the packet, on success PacketCursor
++                                will be moved to the end of the option.
+   @param[in]      IaAddr        The pointer to the IA Address.
+   @param[in]      MessageType   Message type of DHCP6 package.
+ 
+-  @return         Buf           The position to append the next option.
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ 
+ **/
+-UINT8 *
++EFI_STATUS
+ Dhcp6AppendIaAddrOption (
+-  IN OUT UINT8                 *Buf,
++  IN OUT EFI_DHCP6_PACKET      *Packet,
++  IN OUT UINT8                 **PacketCursor,
+   IN     EFI_DHCP6_IA_ADDRESS  *IaAddr,
+   IN     UINT32                MessageType
+   )
+ {
++  UINT32  BytesNeeded;
++  UINT32  Length;
++
+   //  The format of the IA Address option is:
+   //
+   //       0                   1                   2                   3
+@@ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption (
+   //      .                                                               .
+   //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 
++  //
++  // Verify the arguments are valid
++  //
++  if (Packet == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if (IaAddr == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  //
++  // Verify the PacketCursor is within the packet
++  //
++  if (  (*PacketCursor < Packet->Dhcp6.Option)
++     || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
++  {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  BytesNeeded  = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
++  BytesNeeded += sizeof (EFI_IPv6_ADDRESS);
++  //
++  // Even if the preferred-lifetime is 0, it still needs to store it.
++  //
++  BytesNeeded += sizeof (IaAddr->PreferredLifetime);
++  //
++  // Even if the valid-lifetime is 0, it still needs to store it.
++  //
++  BytesNeeded += sizeof (IaAddr->ValidLifetime);
++
++  //
++  // Space remaining in the packet
++  //
++  Length = Packet->Size - Packet->Length;
++  if (Length < BytesNeeded) {
++    return EFI_BUFFER_TOO_SMALL;
++  }
++
+   //
+   // Fill the value of Ia Address option type
+   //
+-  WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr));
+-  Buf += 2;
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr));
++  *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
+ 
+-  WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
+-  Buf += 2;
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
++  *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
+ 
+-  CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
+-  Buf += sizeof (EFI_IPv6_ADDRESS);
++  CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
++  *PacketCursor += sizeof (EFI_IPv6_ADDRESS);
+ 
+   //
+   // Fill the value of preferred-lifetime and valid-lifetime.
+@@ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption (
+   // should set to 0 when initiate a Confirm message.
+   //
+   if (MessageType != Dhcp6MsgConfirm) {
+-    WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime));
++    WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime));
+   }
+ 
+-  Buf += 4;
++  *PacketCursor += sizeof (IaAddr->PreferredLifetime);
+ 
+   if (MessageType != Dhcp6MsgConfirm) {
+-    WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime));
++    WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime));
+   }
+ 
+-  Buf += 4;
++  *PacketCursor += sizeof (IaAddr->ValidLifetime);
++
++  //
++  // Update the packet length
++  //
++  Packet->Length += BytesNeeded;
+ 
+-  return Buf;
++  return EFI_SUCCESS;
+ }
+ 
+ /**
+   Append the appointed Ia option to Buf, and move Buf to the end.
+ 
+-  @param[in, out] Buf           The pointer to the position to append.
++  @param[in, out] Packet        A pointer to the packet, on success Packet->Length
++                                will be updated.
++  @param[in, out] PacketCursor  The pointer in the packet, on success PacketCursor
++                                will be moved to the end of the option.
+   @param[in]      Ia            The pointer to the Ia.
+   @param[in]      T1            The time of T1.
+   @param[in]      T2            The time of T2.
+   @param[in]      MessageType   Message type of DHCP6 package.
+ 
+-  @return         Buf           The position to append the next Ia option.
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ 
+ **/
+-UINT8 *
++EFI_STATUS
+ Dhcp6AppendIaOption (
+-  IN OUT UINT8         *Buf,
+-  IN     EFI_DHCP6_IA  *Ia,
+-  IN     UINT32        T1,
+-  IN     UINT32        T2,
+-  IN     UINT32        MessageType
++  IN OUT EFI_DHCP6_PACKET  *Packet,
++  IN OUT UINT8             **PacketCursor,
++  IN     EFI_DHCP6_IA      *Ia,
++  IN     UINT32            T1,
++  IN     UINT32            T2,
++  IN     UINT32            MessageType
+   )
+ {
+-  UINT8   *AddrOpt;
+-  UINT16  *Len;
+-  UINTN   Index;
++  UINT8       *AddrOpt;
++  UINT16      *Len;
++  UINTN       Index;
++  UINT32      BytesNeeded;
++  UINT32      Length;
++  EFI_STATUS  Status;
+ 
+   //
+   //  The format of IA_NA and IA_TA option:
+@@ -733,32 +859,74 @@ Dhcp6AppendIaOption (
+   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   //
+ 
++  //
++  // Verify the arguments are valid
++  //
++  if (Packet == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if (Ia == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  //
++  // Verify the PacketCursor is within the packet
++  //
++  if (  (*PacketCursor < Packet->Dhcp6.Option)
++     || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
++  {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  BytesNeeded  = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
++  BytesNeeded += sizeof (Ia->Descriptor.IaId);
++  //
++  // + N for the IA_NA-options/IA_TA-options
++  // Dhcp6AppendIaAddrOption will need to check the length for each address
++  //
++  if (Ia->Descriptor.Type == Dhcp6OptIana) {
++    BytesNeeded += sizeof (T1) + sizeof (T2);
++  }
++
++  //
++  // Space remaining in the packet
++  //
++  Length = (UINT16)(Packet->Size - Packet->Length);
++  if (Length < BytesNeeded) {
++    return EFI_BUFFER_TOO_SMALL;
++  }
++
+   //
+   // Fill the value of Ia option type
+   //
+-  WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type));
+-  Buf += 2;
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type));
++  *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
+ 
+   //
+   // Fill the len of Ia option later, keep the pointer first
+   //
+-  Len  = (UINT16 *)Buf;
+-  Buf += 2;
++  Len            = (UINT16 *)*PacketCursor;
++  *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
+ 
+   //
+   // Fill the value of iaid
+   //
+-  WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId));
+-  Buf += 4;
++  WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId));
++  *PacketCursor += sizeof (Ia->Descriptor.IaId);
+ 
+   //
+   // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified.
+   //
+   if (Ia->Descriptor.Type == Dhcp6OptIana) {
+-    WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff));
+-    Buf += 4;
+-    WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff));
+-    Buf += 4;
++    WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff));
++    *PacketCursor += sizeof (T1);
++    WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff));
++    *PacketCursor += sizeof (T2);
+   }
+ 
+   //
+@@ -766,35 +934,51 @@ Dhcp6AppendIaOption (
+   //
+   for (Index = 0; Index < Ia->IaAddressCount; Index++) {
+     AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS);
+-    Buf     = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
++    Status  = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
++    if (EFI_ERROR (Status)) {
++      return Status;
++    }
+   }
+ 
+   //
+   // Fill the value of Ia option length
+   //
+-  *Len = HTONS ((UINT16)(Buf - (UINT8 *)Len - 2));
++  *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2));
+ 
+-  return Buf;
++  //
++  // Update the packet length
++  //
++  Packet->Length += BytesNeeded;
++
++  return EFI_SUCCESS;
+ }
+ 
+ /**
+   Append the appointed Elapsed time option to Buf, and move Buf to the end.
+ 
+-  @param[in, out] Buf           The pointer to the position to append.
++  @param[in, out] Packet        A pointer to the packet, on success Packet->Length
++  @param[in, out] PacketCursor  The pointer in the packet, on success PacketCursor
++                                will be moved to the end of the option.
+   @param[in]      Instance      The pointer to the Dhcp6 instance.
+   @param[out]     Elapsed       The pointer to the elapsed time value in
+-                                  the generated packet.
++                                the generated packet.
+ 
+-  @return         Buf           The position to append the next Ia option.
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ 
+ **/
+-UINT8 *
++EFI_STATUS
+ Dhcp6AppendETOption (
+-  IN OUT UINT8           *Buf,
+-  IN     DHCP6_INSTANCE  *Instance,
+-  OUT    UINT16          **Elapsed
++  IN OUT EFI_DHCP6_PACKET  *Packet,
++  IN OUT UINT8             **PacketCursor,
++  IN     DHCP6_INSTANCE    *Instance,
++  OUT    UINT16            **Elapsed
+   )
+ {
++  UINT32  BytesNeeded;
++  UINT32  Length;
++
+   //
+   //  The format of elapsed time option:
+   //
+@@ -806,27 +990,70 @@ Dhcp6AppendETOption (
+   //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   //
+ 
++  //
++  // Verify the arguments are valid
++  //
++  if (Packet == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if (Instance == NULL) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  if ((Elapsed == NULL)) {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  //
++  // Verify the PacketCursor is within the packet
++  //
++  if (  (*PacketCursor < Packet->Dhcp6.Option)
++     || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
++  {
++    return EFI_INVALID_PARAMETER;
++  }
++
++  BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
++  //
++  // + 2 for elapsed-time
++  //
++  BytesNeeded += sizeof (UINT16);
++  //
++  // Space remaining in the packet
++  //
++  Length = Packet->Size - Packet->Length;
++  if (Length < BytesNeeded) {
++    return EFI_BUFFER_TOO_SMALL;
++  }
++
+   //
+   // Fill the value of elapsed-time option type.
+   //
+-  WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime));
+-  Buf += 2;
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime));
++  *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
+ 
+   //
+   // Fill the len of elapsed-time option, which is fixed.
+   //
+-  WriteUnaligned16 ((UINT16 *)Buf, HTONS (2));
+-  Buf += 2;
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2));
++  *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
+ 
+   //
+   // Fill in elapsed time value with 0 value for now.  The actual value is
+   // filled in later just before the packet is transmitted.
+   //
+-  WriteUnaligned16 ((UINT16 *)Buf, HTONS (0));
+-  *Elapsed = (UINT16 *)Buf;
+-  Buf     += 2;
++  WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0));
++  *Elapsed       = (UINT16 *)*PacketCursor;
++  *PacketCursor += sizeof (UINT16);
+ 
+-  return Buf;
++  Packet->Length += BytesNeeded;
++
++  return EFI_SUCCESS;
+ }
+ 
+ /**
+diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
+index 046454ff4a..06947f6c1f 100644
+--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
++++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
+@@ -160,69 +160,85 @@ Dhcp6OnTransmitted (
+   );
+ 
+ /**
+-  Append the appointed option to the buf, and move the buf to the end.
+-
+-  @param[in, out] Buf           The pointer to buffer.
+-  @param[in]      OptType       The option type.
+-  @param[in]      OptLen        The length of option content.s
+-  @param[in]      Data          The pointer to the option content.
+-
+-  @return         Buf           The position to append the next option.
+-
++  Append the option to Buf, update the length of packet, 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]      OptType        The option type.
++  @param[in]      OptLen         The length of option contents.
++  @param[in]      Data           The pointer to the option content.
++
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ **/
+-UINT8 *
++EFI_STATUS
+ Dhcp6AppendOption (
+-  IN OUT UINT8   *Buf,
+-  IN     UINT16  OptType,
+-  IN     UINT16  OptLen,
+-  IN     UINT8   *Data
++  IN OUT EFI_DHCP6_PACKET  *Packet,
++  IN OUT UINT8             **PacketCursor,
++  IN     UINT16            OptType,
++  IN     UINT16            OptLen,
++  IN     UINT8             *Data
+   );
+ 
+ /**
+-  Append the Ia option to Buf, and move Buf to the end.
+-
+-  @param[in, out] Buf           The pointer to the position to append.
++  Append the appointed Ia option to Buf, update the Ia option length, and move Buf
++  to the end of the option.
++  @param[in, out] Packet        A pointer to the packet, on success Packet->Length
++                                will be updated.
++  @param[in, out] PacketCursor   The pointer in the packet, on success PacketCursor
++                                 will be moved to the end of the option.
+   @param[in]      Ia            The pointer to the Ia.
+   @param[in]      T1            The time of T1.
+   @param[in]      T2            The time of T2.
+   @param[in]      MessageType   Message type of DHCP6 package.
+ 
+-  @return         Buf           The position to append the next Ia option.
+-
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ **/
+-UINT8 *
++EFI_STATUS
+ Dhcp6AppendIaOption (
+-  IN OUT UINT8         *Buf,
+-  IN     EFI_DHCP6_IA  *Ia,
+-  IN     UINT32        T1,
+-  IN     UINT32        T2,
+-  IN     UINT32        MessageType
++  IN OUT EFI_DHCP6_PACKET  *Packet,
++  IN OUT UINT8             **PacketCursor,
++  IN     EFI_DHCP6_IA      *Ia,
++  IN     UINT32            T1,
++  IN     UINT32            T2,
++  IN     UINT32            MessageType
+   );
+ 
+ /**
+   Append the appointed Elapsed time option to Buf, and move Buf to the end.
+ 
+-  @param[in, out] Buf           The pointer to the position to append.
++  @param[in, out] Packet        A pointer to the packet, on success Packet->Length
++  @param[in, out] PacketCursor   The pointer in the packet, on success PacketCursor
++                                 will be moved to the end of the option.
+   @param[in]      Instance      The pointer to the Dhcp6 instance.
+   @param[out]     Elapsed       The pointer to the elapsed time value in
+                                   the generated packet.
+ 
+-  @return         Buf           The position to append the next Ia option.
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ 
+ **/
+-UINT8 *
++EFI_STATUS
+ Dhcp6AppendETOption (
+-  IN OUT UINT8           *Buf,
+-  IN     DHCP6_INSTANCE  *Instance,
+-  OUT    UINT16          **Elapsed
++  IN OUT EFI_DHCP6_PACKET  *Packet,
++  IN OUT UINT8             **PacketCursor,
++  IN     DHCP6_INSTANCE    *Instance,
++  OUT    UINT16            **Elapsed
+   );
+ 
+ /**
+   Set the elapsed time based on the given instance and the pointer to the
+   elapsed time option.
+ 
+-  @param[in]      Elapsed       The pointer to the position to append.
+-  @param[in]      Instance      The pointer to the Dhcp6 instance.
++  @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid
++  @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option.
++  @retval   EFI_SUCCESS           The option is appended successfully.
+ **/
+ VOID
+ SetElapsedTime (
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0002.patch b/meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0002.patch
new file mode 100644
index 0000000000..1f891f8007
--- /dev/null
+++ b/meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0002.patch
@@ -0,0 +1,604 @@ 
+From 5f3658197bf29c83b3349b0ab1d99cdb0c3814bc 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:45 +0800
+Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit 
+ Tests
+
+REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4535
+
+Confirms that reported issue...
+
+"Buffer overflow in the DHCPv6 client via a long Server ID option"
+
+..has been corrected by the provided patch.
+
+Tests the following functions to ensure they appropriately handle
+untrusted data (either too long or too small) to prevent a buffer
+overflow:
+
+Dhcp6AppendOption
+Dhcp6AppendETOption
+Dhcp6AppendIaOption
+
+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-45230
+
+Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/5f3658197bf29c83b3349b0ab1d99cdb0c3814bc]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ .../GoogleTest/Dhcp6DxeGoogleTest.cpp         |  20 +
+ .../GoogleTest/Dhcp6DxeGoogleTest.inf         |  43 ++
+ .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 478 ++++++++++++++++++
+ 3 files changed, 541 insertions(+)
+ create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
+ create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+ create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
+
+diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
+new file mode 100644
+index 0000000000..9aeced2f91
+--- /dev/null
++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
+@@ -0,0 +1,20 @@
++/** @file
++  Acts as the main entry point for the tests for the Dhcp6Dxe module.
++
++  Copyright (c) Microsoft Corporation
++  SPDX-License-Identifier: BSD-2-Clause-Patent
++**/
++#include <gtest/gtest.h>
++
++////////////////////////////////////////////////////////////////////////////////
++// Run the tests
++////////////////////////////////////////////////////////////////////////////////
++int
++main (
++  int   argc,
++  char  *argv[]
++  )
++{
++  testing::InitGoogleTest (&argc, argv);
++  return RUN_ALL_TESTS ();
++}
+diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+new file mode 100644
+index 0000000000..8e9119a371
+--- /dev/null
++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
+@@ -0,0 +1,43 @@
++## @file
++# Unit test suite for the Dhcp6Dxe using Google Test
++#
++# Copyright (c) Microsoft Corporation.<BR>
++# SPDX-License-Identifier: BSD-2-Clause-Patent
++##
++[Defines]
++  INF_VERSION         = 0x00010017
++  BASE_NAME           = Dhcp6DxeGoogleTest
++  FILE_GUID           = 1D2A4C65-38C8-4C2F-BB60-B5FA49625AA9
++  VERSION_STRING      = 1.0
++  MODULE_TYPE         = HOST_APPLICATION
++#
++# The following information is for reference only and not required by the build tools.
++#
++#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
++#
++[Sources]
++  Dhcp6DxeGoogleTest.cpp
++  Dhcp6IoGoogleTest.cpp
++  ../Dhcp6Io.c
++  ../Dhcp6Utility.c
++
++[Packages]
++  MdePkg/MdePkg.dec
++  MdeModulePkg/MdeModulePkg.dec
++  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
++  NetworkPkg/NetworkPkg.dec
++
++[LibraryClasses]
++  GoogleTestLib
++  DebugLib
++  NetLib
++  PcdLib
++
++[Protocols]
++  gEfiDhcp6ServiceBindingProtocolGuid
++
++[Pcd]
++  gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType
++
++[Guids]
++  gZeroGuid
+diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
+new file mode 100644
+index 0000000000..7ee40e4af4
+--- /dev/null
++++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
+@@ -0,0 +1,478 @@
++/** @file
++  Tests for Dhcp6Io.c.
++
++  Copyright (c) Microsoft Corporation
++  SPDX-License-Identifier: BSD-2-Clause-Patent
++**/
++#include <gtest/gtest.h>
++
++extern "C" {
++  #include <Uefi.h>
++  #include <Library/BaseLib.h>
++  #include <Library/DebugLib.h>
++  #include <Library/BaseMemoryLib.h>
++  #include "../Dhcp6Impl.h"
++  #include "../Dhcp6Utility.h"
++}
++
++////////////////////////////////////////////////////////////////////////
++// Defines
++////////////////////////////////////////////////////////////////////////
++
++#define DHCP6_PACKET_MAX_LEN  1500
++
++////////////////////////////////////////////////////////////////////////
++////////////////////////////////////////////////////////////////////////
++// Symbol Definitions
++// These functions are not directly under test - but required to compile
++////////////////////////////////////////////////////////////////////////
++
++// This definition is used by this test but is also required to compile
++// by Dhcp6Io.c
++EFI_IPv6_ADDRESS  mAllDhcpRelayAndServersAddress = {
++  { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 }
++};
++
++EFI_STATUS
++EFIAPI
++UdpIoSendDatagram (
++  IN  UDP_IO           *UdpIo,
++  IN  NET_BUF          *Packet,
++  IN  UDP_END_POINT    *EndPoint OPTIONAL,
++  IN  EFI_IP_ADDRESS   *Gateway  OPTIONAL,
++  IN  UDP_IO_CALLBACK  CallBack,
++  IN  VOID             *Context
++  )
++{
++  return EFI_SUCCESS;
++}
++
++EFI_STATUS
++EFIAPI
++UdpIoRecvDatagram (
++  IN  UDP_IO           *UdpIo,
++  IN  UDP_IO_CALLBACK  CallBack,
++  IN  VOID             *Context,
++  IN  UINT32           HeadLen
++  )
++{
++  return EFI_SUCCESS;
++}
++
++////////////////////////////////////////////////////////////////////////
++// Dhcp6AppendOptionTest Tests
++////////////////////////////////////////////////////////////////////////
++
++class Dhcp6AppendOptionTest : public ::testing::Test {
++public:
++  UINT8 *Buffer = NULL;
++  EFI_DHCP6_PACKET *Packet;
++
++protected:
++  // Add any setup code if needed
++  virtual void
++  SetUp (
++    )
++  {
++    // Initialize any resources or variables
++    Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
++    ASSERT_NE (Buffer, (UINT8 *)NULL);
++
++    Packet       = (EFI_DHCP6_PACKET *)Buffer;
++    Packet->Size = DHCP6_PACKET_MAX_LEN;
++  }
++
++  // Add any cleanup code if needed
++  virtual void
++  TearDown (
++    )
++  {
++    // Clean up any resources or variables
++    if (Buffer != NULL) {
++      FreePool (Buffer);
++    }
++  }
++};
++
++// Test Description:
++// Attempt to append an option to a packet that is too small by a duid that is too large
++TEST_F (Dhcp6AppendOptionTest, InvalidDataExpectBufferTooSmall) {
++  UINT8           *Cursor;
++  EFI_DHCP6_DUID  *UntrustedDuid;
++  EFI_STATUS      Status;
++
++  UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));
++  ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);
++
++  UntrustedDuid->Length = NTOHS (0xFFFF);
++
++  Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;
++
++  Status = Dhcp6AppendOption (
++             Dhcp6AppendOptionTest::Packet,
++             &Cursor,
++             HTONS (Dhcp6OptServerId),
++             UntrustedDuid->Length,
++             UntrustedDuid->Duid
++             );
++
++  ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
++}
++
++// Test Description:
++// Attempt to append an option to a packet that is large enough
++TEST_F (Dhcp6AppendOptionTest, ValidDataExpectSuccess) {
++  UINT8           *Cursor;
++  EFI_DHCP6_DUID  *UntrustedDuid;
++  EFI_STATUS      Status;
++  UINTN           OriginalLength;
++
++  UINT8  Duid[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
++
++  Packet->Length = sizeof (EFI_DHCP6_HEADER);
++  OriginalLength = Packet->Length;
++
++  UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));
++  ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);
++
++  UntrustedDuid->Length = NTOHS (sizeof (Duid));
++  CopyMem (UntrustedDuid->Duid, Duid, sizeof (Duid));
++
++  Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;
++
++  Status = Dhcp6AppendOption (
++             Dhcp6AppendOptionTest::Packet,
++             &Cursor,
++             HTONS (Dhcp6OptServerId),
++             UntrustedDuid->Length,
++             UntrustedDuid->Duid
++             );
++
++  ASSERT_EQ (Status, EFI_SUCCESS);
++
++  // verify that the pointer to cursor moved by the expected amount
++  ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendOptionTest::Packet->Dhcp6.Option + sizeof (Duid) + 4);
++
++  // verify that the length of the packet is now the expected amount
++  ASSERT_EQ (Dhcp6AppendOptionTest::Packet->Length, OriginalLength + sizeof (Duid) + 4);
++}
++
++////////////////////////////////////////////////////////////////////////
++// Dhcp6AppendETOption Tests
++////////////////////////////////////////////////////////////////////////
++
++class Dhcp6AppendETOptionTest : public ::testing::Test {
++public:
++  UINT8 *Buffer = NULL;
++  EFI_DHCP6_PACKET *Packet;
++
++protected:
++  // Add any setup code if needed
++  virtual void
++  SetUp (
++    )
++  {
++    // Initialize any resources or variables
++    Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
++    ASSERT_NE (Buffer, (UINT8 *)NULL);
++
++    Packet         = (EFI_DHCP6_PACKET *)Buffer;
++    Packet->Size   = DHCP6_PACKET_MAX_LEN;
++    Packet->Length = sizeof (EFI_DHCP6_HEADER);
++  }
++
++  // Add any cleanup code if needed
++  virtual void
++  TearDown (
++    )
++  {
++    // Clean up any resources or variables
++    if (Buffer != NULL) {
++      FreePool (Buffer);
++    }
++  }
++};
++
++// Test Description:
++// Attempt to append an option to a packet that is too small by a duid that is too large
++TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) {
++  UINT8           *Cursor;
++  EFI_STATUS      Status;
++  DHCP6_INSTANCE  Instance;
++  UINT16          ElapsedTimeVal;
++  UINT16          *ElapsedTime;
++
++  Cursor      = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;
++  ElapsedTime = &ElapsedTimeVal;
++
++  Packet->Length = Packet->Size - 2;
++
++  Status = Dhcp6AppendETOption (
++             Dhcp6AppendETOptionTest::Packet,
++             &Cursor,
++             &Instance, // Instance is not used in this function
++             &ElapsedTime
++             );
++
++  // verify that we error out because the packet is too small for the option header
++  ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
++
++  // reset the length
++  Packet->Length = sizeof (EFI_DHCP6_HEADER);
++}
++
++// Test Description:
++// Attempt to append an option to a packet that is large enough
++TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) {
++  UINT8           *Cursor;
++  EFI_STATUS      Status;
++  DHCP6_INSTANCE  Instance;
++  UINT16          ElapsedTimeVal;
++  UINT16          *ElapsedTime;
++  UINTN           ExpectedSize;
++  UINTN           OriginalLength;
++
++  Cursor         = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;
++  ElapsedTime    = &ElapsedTimeVal;
++  ExpectedSize   = 6;
++  OriginalLength = Packet->Length;
++
++  Status = Dhcp6AppendETOption (
++             Dhcp6AppendETOptionTest::Packet,
++             &Cursor,
++             &Instance, // Instance is not used in this function
++             &ElapsedTime
++             );
++
++  // verify that the status is EFI_SUCCESS
++  ASSERT_EQ (Status, EFI_SUCCESS);
++
++  // verify that the pointer to cursor moved by the expected amount
++  ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendETOptionTest::Packet->Dhcp6.Option + ExpectedSize);
++
++  // verify that the length of the packet is now the expected amount
++  ASSERT_EQ (Dhcp6AppendETOptionTest::Packet->Length, OriginalLength + ExpectedSize);
++}
++
++////////////////////////////////////////////////////////////////////////
++// Dhcp6AppendIaOption Tests
++////////////////////////////////////////////////////////////////////////
++
++class Dhcp6AppendIaOptionTest : public ::testing::Test {
++public:
++  UINT8 *Buffer = NULL;
++  EFI_DHCP6_PACKET *Packet;
++  EFI_DHCP6_IA *Ia;
++
++protected:
++  // Add any setup code if needed
++  virtual void
++  SetUp (
++    )
++  {
++    // Initialize any resources or variables
++    Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
++    ASSERT_NE (Buffer, (UINT8 *)NULL);
++
++    Packet       = (EFI_DHCP6_PACKET *)Buffer;
++    Packet->Size = DHCP6_PACKET_MAX_LEN;
++
++    Ia = (EFI_DHCP6_IA *)AllocateZeroPool (sizeof (EFI_DHCP6_IA) + sizeof (EFI_DHCP6_IA_ADDRESS) * 2);
++    ASSERT_NE (Ia, (EFI_DHCP6_IA *)NULL);
++
++    CopyMem (Ia->IaAddress, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));
++    CopyMem (Ia->IaAddress + 1, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));
++
++    Ia->IaAddressCount = 2;
++  }
++
++  // Add any cleanup code if needed
++  virtual void
++  TearDown (
++    )
++  {
++    // Clean up any resources or variables
++    if (Buffer != NULL) {
++      FreePool (Buffer);
++    }
++
++    if (Ia != NULL) {
++      FreePool (Ia);
++    }
++  }
++};
++
++// Test Description:
++// Attempt to append an option to a packet that doesn't have enough space
++// for the option header
++TEST_F (Dhcp6AppendIaOptionTest, IaNaInvalidDataExpectBufferTooSmall) {
++  UINT8       *Cursor;
++  EFI_STATUS  Status;
++
++  Packet->Length = Packet->Size - 2;
++
++  Ia->Descriptor.Type = Dhcp6OptIana;
++  Ia->Descriptor.IaId = 0x12345678;
++
++  Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
++
++  Status = Dhcp6AppendIaOption (
++             Dhcp6AppendIaOptionTest::Packet,
++             &Cursor,
++             Ia,
++             0x12345678,
++             0x11111111,
++             Dhcp6OptIana
++             );
++
++  // verify that we error out because the packet is too small for the option header
++  ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
++
++  // reset the length
++  Packet->Length = sizeof (EFI_DHCP6_HEADER);
++}
++
++// Test Description:
++// Attempt to append an option to a packet that doesn't have enough space
++// for the option header
++TEST_F (Dhcp6AppendIaOptionTest, IaTaInvalidDataExpectBufferTooSmall) {
++  UINT8       *Cursor;
++  EFI_STATUS  Status;
++
++  // Use up nearly all the space in the packet
++  Packet->Length = Packet->Size - 2;
++
++  Ia->Descriptor.Type = Dhcp6OptIata;
++  Ia->Descriptor.IaId = 0x12345678;
++
++  Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
++
++  Status = Dhcp6AppendIaOption (
++             Dhcp6AppendIaOptionTest::Packet,
++             &Cursor,
++             Ia,
++             0,
++             0,
++             Dhcp6OptIata
++             );
++
++  // verify that we error out because the packet is too small for the option header
++  ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
++
++  // reset the length
++  Packet->Length = sizeof (EFI_DHCP6_HEADER);
++}
++
++TEST_F (Dhcp6AppendIaOptionTest, IaNaValidDataExpectSuccess) {
++  UINT8       *Cursor;
++  EFI_STATUS  Status;
++  UINTN       ExpectedSize;
++  UINTN       OriginalLength;
++
++  //
++  // 2 bytes for the option header type
++  //
++  ExpectedSize = 2;
++  //
++  // 2 bytes for the option header length
++  //
++  ExpectedSize += 2;
++  //
++  // 4 bytes for the IAID
++  //
++  ExpectedSize += 4;
++  //
++  // + 4 bytes for the T1
++  //
++  ExpectedSize += 4;
++  //
++  // + 4 bytes for the T2
++  //
++  ExpectedSize += 4;
++  //
++  // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
++  //   + 2 bytes for the option header type
++  //   + 2 bytes for the option header length
++  //   + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address
++  //
++  ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
++
++  Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
++
++  Packet->Length = sizeof (EFI_DHCP6_HEADER);
++  OriginalLength = Packet->Length;
++
++  Ia->Descriptor.Type = Dhcp6OptIana;
++  Ia->Descriptor.IaId = 0x12345678;
++
++  Status = Dhcp6AppendIaOption (
++             Dhcp6AppendIaOptionTest::Packet,
++             &Cursor,
++             Ia,
++             0x12345678,
++             0x12345678,
++             Dhcp6OptIana
++             );
++
++  // verify that the pointer to cursor moved by the expected amount
++  ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);
++
++  // verify that the length of the packet is now the expected amount
++  ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);
++
++  // verify that the status is EFI_SUCCESS
++  ASSERT_EQ (Status, EFI_SUCCESS);
++}
++
++TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) {
++  UINT8       *Cursor;
++  EFI_STATUS  Status;
++  UINTN       ExpectedSize;
++  UINTN       OriginalLength;
++
++  //
++  // 2 bytes for the option header type
++  //
++  ExpectedSize = 2;
++  //
++  // 2 bytes for the option header length
++  //
++  ExpectedSize += 2;
++  //
++  // 4 bytes for the IAID
++  //
++  ExpectedSize += 4;
++  //
++  // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
++  //   + 2 bytes for the option header type
++  //   + 2 bytes for the option header length
++  //   + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address
++  //
++  ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
++
++  Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
++
++  Packet->Length = sizeof (EFI_DHCP6_HEADER);
++  OriginalLength = Packet->Length;
++
++  Ia->Descriptor.Type = Dhcp6OptIata;
++  Ia->Descriptor.IaId = 0x12345678;
++
++  Status = Dhcp6AppendIaOption (
++             Dhcp6AppendIaOptionTest::Packet,
++             &Cursor,
++             Ia,
++             0,
++             0,
++             Dhcp6OptIata
++             );
++
++  // verify that the pointer to cursor moved by the expected amount
++  ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);
++
++  // verify that the length of the packet is now the expected amount
++  ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);
++
++  // verify that the status is EFI_SUCCESS
++  ASSERT_EQ (Status, EFI_SUCCESS);
++}
+-- 
+2.40.0
+
diff --git a/meta/recipes-core/ovmf/ovmf_git.bb b/meta/recipes-core/ovmf/ovmf_git.bb
index 59e5598a1b..957a74aabe 100644
--- a/meta/recipes-core/ovmf/ovmf_git.bb
+++ b/meta/recipes-core/ovmf/ovmf_git.bb
@@ -33,6 +33,8 @@  SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
            file://CVE-2022-36764-0001.patch \
            file://CVE-2022-36764-0002.patch \
            file://CVE-2022-36764-0003.patch \
+           file://CVE-2023-45230-0001.patch \
+           file://CVE-2023-45230-0002.patch \
            "
 
 PV = "edk2-stable202202"