From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id C3217D81112 for ; Thu, 25 Jan 2024 23:06:31 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=lTMrlRn8APju2NjjmEXJMwEix27Aw01XtLVHC3opZBc=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1706223990; v=1; b=szei6ADFqeKWuA4EinmFvokVty5+5P6l4xqHgpoQ3pl02khRAhtMv6s+TG5QAnznTZHP7og9 vqSR7ncrmnYildKHR6KtfNNu3j+UbhTtTzr5LBySFnuY4NFe1ZJT46ClJHQQURQxvs1HHWUNUQv vR8Ei2EeakeHLXiBm/PaDqZU= X-Received: by 127.0.0.2 with SMTP id haAjYY7687511xORCFjCSy12; Thu, 25 Jan 2024 15:06:30 -0800 X-Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) by mx.groups.io with SMTP id smtpd.web11.775.1706223989860706912 for ; Thu, 25 Jan 2024 15:06:29 -0800 X-Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-1d71207524dso33291685ad.1 for ; Thu, 25 Jan 2024 15:06:29 -0800 (PST) X-Gm-Message-State: 52fujFXEXLMIlnOLwox9TB2dx7686176AA= X-Google-Smtp-Source: AGHT+IFL4v+d4MebddwKF2V4npjeknMt3tRMNdFCASQZD++GZAvknlnpKQTYvNKn7u14gPNW8eY7WA== X-Received: by 2002:a17:903:2592:b0:1d7:599d:ed25 with SMTP id jb18-20020a170903259200b001d7599ded25mr538361plb.39.1706223988397; Thu, 25 Jan 2024 15:06:28 -0800 (PST) X-Received: from localhost.localdomain ([24.17.138.83]) by smtp.gmail.com with ESMTPSA id jh1-20020a170903328100b001d752c4f180sm16779plb.94.2024.01.25.15.06.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 15:06:27 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Saloni Kasbekar , Zachary Clark-williams Subject: [edk2-devel] [PATCH v2 01/15] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch Date: Thu, 25 Jan 2024 13:54:43 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,dougflick@microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=szei6ADF; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=none REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D4535 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 >=3D 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 Cc: Zachary Clark-williams Signed-off-by: Doug Flick [MSFT] --- NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 43 +++ NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h | 78 +++--- NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 409 +++++++++++++++++++---------- NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 373 +++++++++++++++++++++----- 4 files changed, 666 insertions(+), 237 deletions(-) diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Imp= l.h index 0eb9c669b5a1..f2422c2f2827 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h @@ -45,6 +45,49 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE; #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S')=0D #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I')=0D =0D +//=0D +// For more information on DHCP options see RFC 8415, Section 21.1=0D +//=0D +// The format of DHCP options is:=0D +//=0D +// 0 1 2 3=0D +// 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=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | option-code | option-len |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +// | option-data |=0D +// | (option-len octets) |=0D +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D +//=0D +#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16))=0D +#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16))=0D +=0D +//=0D +// Combined size of Code and Length=0D +//=0D +#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \=0D + DHCP6_SIZE_OF_OPT_LEN)=0D +=0D +STATIC_ASSERT (=0D + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN =3D=3D 4,=0D + "Combined size of Code and Length must be 4 per RFC 8415"=0D + );=0D +=0D +//=0D +// Offset to the length is just past the code=0D +//=0D +#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE)=0D +STATIC_ASSERT (=0D + DHCP6_OPT_LEN_OFFSET (0) =3D=3D 2,=0D + "Offset of length is + 2 past start of option"=0D + );=0D +=0D +#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN= )=0D +STATIC_ASSERT (=0D + DHCP6_OPT_DATA_OFFSET (0) =3D=3D 4,=0D + "Offset to option data should be +4 from start of option"=0D + );=0D +=0D #define DHCP6_PACKET_ALL 0=0D #define DHCP6_PACKET_STATEFUL 1=0D #define DHCP6_PACKET_STATELESS 2=0D diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6= Utility.h index 046454ff4ac2..06947f6c1fcf 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h @@ -160,69 +160,85 @@ Dhcp6OnTransmitted ( );=0D =0D /**=0D - Append the appointed option to the buf, and move the buf to the end.=0D + Append the option to Buf, update the length of packet, and move Buf to t= he end.=0D =0D - @param[in, out] Buf The pointer to buffer.=0D - @param[in] OptType The option type.=0D - @param[in] OptLen The length of option content.s=0D - @param[in] Data The pointer to the option content.=0D -=0D - @return Buf The position to append the next option.=0D + @param[in, out] Packet A pointer to the packet, on success Packe= t->Length=0D + will be updated.=0D + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor=0D + will be moved to the end of the option.=0D + @param[in] OptType The option type.=0D + @param[in] OptLen The length of option contents.=0D + @param[in] Data The pointer to the option content.=0D =0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D **/=0D -UINT8 *=0D +EFI_STATUS=0D Dhcp6AppendOption (=0D - IN OUT UINT8 *Buf,=0D - IN UINT16 OptType,=0D - IN UINT16 OptLen,=0D - IN UINT8 *Data=0D + IN OUT EFI_DHCP6_PACKET *Packet,=0D + IN OUT UINT8 **PacketCursor,=0D + IN UINT16 OptType,=0D + IN UINT16 OptLen,=0D + IN UINT8 *Data=0D );=0D =0D /**=0D - Append the Ia option to Buf, and move Buf to the end.=0D -=0D - @param[in, out] Buf The pointer to the position to append.=0D + Append the appointed Ia option to Buf, update the Ia option length, and = move Buf=0D + to the end of the option.=0D + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length=0D + will be updated.=0D + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor=0D + will be moved to the end of the option.=0D @param[in] Ia The pointer to the Ia.=0D @param[in] T1 The time of T1.=0D @param[in] T2 The time of T2.=0D @param[in] MessageType Message type of DHCP6 package.=0D =0D - @return Buf The position to append the next Ia option.= =0D -=0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D **/=0D -UINT8 *=0D +EFI_STATUS=0D Dhcp6AppendIaOption (=0D - IN OUT UINT8 *Buf,=0D - IN EFI_DHCP6_IA *Ia,=0D - IN UINT32 T1,=0D - IN UINT32 T2,=0D - IN UINT32 MessageType=0D + IN OUT EFI_DHCP6_PACKET *Packet,=0D + IN OUT UINT8 **PacketCursor,=0D + IN EFI_DHCP6_IA *Ia,=0D + IN UINT32 T1,=0D + IN UINT32 T2,=0D + IN UINT32 MessageType=0D );=0D =0D /**=0D Append the appointed Elapsed time option to Buf, and move Buf to the end= .=0D =0D - @param[in, out] Buf The pointer to the position to append.=0D + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length=0D + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor=0D + will be moved to the end of the option.=0D @param[in] Instance The pointer to the Dhcp6 instance.=0D @param[out] Elapsed The pointer to the elapsed time value in=0D the generated packet.=0D =0D - @return Buf The position to append the next Ia option.= =0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D =0D **/=0D -UINT8 *=0D +EFI_STATUS=0D Dhcp6AppendETOption (=0D - IN OUT UINT8 *Buf,=0D - IN DHCP6_INSTANCE *Instance,=0D - OUT UINT16 **Elapsed=0D + IN OUT EFI_DHCP6_PACKET *Packet,=0D + IN OUT UINT8 **PacketCursor,=0D + IN DHCP6_INSTANCE *Instance,=0D + OUT UINT16 **Elapsed=0D );=0D =0D /**=0D Set the elapsed time based on the given instance and the pointer to the= =0D elapsed time option.=0D =0D - @param[in] Elapsed The pointer to the position to append.=0D - @param[in] Instance The pointer to the Dhcp6 instance.=0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D **/=0D VOID=0D SetElapsedTime (=0D diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c index dcd01e6268b1..bf5aa7a769de 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c @@ -3,9 +3,9 @@ =0D (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
=0D Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
=0D + Copyright (c) Microsoft Corporation=0D =0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D -=0D **/=0D =0D #include "Dhcp6Impl.h"=0D @@ -930,7 +930,8 @@ Dhcp6SendSolicitMsg ( //=0D Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);=0D if (Packet =3D=3D NULL) {=0D - return EFI_OUT_OF_RESOURCES;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ON_ERROR;=0D }=0D =0D Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen;= =0D @@ -944,54 +945,64 @@ Dhcp6SendSolicitMsg ( Cursor =3D Packet->Dhcp6.Option;=0D =0D Length =3D HTONS (ClientId->Length);=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptClientId),=0D Length,=0D ClientId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendETOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendETOption (=0D + Packet,=0D + &Cursor,=0D Instance,=0D &Elapsed=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendIaOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendIaOption (=0D + Packet,=0D + &Cursor,=0D Instance->IaCb.Ia,=0D Instance->IaCb.T1,=0D Instance->IaCb.T2,=0D Packet->Dhcp6.Header.MessageType=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D //=0D // Append user-defined when configurate Dhcp6 service.=0D //=0D for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) {=0D UserOpt =3D Instance->Config->OptionList[Index];=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D UserOpt->OpCode,=0D UserOpt->OpLen,=0D UserOpt->Data=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D }=0D =0D - //=0D - // Determine the size/length of packet.=0D - //=0D - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option);=0D ASSERT (Packet->Size > Packet->Length + 8);=0D =0D //=0D // Callback to user with the packet to be sent and check the user's feed= back.=0D //=0D Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D @@ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg ( Instance->StartTime =3D 0;=0D =0D Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D @@ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg ( Elapsed,=0D Instance->Config->SolicitRetransmission=0D );=0D +=0D +ON_ERROR:=0D +=0D + if (Packet) {=0D + FreePool (Packet);=0D + }=0D +=0D + return Status;=0D }=0D =0D /**=0D @@ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg ( //=0D Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);=0D if (Packet =3D=3D NULL) {=0D - return EFI_OUT_OF_RESOURCES;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ON_ERROR;=0D }=0D =0D Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen;= =0D @@ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg ( Cursor =3D Packet->Dhcp6.Option;=0D =0D Length =3D HTONS (ClientId->Length);=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptClientId),=0D Length,=0D ClientId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendETOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendETOption (=0D + Packet,=0D + &Cursor,=0D Instance,=0D &Elapsed=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptServerId),=0D ServerId->Length,=0D ServerId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendIaOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendIaOption (=0D + Packet,=0D + &Cursor,=0D Instance->IaCb.Ia,=0D Instance->IaCb.T1,=0D Instance->IaCb.T2,=0D Packet->Dhcp6.Header.MessageType=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D //=0D // Append user-defined when configurate Dhcp6 service.=0D //=0D for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) {=0D UserOpt =3D Instance->Config->OptionList[Index];=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D UserOpt->OpCode,=0D UserOpt->OpLen,=0D UserOpt->Data=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D }=0D =0D - //=0D - // Determine the size/length of packet.=0D - //=0D - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option);=0D ASSERT (Packet->Size > Packet->Length + 8);=0D =0D //=0D @@ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg ( Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet);=0D =0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D @@ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg ( Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed);=0D =0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D // Enqueue the sent packet for the retransmission in case reply timeout.= =0D //=0D return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);=0D +=0D +ON_ERROR:=0D +=0D + if (Packet) {=0D + FreePool (Packet);=0D + }=0D +=0D + return Status;=0D }=0D =0D /**=0D @@ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg ( //=0D Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);=0D if (Packet =3D=3D NULL) {=0D - return EFI_OUT_OF_RESOURCES;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ON_ERROR;=0D }=0D =0D Packet->Size =3D DHCP6_BASE_PACKET_SIZE;=0D @@ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg ( Cursor =3D Packet->Dhcp6.Option;=0D =0D Length =3D HTONS (ClientId->Length);=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptClientId),=0D Length,=0D ClientId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendETOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendETOption (=0D + Packet,=0D + &Cursor,=0D Instance,=0D &Elapsed=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptServerId),=0D ServerId->Length,=0D ServerId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Heade= r.MessageType);=0D + Status =3D Dhcp6AppendIaOption (=0D + Packet,=0D + &Cursor,=0D + DecIa,=0D + 0,=0D + 0,=0D + Packet->Dhcp6.Header.MessageType=0D + );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - //=0D - // Determine the size/length of packet.=0D - //=0D - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option);=0D ASSERT (Packet->Size > Packet->Length + 8);=0D =0D //=0D // Callback to user with the packet to be sent and check the user's feed= back.=0D //=0D Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D @@ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg ( Instance->StartTime =3D 0;=0D =0D Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D // Enqueue the sent packet for the retransmission in case reply timeout.= =0D //=0D return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);=0D +=0D +ON_ERROR:=0D +=0D + if (Packet) {=0D + FreePool (Packet);=0D + }=0D +=0D + return Status;=0D }=0D =0D /**=0D @@ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg ( //=0D Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);=0D if (Packet =3D=3D NULL) {=0D - return EFI_OUT_OF_RESOURCES;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ON_ERROR;=0D }=0D =0D Packet->Size =3D DHCP6_BASE_PACKET_SIZE;=0D @@ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg ( Cursor =3D Packet->Dhcp6.Option;=0D =0D Length =3D HTONS (ClientId->Length);=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptClientId),=0D Length,=0D ClientId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D //=0D // ServerId is extracted from packet, it's network order.=0D //=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptServerId),=0D ServerId->Length,=0D ServerId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendETOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendETOption (=0D + Packet,=0D + &Cursor,=0D Instance,=0D &Elapsed=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Heade= r.MessageType);=0D + Status =3D Dhcp6AppendIaOption (=0D + Packet,=0D + &Cursor,=0D + RelIa,=0D + 0,=0D + 0,=0D + Packet->Dhcp6.Header.MessageType=0D + );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - //=0D - // Determine the size/length of packet=0D - //=0D - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option);=0D ASSERT (Packet->Size > Packet->Length + 8);=0D =0D //=0D // Callback to user with the packet to be sent and check the user's feed= back.=0D //=0D Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D @@ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg ( Instance->IaCb.Ia->State =3D Dhcp6Releasing;=0D =0D Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D // Enqueue the sent packet for the retransmission in case reply timeout.= =0D //=0D return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);=0D +=0D +ON_ERROR:=0D +=0D + if (Packet) {=0D + FreePool (Packet);=0D + }=0D +=0D + return Status;=0D }=0D =0D /**=0D @@ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg ( //=0D Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);=0D if (Packet =3D=3D NULL) {=0D - return EFI_OUT_OF_RESOURCES;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ON_ERROR;=0D }=0D =0D Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen;= =0D @@ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg ( Cursor =3D Packet->Dhcp6.Option;=0D =0D Length =3D HTONS (ClientId->Length);=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptClientId),=0D Length,=0D ClientId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendETOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendETOption (=0D + Packet,=0D + &Cursor,=0D Instance,=0D &Elapsed=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendIaOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendIaOption (=0D + Packet,=0D + &Cursor,=0D Instance->IaCb.Ia,=0D Instance->IaCb.T1,=0D Instance->IaCb.T2,=0D Packet->Dhcp6.Header.MessageType=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D if (!RebindRequest) {=0D //=0D @@ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg ( Dhcp6OptServerId=0D );=0D if (Option =3D=3D NULL) {=0D - FreePool (Packet);=0D - return EFI_DEVICE_ERROR;=0D + Status =3D EFI_DEVICE_ERROR;=0D + goto ON_ERROR;=0D }=0D =0D ServerId =3D (EFI_DHCP6_DUID *)(Option + 2);=0D =0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptServerId),=0D ServerId->Length,=0D ServerId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D }=0D =0D //=0D @@ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg ( //=0D for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) {=0D UserOpt =3D Instance->Config->OptionList[Index];=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D UserOpt->OpCode,=0D UserOpt->OpLen,=0D UserOpt->Data=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D }=0D =0D - //=0D - // Determine the size/length of packet.=0D - //=0D - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option);=0D ASSERT (Packet->Size > Packet->Length + 8);=0D =0D //=0D @@ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg ( Event =3D (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing;=0D =0D Status =3D Dhcp6CallbackUser (Instance, Event, &Packet);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D @@ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg ( Instance->StartTime =3D 0;=0D =0D Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D // Enqueue the sent packet for the retransmission in case reply timeout.= =0D //=0D return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);=0D +=0D +ON_ERROR:=0D +=0D + if (Packet) {=0D + FreePool (Packet);=0D + }=0D +=0D + return Status;=0D }=0D =0D /**=0D @@ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg ( //=0D Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);=0D if (Packet =3D=3D NULL) {=0D - return EFI_OUT_OF_RESOURCES;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ON_ERROR;=0D }=0D =0D Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen;= =0D @@ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg ( =0D if (SendClientId) {=0D Length =3D HTONS (ClientId->Length);=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptClientId),=0D Length,=0D ClientId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D }=0D =0D - Cursor =3D Dhcp6AppendETOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendETOption (=0D + Packet,=0D + &Cursor,=0D Instance,=0D &Elapsed=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D OptionRequest->OpCode,=0D OptionRequest->OpLen,=0D OptionRequest->Data=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D //=0D // Append user-defined when configurate Dhcp6 service.=0D //=0D for (Index =3D 0; Index < OptionCount; Index++) {=0D UserOpt =3D OptionList[Index];=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D UserOpt->OpCode,=0D UserOpt->OpLen,=0D UserOpt->Data=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D }=0D =0D - //=0D - // Determine the size/length of packet.=0D - //=0D - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option);=0D ASSERT (Packet->Size > Packet->Length + 8);=0D =0D //=0D @@ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg ( // Send info-request packet with no state.=0D //=0D Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D // Enqueue the sent packet for the retransmission in case reply timeout.= =0D //=0D return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission);=0D +=0D +ON_ERROR:=0D +=0D + if (Packet) {=0D + FreePool (Packet);=0D + }=0D +=0D + return Status;=0D }=0D =0D /**=0D @@ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg ( //=0D Packet =3D AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);=0D if (Packet =3D=3D NULL) {=0D - return EFI_OUT_OF_RESOURCES;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto ON_ERROR;=0D }=0D =0D Packet->Size =3D DHCP6_BASE_PACKET_SIZE + UserLen;= =0D @@ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg ( Cursor =3D Packet->Dhcp6.Option;=0D =0D Length =3D HTONS (ClientId->Length);=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D HTONS (Dhcp6OptClientId),=0D Length,=0D ClientId->Duid=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendETOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendETOption (=0D + Packet,=0D + &Cursor,=0D Instance,=0D &Elapsed=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D - Cursor =3D Dhcp6AppendIaOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendIaOption (=0D + Packet,=0D + &Cursor,=0D Instance->IaCb.Ia,=0D Instance->IaCb.T1,=0D Instance->IaCb.T2,=0D Packet->Dhcp6.Header.MessageType=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D =0D //=0D // Append user-defined when configurate Dhcp6 service.=0D //=0D for (Index =3D 0; Index < Instance->Config->OptionCount; Index++) {=0D UserOpt =3D Instance->Config->OptionList[Index];=0D - Cursor =3D Dhcp6AppendOption (=0D - Cursor,=0D + Status =3D Dhcp6AppendOption (=0D + Packet,=0D + &Cursor,=0D UserOpt->OpCode,=0D UserOpt->OpLen,=0D UserOpt->Data=0D );=0D + if (EFI_ERROR (Status)) {=0D + goto ON_ERROR;=0D + }=0D }=0D =0D - //=0D - // Determine the size/length of packet.=0D - //=0D - Packet->Length +=3D (UINT32)(Cursor - Packet->Dhcp6.Option);=0D ASSERT (Packet->Size > Packet->Length + 8);=0D =0D //=0D // Callback to user with the packet to be sent and check the user's feed= back.=0D //=0D Status =3D Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D @@ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg ( Instance->StartTime =3D 0;=0D =0D Status =3D Dhcp6TransmitPacket (Instance, Packet, Elapsed);=0D -=0D if (EFI_ERROR (Status)) {=0D - FreePool (Packet);=0D - return Status;=0D + goto ON_ERROR;=0D }=0D =0D //=0D // Enqueue the sent packet for the retransmission in case reply timeout.= =0D //=0D return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);=0D +=0D +ON_ERROR:=0D +=0D + if (Packet) {=0D + FreePool (Packet);=0D + }=0D +=0D + return Status;=0D }=0D =0D /**=0D diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6= Utility.c index e6368b5b1c6c..705c665c519d 100644 --- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c +++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c @@ -577,24 +577,33 @@ Dhcp6OnTransmitted ( }=0D =0D /**=0D - Append the option to Buf, and move Buf to the end.=0D + Append the option to Buf, update the length of packet, and move Buf to t= he end.=0D =0D - @param[in, out] Buf The pointer to the buffer.=0D - @param[in] OptType The option type.=0D - @param[in] OptLen The length of option contents.=0D - @param[in] Data The pointer to the option content.=0D + @param[in, out] Packet A pointer to the packet, on success Packe= t->Length=0D + will be updated.=0D + @param[in, out] PacketCursor The pointer in the packet, on success Pac= ketCursor=0D + will be moved to the end of the option.=0D + @param[in] OptType The option type.=0D + @param[in] OptLen The length of option contents.=0D + @param[in] Data The pointer to the option content.=0D =0D - @return Buf The position to append the next option.=0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D =0D **/=0D -UINT8 *=0D +EFI_STATUS=0D Dhcp6AppendOption (=0D - IN OUT UINT8 *Buf,=0D - IN UINT16 OptType,=0D - IN UINT16 OptLen,=0D - IN UINT8 *Data=0D + IN OUT EFI_DHCP6_PACKET *Packet,=0D + IN OUT UINT8 **PacketCursor,=0D + IN UINT16 OptType,=0D + IN UINT16 OptLen,=0D + IN UINT8 *Data=0D )=0D {=0D + UINT32 Length;=0D + UINT32 BytesNeeded;=0D +=0D //=0D // The format of Dhcp6 option:=0D //=0D @@ -607,35 +616,95 @@ Dhcp6AppendOption ( // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D //=0D =0D - ASSERT (OptLen !=3D 0);=0D + //=0D + // Verify the arguments are valid=0D + //=0D + if (Packet =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D =0D - WriteUnaligned16 ((UINT16 *)Buf, OptType);=0D - Buf +=3D 2;=0D - WriteUnaligned16 ((UINT16 *)Buf, OptLen);=0D - Buf +=3D 2;=0D - CopyMem (Buf, Data, NTOHS (OptLen));=0D - Buf +=3D NTOHS (OptLen);=0D + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D =0D - return Buf;=0D + if (Data =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (OptLen =3D=3D 0) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Verify the PacketCursor is within the packet=0D + //=0D + if ( (*PacketCursor < Packet->Dhcp6.Option)=0D + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER))))=0D + {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Calculate the bytes needed for the option=0D + //=0D + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen);=0D +=0D + //=0D + // Space remaining in the packet=0D + //=0D + Length =3D Packet->Size - Packet->Length;=0D + if (Length < BytesNeeded) {=0D + return EFI_BUFFER_TOO_SMALL;=0D + }=0D +=0D + //=0D + // Verify the PacketCursor is within the packet=0D + //=0D + if ( (*PacketCursor < Packet->Dhcp6.Option)=0D + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER))))=0D + {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType);=0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE;=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen);=0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN;=0D + CopyMem (*PacketCursor, Data, NTOHS (OptLen));=0D + *PacketCursor +=3D NTOHS (OptLen);=0D +=0D + // Update the packet length by the length of the option + 4 bytes=0D + Packet->Length +=3D BytesNeeded;=0D +=0D + return EFI_SUCCESS;=0D }=0D =0D /**=0D Append the appointed IA Address option to Buf, and move Buf to the end.= =0D =0D - @param[in, out] Buf The pointer to the position to append.=0D + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length=0D + will be updated.=0D + @param[in, out] PacketCursor The pointer in the packet, on success Pack= etCursor=0D + will be moved to the end of the option.=0D @param[in] IaAddr The pointer to the IA Address.=0D @param[in] MessageType Message type of DHCP6 package.=0D =0D - @return Buf The position to append the next option.=0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D =0D **/=0D -UINT8 *=0D +EFI_STATUS=0D Dhcp6AppendIaAddrOption (=0D - IN OUT UINT8 *Buf,=0D + IN OUT EFI_DHCP6_PACKET *Packet,=0D + IN OUT UINT8 **PacketCursor,=0D IN EFI_DHCP6_IA_ADDRESS *IaAddr,=0D IN UINT32 MessageType=0D )=0D {=0D + UINT32 BytesNeeded;=0D + UINT32 Length;=0D +=0D // The format of the IA Address option is:=0D //=0D // 0 1 2 3=0D @@ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption ( // . = .=0D // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-= +=0D =0D + //=0D + // Verify the arguments are valid=0D + //=0D + if (Packet =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (IaAddr =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Verify the PacketCursor is within the packet=0D + //=0D + if ( (*PacketCursor < Packet->Dhcp6.Option)=0D + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER))))=0D + {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;=0D + BytesNeeded +=3D sizeof (EFI_IPv6_ADDRESS);=0D + //=0D + // Even if the preferred-lifetime is 0, it still needs to store it.=0D + //=0D + BytesNeeded +=3D sizeof (IaAddr->PreferredLifetime);=0D + //=0D + // Even if the valid-lifetime is 0, it still needs to store it.=0D + //=0D + BytesNeeded +=3D sizeof (IaAddr->ValidLifetime);=0D +=0D + //=0D + // Space remaining in the packet=0D + //=0D + Length =3D Packet->Size - Packet->Length;=0D + if (Length < BytesNeeded) {=0D + return EFI_BUFFER_TOO_SMALL;=0D + }=0D +=0D //=0D // Fill the value of Ia Address option type=0D //=0D - WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr));=0D - Buf +=3D 2;=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr));=0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE;=0D =0D - WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));= =0D - Buf +=3D 2;=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_A= DDRESS)));=0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN;=0D =0D - CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));=0D - Buf +=3D sizeof (EFI_IPv6_ADDRESS);=0D + CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));= =0D + *PacketCursor +=3D sizeof (EFI_IPv6_ADDRESS);=0D =0D //=0D // Fill the value of preferred-lifetime and valid-lifetime.=0D @@ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption ( // should set to 0 when initiate a Confirm message.=0D //=0D if (MessageType !=3D Dhcp6MsgConfirm) {=0D - WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime));=0D + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLif= etime));=0D }=0D =0D - Buf +=3D 4;=0D + *PacketCursor +=3D sizeof (IaAddr->PreferredLifetime);=0D =0D if (MessageType !=3D Dhcp6MsgConfirm) {=0D - WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime));=0D + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetim= e));=0D }=0D =0D - Buf +=3D 4;=0D + *PacketCursor +=3D sizeof (IaAddr->ValidLifetime);=0D =0D - return Buf;=0D + //=0D + // Update the packet length=0D + //=0D + Packet->Length +=3D BytesNeeded;=0D +=0D + return EFI_SUCCESS;=0D }=0D =0D /**=0D Append the appointed Ia option to Buf, and move Buf to the end.=0D =0D - @param[in, out] Buf The pointer to the position to append.=0D + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length=0D + will be updated.=0D + @param[in, out] PacketCursor The pointer in the packet, on success Pack= etCursor=0D + will be moved to the end of the option.=0D @param[in] Ia The pointer to the Ia.=0D @param[in] T1 The time of T1.=0D @param[in] T2 The time of T2.=0D @param[in] MessageType Message type of DHCP6 package.=0D =0D - @return Buf The position to append the next Ia option.= =0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D =0D **/=0D -UINT8 *=0D +EFI_STATUS=0D Dhcp6AppendIaOption (=0D - IN OUT UINT8 *Buf,=0D - IN EFI_DHCP6_IA *Ia,=0D - IN UINT32 T1,=0D - IN UINT32 T2,=0D - IN UINT32 MessageType=0D + IN OUT EFI_DHCP6_PACKET *Packet,=0D + IN OUT UINT8 **PacketCursor,=0D + IN EFI_DHCP6_IA *Ia,=0D + IN UINT32 T1,=0D + IN UINT32 T2,=0D + IN UINT32 MessageType=0D )=0D {=0D - UINT8 *AddrOpt;=0D - UINT16 *Len;=0D - UINTN Index;=0D + UINT8 *AddrOpt;=0D + UINT16 *Len;=0D + UINTN Index;=0D + UINT32 BytesNeeded;=0D + UINT32 Length;=0D + EFI_STATUS Status;=0D =0D //=0D // The format of IA_NA and IA_TA option:=0D @@ -733,32 +859,74 @@ Dhcp6AppendIaOption ( // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+= =0D //=0D =0D + //=0D + // Verify the arguments are valid=0D + //=0D + if (Packet =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (Ia =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Verify the PacketCursor is within the packet=0D + //=0D + if ( (*PacketCursor < Packet->Dhcp6.Option)=0D + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER))))=0D + {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;=0D + BytesNeeded +=3D sizeof (Ia->Descriptor.IaId);=0D + //=0D + // + N for the IA_NA-options/IA_TA-options=0D + // Dhcp6AppendIaAddrOption will need to check the length for each addres= s=0D + //=0D + if (Ia->Descriptor.Type =3D=3D Dhcp6OptIana) {=0D + BytesNeeded +=3D sizeof (T1) + sizeof (T2);=0D + }=0D +=0D + //=0D + // Space remaining in the packet=0D + //=0D + Length =3D (UINT16)(Packet->Size - Packet->Length);=0D + if (Length < BytesNeeded) {=0D + return EFI_BUFFER_TOO_SMALL;=0D + }=0D +=0D //=0D // Fill the value of Ia option type=0D //=0D - WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type));=0D - Buf +=3D 2;=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type));= =0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE;=0D =0D //=0D // Fill the len of Ia option later, keep the pointer first=0D //=0D - Len =3D (UINT16 *)Buf;=0D - Buf +=3D 2;=0D + Len =3D (UINT16 *)*PacketCursor;=0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN;=0D =0D //=0D // Fill the value of iaid=0D //=0D - WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId));=0D - Buf +=3D 4;=0D + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId));= =0D + *PacketCursor +=3D sizeof (Ia->Descriptor.IaId);=0D =0D //=0D // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specifi= ed.=0D //=0D if (Ia->Descriptor.Type =3D=3D Dhcp6OptIana) {=0D - WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 !=3D 0) ? T1 : 0xffffffff)= );=0D - Buf +=3D 4;=0D - WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 !=3D 0) ? T2 : 0xffffffff)= );=0D - Buf +=3D 4;=0D + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 !=3D 0) ? T1 : 0= xffffffff));=0D + *PacketCursor +=3D sizeof (T1);=0D + WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 !=3D 0) ? T2 : 0= xffffffff));=0D + *PacketCursor +=3D sizeof (T2);=0D }=0D =0D //=0D @@ -766,35 +934,51 @@ Dhcp6AppendIaOption ( //=0D for (Index =3D 0; Index < Ia->IaAddressCount; Index++) {=0D AddrOpt =3D (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDR= ESS);=0D - Buf =3D Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)Addr= Opt, MessageType);=0D + Status =3D Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_= IA_ADDRESS *)AddrOpt, MessageType);=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D }=0D =0D //=0D // Fill the value of Ia option length=0D //=0D - *Len =3D HTONS ((UINT16)(Buf - (UINT8 *)Len - 2));=0D + *Len =3D HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2));=0D =0D - return Buf;=0D + //=0D + // Update the packet length=0D + //=0D + Packet->Length +=3D BytesNeeded;=0D +=0D + return EFI_SUCCESS;=0D }=0D =0D /**=0D Append the appointed Elapsed time option to Buf, and move Buf to the end= .=0D =0D - @param[in, out] Buf The pointer to the position to append.=0D + @param[in, out] Packet A pointer to the packet, on success Packet= ->Length=0D + @param[in, out] PacketCursor The pointer in the packet, on success Pack= etCursor=0D + will be moved to the end of the option.=0D @param[in] Instance The pointer to the Dhcp6 instance.=0D @param[out] Elapsed The pointer to the elapsed time value in=0D - the generated packet.=0D + the generated packet.=0D =0D - @return Buf The position to append the next Ia option.= =0D + @retval EFI_INVALID_PARAMETER An argument provided to the function was= invalid=0D + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the op= tion.=0D + @retval EFI_SUCCESS The option is appended successfully.=0D =0D **/=0D -UINT8 *=0D +EFI_STATUS=0D Dhcp6AppendETOption (=0D - IN OUT UINT8 *Buf,=0D - IN DHCP6_INSTANCE *Instance,=0D - OUT UINT16 **Elapsed=0D + IN OUT EFI_DHCP6_PACKET *Packet,=0D + IN OUT UINT8 **PacketCursor,=0D + IN DHCP6_INSTANCE *Instance,=0D + OUT UINT16 **Elapsed=0D )=0D {=0D + UINT32 BytesNeeded;=0D + UINT32 Length;=0D +=0D //=0D // The format of elapsed time option:=0D //=0D @@ -806,27 +990,70 @@ Dhcp6AppendETOption ( // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+=0D //=0D =0D + //=0D + // Verify the arguments are valid=0D + //=0D + if (Packet =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if ((PacketCursor =3D=3D NULL) || (*PacketCursor =3D=3D NULL)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (Instance =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if ((Elapsed =3D=3D NULL)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Verify the PacketCursor is within the packet=0D + //=0D + if ( (*PacketCursor < Packet->Dhcp6.Option)=0D + || (*PacketCursor >=3D Packet->Dhcp6.Option + (Packet->Size - sizeof = (EFI_DHCP6_HEADER))))=0D + {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + BytesNeeded =3D DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;=0D + //=0D + // + 2 for elapsed-time=0D + //=0D + BytesNeeded +=3D sizeof (UINT16);=0D + //=0D + // Space remaining in the packet=0D + //=0D + Length =3D Packet->Size - Packet->Length;=0D + if (Length < BytesNeeded) {=0D + return EFI_BUFFER_TOO_SMALL;=0D + }=0D +=0D //=0D // Fill the value of elapsed-time option type.=0D //=0D - WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime));=0D - Buf +=3D 2;=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime));= =0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_CODE;=0D =0D //=0D // Fill the len of elapsed-time option, which is fixed.=0D //=0D - WriteUnaligned16 ((UINT16 *)Buf, HTONS (2));=0D - Buf +=3D 2;=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2));=0D + *PacketCursor +=3D DHCP6_SIZE_OF_OPT_LEN;=0D =0D //=0D // Fill in elapsed time value with 0 value for now. The actual value is= =0D // filled in later just before the packet is transmitted.=0D //=0D - WriteUnaligned16 ((UINT16 *)Buf, HTONS (0));=0D - *Elapsed =3D (UINT16 *)Buf;=0D - Buf +=3D 2;=0D + WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0));=0D + *Elapsed =3D (UINT16 *)*PacketCursor;=0D + *PacketCursor +=3D sizeof (UINT16);=0D =0D - return Buf;=0D + Packet->Length +=3D BytesNeeded;=0D +=0D + return EFI_SUCCESS;=0D }=0D =0D /**=0D --=20 2.43.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114463): https://edk2.groups.io/g/devel/message/114463 Mute This Topic: https://groups.io/mt/103964976/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-