1 /** @file
2   The logic to process capsule.
3 
4   Caution: This module requires additional review when modified.
5   This driver will have external input - capsule image.
6   This external input must be validated carefully to avoid security issue like
7   buffer overflow, integer overflow.
8 
9   CapsuleDataCoalesce() will do basic validation before coalesce capsule data
10   into memory.
11 
12 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
13 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
14 SPDX-License-Identifier: BSD-2-Clause-Patent
15 
16 **/
17 
18 #include <Uefi.h>
19 #include <PiPei.h>
20 
21 #include <Guid/CapsuleVendor.h>
22 
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/PrintLib.h>
26 #include <Library/BaseLib.h>
27 
28 #include "CommonHeader.h"
29 
30 #define MIN_COALESCE_ADDR                     (1024 * 1024)
31 
32 /**
33   Given a pointer to the capsule block list, info on the available system
34   memory, and the size of a buffer, find a free block of memory where a
35   buffer of the given size can be copied to safely.
36 
37   @param BlockList   Pointer to head of capsule block descriptors
38   @param MemBase     Pointer to the base of memory in which we want to find free space
39   @param MemSize     The size of the block of memory pointed to by MemBase
40   @param DataSize    How big a free block we want to find
41 
42   @return A pointer to a memory block of at least DataSize that lies somewhere
43           between MemBase and (MemBase + MemSize). The memory pointed to does not
44           contain any of the capsule block descriptors or capsule blocks pointed to
45           by the BlockList.
46 
47 **/
48 UINT8 *
49 FindFreeMem (
50   EFI_CAPSULE_BLOCK_DESCRIPTOR     *BlockList,
51   UINT8                            *MemBase,
52   UINTN                             MemSize,
53   UINTN                             DataSize
54   );
55 
56 /**
57   The capsule block descriptors may be fragmented and spread all over memory.
58   To simplify the coalescing of capsule blocks, first coalesce all the
59   capsule block descriptors low in memory.
60 
61   The descriptors passed in can be fragmented throughout memory. Here
62   they are relocated into memory to turn them into a contiguous (null
63   terminated) array.
64 
65   @param PeiServices    pointer to PEI services table
66   @param BlockList      pointer to the capsule block descriptors
67   @param NumDescriptors number of capsule data block descriptors, whose Length is non-zero.
68   @param MemBase        base of system memory in which we can work
69   @param MemSize        size of the system memory pointed to by MemBase
70 
71   @retval NULL    could not relocate the descriptors
72   @retval Pointer to the base of the successfully-relocated block descriptors.
73 
74 **/
75 EFI_CAPSULE_BLOCK_DESCRIPTOR *
76 RelocateBlockDescriptors (
77   IN EFI_PEI_SERVICES                  **PeiServices,
78   IN EFI_CAPSULE_BLOCK_DESCRIPTOR      *BlockList,
79   IN UINTN                              NumDescriptors,
80   IN UINT8                             *MemBase,
81   IN UINTN                             MemSize
82   );
83 
84 /**
85   Check every capsule header.
86 
87   @param CapsuleHeader   The pointer to EFI_CAPSULE_HEADER
88 
89   @retval FALSE  Capsule is OK
90   @retval TRUE   Capsule is corrupted
91 
92 **/
93 BOOLEAN
94 IsCapsuleCorrupted (
95   IN EFI_CAPSULE_HEADER       *CapsuleHeader
96   );
97 
98 /**
99   Determine if two buffers overlap in memory.
100 
101   @param Buff1   pointer to first buffer
102   @param Size1   size of Buff1
103   @param Buff2   pointer to second buffer
104   @param Size2   size of Buff2
105 
106   @retval TRUE    Buffers overlap in memory.
107   @retval FALSE   Buffer doesn't overlap.
108 
109 **/
110 BOOLEAN
111 IsOverlapped (
112   UINT8     *Buff1,
113   UINTN     Size1,
114   UINT8     *Buff2,
115   UINTN     Size2
116   );
117 
118 /**
119   Given a pointer to a capsule block descriptor, traverse the list to figure
120   out how many legitimate descriptors there are, and how big the capsule it
121   refers to is.
122 
123   @param Desc            Pointer to the capsule block descriptors
124   @param NumDescriptors  Optional pointer to where to return the number of capsule data descriptors, whose Length is non-zero.
125   @param CapsuleSize     Optional pointer to where to return the capsule image size
126   @param CapsuleNumber   Optional pointer to where to return the number of capsule
127 
128   @retval EFI_NOT_FOUND   No descriptors containing data in the list
129   @retval EFI_SUCCESS     Return data is valid
130 
131 **/
132 EFI_STATUS
133 GetCapsuleInfo (
134   IN EFI_CAPSULE_BLOCK_DESCRIPTOR   *Desc,
135   IN OUT UINTN                      *NumDescriptors OPTIONAL,
136   IN OUT UINTN                      *CapsuleSize OPTIONAL,
137   IN OUT UINTN                      *CapsuleNumber OPTIONAL
138   );
139 
140 /**
141   Given a pointer to the capsule block list, info on the available system
142   memory, and the size of a buffer, find a free block of memory where a
143   buffer of the given size can be copied to safely.
144 
145   @param BlockList   Pointer to head of capsule block descriptors
146   @param MemBase     Pointer to the base of memory in which we want to find free space
147   @param MemSize     The size of the block of memory pointed to by MemBase
148   @param DataSize    How big a free block we want to find
149 
150   @return A pointer to a memory block of at least DataSize that lies somewhere
151           between MemBase and (MemBase + MemSize). The memory pointed to does not
152           contain any of the capsule block descriptors or capsule blocks pointed to
153           by the BlockList.
154 
155 **/
156 UINT8 *
FindFreeMem(EFI_CAPSULE_BLOCK_DESCRIPTOR * BlockList,UINT8 * MemBase,UINTN MemSize,UINTN DataSize)157 FindFreeMem (
158   EFI_CAPSULE_BLOCK_DESCRIPTOR      *BlockList,
159   UINT8                             *MemBase,
160   UINTN                             MemSize,
161   UINTN                             DataSize
162   )
163 {
164   UINTN                           Size;
165   EFI_CAPSULE_BLOCK_DESCRIPTOR    *CurrDesc;
166   EFI_CAPSULE_BLOCK_DESCRIPTOR    *TempDesc;
167   UINT8                           *MemEnd;
168   BOOLEAN                         Failed;
169 
170   //
171   // Need at least enough to copy the data to at the end of the buffer, so
172   // say the end is less the data size for easy comparisons here.
173   //
174   MemEnd    = MemBase + MemSize - DataSize;
175   CurrDesc  = BlockList;
176   //
177   // Go through all the descriptor blocks and see if any obstruct the range
178   //
179   while (CurrDesc != NULL) {
180     //
181     // Get the size of this block list and see if it's in the way
182     //
183     Failed    = FALSE;
184     TempDesc  = CurrDesc;
185     Size      = sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
186     while (TempDesc->Length != 0) {
187       Size += sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
188       TempDesc++;
189     }
190 
191     if (IsOverlapped (MemBase, DataSize, (UINT8 *) CurrDesc, Size)) {
192       //
193       // Set our new base to the end of this block list and start all over
194       //
195       MemBase   = (UINT8 *) CurrDesc + Size;
196       CurrDesc  = BlockList;
197       if (MemBase > MemEnd) {
198         return NULL;
199       }
200 
201       Failed = TRUE;
202     }
203     //
204     // Now go through all the blocks and make sure none are in the way
205     //
206     while ((CurrDesc->Length != 0) && (!Failed)) {
207       if (IsOverlapped (MemBase, DataSize, (UINT8 *) (UINTN) CurrDesc->Union.DataBlock, (UINTN) CurrDesc->Length)) {
208         //
209         // Set our new base to the end of this block and start all over
210         //
211         Failed    = TRUE;
212         MemBase   = (UINT8 *) ((UINTN) CurrDesc->Union.DataBlock) + CurrDesc->Length;
213         CurrDesc  = BlockList;
214         if (MemBase > MemEnd) {
215           return NULL;
216         }
217       }
218       CurrDesc++;
219     }
220     //
221     // Normal continuation -- jump to next block descriptor list
222     //
223     if (!Failed) {
224       CurrDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) CurrDesc->Union.ContinuationPointer;
225     }
226   }
227   return MemBase;
228 }
229 
230 /**
231   Validate capsule by MemoryResource.
232 
233   @param MemoryResource  Pointer to the buffer of memory resource descriptor.
234   @param Address         Address to be validated.
235   @param Size            Size to be validated.
236 
237   @retval TRUE  No memory resource descriptor reported in HOB list before capsule Coalesce,
238                 or it is valid in one MemoryResource.
239           FALSE It is not in any MemoryResource.
240 
241 **/
242 BOOLEAN
ValidateCapsuleByMemoryResource(IN MEMORY_RESOURCE_DESCRIPTOR * MemoryResource,IN EFI_PHYSICAL_ADDRESS Address,IN UINT64 Size)243 ValidateCapsuleByMemoryResource (
244   IN MEMORY_RESOURCE_DESCRIPTOR     *MemoryResource,
245   IN EFI_PHYSICAL_ADDRESS           Address,
246   IN UINT64                         Size
247   )
248 {
249   UINTN             Index;
250 
251   //
252   // Sanity Check
253   //
254   if (Size > MAX_ADDRESS) {
255     DEBUG ((DEBUG_ERROR, "ERROR: Size(0x%lx) > MAX_ADDRESS\n", Size));
256     return FALSE;
257   }
258 
259   //
260   // Sanity Check
261   //
262   if (Address > (MAX_ADDRESS - Size)) {
263     DEBUG ((DEBUG_ERROR, "ERROR: Address(0x%lx) > (MAX_ADDRESS - Size(0x%lx))\n", Address, Size));
264     return FALSE;
265   }
266 
267   if (MemoryResource == NULL) {
268     //
269     // No memory resource descriptor reported in HOB list before capsule Coalesce.
270     //
271     return TRUE;
272   }
273 
274   for (Index = 0; MemoryResource[Index].ResourceLength != 0; Index++) {
275     if ((Address >= MemoryResource[Index].PhysicalStart) &&
276         ((Address + Size) <= (MemoryResource[Index].PhysicalStart + MemoryResource[Index].ResourceLength))) {
277       DEBUG ((DEBUG_INFO, "Address(0x%lx) Size(0x%lx) in MemoryResource[0x%x] - Start(0x%lx) Length(0x%lx)\n",
278                           Address, Size,
279                           Index, MemoryResource[Index].PhysicalStart, MemoryResource[Index].ResourceLength));
280       return TRUE;
281     }
282   }
283 
284   DEBUG ((DEBUG_ERROR, "ERROR: Address(0x%lx) Size(0x%lx) not in any MemoryResource\n", Address, Size));
285   return FALSE;
286 }
287 
288 /**
289   Check the integrity of the capsule descriptors.
290 
291   @param BlockList       Pointer to the capsule descriptors
292   @param MemoryResource  Pointer to the buffer of memory resource descriptor.
293 
294   @retval NULL           BlockList is not valid.
295   @retval LastBlockDesc  Last one Block in BlockList
296 
297 **/
298 EFI_CAPSULE_BLOCK_DESCRIPTOR *
ValidateCapsuleIntegrity(IN EFI_CAPSULE_BLOCK_DESCRIPTOR * BlockList,IN MEMORY_RESOURCE_DESCRIPTOR * MemoryResource)299 ValidateCapsuleIntegrity (
300   IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList,
301   IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource
302   )
303 {
304   EFI_CAPSULE_HEADER             *CapsuleHeader;
305   UINT64                         CapsuleSize;
306   UINTN                          CapsuleCount;
307   EFI_CAPSULE_BLOCK_DESCRIPTOR   *Ptr;
308 
309   DEBUG ((DEBUG_INFO, "ValidateCapsuleIntegrity\n"));
310 
311   //
312   // Go through the list to look for inconsistencies. Check for:
313   //   * misaligned block descriptors.
314   //   * The first capsule header guid
315   //   * The first capsule header flag
316   //   * The first capsule header HeaderSize
317   //   * Below check will be done in ValidateCapsuleByMemoryResource()
318   //     Length > MAX_ADDRESS
319   //     Ptr + sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR) > MAX_ADDRESS
320   //     DataBlock + Length > MAX_ADDRESS
321   //
322   CapsuleSize  = 0;
323   CapsuleCount = 0;
324   Ptr = BlockList;
325 
326   if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
327     return NULL;
328   }
329 
330   DEBUG ((DEBUG_INFO, "Ptr - 0x%p\n", Ptr));
331   DEBUG ((DEBUG_INFO, "Ptr->Length - 0x%lx\n", Ptr->Length));
332   DEBUG ((DEBUG_INFO, "Ptr->Union - 0x%lx\n", Ptr->Union.ContinuationPointer));
333   while ((Ptr->Length != 0) || (Ptr->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
334     //
335     // Make sure the descriptor is aligned at UINT64 in memory
336     //
337     if ((UINTN) Ptr & (sizeof(UINT64) - 1)) {
338       DEBUG ((DEBUG_ERROR, "ERROR: BlockList address failed alignment check\n"));
339       return NULL;
340     }
341 
342     if (Ptr->Length == 0) {
343       //
344       // Descriptor points to another list of block descriptors somewhere
345       // else.
346       //
347       Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Ptr->Union.ContinuationPointer;
348       if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
349         return NULL;
350       }
351       DEBUG ((DEBUG_INFO, "Ptr(C) - 0x%p\n", Ptr));
352       DEBUG ((DEBUG_INFO, "Ptr->Length - 0x%lx\n", Ptr->Length));
353       DEBUG ((DEBUG_INFO, "Ptr->Union - 0x%lx\n", Ptr->Union.ContinuationPointer));
354     } else {
355       if (!ValidateCapsuleByMemoryResource (MemoryResource, Ptr->Union.DataBlock, Ptr->Length)) {
356         return NULL;
357       }
358 
359       //
360       //To enhance the reliability of check-up, the first capsule's header is checked here.
361       //More reliabilities check-up will do later.
362       //
363       if (CapsuleSize == 0) {
364         //
365         //Move to the first capsule to check its header.
366         //
367         CapsuleHeader = (EFI_CAPSULE_HEADER*)((UINTN)Ptr->Union.DataBlock);
368         //
369         // Sanity check
370         //
371         if (Ptr->Length < sizeof(EFI_CAPSULE_HEADER)) {
372           DEBUG ((DEBUG_ERROR, "ERROR: Ptr->Length(0x%lx) < sizeof(EFI_CAPSULE_HEADER)\n", Ptr->Length));
373           return NULL;
374         }
375         //
376         // Make sure HeaderSize field is valid
377         //
378         if (CapsuleHeader->HeaderSize > CapsuleHeader->CapsuleImageSize) {
379           DEBUG ((DEBUG_ERROR, "ERROR: CapsuleHeader->HeaderSize(0x%x) > CapsuleHeader->CapsuleImageSize(0x%x)\n", CapsuleHeader->HeaderSize, CapsuleHeader->CapsuleImageSize));
380           return NULL;
381         }
382         if (IsCapsuleCorrupted (CapsuleHeader)) {
383           return NULL;
384         }
385         CapsuleCount ++;
386         CapsuleSize = CapsuleHeader->CapsuleImageSize;
387       }
388 
389       if (CapsuleSize >= Ptr->Length) {
390         CapsuleSize = CapsuleSize - Ptr->Length;
391       } else {
392         DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize(0x%lx) < Ptr->Length(0x%lx)\n", CapsuleSize, Ptr->Length));
393         //
394         // Sanity check
395         //
396         return NULL;
397       }
398 
399       //
400       // Move to next BLOCK descriptor
401       //
402       Ptr++;
403       if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
404         return NULL;
405       }
406       DEBUG ((DEBUG_INFO, "Ptr(B) - 0x%p\n", Ptr));
407       DEBUG ((DEBUG_INFO, "Ptr->Length - 0x%lx\n", Ptr->Length));
408       DEBUG ((DEBUG_INFO, "Ptr->Union - 0x%lx\n", Ptr->Union.ContinuationPointer));
409     }
410   }
411 
412   if (CapsuleCount == 0) {
413     //
414     // No any capsule is found in BlockList
415     //
416     DEBUG ((DEBUG_ERROR, "ERROR: CapsuleCount(0x%x) == 0\n", CapsuleCount));
417     return NULL;
418   }
419 
420   if (CapsuleSize != 0) {
421     //
422     // Capsule data is incomplete.
423     //
424     DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize(0x%lx) != 0\n", CapsuleSize));
425     return NULL;
426   }
427 
428   return Ptr;
429 }
430 
431 /**
432   The capsule block descriptors may be fragmented and spread all over memory.
433   To simplify the coalescing of capsule blocks, first coalesce all the
434   capsule block descriptors low in memory.
435 
436   The descriptors passed in can be fragmented throughout memory. Here
437   they are relocated into memory to turn them into a contiguous (null
438   terminated) array.
439 
440   @param PeiServices    pointer to PEI services table
441   @param BlockList      pointer to the capsule block descriptors
442   @param NumDescriptors number of capsule data block descriptors, whose Length is non-zero.
443   @param MemBase        base of system memory in which we can work
444   @param MemSize        size of the system memory pointed to by MemBase
445 
446   @retval NULL    could not relocate the descriptors
447   @retval Pointer to the base of the successfully-relocated block descriptors.
448 
449 **/
450 EFI_CAPSULE_BLOCK_DESCRIPTOR  *
RelocateBlockDescriptors(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_CAPSULE_BLOCK_DESCRIPTOR * BlockList,IN UINTN NumDescriptors,IN UINT8 * MemBase,IN UINTN MemSize)451 RelocateBlockDescriptors (
452   IN EFI_PEI_SERVICES                   **PeiServices,
453   IN EFI_CAPSULE_BLOCK_DESCRIPTOR       *BlockList,
454   IN UINTN                              NumDescriptors,
455   IN UINT8                              *MemBase,
456   IN UINTN                              MemSize
457   )
458 {
459   EFI_CAPSULE_BLOCK_DESCRIPTOR   *NewBlockList;
460   EFI_CAPSULE_BLOCK_DESCRIPTOR   *CurrBlockDescHead;
461   EFI_CAPSULE_BLOCK_DESCRIPTOR   *TempBlockDesc;
462   EFI_CAPSULE_BLOCK_DESCRIPTOR   *PrevBlockDescTail;
463   UINTN                          BufferSize;
464   UINT8                          *RelocBuffer;
465   UINTN                          BlockListSize;
466 
467   //
468   // Get the info on the blocks and descriptors. Since we're going to move
469   // the descriptors low in memory, adjust the base/size values accordingly here.
470   // NumDescriptors is the number of legit data descriptors, so add one for
471   // a terminator. (Already done by caller, no check is needed.)
472   //
473 
474   BufferSize    = NumDescriptors * sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
475   NewBlockList  = (EFI_CAPSULE_BLOCK_DESCRIPTOR *) MemBase;
476   if (MemSize < BufferSize) {
477     return NULL;
478   }
479 
480   MemSize -= BufferSize;
481   MemBase += BufferSize;
482   //
483   // Go through all the blocks and make sure none are in the way
484   //
485   TempBlockDesc = BlockList;
486   while (TempBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {
487     if (TempBlockDesc->Length == 0) {
488       //
489       // Next block of descriptors
490       //
491       TempBlockDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) TempBlockDesc->Union.ContinuationPointer;
492     } else {
493       //
494       // If the capsule data pointed to by this descriptor is in the way,
495       // move it.
496       //
497       if (IsOverlapped (
498             (UINT8 *) NewBlockList,
499             BufferSize,
500             (UINT8 *) (UINTN) TempBlockDesc->Union.DataBlock,
501             (UINTN) TempBlockDesc->Length
502             )) {
503         //
504         // Relocate the block
505         //
506         RelocBuffer = FindFreeMem (BlockList, MemBase, MemSize, (UINTN) TempBlockDesc->Length);
507         if (RelocBuffer == NULL) {
508           return NULL;
509         }
510 
511         CopyMem ((VOID *) RelocBuffer, (VOID *) (UINTN) TempBlockDesc->Union.DataBlock, (UINTN) TempBlockDesc->Length);
512         DEBUG ((DEBUG_INFO, "Capsule relocate descriptors from/to/size  0x%lX 0x%lX 0x%lX\n", TempBlockDesc->Union.DataBlock, (UINT64)(UINTN)RelocBuffer, TempBlockDesc->Length));
513         TempBlockDesc->Union.DataBlock = (EFI_PHYSICAL_ADDRESS) (UINTN) RelocBuffer;
514       }
515       TempBlockDesc++;
516     }
517   }
518   //
519   // Now go through all the block descriptors to make sure that they're not
520   // in the memory region we want to copy them to.
521   //
522   CurrBlockDescHead = BlockList;
523   PrevBlockDescTail = NULL;
524   while ((CurrBlockDescHead != NULL) && (CurrBlockDescHead->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
525     //
526     // Get the size of this list then see if it overlaps our low region
527     //
528     TempBlockDesc = CurrBlockDescHead;
529     BlockListSize = sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
530     while (TempBlockDesc->Length != 0) {
531       BlockListSize += sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
532       TempBlockDesc++;
533     }
534 
535     if (IsOverlapped (
536           (UINT8 *) NewBlockList,
537           BufferSize,
538           (UINT8 *) CurrBlockDescHead,
539           BlockListSize
540           )) {
541       //
542       // Overlaps, so move it out of the way
543       //
544       RelocBuffer = FindFreeMem (BlockList, MemBase, MemSize, BlockListSize);
545       if (RelocBuffer == NULL) {
546         return NULL;
547       }
548       CopyMem ((VOID *) RelocBuffer, (VOID *) CurrBlockDescHead, BlockListSize);
549       DEBUG ((DEBUG_INFO, "Capsule reloc descriptor block #2\n"));
550       //
551       // Point the previous block's next point to this copied version. If
552       // the tail pointer is null, then this is the first descriptor block.
553       //
554       if (PrevBlockDescTail == NULL) {
555         BlockList = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) RelocBuffer;
556       } else {
557         PrevBlockDescTail->Union.DataBlock = (EFI_PHYSICAL_ADDRESS) (UINTN) RelocBuffer;
558       }
559     }
560     //
561     // Save our new tail and jump to the next block list
562     //
563     PrevBlockDescTail = TempBlockDesc;
564     CurrBlockDescHead = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) TempBlockDesc->Union.ContinuationPointer;
565   }
566   //
567   // Cleared out low memory. Now copy the descriptors down there.
568   //
569   TempBlockDesc     = BlockList;
570   CurrBlockDescHead = NewBlockList;
571   while ((TempBlockDesc != NULL) && (TempBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
572     if (TempBlockDesc->Length != 0) {
573       CurrBlockDescHead->Union.DataBlock = TempBlockDesc->Union.DataBlock;
574       CurrBlockDescHead->Length = TempBlockDesc->Length;
575       CurrBlockDescHead++;
576       TempBlockDesc++;
577     } else {
578       TempBlockDesc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) TempBlockDesc->Union.ContinuationPointer;
579     }
580   }
581   //
582   // Null terminate
583   //
584   CurrBlockDescHead->Union.ContinuationPointer   = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
585   CurrBlockDescHead->Length = 0;
586   return NewBlockList;
587 }
588 
589 /**
590   Determine if two buffers overlap in memory.
591 
592   @param Buff1   pointer to first buffer
593   @param Size1   size of Buff1
594   @param Buff2   pointer to second buffer
595   @param Size2   size of Buff2
596 
597   @retval TRUE    Buffers overlap in memory.
598   @retval FALSE   Buffer doesn't overlap.
599 
600 **/
601 BOOLEAN
IsOverlapped(UINT8 * Buff1,UINTN Size1,UINT8 * Buff2,UINTN Size2)602 IsOverlapped (
603   UINT8     *Buff1,
604   UINTN     Size1,
605   UINT8     *Buff2,
606   UINTN     Size2
607   )
608 {
609   //
610   // If buff1's end is less than the start of buff2, then it's ok.
611   // Also, if buff1's start is beyond buff2's end, then it's ok.
612   //
613   if (((Buff1 + Size1) <= Buff2) || (Buff1 >= (Buff2 + Size2))) {
614     return FALSE;
615   }
616 
617   return TRUE;
618 }
619 
620 /**
621   Given a pointer to a capsule block descriptor, traverse the list to figure
622   out how many legitimate descriptors there are, and how big the capsule it
623   refers to is.
624 
625   @param Desc            Pointer to the capsule block descriptors
626   @param NumDescriptors  Optional pointer to where to return the number of capsule data descriptors, whose Length is non-zero.
627   @param CapsuleSize     Optional pointer to where to return the capsule image size
628   @param CapsuleNumber   Optional pointer to where to return the number of capsule
629 
630   @retval EFI_NOT_FOUND   No descriptors containing data in the list
631   @retval EFI_SUCCESS     Return data is valid
632 
633 **/
634 EFI_STATUS
GetCapsuleInfo(IN EFI_CAPSULE_BLOCK_DESCRIPTOR * Desc,IN OUT UINTN * NumDescriptors OPTIONAL,IN OUT UINTN * CapsuleSize OPTIONAL,IN OUT UINTN * CapsuleNumber OPTIONAL)635 GetCapsuleInfo (
636   IN EFI_CAPSULE_BLOCK_DESCRIPTOR   *Desc,
637   IN OUT UINTN                      *NumDescriptors OPTIONAL,
638   IN OUT UINTN                      *CapsuleSize OPTIONAL,
639   IN OUT UINTN                      *CapsuleNumber OPTIONAL
640   )
641 {
642   UINTN                          Count;
643   UINTN                          Size;
644   UINTN                          Number;
645   UINTN                          ThisCapsuleImageSize;
646   EFI_CAPSULE_HEADER             *CapsuleHeader;
647 
648   DEBUG ((DEBUG_INFO, "GetCapsuleInfo enter\n"));
649 
650   ASSERT (Desc != NULL);
651 
652   Count = 0;
653   Size  = 0;
654   Number = 0;
655   ThisCapsuleImageSize = 0;
656 
657   while (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {
658     if (Desc->Length == 0) {
659       //
660       // Descriptor points to another list of block descriptors somewhere
661       //
662       Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Desc->Union.ContinuationPointer;
663     } else {
664       //
665       // Sanity Check
666       // It is needed, because ValidateCapsuleIntegrity() only validate one individual capsule Size.
667       // While here we need check all capsules size.
668       //
669       if (Desc->Length >= (MAX_ADDRESS - Size)) {
670         DEBUG ((DEBUG_ERROR, "ERROR: Desc->Length(0x%lx) >= (MAX_ADDRESS - Size(0x%x))\n", Desc->Length, Size));
671         return EFI_OUT_OF_RESOURCES;
672       }
673       Size += (UINTN) Desc->Length;
674       Count++;
675 
676       //
677       // See if this is first capsule's header
678       //
679       if (ThisCapsuleImageSize == 0) {
680         CapsuleHeader = (EFI_CAPSULE_HEADER*)((UINTN)Desc->Union.DataBlock);
681         //
682         // This has been checked in ValidateCapsuleIntegrity()
683         //
684         Number ++;
685         ThisCapsuleImageSize = CapsuleHeader->CapsuleImageSize;
686       }
687 
688       //
689       // This has been checked in ValidateCapsuleIntegrity()
690       //
691       ASSERT (ThisCapsuleImageSize >= Desc->Length);
692       ThisCapsuleImageSize = (UINTN)(ThisCapsuleImageSize - Desc->Length);
693 
694       //
695       // Move to next
696       //
697       Desc++;
698     }
699   }
700   //
701   // If no descriptors, then fail
702   //
703   if (Count == 0) {
704     DEBUG ((DEBUG_ERROR, "ERROR: Count == 0\n"));
705     return EFI_NOT_FOUND;
706   }
707 
708   //
709   // checked in ValidateCapsuleIntegrity()
710   //
711   ASSERT (ThisCapsuleImageSize == 0);
712 
713   if (NumDescriptors != NULL) {
714     *NumDescriptors = Count;
715   }
716 
717   if (CapsuleSize != NULL) {
718     *CapsuleSize = Size;
719   }
720 
721   if (CapsuleNumber != NULL) {
722     *CapsuleNumber = Number;
723   }
724 
725   return EFI_SUCCESS;
726 }
727 
728 /**
729   Check every capsule header.
730 
731   @param CapsuleHeader   The pointer to EFI_CAPSULE_HEADER
732 
733   @retval FALSE  Capsule is OK
734   @retval TRUE   Capsule is corrupted
735 
736 **/
737 BOOLEAN
IsCapsuleCorrupted(IN EFI_CAPSULE_HEADER * CapsuleHeader)738 IsCapsuleCorrupted (
739   IN EFI_CAPSULE_HEADER       *CapsuleHeader
740   )
741 {
742   //
743   //A capsule to be updated across a system reset should contain CAPSULE_FLAGS_PERSIST_ACROSS_RESET.
744   //
745   if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) {
746     return TRUE;
747   }
748   //
749   //Make sure the flags combination is supported by the platform.
750   //
751   if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
752     return TRUE;
753   }
754   if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
755     return TRUE;
756   }
757 
758   return FALSE;
759 }
760 
761 /**
762   Try to verify the integrity of a capsule test pattern before the
763   capsule gets coalesced. This can be useful in narrowing down
764   where capsule data corruption occurs.
765 
766   The test pattern mode fills in memory with a counting UINT32 value.
767   If the capsule is not divided up in a multiple of 4-byte blocks, then
768   things get messy doing the check. Therefore there are some cases
769   here where we just give up and skip the pre-coalesce check.
770 
771   @param PeiServices  PEI services table
772   @param Desc         Pointer to capsule descriptors
773 **/
774 VOID
CapsuleTestPatternPreCoalesce(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_CAPSULE_BLOCK_DESCRIPTOR * Desc)775 CapsuleTestPatternPreCoalesce (
776   IN EFI_PEI_SERVICES              **PeiServices,
777   IN EFI_CAPSULE_BLOCK_DESCRIPTOR  *Desc
778   )
779 {
780   UINT32  *TestPtr;
781   UINT32  TestCounter;
782   UINT32  TestSize;
783 
784   DEBUG ((DEBUG_INFO, "CapsuleTestPatternPreCoalesce\n"));
785 
786   //
787   // Find first data descriptor
788   //
789   while ((Desc->Length == 0) && (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
790     Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Desc->Union.ContinuationPointer;
791   }
792 
793   if (Desc->Union.ContinuationPointer == 0) {
794     return ;
795   }
796   //
797   // First one better be long enough to at least hold the test signature
798   //
799   if (Desc->Length < sizeof (UINT32)) {
800     DEBUG ((DEBUG_INFO, "Capsule test pattern pre-coalesce punted #1\n"));
801     return ;
802   }
803 
804   TestPtr = (UINT32 *) (UINTN) Desc->Union.DataBlock;
805   //
806   // 0x54534554 "TEST"
807   //
808   if (*TestPtr != 0x54534554) {
809     return ;
810   }
811 
812   TestCounter = 0;
813   TestSize    = (UINT32) Desc->Length - 2 * sizeof (UINT32);
814   //
815   // Skip over the signature and the size fields in the pattern data header
816   //
817   TestPtr += 2;
818   while (1) {
819     if ((TestSize & 0x03) != 0) {
820       DEBUG ((DEBUG_INFO, "Capsule test pattern pre-coalesce punted #2\n"));
821       return ;
822     }
823 
824     while (TestSize > 0) {
825       if (*TestPtr != TestCounter) {
826         DEBUG ((DEBUG_INFO, "Capsule test pattern pre-coalesce failed data corruption check\n"));
827         return ;
828       }
829 
830       TestSize -= sizeof (UINT32);
831       TestCounter++;
832       TestPtr++;
833     }
834     Desc++;
835     while ((Desc->Length == 0) && (Desc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
836       Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Desc->Union.ContinuationPointer;
837     }
838 
839     if (Desc->Union.ContinuationPointer == (EFI_PHYSICAL_ADDRESS) (UINTN) NULL) {
840       return ;
841     }
842     TestSize = (UINT32) Desc->Length;
843     TestPtr  = (UINT32 *) (UINTN) Desc->Union.DataBlock;
844   }
845 }
846 
847 /**
848   Checks for the presence of capsule descriptors.
849   Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
850 
851   @param BlockListBuffer            Pointer to the buffer of capsule descriptors variables
852   @param MemoryResource             Pointer to the buffer of memory resource descriptor.
853   @param BlockDescriptorList        Pointer to the capsule descriptors list
854 
855   @retval EFI_SUCCESS               a valid capsule is present
856   @retval EFI_NOT_FOUND             if a valid capsule is not present
857 **/
858 EFI_STATUS
BuildCapsuleDescriptors(IN EFI_PHYSICAL_ADDRESS * BlockListBuffer,IN MEMORY_RESOURCE_DESCRIPTOR * MemoryResource,OUT EFI_CAPSULE_BLOCK_DESCRIPTOR ** BlockDescriptorList)859 BuildCapsuleDescriptors (
860   IN  EFI_PHYSICAL_ADDRESS            *BlockListBuffer,
861   IN  MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,
862   OUT EFI_CAPSULE_BLOCK_DESCRIPTOR    **BlockDescriptorList
863   )
864 {
865   UINTN                            Index;
866   EFI_CAPSULE_BLOCK_DESCRIPTOR     *LastBlock;
867   EFI_CAPSULE_BLOCK_DESCRIPTOR     *TempBlock;
868   EFI_CAPSULE_BLOCK_DESCRIPTOR     *HeadBlock;
869 
870   DEBUG ((DEBUG_INFO, "BuildCapsuleDescriptors enter\n"));
871 
872   LastBlock         = NULL;
873   HeadBlock         = NULL;
874   TempBlock         = NULL;
875   Index             = 0;
876 
877   while (BlockListBuffer[Index] != 0) {
878     //
879     // Test integrity of descriptors.
880     //
881     if (BlockListBuffer[Index] < MAX_ADDRESS) {
882       TempBlock = ValidateCapsuleIntegrity ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index], MemoryResource);
883       if (TempBlock != NULL) {
884         if (LastBlock == NULL) {
885           LastBlock = TempBlock;
886 
887           //
888           // Return the base of the block descriptors
889           //
890           HeadBlock = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index];
891         } else {
892           //
893           // Combine the different BlockList into single BlockList.
894           //
895           LastBlock->Union.DataBlock = (EFI_PHYSICAL_ADDRESS)(UINTN)BlockListBuffer[Index];
896           LastBlock->Length          = 0;
897           LastBlock                  = TempBlock;
898         }
899       }
900     } else {
901       DEBUG ((DEBUG_ERROR, "ERROR: BlockListBuffer[Index](0x%lx) < MAX_ADDRESS\n", BlockListBuffer[Index]));
902     }
903     Index ++;
904   }
905 
906   if (HeadBlock != NULL) {
907     *BlockDescriptorList = HeadBlock;
908     return EFI_SUCCESS;
909   }
910   return EFI_NOT_FOUND;
911 }
912 
913 /**
914   The function to coalesce a fragmented capsule in memory.
915 
916   Memory Map for coalesced capsule:
917   MemBase +   ---->+---------------------------+<-----------+
918   MemSize          | ------------------------- |            |
919                    | |  Capsule [Num-1]      | |            |
920                    | ------------------------- |            |
921                    | |  ................     | |            |
922                    | ------------------------- |            |
923                    | |  Capsule [1]          | |            |
924                    | ------------------------- |            |
925                    | |  Capsule [0]          | |            |
926                    | ------------------------- |            |
927                    |    Capsule Image          |            |
928 CapsuleImageBase-->+---------------------------+
929                    | ------------------------- |            |
930                    | |  CapsuleOffset[Num-1] | |            |
931                    | ------------------------- |            |
932                    | |  ................     | |        CapsuleSize
933                    | ------------------------- |            |
934                    | |  CapsuleOffset[1]     | |            |
935                    | ------------------------- |            |
936                    | |  CapsuleOffset[0]     | |            |
937                    |---------------------------|            |
938                    | |  CapsuleNumber        | |            |
939                    | ------------------------- |            |
940                    | |  CapsuleAllImageSize  | |            |
941                    | ------------------------- |            |
942                    |    PrivateData            |            |
943      DestPtr  ---->+---------------------------+<-----------+
944                    |                           |            |
945                    |     FreeMem               |        FreeMemSize
946                    |                           |            |
947    FreeMemBase --->+---------------------------+<-----------+
948                    |    Terminator             |
949                    +---------------------------+
950                    |    BlockDescriptor n      |
951                    +---------------------------+
952                    |    .................      |
953                    +---------------------------+
954                    |    BlockDescriptor 1      |
955                    +---------------------------+
956                    |    BlockDescriptor 0      |
957                    +---------------------------+
958                    |    PrivateDataDesc 0      |
959       MemBase ---->+---------------------------+<----- BlockList
960 
961   Caution: This function may receive untrusted input.
962   The capsule data is external input, so this routine will do basic validation before
963   coalesce capsule data into memory.
964 
965   @param PeiServices        General purpose services available to every PEIM.
966   @param BlockListBuffer    Pointer to the buffer of Capsule Descriptor Variables.
967   @param MemoryResource     Pointer to the buffer of memory resource descriptor.
968   @param MemoryBase         Pointer to the base of a block of memory that we can walk
969                             all over while trying to coalesce our buffers.
970                             On output, this variable will hold the base address of
971                             a coalesced capsule.
972   @param MemorySize         Size of the memory region pointed to by MemoryBase.
973                             On output, this variable will contain the size of the
974                             coalesced capsule.
975 
976   @retval EFI_NOT_FOUND     If we could not find the capsule descriptors.
977 
978   @retval EFI_BUFFER_TOO_SMALL
979                             If we could not coalesce the capsule in the memory
980                             region provided to us.
981 
982   @retval EFI_SUCCESS       Processed the capsule successfully.
983 **/
984 EFI_STATUS
985 EFIAPI
CapsuleDataCoalesce(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_PHYSICAL_ADDRESS * BlockListBuffer,IN MEMORY_RESOURCE_DESCRIPTOR * MemoryResource,IN OUT VOID ** MemoryBase,IN OUT UINTN * MemorySize)986 CapsuleDataCoalesce (
987   IN EFI_PEI_SERVICES                **PeiServices,
988   IN EFI_PHYSICAL_ADDRESS            *BlockListBuffer,
989   IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,
990   IN OUT VOID                        **MemoryBase,
991   IN OUT UINTN                       *MemorySize
992   )
993 {
994   VOID                           *NewCapsuleBase;
995   VOID                           *CapsuleImageBase;
996   UINTN                          CapsuleIndex;
997   UINT8                          *FreeMemBase;
998   UINT8                          *DestPtr;
999   UINTN                          DestLength;
1000   UINT8                          *RelocPtr;
1001   UINTN                          CapsuleTimes;
1002   UINT64                         SizeLeft;
1003   UINT64                         CapsuleImageSize;
1004   UINTN                          CapsuleSize;
1005   UINTN                          CapsuleNumber;
1006   UINTN                          DescriptorsSize;
1007   UINTN                          FreeMemSize;
1008   UINTN                          NumDescriptors;
1009   BOOLEAN                        CapsuleBeginFlag;
1010   EFI_STATUS                     Status;
1011   EFI_CAPSULE_HEADER             *CapsuleHeader;
1012   EFI_CAPSULE_PEIM_PRIVATE_DATA  PrivateData;
1013   EFI_CAPSULE_PEIM_PRIVATE_DATA  *PrivateDataPtr;
1014   EFI_CAPSULE_BLOCK_DESCRIPTOR   *BlockList;
1015   EFI_CAPSULE_BLOCK_DESCRIPTOR   *CurrentBlockDesc;
1016   EFI_CAPSULE_BLOCK_DESCRIPTOR   *TempBlockDesc;
1017   EFI_CAPSULE_BLOCK_DESCRIPTOR   PrivateDataDesc[2];
1018 
1019   DEBUG ((DEBUG_INFO, "CapsuleDataCoalesce enter\n"));
1020 
1021   CapsuleIndex     = 0;
1022   SizeLeft         = 0;
1023   CapsuleTimes     = 0;
1024   CapsuleImageSize = 0;
1025   PrivateDataPtr   = NULL;
1026   CapsuleHeader    = NULL;
1027   CapsuleBeginFlag = TRUE;
1028   CapsuleSize      = 0;
1029   NumDescriptors   = 0;
1030 
1031   //
1032   // Build capsule descriptors list
1033   //
1034   Status = BuildCapsuleDescriptors (BlockListBuffer, MemoryResource, &BlockList);
1035   if (EFI_ERROR (Status)) {
1036     return Status;
1037   }
1038 
1039   DEBUG_CODE (
1040     CapsuleTestPatternPreCoalesce (PeiServices, BlockList);
1041   );
1042 
1043   //
1044   // Get the size of our descriptors and the capsule size. GetCapsuleInfo()
1045   // returns the number of descriptors that actually point to data, so add
1046   // one for a terminator. Do that below.
1047   //
1048   Status = GetCapsuleInfo (BlockList, &NumDescriptors, &CapsuleSize, &CapsuleNumber);
1049   if (EFI_ERROR (Status)) {
1050     return Status;
1051   }
1052   DEBUG ((DEBUG_INFO, "CapsuleSize - 0x%x\n", CapsuleSize));
1053   DEBUG ((DEBUG_INFO, "CapsuleNumber - 0x%x\n", CapsuleNumber));
1054   DEBUG ((DEBUG_INFO, "NumDescriptors - 0x%x\n", NumDescriptors));
1055   if ((CapsuleSize == 0) || (NumDescriptors == 0) || (CapsuleNumber == 0)) {
1056     return EFI_NOT_FOUND;
1057   }
1058 
1059   if (CapsuleNumber - 1 >= (MAX_ADDRESS - (sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA)  + sizeof(UINT64))) / sizeof(UINT64)) {
1060     DEBUG ((DEBUG_ERROR, "ERROR: CapsuleNumber - 0x%x\n", CapsuleNumber));
1061     return EFI_BUFFER_TOO_SMALL;
1062   }
1063 
1064   //
1065   // Initialize our local copy of private data. When we're done, we'll create a
1066   // descriptor for it as well so that it can be put into free memory without
1067   // trashing anything.
1068   //
1069   PrivateData.Signature           = EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE;
1070   PrivateData.CapsuleAllImageSize = (UINT64) CapsuleSize;
1071   PrivateData.CapsuleNumber       = (UINT64) CapsuleNumber;
1072   PrivateData.CapsuleOffset[0]    = 0;
1073   //
1074   // NOTE: Only data in sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) is valid, CapsuleOffset field is uninitialized at this moment.
1075   // The code sets partial length here for Descriptor.Length check, but later it will use full length to reserve those PrivateData region.
1076   //
1077   PrivateDataDesc[0].Union.DataBlock  = (EFI_PHYSICAL_ADDRESS) (UINTN) &PrivateData;
1078   PrivateDataDesc[0].Length           = sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA);
1079   PrivateDataDesc[1].Union.DataBlock  = (EFI_PHYSICAL_ADDRESS) (UINTN) BlockList;
1080   PrivateDataDesc[1].Length           = 0;
1081   //
1082   // Add PrivateDataDesc[0] in beginning, as it is new descriptor. PrivateDataDesc[1] is NOT needed.
1083   // In addition, one NULL terminator is added in the end. See RelocateBlockDescriptors().
1084   //
1085   NumDescriptors  += 2;
1086   //
1087   // Sanity check
1088   //
1089   if (CapsuleSize >= (MAX_ADDRESS - (sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64) + sizeof(UINT64)))) {
1090     DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize - 0x%x\n", CapsuleSize));
1091     return EFI_BUFFER_TOO_SMALL;
1092   }
1093   //
1094   // Need add sizeof(UINT64) for PrivateData alignment
1095   //
1096   CapsuleSize     += sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64) + sizeof(UINT64);
1097   BlockList        = PrivateDataDesc;
1098   //
1099   // Sanity check
1100   //
1101   if (NumDescriptors >= (MAX_ADDRESS / sizeof(EFI_CAPSULE_BLOCK_DESCRIPTOR))) {
1102     DEBUG ((DEBUG_ERROR, "ERROR: NumDescriptors - 0x%x\n", NumDescriptors));
1103     return EFI_BUFFER_TOO_SMALL;
1104   }
1105   DescriptorsSize  = NumDescriptors * sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR);
1106   //
1107   // Sanity check
1108   //
1109   if (DescriptorsSize >= (MAX_ADDRESS - CapsuleSize)) {
1110     DEBUG ((DEBUG_ERROR, "ERROR: DescriptorsSize - 0x%lx, CapsuleSize - 0x%lx\n", (UINT64)DescriptorsSize, (UINT64)CapsuleSize));
1111     return EFI_BUFFER_TOO_SMALL;
1112   }
1113 
1114   //
1115   // Don't go below some min address. If the base is below it,
1116   // then move it up and adjust the size accordingly.
1117   //
1118   DEBUG ((DEBUG_INFO, "Capsule Memory range from 0x%8X to 0x%8X\n", (UINTN) *MemoryBase, (UINTN)*MemoryBase + *MemorySize));
1119   if ((UINTN)*MemoryBase < (UINTN) MIN_COALESCE_ADDR) {
1120     if (((UINTN)*MemoryBase + *MemorySize) < (UINTN) MIN_COALESCE_ADDR) {
1121       DEBUG ((DEBUG_ERROR, "ERROR: *MemoryBase + *MemorySize - 0x%x\n", (UINTN)*MemoryBase + *MemorySize));
1122       return EFI_BUFFER_TOO_SMALL;
1123     } else {
1124       *MemorySize = *MemorySize - ((UINTN) MIN_COALESCE_ADDR - (UINTN) *MemoryBase);
1125       *MemoryBase = (VOID *) (UINTN) MIN_COALESCE_ADDR;
1126     }
1127   }
1128 
1129   if (*MemorySize <= (CapsuleSize + DescriptorsSize)) {
1130     DEBUG ((DEBUG_ERROR, "ERROR: CapsuleSize + DescriptorsSize - 0x%x\n", CapsuleSize + DescriptorsSize));
1131     return EFI_BUFFER_TOO_SMALL;
1132   }
1133 
1134   FreeMemBase = *MemoryBase;
1135   FreeMemSize = *MemorySize;
1136   DEBUG ((DEBUG_INFO, "Capsule Free Memory from 0x%8X to 0x%8X\n", (UINTN) FreeMemBase, (UINTN) FreeMemBase + FreeMemSize));
1137 
1138   //
1139   // Relocate all the block descriptors to low memory to make further
1140   // processing easier.
1141   //
1142   BlockList = RelocateBlockDescriptors (PeiServices, BlockList, NumDescriptors, FreeMemBase, FreeMemSize);
1143   if (BlockList == NULL) {
1144     //
1145     // Not enough room to relocate the descriptors
1146     //
1147     return EFI_BUFFER_TOO_SMALL;
1148   }
1149 
1150   //
1151   // Take the top of memory for the capsule. UINT64 align up.
1152   //
1153   DestPtr         = FreeMemBase + FreeMemSize - CapsuleSize;
1154   DestPtr         = (UINT8 *) (((UINTN)DestPtr + sizeof (UINT64) - 1) & ~(sizeof (UINT64) - 1));
1155   FreeMemBase     = (UINT8 *) BlockList + DescriptorsSize;
1156   FreeMemSize     = (UINTN) DestPtr - (UINTN) FreeMemBase;
1157   NewCapsuleBase  = (VOID *) DestPtr;
1158   CapsuleImageBase = (UINT8 *)NewCapsuleBase + sizeof(EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64);
1159 
1160   PrivateDataPtr = (EFI_CAPSULE_PEIM_PRIVATE_DATA *) NewCapsuleBase;
1161 
1162   //
1163   // Move all the blocks to the top (high) of memory.
1164   // Relocate all the obstructing blocks. Note that the block descriptors
1165   // were coalesced when they were relocated, so we can just ++ the pointer.
1166   //
1167   CurrentBlockDesc = BlockList;
1168   while ((CurrentBlockDesc->Length != 0) || (CurrentBlockDesc->Union.ContinuationPointer != (EFI_PHYSICAL_ADDRESS) (UINTN) NULL)) {
1169     if (CapsuleTimes == 0) {
1170       //
1171       // The first entry is the block descriptor for EFI_CAPSULE_PEIM_PRIVATE_DATA.
1172       // CapsuleOffset field is uninitialized at this time. No need copy it, but need to reserve for future use.
1173       //
1174       ASSERT (CurrentBlockDesc->Union.DataBlock == (UINT64)(UINTN)&PrivateData);
1175       DestLength = sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64);
1176     } else {
1177       DestLength = (UINTN)CurrentBlockDesc->Length;
1178     }
1179     //
1180     // See if any of the remaining capsule blocks are in the way
1181     //
1182     TempBlockDesc = CurrentBlockDesc;
1183     while (TempBlockDesc->Length != 0) {
1184       //
1185       // Is this block in the way of where we want to copy the current descriptor to?
1186       //
1187       if (IsOverlapped (
1188             (UINT8 *) DestPtr,
1189             (UINTN) DestLength,
1190             (UINT8 *) (UINTN) TempBlockDesc->Union.DataBlock,
1191             (UINTN) TempBlockDesc->Length
1192             )) {
1193         //
1194         // Relocate the block
1195         //
1196         RelocPtr = FindFreeMem (BlockList, FreeMemBase, FreeMemSize, (UINTN) TempBlockDesc->Length);
1197         if (RelocPtr == NULL) {
1198           return EFI_BUFFER_TOO_SMALL;
1199         }
1200 
1201         CopyMem ((VOID *) RelocPtr, (VOID *) (UINTN) TempBlockDesc->Union.DataBlock, (UINTN) TempBlockDesc->Length);
1202         DEBUG ((DEBUG_INFO, "Capsule reloc data block from 0x%8X to 0x%8X with size 0x%8X\n",
1203                 (UINTN) TempBlockDesc->Union.DataBlock, (UINTN) RelocPtr, (UINTN) TempBlockDesc->Length));
1204 
1205         TempBlockDesc->Union.DataBlock = (EFI_PHYSICAL_ADDRESS) (UINTN) RelocPtr;
1206       }
1207       //
1208       // Next descriptor
1209       //
1210       TempBlockDesc++;
1211     }
1212     //
1213     // Ok, we made it through. Copy the block.
1214     // we just support greping one capsule from the lists of block descs list.
1215     //
1216     CapsuleTimes ++;
1217     //
1218     //Skip the first block descriptor that filled with EFI_CAPSULE_PEIM_PRIVATE_DATA
1219     //
1220     if (CapsuleTimes > 1) {
1221       //
1222       //For every capsule entry point, check its header to determine whether to relocate it.
1223       //If it is invalid, skip it and move on to the next capsule. If it is valid, relocate it.
1224       //
1225       if (CapsuleBeginFlag) {
1226         CapsuleBeginFlag  = FALSE;
1227         CapsuleHeader     = (EFI_CAPSULE_HEADER*)(UINTN)CurrentBlockDesc->Union.DataBlock;
1228         SizeLeft          = CapsuleHeader->CapsuleImageSize;
1229 
1230         //
1231         // No more check here is needed, because IsCapsuleCorrupted() already in ValidateCapsuleIntegrity()
1232         //
1233         ASSERT (CapsuleIndex < CapsuleNumber);
1234 
1235         //
1236         // Relocate this capsule
1237         //
1238         CapsuleImageSize += SizeLeft;
1239         //
1240         // Cache the begin offset of this capsule
1241         //
1242         ASSERT (PrivateDataPtr->Signature == EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE);
1243         ASSERT ((UINTN)DestPtr >= (UINTN)CapsuleImageBase);
1244         PrivateDataPtr->CapsuleOffset[CapsuleIndex++] = (UINTN)DestPtr - (UINTN)CapsuleImageBase;
1245       }
1246 
1247       //
1248       // Below ASSERT is checked in ValidateCapsuleIntegrity()
1249       //
1250       ASSERT (CurrentBlockDesc->Length <= SizeLeft);
1251 
1252       CopyMem ((VOID *) DestPtr, (VOID *) (UINTN) (CurrentBlockDesc->Union.DataBlock), (UINTN)CurrentBlockDesc->Length);
1253       DEBUG ((DEBUG_INFO, "Capsule coalesce block no.0x%lX from 0x%lX to 0x%lX with size 0x%lX\n",(UINT64)CapsuleTimes,
1254              CurrentBlockDesc->Union.DataBlock, (UINT64)(UINTN)DestPtr, CurrentBlockDesc->Length));
1255       DestPtr += CurrentBlockDesc->Length;
1256       SizeLeft -= CurrentBlockDesc->Length;
1257 
1258       if (SizeLeft == 0) {
1259         //
1260         //Here is the end of the current capsule image.
1261         //
1262         CapsuleBeginFlag = TRUE;
1263       }
1264     } else {
1265       //
1266       // The first entry is the block descriptor for EFI_CAPSULE_PEIM_PRIVATE_DATA.
1267       // CapsuleOffset field is uninitialized at this time. No need copy it, but need to reserve for future use.
1268       //
1269       ASSERT (CurrentBlockDesc->Length == sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA));
1270       ASSERT ((UINTN)DestPtr == (UINTN)NewCapsuleBase);
1271       CopyMem ((VOID *) DestPtr, (VOID *) (UINTN) CurrentBlockDesc->Union.DataBlock, (UINTN) CurrentBlockDesc->Length);
1272       DestPtr += sizeof (EFI_CAPSULE_PEIM_PRIVATE_DATA) + (CapsuleNumber - 1) * sizeof(UINT64);
1273     }
1274     //
1275     //Walk through the block descriptor list.
1276     //
1277     CurrentBlockDesc++;
1278   }
1279   //
1280   // We return the base of memory we want reserved, and the size.
1281   // The memory peim should handle it appropriately from there.
1282   //
1283   *MemorySize = (UINTN) CapsuleSize;
1284   *MemoryBase = (VOID *) NewCapsuleBase;
1285 
1286   ASSERT (PrivateDataPtr->Signature == EFI_CAPSULE_PEIM_PRIVATE_DATA_SIGNATURE);
1287   ASSERT (PrivateDataPtr->CapsuleAllImageSize == CapsuleImageSize);
1288   ASSERT (PrivateDataPtr->CapsuleNumber == CapsuleIndex);
1289 
1290   return EFI_SUCCESS;
1291 }
1292