summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0001.patch1617
-rw-r--r--meta/recipes-core/ovmf/ovmf/CVE-2023-45230-0002.patch604
-rw-r--r--meta/recipes-core/ovmf/ovmf_git.bb2
3 files changed, 2223 insertions, 0 deletions
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 @@
1From f31453e8d6542461d92d835e0b79fec8b039174d Mon Sep 17 00:00:00 2001
2From: "Doug Flick via groups.io" <dougflick=microsoft.com@groups.io>
3Date: Fri, 26 Jan 2024 05:54:43 +0800
4Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch
5
6REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535
7
8Bug Details:
9PixieFail Bug #2
10CVE-2023-45230
11CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
12CWE-119 Improper Restriction of Operations within the Bounds
13 of a Memory Buffer
14
15Changes Overview:
16> -UINT8 *
17> +EFI_STATUS
18> Dhcp6AppendOption (
19> - IN OUT UINT8 *Buf,
20> - IN UINT16 OptType,
21> - IN UINT16 OptLen,
22> - IN UINT8 *Data
23> + IN OUT EFI_DHCP6_PACKET *Packet,
24> + IN OUT UINT8 **PacketCursor,
25> + IN UINT16 OptType,
26> + IN UINT16 OptLen,
27> + IN UINT8 *Data
28> );
29
30Dhcp6AppendOption() and variants can return errors now. All callsites
31are adapted accordingly.
32
33It gets passed in EFI_DHCP6_PACKET as additional parameter ...
34
35> + //
36> + // Verify the PacketCursor is within the packet
37> + //
38> + if ( (*PacketCursor < Packet->Dhcp6.Option)
39> + || (*PacketCursor >= Packet->Dhcp6.Option +
40 (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
41> + {
42> + return EFI_INVALID_PARAMETER;
43> + }
44
45... so it can look at Packet->Size when checking buffer space.
46Also to allow Packet->Length updates.
47
48Lots of checks added.
49
50Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
51Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
52
53Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
54Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
55
56CVE: CVE-2023-45230
57
58Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/f31453e8d6542461d92d835e0b79fec8b039174d]
59
60Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
61---
62 NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h | 43 +++
63 NetworkPkg/Dhcp6Dxe/Dhcp6Io.c | 409 +++++++++++++++++++----------
64 NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c | 373 +++++++++++++++++++++-----
65 NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h | 82 +++---
66 4 files changed, 668 insertions(+), 239 deletions(-)
67
68diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
69index 0eb9c669b5..f2422c2f28 100644
70--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
71+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
72@@ -45,6 +45,49 @@ typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE;
73 #define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S')
74 #define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I')
75
76+//
77+// For more information on DHCP options see RFC 8415, Section 21.1
78+//
79+// The format of DHCP options is:
80+//
81+// 0 1 2 3
82+// 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
83+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84+// | option-code | option-len |
85+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86+// | option-data |
87+// | (option-len octets) |
88+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
89+//
90+#define DHCP6_SIZE_OF_OPT_CODE (sizeof(UINT16))
91+#define DHCP6_SIZE_OF_OPT_LEN (sizeof(UINT16))
92+
93+//
94+// Combined size of Code and Length
95+//
96+#define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN (DHCP6_SIZE_OF_OPT_CODE + \
97+ DHCP6_SIZE_OF_OPT_LEN)
98+
99+STATIC_ASSERT (
100+ DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN == 4,
101+ "Combined size of Code and Length must be 4 per RFC 8415"
102+ );
103+
104+//
105+// Offset to the length is just past the code
106+//
107+#define DHCP6_OPT_LEN_OFFSET(a) (a + DHCP6_SIZE_OF_OPT_CODE)
108+STATIC_ASSERT (
109+ DHCP6_OPT_LEN_OFFSET (0) == 2,
110+ "Offset of length is + 2 past start of option"
111+ );
112+
113+#define DHCP6_OPT_DATA_OFFSET(a) (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN)
114+STATIC_ASSERT (
115+ DHCP6_OPT_DATA_OFFSET (0) == 4,
116+ "Offset to option data should be +4 from start of option"
117+ );
118+
119 #define DHCP6_PACKET_ALL 0
120 #define DHCP6_PACKET_STATEFUL 1
121 #define DHCP6_PACKET_STATELESS 2
122diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
123index dcd01e6268..bf5aa7a769 100644
124--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
125+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
126@@ -3,9 +3,9 @@
127
128 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
129 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
130+ Copyright (c) Microsoft Corporation
131
132 SPDX-License-Identifier: BSD-2-Clause-Patent
133-
134 **/
135
136 #include "Dhcp6Impl.h"
137@@ -930,7 +930,8 @@ Dhcp6SendSolicitMsg (
138 //
139 Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
140 if (Packet == NULL) {
141- return EFI_OUT_OF_RESOURCES;
142+ Status = EFI_OUT_OF_RESOURCES;
143+ goto ON_ERROR;
144 }
145
146 Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
147@@ -944,54 +945,64 @@ Dhcp6SendSolicitMsg (
148 Cursor = Packet->Dhcp6.Option;
149
150 Length = HTONS (ClientId->Length);
151- Cursor = Dhcp6AppendOption (
152- Cursor,
153+ Status = Dhcp6AppendOption (
154+ Packet,
155+ &Cursor,
156 HTONS (Dhcp6OptClientId),
157 Length,
158 ClientId->Duid
159 );
160+ if (EFI_ERROR (Status)) {
161+ goto ON_ERROR;
162+ }
163
164- Cursor = Dhcp6AppendETOption (
165- Cursor,
166+ Status = Dhcp6AppendETOption (
167+ Packet,
168+ &Cursor,
169 Instance,
170 &Elapsed
171 );
172+ if (EFI_ERROR (Status)) {
173+ goto ON_ERROR;
174+ }
175
176- Cursor = Dhcp6AppendIaOption (
177- Cursor,
178+ Status = Dhcp6AppendIaOption (
179+ Packet,
180+ &Cursor,
181 Instance->IaCb.Ia,
182 Instance->IaCb.T1,
183 Instance->IaCb.T2,
184 Packet->Dhcp6.Header.MessageType
185 );
186+ if (EFI_ERROR (Status)) {
187+ goto ON_ERROR;
188+ }
189
190 //
191 // Append user-defined when configurate Dhcp6 service.
192 //
193 for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
194 UserOpt = Instance->Config->OptionList[Index];
195- Cursor = Dhcp6AppendOption (
196- Cursor,
197+ Status = Dhcp6AppendOption (
198+ Packet,
199+ &Cursor,
200 UserOpt->OpCode,
201 UserOpt->OpLen,
202 UserOpt->Data
203 );
204+ if (EFI_ERROR (Status)) {
205+ goto ON_ERROR;
206+ }
207 }
208
209- //
210- // Determine the size/length of packet.
211- //
212- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
213 ASSERT (Packet->Size > Packet->Length + 8);
214
215 //
216 // Callback to user with the packet to be sent and check the user's feedback.
217 //
218 Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet);
219-
220 if (EFI_ERROR (Status)) {
221- FreePool (Packet);
222- return Status;
223+ goto ON_ERROR;
224 }
225
226 //
227@@ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg (
228 Instance->StartTime = 0;
229
230 Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
231-
232 if (EFI_ERROR (Status)) {
233- FreePool (Packet);
234- return Status;
235+ goto ON_ERROR;
236 }
237
238 //
239@@ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg (
240 Elapsed,
241 Instance->Config->SolicitRetransmission
242 );
243+
244+ON_ERROR:
245+
246+ if (Packet) {
247+ FreePool (Packet);
248+ }
249+
250+ return Status;
251 }
252
253 /**
254@@ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg (
255 //
256 Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
257 if (Packet == NULL) {
258- return EFI_OUT_OF_RESOURCES;
259+ Status = EFI_OUT_OF_RESOURCES;
260+ goto ON_ERROR;
261 }
262
263 Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
264@@ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg (
265 Cursor = Packet->Dhcp6.Option;
266
267 Length = HTONS (ClientId->Length);
268- Cursor = Dhcp6AppendOption (
269- Cursor,
270+ Status = Dhcp6AppendOption (
271+ Packet,
272+ &Cursor,
273 HTONS (Dhcp6OptClientId),
274 Length,
275 ClientId->Duid
276 );
277+ if (EFI_ERROR (Status)) {
278+ goto ON_ERROR;
279+ }
280
281- Cursor = Dhcp6AppendETOption (
282- Cursor,
283+ Status = Dhcp6AppendETOption (
284+ Packet,
285+ &Cursor,
286 Instance,
287 &Elapsed
288 );
289+ if (EFI_ERROR (Status)) {
290+ goto ON_ERROR;
291+ }
292
293- Cursor = Dhcp6AppendOption (
294- Cursor,
295+ Status = Dhcp6AppendOption (
296+ Packet,
297+ &Cursor,
298 HTONS (Dhcp6OptServerId),
299 ServerId->Length,
300 ServerId->Duid
301 );
302+ if (EFI_ERROR (Status)) {
303+ goto ON_ERROR;
304+ }
305
306- Cursor = Dhcp6AppendIaOption (
307- Cursor,
308+ Status = Dhcp6AppendIaOption (
309+ Packet,
310+ &Cursor,
311 Instance->IaCb.Ia,
312 Instance->IaCb.T1,
313 Instance->IaCb.T2,
314 Packet->Dhcp6.Header.MessageType
315 );
316+ if (EFI_ERROR (Status)) {
317+ goto ON_ERROR;
318+ }
319
320 //
321 // Append user-defined when configurate Dhcp6 service.
322 //
323 for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
324 UserOpt = Instance->Config->OptionList[Index];
325- Cursor = Dhcp6AppendOption (
326- Cursor,
327+ Status = Dhcp6AppendOption (
328+ Packet,
329+ &Cursor,
330 UserOpt->OpCode,
331 UserOpt->OpLen,
332 UserOpt->Data
333 );
334+ if (EFI_ERROR (Status)) {
335+ goto ON_ERROR;
336+ }
337 }
338
339- //
340- // Determine the size/length of packet.
341- //
342- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
343 ASSERT (Packet->Size > Packet->Length + 8);
344
345 //
346@@ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg (
347 Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet);
348
349 if (EFI_ERROR (Status)) {
350- FreePool (Packet);
351- return Status;
352+ goto ON_ERROR;
353 }
354
355 //
356@@ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg (
357 Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
358
359 if (EFI_ERROR (Status)) {
360- FreePool (Packet);
361- return Status;
362+ goto ON_ERROR;
363 }
364
365 //
366 // Enqueue the sent packet for the retransmission in case reply timeout.
367 //
368 return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
369+
370+ON_ERROR:
371+
372+ if (Packet) {
373+ FreePool (Packet);
374+ }
375+
376+ return Status;
377 }
378
379 /**
380@@ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg (
381 //
382 Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
383 if (Packet == NULL) {
384- return EFI_OUT_OF_RESOURCES;
385+ Status = EFI_OUT_OF_RESOURCES;
386+ goto ON_ERROR;
387 }
388
389 Packet->Size = DHCP6_BASE_PACKET_SIZE;
390@@ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg (
391 Cursor = Packet->Dhcp6.Option;
392
393 Length = HTONS (ClientId->Length);
394- Cursor = Dhcp6AppendOption (
395- Cursor,
396+ Status = Dhcp6AppendOption (
397+ Packet,
398+ &Cursor,
399 HTONS (Dhcp6OptClientId),
400 Length,
401 ClientId->Duid
402 );
403+ if (EFI_ERROR (Status)) {
404+ goto ON_ERROR;
405+ }
406
407- Cursor = Dhcp6AppendETOption (
408- Cursor,
409+ Status = Dhcp6AppendETOption (
410+ Packet,
411+ &Cursor,
412 Instance,
413 &Elapsed
414 );
415+ if (EFI_ERROR (Status)) {
416+ goto ON_ERROR;
417+ }
418
419- Cursor = Dhcp6AppendOption (
420- Cursor,
421+ Status = Dhcp6AppendOption (
422+ Packet,
423+ &Cursor,
424 HTONS (Dhcp6OptServerId),
425 ServerId->Length,
426 ServerId->Duid
427 );
428+ if (EFI_ERROR (Status)) {
429+ goto ON_ERROR;
430+ }
431
432- Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType);
433+ Status = Dhcp6AppendIaOption (
434+ Packet,
435+ &Cursor,
436+ DecIa,
437+ 0,
438+ 0,
439+ Packet->Dhcp6.Header.MessageType
440+ );
441+ if (EFI_ERROR (Status)) {
442+ goto ON_ERROR;
443+ }
444
445- //
446- // Determine the size/length of packet.
447- //
448- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
449 ASSERT (Packet->Size > Packet->Length + 8);
450
451 //
452 // Callback to user with the packet to be sent and check the user's feedback.
453 //
454 Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet);
455-
456 if (EFI_ERROR (Status)) {
457- FreePool (Packet);
458- return Status;
459+ goto ON_ERROR;
460 }
461
462 //
463@@ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg (
464 Instance->StartTime = 0;
465
466 Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
467-
468 if (EFI_ERROR (Status)) {
469- FreePool (Packet);
470- return Status;
471+ goto ON_ERROR;
472 }
473
474 //
475 // Enqueue the sent packet for the retransmission in case reply timeout.
476 //
477 return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
478+
479+ON_ERROR:
480+
481+ if (Packet) {
482+ FreePool (Packet);
483+ }
484+
485+ return Status;
486 }
487
488 /**
489@@ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg (
490 //
491 Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE);
492 if (Packet == NULL) {
493- return EFI_OUT_OF_RESOURCES;
494+ Status = EFI_OUT_OF_RESOURCES;
495+ goto ON_ERROR;
496 }
497
498 Packet->Size = DHCP6_BASE_PACKET_SIZE;
499@@ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg (
500 Cursor = Packet->Dhcp6.Option;
501
502 Length = HTONS (ClientId->Length);
503- Cursor = Dhcp6AppendOption (
504- Cursor,
505+ Status = Dhcp6AppendOption (
506+ Packet,
507+ &Cursor,
508 HTONS (Dhcp6OptClientId),
509 Length,
510 ClientId->Duid
511 );
512+ if (EFI_ERROR (Status)) {
513+ goto ON_ERROR;
514+ }
515
516 //
517 // ServerId is extracted from packet, it's network order.
518 //
519- Cursor = Dhcp6AppendOption (
520- Cursor,
521+ Status = Dhcp6AppendOption (
522+ Packet,
523+ &Cursor,
524 HTONS (Dhcp6OptServerId),
525 ServerId->Length,
526 ServerId->Duid
527 );
528+ if (EFI_ERROR (Status)) {
529+ goto ON_ERROR;
530+ }
531
532- Cursor = Dhcp6AppendETOption (
533- Cursor,
534+ Status = Dhcp6AppendETOption (
535+ Packet,
536+ &Cursor,
537 Instance,
538 &Elapsed
539 );
540+ if (EFI_ERROR (Status)) {
541+ goto ON_ERROR;
542+ }
543
544- Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType);
545+ Status = Dhcp6AppendIaOption (
546+ Packet,
547+ &Cursor,
548+ RelIa,
549+ 0,
550+ 0,
551+ Packet->Dhcp6.Header.MessageType
552+ );
553+ if (EFI_ERROR (Status)) {
554+ goto ON_ERROR;
555+ }
556
557- //
558- // Determine the size/length of packet
559- //
560- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
561 ASSERT (Packet->Size > Packet->Length + 8);
562
563 //
564 // Callback to user with the packet to be sent and check the user's feedback.
565 //
566 Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet);
567-
568 if (EFI_ERROR (Status)) {
569- FreePool (Packet);
570- return Status;
571+ goto ON_ERROR;
572 }
573
574 //
575@@ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg (
576 Instance->IaCb.Ia->State = Dhcp6Releasing;
577
578 Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
579-
580 if (EFI_ERROR (Status)) {
581- FreePool (Packet);
582- return Status;
583+ goto ON_ERROR;
584 }
585
586 //
587 // Enqueue the sent packet for the retransmission in case reply timeout.
588 //
589 return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
590+
591+ON_ERROR:
592+
593+ if (Packet) {
594+ FreePool (Packet);
595+ }
596+
597+ return Status;
598 }
599
600 /**
601@@ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg (
602 //
603 Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
604 if (Packet == NULL) {
605- return EFI_OUT_OF_RESOURCES;
606+ Status = EFI_OUT_OF_RESOURCES;
607+ goto ON_ERROR;
608 }
609
610 Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
611@@ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg (
612 Cursor = Packet->Dhcp6.Option;
613
614 Length = HTONS (ClientId->Length);
615- Cursor = Dhcp6AppendOption (
616- Cursor,
617+ Status = Dhcp6AppendOption (
618+ Packet,
619+ &Cursor,
620 HTONS (Dhcp6OptClientId),
621 Length,
622 ClientId->Duid
623 );
624+ if (EFI_ERROR (Status)) {
625+ goto ON_ERROR;
626+ }
627
628- Cursor = Dhcp6AppendETOption (
629- Cursor,
630+ Status = Dhcp6AppendETOption (
631+ Packet,
632+ &Cursor,
633 Instance,
634 &Elapsed
635 );
636+ if (EFI_ERROR (Status)) {
637+ goto ON_ERROR;
638+ }
639
640- Cursor = Dhcp6AppendIaOption (
641- Cursor,
642+ Status = Dhcp6AppendIaOption (
643+ Packet,
644+ &Cursor,
645 Instance->IaCb.Ia,
646 Instance->IaCb.T1,
647 Instance->IaCb.T2,
648 Packet->Dhcp6.Header.MessageType
649 );
650+ if (EFI_ERROR (Status)) {
651+ goto ON_ERROR;
652+ }
653
654 if (!RebindRequest) {
655 //
656@@ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg (
657 Dhcp6OptServerId
658 );
659 if (Option == NULL) {
660- FreePool (Packet);
661- return EFI_DEVICE_ERROR;
662+ Status = EFI_DEVICE_ERROR;
663+ goto ON_ERROR;
664 }
665
666 ServerId = (EFI_DHCP6_DUID *)(Option + 2);
667
668- Cursor = Dhcp6AppendOption (
669- Cursor,
670+ Status = Dhcp6AppendOption (
671+ Packet,
672+ &Cursor,
673 HTONS (Dhcp6OptServerId),
674 ServerId->Length,
675 ServerId->Duid
676 );
677+ if (EFI_ERROR (Status)) {
678+ goto ON_ERROR;
679+ }
680 }
681
682 //
683@@ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg (
684 //
685 for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
686 UserOpt = Instance->Config->OptionList[Index];
687- Cursor = Dhcp6AppendOption (
688- Cursor,
689+ Status = Dhcp6AppendOption (
690+ Packet,
691+ &Cursor,
692 UserOpt->OpCode,
693 UserOpt->OpLen,
694 UserOpt->Data
695 );
696+ if (EFI_ERROR (Status)) {
697+ goto ON_ERROR;
698+ }
699 }
700
701- //
702- // Determine the size/length of packet.
703- //
704- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
705 ASSERT (Packet->Size > Packet->Length + 8);
706
707 //
708@@ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg (
709 Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing;
710
711 Status = Dhcp6CallbackUser (Instance, Event, &Packet);
712-
713 if (EFI_ERROR (Status)) {
714- FreePool (Packet);
715- return Status;
716+ goto ON_ERROR;
717 }
718
719 //
720@@ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg (
721 Instance->StartTime = 0;
722
723 Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
724-
725 if (EFI_ERROR (Status)) {
726- FreePool (Packet);
727- return Status;
728+ goto ON_ERROR;
729 }
730
731 //
732 // Enqueue the sent packet for the retransmission in case reply timeout.
733 //
734 return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
735+
736+ON_ERROR:
737+
738+ if (Packet) {
739+ FreePool (Packet);
740+ }
741+
742+ return Status;
743 }
744
745 /**
746@@ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg (
747 //
748 Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
749 if (Packet == NULL) {
750- return EFI_OUT_OF_RESOURCES;
751+ Status = EFI_OUT_OF_RESOURCES;
752+ goto ON_ERROR;
753 }
754
755 Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
756@@ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg (
757
758 if (SendClientId) {
759 Length = HTONS (ClientId->Length);
760- Cursor = Dhcp6AppendOption (
761- Cursor,
762+ Status = Dhcp6AppendOption (
763+ Packet,
764+ &Cursor,
765 HTONS (Dhcp6OptClientId),
766 Length,
767 ClientId->Duid
768 );
769+ if (EFI_ERROR (Status)) {
770+ goto ON_ERROR;
771+ }
772 }
773
774- Cursor = Dhcp6AppendETOption (
775- Cursor,
776+ Status = Dhcp6AppendETOption (
777+ Packet,
778+ &Cursor,
779 Instance,
780 &Elapsed
781 );
782+ if (EFI_ERROR (Status)) {
783+ goto ON_ERROR;
784+ }
785
786- Cursor = Dhcp6AppendOption (
787- Cursor,
788+ Status = Dhcp6AppendOption (
789+ Packet,
790+ &Cursor,
791 OptionRequest->OpCode,
792 OptionRequest->OpLen,
793 OptionRequest->Data
794 );
795+ if (EFI_ERROR (Status)) {
796+ goto ON_ERROR;
797+ }
798
799 //
800 // Append user-defined when configurate Dhcp6 service.
801 //
802 for (Index = 0; Index < OptionCount; Index++) {
803 UserOpt = OptionList[Index];
804- Cursor = Dhcp6AppendOption (
805- Cursor,
806+ Status = Dhcp6AppendOption (
807+ Packet,
808+ &Cursor,
809 UserOpt->OpCode,
810 UserOpt->OpLen,
811 UserOpt->Data
812 );
813+ if (EFI_ERROR (Status)) {
814+ goto ON_ERROR;
815+ }
816 }
817
818- //
819- // Determine the size/length of packet.
820- //
821- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
822 ASSERT (Packet->Size > Packet->Length + 8);
823
824 //
825@@ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg (
826 // Send info-request packet with no state.
827 //
828 Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
829-
830 if (EFI_ERROR (Status)) {
831- FreePool (Packet);
832- return Status;
833+ goto ON_ERROR;
834 }
835
836 //
837 // Enqueue the sent packet for the retransmission in case reply timeout.
838 //
839 return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission);
840+
841+ON_ERROR:
842+
843+ if (Packet) {
844+ FreePool (Packet);
845+ }
846+
847+ return Status;
848 }
849
850 /**
851@@ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg (
852 //
853 Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen);
854 if (Packet == NULL) {
855- return EFI_OUT_OF_RESOURCES;
856+ Status = EFI_OUT_OF_RESOURCES;
857+ goto ON_ERROR;
858 }
859
860 Packet->Size = DHCP6_BASE_PACKET_SIZE + UserLen;
861@@ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg (
862 Cursor = Packet->Dhcp6.Option;
863
864 Length = HTONS (ClientId->Length);
865- Cursor = Dhcp6AppendOption (
866- Cursor,
867+ Status = Dhcp6AppendOption (
868+ Packet,
869+ &Cursor,
870 HTONS (Dhcp6OptClientId),
871 Length,
872 ClientId->Duid
873 );
874+ if (EFI_ERROR (Status)) {
875+ goto ON_ERROR;
876+ }
877
878- Cursor = Dhcp6AppendETOption (
879- Cursor,
880+ Status = Dhcp6AppendETOption (
881+ Packet,
882+ &Cursor,
883 Instance,
884 &Elapsed
885 );
886+ if (EFI_ERROR (Status)) {
887+ goto ON_ERROR;
888+ }
889
890- Cursor = Dhcp6AppendIaOption (
891- Cursor,
892+ Status = Dhcp6AppendIaOption (
893+ Packet,
894+ &Cursor,
895 Instance->IaCb.Ia,
896 Instance->IaCb.T1,
897 Instance->IaCb.T2,
898 Packet->Dhcp6.Header.MessageType
899 );
900+ if (EFI_ERROR (Status)) {
901+ goto ON_ERROR;
902+ }
903
904 //
905 // Append user-defined when configurate Dhcp6 service.
906 //
907 for (Index = 0; Index < Instance->Config->OptionCount; Index++) {
908 UserOpt = Instance->Config->OptionList[Index];
909- Cursor = Dhcp6AppendOption (
910- Cursor,
911+ Status = Dhcp6AppendOption (
912+ Packet,
913+ &Cursor,
914 UserOpt->OpCode,
915 UserOpt->OpLen,
916 UserOpt->Data
917 );
918+ if (EFI_ERROR (Status)) {
919+ goto ON_ERROR;
920+ }
921 }
922
923- //
924- // Determine the size/length of packet.
925- //
926- Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option);
927 ASSERT (Packet->Size > Packet->Length + 8);
928
929 //
930 // Callback to user with the packet to be sent and check the user's feedback.
931 //
932 Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet);
933-
934 if (EFI_ERROR (Status)) {
935- FreePool (Packet);
936- return Status;
937+ goto ON_ERROR;
938 }
939
940 //
941@@ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg (
942 Instance->StartTime = 0;
943
944 Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed);
945-
946 if (EFI_ERROR (Status)) {
947- FreePool (Packet);
948- return Status;
949+ goto ON_ERROR;
950 }
951
952 //
953 // Enqueue the sent packet for the retransmission in case reply timeout.
954 //
955 return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);
956+
957+ON_ERROR:
958+
959+ if (Packet) {
960+ FreePool (Packet);
961+ }
962+
963+ return Status;
964 }
965
966 /**
967diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
968index e6368b5b1c..705c665c51 100644
969--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
970+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
971@@ -577,24 +577,33 @@ Dhcp6OnTransmitted (
972 }
973
974 /**
975- Append the option to Buf, and move Buf to the end.
976+ Append the option to Buf, update the length of packet, and move Buf to the end.
977
978- @param[in, out] Buf The pointer to the buffer.
979- @param[in] OptType The option type.
980- @param[in] OptLen The length of option contents.
981- @param[in] Data The pointer to the option content.
982+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
983+ will be updated.
984+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
985+ will be moved to the end of the option.
986+ @param[in] OptType The option type.
987+ @param[in] OptLen The length of option contents.
988+ @param[in] Data The pointer to the option content.
989
990- @return Buf The position to append the next option.
991+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
992+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
993+ @retval EFI_SUCCESS The option is appended successfully.
994
995 **/
996-UINT8 *
997+EFI_STATUS
998 Dhcp6AppendOption (
999- IN OUT UINT8 *Buf,
1000- IN UINT16 OptType,
1001- IN UINT16 OptLen,
1002- IN UINT8 *Data
1003+ IN OUT EFI_DHCP6_PACKET *Packet,
1004+ IN OUT UINT8 **PacketCursor,
1005+ IN UINT16 OptType,
1006+ IN UINT16 OptLen,
1007+ IN UINT8 *Data
1008 )
1009 {
1010+ UINT32 Length;
1011+ UINT32 BytesNeeded;
1012+
1013 //
1014 // The format of Dhcp6 option:
1015 //
1016@@ -607,35 +616,95 @@ Dhcp6AppendOption (
1017 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1018 //
1019
1020- ASSERT (OptLen != 0);
1021+ //
1022+ // Verify the arguments are valid
1023+ //
1024+ if (Packet == NULL) {
1025+ return EFI_INVALID_PARAMETER;
1026+ }
1027+
1028+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
1029+ return EFI_INVALID_PARAMETER;
1030+ }
1031+
1032+ if (Data == NULL) {
1033+ return EFI_INVALID_PARAMETER;
1034+ }
1035+
1036+ if (OptLen == 0) {
1037+ return EFI_INVALID_PARAMETER;
1038+ }
1039+
1040+ //
1041+ // Verify the PacketCursor is within the packet
1042+ //
1043+ if ( (*PacketCursor < Packet->Dhcp6.Option)
1044+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
1045+ {
1046+ return EFI_INVALID_PARAMETER;
1047+ }
1048+
1049+ //
1050+ // Calculate the bytes needed for the option
1051+ //
1052+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen);
1053+
1054+ //
1055+ // Space remaining in the packet
1056+ //
1057+ Length = Packet->Size - Packet->Length;
1058+ if (Length < BytesNeeded) {
1059+ return EFI_BUFFER_TOO_SMALL;
1060+ }
1061+
1062+ //
1063+ // Verify the PacketCursor is within the packet
1064+ //
1065+ if ( (*PacketCursor < Packet->Dhcp6.Option)
1066+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
1067+ {
1068+ return EFI_INVALID_PARAMETER;
1069+ }
1070+
1071+ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType);
1072+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
1073+ WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen);
1074+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
1075+ CopyMem (*PacketCursor, Data, NTOHS (OptLen));
1076+ *PacketCursor += NTOHS (OptLen);
1077
1078- WriteUnaligned16 ((UINT16 *)Buf, OptType);
1079- Buf += 2;
1080- WriteUnaligned16 ((UINT16 *)Buf, OptLen);
1081- Buf += 2;
1082- CopyMem (Buf, Data, NTOHS (OptLen));
1083- Buf += NTOHS (OptLen);
1084+ // Update the packet length by the length of the option + 4 bytes
1085+ Packet->Length += BytesNeeded;
1086
1087- return Buf;
1088+ return EFI_SUCCESS;
1089 }
1090
1091 /**
1092 Append the appointed IA Address option to Buf, and move Buf to the end.
1093
1094- @param[in, out] Buf The pointer to the position to append.
1095+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
1096+ will be updated.
1097+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
1098+ will be moved to the end of the option.
1099 @param[in] IaAddr The pointer to the IA Address.
1100 @param[in] MessageType Message type of DHCP6 package.
1101
1102- @return Buf The position to append the next option.
1103+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
1104+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
1105+ @retval EFI_SUCCESS The option is appended successfully.
1106
1107 **/
1108-UINT8 *
1109+EFI_STATUS
1110 Dhcp6AppendIaAddrOption (
1111- IN OUT UINT8 *Buf,
1112+ IN OUT EFI_DHCP6_PACKET *Packet,
1113+ IN OUT UINT8 **PacketCursor,
1114 IN EFI_DHCP6_IA_ADDRESS *IaAddr,
1115 IN UINT32 MessageType
1116 )
1117 {
1118+ UINT32 BytesNeeded;
1119+ UINT32 Length;
1120+
1121 // The format of the IA Address option is:
1122 //
1123 // 0 1 2 3
1124@@ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption (
1125 // . .
1126 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1127
1128+ //
1129+ // Verify the arguments are valid
1130+ //
1131+ if (Packet == NULL) {
1132+ return EFI_INVALID_PARAMETER;
1133+ }
1134+
1135+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
1136+ return EFI_INVALID_PARAMETER;
1137+ }
1138+
1139+ if (IaAddr == NULL) {
1140+ return EFI_INVALID_PARAMETER;
1141+ }
1142+
1143+ //
1144+ // Verify the PacketCursor is within the packet
1145+ //
1146+ if ( (*PacketCursor < Packet->Dhcp6.Option)
1147+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
1148+ {
1149+ return EFI_INVALID_PARAMETER;
1150+ }
1151+
1152+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
1153+ BytesNeeded += sizeof (EFI_IPv6_ADDRESS);
1154+ //
1155+ // Even if the preferred-lifetime is 0, it still needs to store it.
1156+ //
1157+ BytesNeeded += sizeof (IaAddr->PreferredLifetime);
1158+ //
1159+ // Even if the valid-lifetime is 0, it still needs to store it.
1160+ //
1161+ BytesNeeded += sizeof (IaAddr->ValidLifetime);
1162+
1163+ //
1164+ // Space remaining in the packet
1165+ //
1166+ Length = Packet->Size - Packet->Length;
1167+ if (Length < BytesNeeded) {
1168+ return EFI_BUFFER_TOO_SMALL;
1169+ }
1170+
1171 //
1172 // Fill the value of Ia Address option type
1173 //
1174- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr));
1175- Buf += 2;
1176+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr));
1177+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
1178
1179- WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
1180- Buf += 2;
1181+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
1182+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
1183
1184- CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
1185- Buf += sizeof (EFI_IPv6_ADDRESS);
1186+ CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
1187+ *PacketCursor += sizeof (EFI_IPv6_ADDRESS);
1188
1189 //
1190 // Fill the value of preferred-lifetime and valid-lifetime.
1191@@ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption (
1192 // should set to 0 when initiate a Confirm message.
1193 //
1194 if (MessageType != Dhcp6MsgConfirm) {
1195- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime));
1196+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime));
1197 }
1198
1199- Buf += 4;
1200+ *PacketCursor += sizeof (IaAddr->PreferredLifetime);
1201
1202 if (MessageType != Dhcp6MsgConfirm) {
1203- WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime));
1204+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime));
1205 }
1206
1207- Buf += 4;
1208+ *PacketCursor += sizeof (IaAddr->ValidLifetime);
1209+
1210+ //
1211+ // Update the packet length
1212+ //
1213+ Packet->Length += BytesNeeded;
1214
1215- return Buf;
1216+ return EFI_SUCCESS;
1217 }
1218
1219 /**
1220 Append the appointed Ia option to Buf, and move Buf to the end.
1221
1222- @param[in, out] Buf The pointer to the position to append.
1223+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
1224+ will be updated.
1225+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
1226+ will be moved to the end of the option.
1227 @param[in] Ia The pointer to the Ia.
1228 @param[in] T1 The time of T1.
1229 @param[in] T2 The time of T2.
1230 @param[in] MessageType Message type of DHCP6 package.
1231
1232- @return Buf The position to append the next Ia option.
1233+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
1234+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
1235+ @retval EFI_SUCCESS The option is appended successfully.
1236
1237 **/
1238-UINT8 *
1239+EFI_STATUS
1240 Dhcp6AppendIaOption (
1241- IN OUT UINT8 *Buf,
1242- IN EFI_DHCP6_IA *Ia,
1243- IN UINT32 T1,
1244- IN UINT32 T2,
1245- IN UINT32 MessageType
1246+ IN OUT EFI_DHCP6_PACKET *Packet,
1247+ IN OUT UINT8 **PacketCursor,
1248+ IN EFI_DHCP6_IA *Ia,
1249+ IN UINT32 T1,
1250+ IN UINT32 T2,
1251+ IN UINT32 MessageType
1252 )
1253 {
1254- UINT8 *AddrOpt;
1255- UINT16 *Len;
1256- UINTN Index;
1257+ UINT8 *AddrOpt;
1258+ UINT16 *Len;
1259+ UINTN Index;
1260+ UINT32 BytesNeeded;
1261+ UINT32 Length;
1262+ EFI_STATUS Status;
1263
1264 //
1265 // The format of IA_NA and IA_TA option:
1266@@ -733,32 +859,74 @@ Dhcp6AppendIaOption (
1267 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1268 //
1269
1270+ //
1271+ // Verify the arguments are valid
1272+ //
1273+ if (Packet == NULL) {
1274+ return EFI_INVALID_PARAMETER;
1275+ }
1276+
1277+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
1278+ return EFI_INVALID_PARAMETER;
1279+ }
1280+
1281+ if (Ia == NULL) {
1282+ return EFI_INVALID_PARAMETER;
1283+ }
1284+
1285+ //
1286+ // Verify the PacketCursor is within the packet
1287+ //
1288+ if ( (*PacketCursor < Packet->Dhcp6.Option)
1289+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
1290+ {
1291+ return EFI_INVALID_PARAMETER;
1292+ }
1293+
1294+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
1295+ BytesNeeded += sizeof (Ia->Descriptor.IaId);
1296+ //
1297+ // + N for the IA_NA-options/IA_TA-options
1298+ // Dhcp6AppendIaAddrOption will need to check the length for each address
1299+ //
1300+ if (Ia->Descriptor.Type == Dhcp6OptIana) {
1301+ BytesNeeded += sizeof (T1) + sizeof (T2);
1302+ }
1303+
1304+ //
1305+ // Space remaining in the packet
1306+ //
1307+ Length = (UINT16)(Packet->Size - Packet->Length);
1308+ if (Length < BytesNeeded) {
1309+ return EFI_BUFFER_TOO_SMALL;
1310+ }
1311+
1312 //
1313 // Fill the value of Ia option type
1314 //
1315- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type));
1316- Buf += 2;
1317+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type));
1318+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
1319
1320 //
1321 // Fill the len of Ia option later, keep the pointer first
1322 //
1323- Len = (UINT16 *)Buf;
1324- Buf += 2;
1325+ Len = (UINT16 *)*PacketCursor;
1326+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
1327
1328 //
1329 // Fill the value of iaid
1330 //
1331- WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId));
1332- Buf += 4;
1333+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId));
1334+ *PacketCursor += sizeof (Ia->Descriptor.IaId);
1335
1336 //
1337 // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified.
1338 //
1339 if (Ia->Descriptor.Type == Dhcp6OptIana) {
1340- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff));
1341- Buf += 4;
1342- WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff));
1343- Buf += 4;
1344+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff));
1345+ *PacketCursor += sizeof (T1);
1346+ WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff));
1347+ *PacketCursor += sizeof (T2);
1348 }
1349
1350 //
1351@@ -766,35 +934,51 @@ Dhcp6AppendIaOption (
1352 //
1353 for (Index = 0; Index < Ia->IaAddressCount; Index++) {
1354 AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS);
1355- Buf = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
1356+ Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
1357+ if (EFI_ERROR (Status)) {
1358+ return Status;
1359+ }
1360 }
1361
1362 //
1363 // Fill the value of Ia option length
1364 //
1365- *Len = HTONS ((UINT16)(Buf - (UINT8 *)Len - 2));
1366+ *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2));
1367
1368- return Buf;
1369+ //
1370+ // Update the packet length
1371+ //
1372+ Packet->Length += BytesNeeded;
1373+
1374+ return EFI_SUCCESS;
1375 }
1376
1377 /**
1378 Append the appointed Elapsed time option to Buf, and move Buf to the end.
1379
1380- @param[in, out] Buf The pointer to the position to append.
1381+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
1382+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
1383+ will be moved to the end of the option.
1384 @param[in] Instance The pointer to the Dhcp6 instance.
1385 @param[out] Elapsed The pointer to the elapsed time value in
1386- the generated packet.
1387+ the generated packet.
1388
1389- @return Buf The position to append the next Ia option.
1390+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
1391+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
1392+ @retval EFI_SUCCESS The option is appended successfully.
1393
1394 **/
1395-UINT8 *
1396+EFI_STATUS
1397 Dhcp6AppendETOption (
1398- IN OUT UINT8 *Buf,
1399- IN DHCP6_INSTANCE *Instance,
1400- OUT UINT16 **Elapsed
1401+ IN OUT EFI_DHCP6_PACKET *Packet,
1402+ IN OUT UINT8 **PacketCursor,
1403+ IN DHCP6_INSTANCE *Instance,
1404+ OUT UINT16 **Elapsed
1405 )
1406 {
1407+ UINT32 BytesNeeded;
1408+ UINT32 Length;
1409+
1410 //
1411 // The format of elapsed time option:
1412 //
1413@@ -806,27 +990,70 @@ Dhcp6AppendETOption (
1414 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1415 //
1416
1417+ //
1418+ // Verify the arguments are valid
1419+ //
1420+ if (Packet == NULL) {
1421+ return EFI_INVALID_PARAMETER;
1422+ }
1423+
1424+ if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
1425+ return EFI_INVALID_PARAMETER;
1426+ }
1427+
1428+ if (Instance == NULL) {
1429+ return EFI_INVALID_PARAMETER;
1430+ }
1431+
1432+ if ((Elapsed == NULL)) {
1433+ return EFI_INVALID_PARAMETER;
1434+ }
1435+
1436+ //
1437+ // Verify the PacketCursor is within the packet
1438+ //
1439+ if ( (*PacketCursor < Packet->Dhcp6.Option)
1440+ || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
1441+ {
1442+ return EFI_INVALID_PARAMETER;
1443+ }
1444+
1445+ BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
1446+ //
1447+ // + 2 for elapsed-time
1448+ //
1449+ BytesNeeded += sizeof (UINT16);
1450+ //
1451+ // Space remaining in the packet
1452+ //
1453+ Length = Packet->Size - Packet->Length;
1454+ if (Length < BytesNeeded) {
1455+ return EFI_BUFFER_TOO_SMALL;
1456+ }
1457+
1458 //
1459 // Fill the value of elapsed-time option type.
1460 //
1461- WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime));
1462- Buf += 2;
1463+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime));
1464+ *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
1465
1466 //
1467 // Fill the len of elapsed-time option, which is fixed.
1468 //
1469- WriteUnaligned16 ((UINT16 *)Buf, HTONS (2));
1470- Buf += 2;
1471+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2));
1472+ *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
1473
1474 //
1475 // Fill in elapsed time value with 0 value for now. The actual value is
1476 // filled in later just before the packet is transmitted.
1477 //
1478- WriteUnaligned16 ((UINT16 *)Buf, HTONS (0));
1479- *Elapsed = (UINT16 *)Buf;
1480- Buf += 2;
1481+ WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0));
1482+ *Elapsed = (UINT16 *)*PacketCursor;
1483+ *PacketCursor += sizeof (UINT16);
1484
1485- return Buf;
1486+ Packet->Length += BytesNeeded;
1487+
1488+ return EFI_SUCCESS;
1489 }
1490
1491 /**
1492diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
1493index 046454ff4a..06947f6c1f 100644
1494--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
1495+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h
1496@@ -160,69 +160,85 @@ Dhcp6OnTransmitted (
1497 );
1498
1499 /**
1500- Append the appointed option to the buf, and move the buf to the end.
1501-
1502- @param[in, out] Buf The pointer to buffer.
1503- @param[in] OptType The option type.
1504- @param[in] OptLen The length of option content.s
1505- @param[in] Data The pointer to the option content.
1506-
1507- @return Buf The position to append the next option.
1508-
1509+ Append the option to Buf, update the length of packet, and move Buf to the end.
1510+
1511+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
1512+ will be updated.
1513+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
1514+ will be moved to the end of the option.
1515+ @param[in] OptType The option type.
1516+ @param[in] OptLen The length of option contents.
1517+ @param[in] Data The pointer to the option content.
1518+
1519+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
1520+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
1521+ @retval EFI_SUCCESS The option is appended successfully.
1522 **/
1523-UINT8 *
1524+EFI_STATUS
1525 Dhcp6AppendOption (
1526- IN OUT UINT8 *Buf,
1527- IN UINT16 OptType,
1528- IN UINT16 OptLen,
1529- IN UINT8 *Data
1530+ IN OUT EFI_DHCP6_PACKET *Packet,
1531+ IN OUT UINT8 **PacketCursor,
1532+ IN UINT16 OptType,
1533+ IN UINT16 OptLen,
1534+ IN UINT8 *Data
1535 );
1536
1537 /**
1538- Append the Ia option to Buf, and move Buf to the end.
1539-
1540- @param[in, out] Buf The pointer to the position to append.
1541+ Append the appointed Ia option to Buf, update the Ia option length, and move Buf
1542+ to the end of the option.
1543+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
1544+ will be updated.
1545+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
1546+ will be moved to the end of the option.
1547 @param[in] Ia The pointer to the Ia.
1548 @param[in] T1 The time of T1.
1549 @param[in] T2 The time of T2.
1550 @param[in] MessageType Message type of DHCP6 package.
1551
1552- @return Buf The position to append the next Ia option.
1553-
1554+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
1555+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
1556+ @retval EFI_SUCCESS The option is appended successfully.
1557 **/
1558-UINT8 *
1559+EFI_STATUS
1560 Dhcp6AppendIaOption (
1561- IN OUT UINT8 *Buf,
1562- IN EFI_DHCP6_IA *Ia,
1563- IN UINT32 T1,
1564- IN UINT32 T2,
1565- IN UINT32 MessageType
1566+ IN OUT EFI_DHCP6_PACKET *Packet,
1567+ IN OUT UINT8 **PacketCursor,
1568+ IN EFI_DHCP6_IA *Ia,
1569+ IN UINT32 T1,
1570+ IN UINT32 T2,
1571+ IN UINT32 MessageType
1572 );
1573
1574 /**
1575 Append the appointed Elapsed time option to Buf, and move Buf to the end.
1576
1577- @param[in, out] Buf The pointer to the position to append.
1578+ @param[in, out] Packet A pointer to the packet, on success Packet->Length
1579+ @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor
1580+ will be moved to the end of the option.
1581 @param[in] Instance The pointer to the Dhcp6 instance.
1582 @param[out] Elapsed The pointer to the elapsed time value in
1583 the generated packet.
1584
1585- @return Buf The position to append the next Ia option.
1586+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
1587+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
1588+ @retval EFI_SUCCESS The option is appended successfully.
1589
1590 **/
1591-UINT8 *
1592+EFI_STATUS
1593 Dhcp6AppendETOption (
1594- IN OUT UINT8 *Buf,
1595- IN DHCP6_INSTANCE *Instance,
1596- OUT UINT16 **Elapsed
1597+ IN OUT EFI_DHCP6_PACKET *Packet,
1598+ IN OUT UINT8 **PacketCursor,
1599+ IN DHCP6_INSTANCE *Instance,
1600+ OUT UINT16 **Elapsed
1601 );
1602
1603 /**
1604 Set the elapsed time based on the given instance and the pointer to the
1605 elapsed time option.
1606
1607- @param[in] Elapsed The pointer to the position to append.
1608- @param[in] Instance The pointer to the Dhcp6 instance.
1609+ @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid
1610+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option.
1611+ @retval EFI_SUCCESS The option is appended successfully.
1612 **/
1613 VOID
1614 SetElapsedTime (
1615--
16162.40.0
1617
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 @@
1From 5f3658197bf29c83b3349b0ab1d99cdb0c3814bc Mon Sep 17 00:00:00 2001
2From: "Doug Flick via groups.io" <dougflick=microsoft.com@groups.io>
3Date: Fri, 26 Jan 2024 05:54:45 +0800
4Subject: [PATCH] NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Unit
5 Tests
6
7REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4535
8
9Confirms that reported issue...
10
11"Buffer overflow in the DHCPv6 client via a long Server ID option"
12
13..has been corrected by the provided patch.
14
15Tests the following functions to ensure they appropriately handle
16untrusted data (either too long or too small) to prevent a buffer
17overflow:
18
19Dhcp6AppendOption
20Dhcp6AppendETOption
21Dhcp6AppendIaOption
22
23Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
24Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>
25
26Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
27Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
28
29CVE: CVE-2023-45230
30
31Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/5f3658197bf29c83b3349b0ab1d99cdb0c3814bc]
32
33Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
34---
35 .../GoogleTest/Dhcp6DxeGoogleTest.cpp | 20 +
36 .../GoogleTest/Dhcp6DxeGoogleTest.inf | 43 ++
37 .../Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp | 478 ++++++++++++++++++
38 3 files changed, 541 insertions(+)
39 create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
40 create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
41 create mode 100644 NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
42
43diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
44new file mode 100644
45index 0000000000..9aeced2f91
46--- /dev/null
47+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.cpp
48@@ -0,0 +1,20 @@
49+/** @file
50+ Acts as the main entry point for the tests for the Dhcp6Dxe module.
51+
52+ Copyright (c) Microsoft Corporation
53+ SPDX-License-Identifier: BSD-2-Clause-Patent
54+**/
55+#include <gtest/gtest.h>
56+
57+////////////////////////////////////////////////////////////////////////////////
58+// Run the tests
59+////////////////////////////////////////////////////////////////////////////////
60+int
61+main (
62+ int argc,
63+ char *argv[]
64+ )
65+{
66+ testing::InitGoogleTest (&argc, argv);
67+ return RUN_ALL_TESTS ();
68+}
69diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
70new file mode 100644
71index 0000000000..8e9119a371
72--- /dev/null
73+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6DxeGoogleTest.inf
74@@ -0,0 +1,43 @@
75+## @file
76+# Unit test suite for the Dhcp6Dxe using Google Test
77+#
78+# Copyright (c) Microsoft Corporation.<BR>
79+# SPDX-License-Identifier: BSD-2-Clause-Patent
80+##
81+[Defines]
82+ INF_VERSION = 0x00010017
83+ BASE_NAME = Dhcp6DxeGoogleTest
84+ FILE_GUID = 1D2A4C65-38C8-4C2F-BB60-B5FA49625AA9
85+ VERSION_STRING = 1.0
86+ MODULE_TYPE = HOST_APPLICATION
87+#
88+# The following information is for reference only and not required by the build tools.
89+#
90+# VALID_ARCHITECTURES = IA32 X64 AARCH64
91+#
92+[Sources]
93+ Dhcp6DxeGoogleTest.cpp
94+ Dhcp6IoGoogleTest.cpp
95+ ../Dhcp6Io.c
96+ ../Dhcp6Utility.c
97+
98+[Packages]
99+ MdePkg/MdePkg.dec
100+ MdeModulePkg/MdeModulePkg.dec
101+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
102+ NetworkPkg/NetworkPkg.dec
103+
104+[LibraryClasses]
105+ GoogleTestLib
106+ DebugLib
107+ NetLib
108+ PcdLib
109+
110+[Protocols]
111+ gEfiDhcp6ServiceBindingProtocolGuid
112+
113+[Pcd]
114+ gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType
115+
116+[Guids]
117+ gZeroGuid
118diff --git a/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
119new file mode 100644
120index 0000000000..7ee40e4af4
121--- /dev/null
122+++ b/NetworkPkg/Dhcp6Dxe/GoogleTest/Dhcp6IoGoogleTest.cpp
123@@ -0,0 +1,478 @@
124+/** @file
125+ Tests for Dhcp6Io.c.
126+
127+ Copyright (c) Microsoft Corporation
128+ SPDX-License-Identifier: BSD-2-Clause-Patent
129+**/
130+#include <gtest/gtest.h>
131+
132+extern "C" {
133+ #include <Uefi.h>
134+ #include <Library/BaseLib.h>
135+ #include <Library/DebugLib.h>
136+ #include <Library/BaseMemoryLib.h>
137+ #include "../Dhcp6Impl.h"
138+ #include "../Dhcp6Utility.h"
139+}
140+
141+////////////////////////////////////////////////////////////////////////
142+// Defines
143+////////////////////////////////////////////////////////////////////////
144+
145+#define DHCP6_PACKET_MAX_LEN 1500
146+
147+////////////////////////////////////////////////////////////////////////
148+////////////////////////////////////////////////////////////////////////
149+// Symbol Definitions
150+// These functions are not directly under test - but required to compile
151+////////////////////////////////////////////////////////////////////////
152+
153+// This definition is used by this test but is also required to compile
154+// by Dhcp6Io.c
155+EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = {
156+ { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 }
157+};
158+
159+EFI_STATUS
160+EFIAPI
161+UdpIoSendDatagram (
162+ IN UDP_IO *UdpIo,
163+ IN NET_BUF *Packet,
164+ IN UDP_END_POINT *EndPoint OPTIONAL,
165+ IN EFI_IP_ADDRESS *Gateway OPTIONAL,
166+ IN UDP_IO_CALLBACK CallBack,
167+ IN VOID *Context
168+ )
169+{
170+ return EFI_SUCCESS;
171+}
172+
173+EFI_STATUS
174+EFIAPI
175+UdpIoRecvDatagram (
176+ IN UDP_IO *UdpIo,
177+ IN UDP_IO_CALLBACK CallBack,
178+ IN VOID *Context,
179+ IN UINT32 HeadLen
180+ )
181+{
182+ return EFI_SUCCESS;
183+}
184+
185+////////////////////////////////////////////////////////////////////////
186+// Dhcp6AppendOptionTest Tests
187+////////////////////////////////////////////////////////////////////////
188+
189+class Dhcp6AppendOptionTest : public ::testing::Test {
190+public:
191+ UINT8 *Buffer = NULL;
192+ EFI_DHCP6_PACKET *Packet;
193+
194+protected:
195+ // Add any setup code if needed
196+ virtual void
197+ SetUp (
198+ )
199+ {
200+ // Initialize any resources or variables
201+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
202+ ASSERT_NE (Buffer, (UINT8 *)NULL);
203+
204+ Packet = (EFI_DHCP6_PACKET *)Buffer;
205+ Packet->Size = DHCP6_PACKET_MAX_LEN;
206+ }
207+
208+ // Add any cleanup code if needed
209+ virtual void
210+ TearDown (
211+ )
212+ {
213+ // Clean up any resources or variables
214+ if (Buffer != NULL) {
215+ FreePool (Buffer);
216+ }
217+ }
218+};
219+
220+// Test Description:
221+// Attempt to append an option to a packet that is too small by a duid that is too large
222+TEST_F (Dhcp6AppendOptionTest, InvalidDataExpectBufferTooSmall) {
223+ UINT8 *Cursor;
224+ EFI_DHCP6_DUID *UntrustedDuid;
225+ EFI_STATUS Status;
226+
227+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));
228+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);
229+
230+ UntrustedDuid->Length = NTOHS (0xFFFF);
231+
232+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;
233+
234+ Status = Dhcp6AppendOption (
235+ Dhcp6AppendOptionTest::Packet,
236+ &Cursor,
237+ HTONS (Dhcp6OptServerId),
238+ UntrustedDuid->Length,
239+ UntrustedDuid->Duid
240+ );
241+
242+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
243+}
244+
245+// Test Description:
246+// Attempt to append an option to a packet that is large enough
247+TEST_F (Dhcp6AppendOptionTest, ValidDataExpectSuccess) {
248+ UINT8 *Cursor;
249+ EFI_DHCP6_DUID *UntrustedDuid;
250+ EFI_STATUS Status;
251+ UINTN OriginalLength;
252+
253+ UINT8 Duid[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
254+
255+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
256+ OriginalLength = Packet->Length;
257+
258+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));
259+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);
260+
261+ UntrustedDuid->Length = NTOHS (sizeof (Duid));
262+ CopyMem (UntrustedDuid->Duid, Duid, sizeof (Duid));
263+
264+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;
265+
266+ Status = Dhcp6AppendOption (
267+ Dhcp6AppendOptionTest::Packet,
268+ &Cursor,
269+ HTONS (Dhcp6OptServerId),
270+ UntrustedDuid->Length,
271+ UntrustedDuid->Duid
272+ );
273+
274+ ASSERT_EQ (Status, EFI_SUCCESS);
275+
276+ // verify that the pointer to cursor moved by the expected amount
277+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendOptionTest::Packet->Dhcp6.Option + sizeof (Duid) + 4);
278+
279+ // verify that the length of the packet is now the expected amount
280+ ASSERT_EQ (Dhcp6AppendOptionTest::Packet->Length, OriginalLength + sizeof (Duid) + 4);
281+}
282+
283+////////////////////////////////////////////////////////////////////////
284+// Dhcp6AppendETOption Tests
285+////////////////////////////////////////////////////////////////////////
286+
287+class Dhcp6AppendETOptionTest : public ::testing::Test {
288+public:
289+ UINT8 *Buffer = NULL;
290+ EFI_DHCP6_PACKET *Packet;
291+
292+protected:
293+ // Add any setup code if needed
294+ virtual void
295+ SetUp (
296+ )
297+ {
298+ // Initialize any resources or variables
299+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
300+ ASSERT_NE (Buffer, (UINT8 *)NULL);
301+
302+ Packet = (EFI_DHCP6_PACKET *)Buffer;
303+ Packet->Size = DHCP6_PACKET_MAX_LEN;
304+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
305+ }
306+
307+ // Add any cleanup code if needed
308+ virtual void
309+ TearDown (
310+ )
311+ {
312+ // Clean up any resources or variables
313+ if (Buffer != NULL) {
314+ FreePool (Buffer);
315+ }
316+ }
317+};
318+
319+// Test Description:
320+// Attempt to append an option to a packet that is too small by a duid that is too large
321+TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) {
322+ UINT8 *Cursor;
323+ EFI_STATUS Status;
324+ DHCP6_INSTANCE Instance;
325+ UINT16 ElapsedTimeVal;
326+ UINT16 *ElapsedTime;
327+
328+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;
329+ ElapsedTime = &ElapsedTimeVal;
330+
331+ Packet->Length = Packet->Size - 2;
332+
333+ Status = Dhcp6AppendETOption (
334+ Dhcp6AppendETOptionTest::Packet,
335+ &Cursor,
336+ &Instance, // Instance is not used in this function
337+ &ElapsedTime
338+ );
339+
340+ // verify that we error out because the packet is too small for the option header
341+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
342+
343+ // reset the length
344+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
345+}
346+
347+// Test Description:
348+// Attempt to append an option to a packet that is large enough
349+TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) {
350+ UINT8 *Cursor;
351+ EFI_STATUS Status;
352+ DHCP6_INSTANCE Instance;
353+ UINT16 ElapsedTimeVal;
354+ UINT16 *ElapsedTime;
355+ UINTN ExpectedSize;
356+ UINTN OriginalLength;
357+
358+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;
359+ ElapsedTime = &ElapsedTimeVal;
360+ ExpectedSize = 6;
361+ OriginalLength = Packet->Length;
362+
363+ Status = Dhcp6AppendETOption (
364+ Dhcp6AppendETOptionTest::Packet,
365+ &Cursor,
366+ &Instance, // Instance is not used in this function
367+ &ElapsedTime
368+ );
369+
370+ // verify that the status is EFI_SUCCESS
371+ ASSERT_EQ (Status, EFI_SUCCESS);
372+
373+ // verify that the pointer to cursor moved by the expected amount
374+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendETOptionTest::Packet->Dhcp6.Option + ExpectedSize);
375+
376+ // verify that the length of the packet is now the expected amount
377+ ASSERT_EQ (Dhcp6AppendETOptionTest::Packet->Length, OriginalLength + ExpectedSize);
378+}
379+
380+////////////////////////////////////////////////////////////////////////
381+// Dhcp6AppendIaOption Tests
382+////////////////////////////////////////////////////////////////////////
383+
384+class Dhcp6AppendIaOptionTest : public ::testing::Test {
385+public:
386+ UINT8 *Buffer = NULL;
387+ EFI_DHCP6_PACKET *Packet;
388+ EFI_DHCP6_IA *Ia;
389+
390+protected:
391+ // Add any setup code if needed
392+ virtual void
393+ SetUp (
394+ )
395+ {
396+ // Initialize any resources or variables
397+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);
398+ ASSERT_NE (Buffer, (UINT8 *)NULL);
399+
400+ Packet = (EFI_DHCP6_PACKET *)Buffer;
401+ Packet->Size = DHCP6_PACKET_MAX_LEN;
402+
403+ Ia = (EFI_DHCP6_IA *)AllocateZeroPool (sizeof (EFI_DHCP6_IA) + sizeof (EFI_DHCP6_IA_ADDRESS) * 2);
404+ ASSERT_NE (Ia, (EFI_DHCP6_IA *)NULL);
405+
406+ CopyMem (Ia->IaAddress, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));
407+ CopyMem (Ia->IaAddress + 1, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));
408+
409+ Ia->IaAddressCount = 2;
410+ }
411+
412+ // Add any cleanup code if needed
413+ virtual void
414+ TearDown (
415+ )
416+ {
417+ // Clean up any resources or variables
418+ if (Buffer != NULL) {
419+ FreePool (Buffer);
420+ }
421+
422+ if (Ia != NULL) {
423+ FreePool (Ia);
424+ }
425+ }
426+};
427+
428+// Test Description:
429+// Attempt to append an option to a packet that doesn't have enough space
430+// for the option header
431+TEST_F (Dhcp6AppendIaOptionTest, IaNaInvalidDataExpectBufferTooSmall) {
432+ UINT8 *Cursor;
433+ EFI_STATUS Status;
434+
435+ Packet->Length = Packet->Size - 2;
436+
437+ Ia->Descriptor.Type = Dhcp6OptIana;
438+ Ia->Descriptor.IaId = 0x12345678;
439+
440+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
441+
442+ Status = Dhcp6AppendIaOption (
443+ Dhcp6AppendIaOptionTest::Packet,
444+ &Cursor,
445+ Ia,
446+ 0x12345678,
447+ 0x11111111,
448+ Dhcp6OptIana
449+ );
450+
451+ // verify that we error out because the packet is too small for the option header
452+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
453+
454+ // reset the length
455+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
456+}
457+
458+// Test Description:
459+// Attempt to append an option to a packet that doesn't have enough space
460+// for the option header
461+TEST_F (Dhcp6AppendIaOptionTest, IaTaInvalidDataExpectBufferTooSmall) {
462+ UINT8 *Cursor;
463+ EFI_STATUS Status;
464+
465+ // Use up nearly all the space in the packet
466+ Packet->Length = Packet->Size - 2;
467+
468+ Ia->Descriptor.Type = Dhcp6OptIata;
469+ Ia->Descriptor.IaId = 0x12345678;
470+
471+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
472+
473+ Status = Dhcp6AppendIaOption (
474+ Dhcp6AppendIaOptionTest::Packet,
475+ &Cursor,
476+ Ia,
477+ 0,
478+ 0,
479+ Dhcp6OptIata
480+ );
481+
482+ // verify that we error out because the packet is too small for the option header
483+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);
484+
485+ // reset the length
486+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
487+}
488+
489+TEST_F (Dhcp6AppendIaOptionTest, IaNaValidDataExpectSuccess) {
490+ UINT8 *Cursor;
491+ EFI_STATUS Status;
492+ UINTN ExpectedSize;
493+ UINTN OriginalLength;
494+
495+ //
496+ // 2 bytes for the option header type
497+ //
498+ ExpectedSize = 2;
499+ //
500+ // 2 bytes for the option header length
501+ //
502+ ExpectedSize += 2;
503+ //
504+ // 4 bytes for the IAID
505+ //
506+ ExpectedSize += 4;
507+ //
508+ // + 4 bytes for the T1
509+ //
510+ ExpectedSize += 4;
511+ //
512+ // + 4 bytes for the T2
513+ //
514+ ExpectedSize += 4;
515+ //
516+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
517+ // + 2 bytes for the option header type
518+ // + 2 bytes for the option header length
519+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address
520+ //
521+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
522+
523+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
524+
525+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
526+ OriginalLength = Packet->Length;
527+
528+ Ia->Descriptor.Type = Dhcp6OptIana;
529+ Ia->Descriptor.IaId = 0x12345678;
530+
531+ Status = Dhcp6AppendIaOption (
532+ Dhcp6AppendIaOptionTest::Packet,
533+ &Cursor,
534+ Ia,
535+ 0x12345678,
536+ 0x12345678,
537+ Dhcp6OptIana
538+ );
539+
540+ // verify that the pointer to cursor moved by the expected amount
541+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);
542+
543+ // verify that the length of the packet is now the expected amount
544+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);
545+
546+ // verify that the status is EFI_SUCCESS
547+ ASSERT_EQ (Status, EFI_SUCCESS);
548+}
549+
550+TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) {
551+ UINT8 *Cursor;
552+ EFI_STATUS Status;
553+ UINTN ExpectedSize;
554+ UINTN OriginalLength;
555+
556+ //
557+ // 2 bytes for the option header type
558+ //
559+ ExpectedSize = 2;
560+ //
561+ // 2 bytes for the option header length
562+ //
563+ ExpectedSize += 2;
564+ //
565+ // 4 bytes for the IAID
566+ //
567+ ExpectedSize += 4;
568+ //
569+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
570+ // + 2 bytes for the option header type
571+ // + 2 bytes for the option header length
572+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address
573+ //
574+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;
575+
576+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;
577+
578+ Packet->Length = sizeof (EFI_DHCP6_HEADER);
579+ OriginalLength = Packet->Length;
580+
581+ Ia->Descriptor.Type = Dhcp6OptIata;
582+ Ia->Descriptor.IaId = 0x12345678;
583+
584+ Status = Dhcp6AppendIaOption (
585+ Dhcp6AppendIaOptionTest::Packet,
586+ &Cursor,
587+ Ia,
588+ 0,
589+ 0,
590+ Dhcp6OptIata
591+ );
592+
593+ // verify that the pointer to cursor moved by the expected amount
594+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);
595+
596+ // verify that the length of the packet is now the expected amount
597+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);
598+
599+ // verify that the status is EFI_SUCCESS
600+ ASSERT_EQ (Status, EFI_SUCCESS);
601+}
602--
6032.40.0
604
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 \
33 file://CVE-2022-36764-0001.patch \ 33 file://CVE-2022-36764-0001.patch \
34 file://CVE-2022-36764-0002.patch \ 34 file://CVE-2022-36764-0002.patch \
35 file://CVE-2022-36764-0003.patch \ 35 file://CVE-2022-36764-0003.patch \
36 file://CVE-2023-45230-0001.patch \
37 file://CVE-2023-45230-0002.patch \
36 " 38 "
37 39
38PV = "edk2-stable202202" 40PV = "edk2-stable202202"