X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FCapsulePei%2FCommon%2FCapsuleCoalesce.c;h=9e8315eb97c62c7d87aca443424f8eb097c9855f;hb=359cb1a3b91fe6a31213fc213ee7d630a40f399b;hp=006d9006369c280182a7e56c461d0ae944466351;hpb=ed3ff1acb47570ae00a34eb115c59c298cf2d66a;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c b/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c index 006d900636..9e8315eb97 100644 --- a/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c +++ b/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c @@ -59,20 +59,6 @@ FindFreeMem ( UINTN DataSize ); -/** - Check the integrity of the capsule descriptors. - - @param BlockList Pointer to the capsule descriptors - - @retval NULL BlockList is not valid. - @retval LastBlockDesc Last one Block in BlockList - -**/ -EFI_CAPSULE_BLOCK_DESCRIPTOR * -ValidateCapsuleIntegrity ( - IN EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockList - ); - /** The capsule block descriptors may be fragmented and spread all over memory. To simplify the coalescing of capsule blocks, first coalesce all the @@ -247,10 +233,69 @@ FindFreeMem ( return MemBase; } +/** + Validate capsule by MemoryResource. + + @param MemoryResource Pointer to the buffer of memory resource descriptor. + @param Address Address to be validated. + @param Size Size to be validated. + + @retval TRUE No memory resource descriptor reported in HOB list before capsule Coalesce, + or it is valid in one MemoryResource. + FALSE It is not in any MemoryResource. + +**/ +BOOLEAN +ValidateCapsuleByMemoryResource ( + IN MEMORY_RESOURCE_DESCRIPTOR *MemoryResource, + IN EFI_PHYSICAL_ADDRESS Address, + IN UINT64 Size + ) +{ + UINTN Index; + + // + // Sanity Check + // + if (Size > MAX_ADDRESS) { + DEBUG ((EFI_D_ERROR, "ERROR: Size(0x%lx) > MAX_ADDRESS\n", Size)); + return FALSE; + } + + // + // Sanity Check + // + if (Address > (MAX_ADDRESS - Size)) { + DEBUG ((EFI_D_ERROR, "ERROR: Address(0x%lx) > (MAX_ADDRESS - Size(0x%lx))\n", Address, Size)); + return FALSE; + } + + if (MemoryResource == NULL) { + // + // No memory resource descriptor reported in HOB list before capsule Coalesce. + // + return TRUE; + } + + for (Index = 0; MemoryResource[Index].ResourceLength != 0; Index++) { + if ((Address >= MemoryResource[Index].PhysicalStart) && + ((Address + Size) <= (MemoryResource[Index].PhysicalStart + MemoryResource[Index].ResourceLength))) { + DEBUG ((EFI_D_INFO, "Address(0x%lx) Size(0x%lx) in MemoryResource[0x%x] - Start(0x%lx) Length(0x%lx)\n", + Address, Size, + Index, MemoryResource[Index].PhysicalStart, MemoryResource[Index].ResourceLength)); + return TRUE; + } + } + + DEBUG ((EFI_D_ERROR, "ERROR: Address(0x%lx) Size(0x%lx) not in any MemoryResource\n", Address, Size)); + return FALSE; +} + /** Check the integrity of the capsule descriptors. - @param BlockList Pointer to the capsule descriptors + @param BlockList Pointer to the capsule descriptors + @param MemoryResource Pointer to the buffer of memory resource descriptor. @retval NULL BlockList is not valid. @retval LastBlockDesc Last one Block in BlockList @@ -258,7 +303,8 @@ FindFreeMem ( **/ EFI_CAPSULE_BLOCK_DESCRIPTOR * ValidateCapsuleIntegrity ( - IN EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockList + IN EFI_CAPSULE_BLOCK_DESCRIPTOR *BlockList, + IN MEMORY_RESOURCE_DESCRIPTOR *MemoryResource ) { EFI_CAPSULE_HEADER *CapsuleHeader; @@ -274,14 +320,19 @@ ValidateCapsuleIntegrity ( // * The first capsule header guid // * The first capsule header flag // * The first capsule header HeaderSize - // * Length > MAX_ADDRESS - // * ContinuationPointer > MAX_ADDRESS - // * DataBlock + Length > MAX_ADDRESS + // * Below check will be done in ValidateCapsuleByMemoryResource() + // Length > MAX_ADDRESS + // Ptr + sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR) > MAX_ADDRESS + // DataBlock + Length > MAX_ADDRESS // CapsuleSize = 0; CapsuleCount = 0; Ptr = BlockList; + if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) { + return NULL; + } + DEBUG ((EFI_D_INFO, "Ptr - 0x%x\n", Ptr)); DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length)); DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer)); @@ -293,36 +344,21 @@ ValidateCapsuleIntegrity ( DEBUG ((EFI_D_ERROR, "ERROR: BlockList address failed alignment check\n")); return NULL; } - // - // Sanity Check - // - if (Ptr->Length > MAX_ADDRESS) { - DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Length(0x%lx) > MAX_ADDRESS\n", Ptr->Length)); - return NULL; - } if (Ptr->Length == 0) { - // - // Sanity Check - // - if (Ptr->Union.ContinuationPointer > MAX_ADDRESS) { - DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Union.ContinuationPointer(0x%lx) > MAX_ADDRESS\n", Ptr->Union.ContinuationPointer)); - return NULL; - } // // Descriptor points to another list of block descriptors somewhere // else. // Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *) (UINTN) Ptr->Union.ContinuationPointer; + if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) { + return NULL; + } DEBUG ((EFI_D_INFO, "Ptr(C) - 0x%x\n", Ptr)); DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length)); DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer)); } else { - // - // Sanity Check - // - if (Ptr->Union.DataBlock > (MAX_ADDRESS - (UINTN)Ptr->Length)) { - DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Union.DataBlock(0x%lx) > (MAX_ADDRESS - (UINTN)Ptr->Length(0x%lx))\n", Ptr->Union.DataBlock, Ptr->Length)); + if (!ValidateCapsuleByMemoryResource (MemoryResource, Ptr->Union.DataBlock, Ptr->Length)) { return NULL; } @@ -370,6 +406,9 @@ ValidateCapsuleIntegrity ( // Move to next BLOCK descriptor // Ptr++; + if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) { + return NULL; + } DEBUG ((EFI_D_INFO, "Ptr(B) - 0x%x\n", Ptr)); DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length)); DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer)); @@ -816,6 +855,7 @@ CapsuleTestPatternPreCoalesce ( Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2... @param BlockListBuffer Pointer to the buffer of capsule descriptors variables + @param MemoryResource Pointer to the buffer of memory resource descriptor. @param BlockDescriptorList Pointer to the capsule descriptors list @retval EFI_SUCCESS a valid capsule is present @@ -824,6 +864,7 @@ CapsuleTestPatternPreCoalesce ( EFI_STATUS BuildCapsuleDescriptors ( IN EFI_PHYSICAL_ADDRESS *BlockListBuffer, + IN MEMORY_RESOURCE_DESCRIPTOR *MemoryResource, OUT EFI_CAPSULE_BLOCK_DESCRIPTOR **BlockDescriptorList ) { @@ -844,7 +885,7 @@ BuildCapsuleDescriptors ( // Test integrity of descriptors. // if (BlockListBuffer[Index] < MAX_ADDRESS) { - TempBlock = ValidateCapsuleIntegrity ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index]); + TempBlock = ValidateCapsuleIntegrity ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index], MemoryResource); if (TempBlock != NULL) { if (LastBlock == NULL) { LastBlock = TempBlock; @@ -928,7 +969,8 @@ CapsuleImageBase-->+---------------------------+ coalesce capsule data into memory. @param PeiServices General purpose services available to every PEIM. - @param BlockListBuffer Point to the buffer of Capsule Descriptor Variables. + @param BlockListBuffer Pointer to the buffer of Capsule Descriptor Variables. + @param MemoryResource Pointer to the buffer of memory resource descriptor. @param MemoryBase Pointer to the base of a block of memory that we can walk all over while trying to coalesce our buffers. On output, this variable will hold the base address of @@ -950,6 +992,7 @@ 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 ) @@ -994,7 +1037,7 @@ CapsuleDataCoalesce ( // // Build capsule descriptors list // - Status = BuildCapsuleDescriptors (BlockListBuffer, &BlockList); + Status = BuildCapsuleDescriptors (BlockListBuffer, MemoryResource, &BlockList); if (EFI_ERROR (Status)) { return Status; }