ProcessCapsules(), ProcessTheseCapsules() will receive untrusted\r
input and do basic validation.\r
\r
- Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
IN UINT64 CapsuleSize\r
);\r
\r
+/**\r
+ Return if this capsule is a capsule name capsule, based upon CapsuleHeader.\r
+\r
+ @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER\r
+\r
+ @retval TRUE It is a capsule name capsule.\r
+ @retval FALSE It is not a capsule name capsule.\r
+**/\r
+BOOLEAN\r
+IsCapsuleNameCapsule (\r
+ IN EFI_CAPSULE_HEADER *CapsuleHeader\r
+ );\r
+\r
+/**\r
+ Check the integrity of the capsule name capsule.\r
+ If the capsule is vaild, return the physical address of each capsule name string.\r
+\r
+ @param[in] CapsuleHeader Pointer to the capsule header of a capsule name capsule.\r
+ @param[out] CapsuleNameNum Number of capsule name.\r
+\r
+ @retval NULL Capsule name capsule is not valid.\r
+ @retval CapsuleNameBuf Array of capsule name physical address.\r
+\r
+**/\r
+EFI_PHYSICAL_ADDRESS *\r
+ValidateCapsuleNameCapsuleIntegrity (\r
+ IN EFI_CAPSULE_HEADER *CapsuleHeader,\r
+ OUT UINTN *CapsuleNameNum\r
+ );\r
+\r
extern BOOLEAN mDxeCapsuleLibEndOfDxe;\r
BOOLEAN mNeedReset = FALSE;\r
\r
VOID **mCapsulePtr;\r
+CHAR16 **mCapsuleNamePtr;\r
EFI_STATUS *mCapsuleStatusArray;\r
UINT32 mCapsuleTotalNumber;\r
\r
EFIAPI\r
ProcessThisCapsuleImage (\r
IN EFI_CAPSULE_HEADER *CapsuleHeader,\r
+ IN CHAR16 *CapFileName, OPTIONAL\r
OUT BOOLEAN *ResetRequired OPTIONAL\r
);\r
\r
{\r
EFI_PEI_HOB_POINTERS HobPointer;\r
UINTN Index;\r
+ UINTN Index2;\r
+ UINTN Index3;\r
+ UINTN CapsuleNameNumber;\r
+ UINTN CapsuleNameTotalNumber;\r
+ UINTN CapsuleNameCapsuleTotalNumber;\r
+ VOID **CapsuleNameCapsulePtr;\r
+ EFI_PHYSICAL_ADDRESS *CapsuleNameAddress;\r
+\r
+ CapsuleNameNumber = 0;\r
+ CapsuleNameTotalNumber = 0;\r
+ CapsuleNameCapsuleTotalNumber = 0;\r
+ CapsuleNameCapsulePtr = NULL;\r
\r
//\r
// Find all capsule images from hob\r
if (!IsValidCapsuleHeader((VOID *)(UINTN)HobPointer.Capsule->BaseAddress, HobPointer.Capsule->Length)) {\r
HobPointer.Header->HobType = EFI_HOB_TYPE_UNUSED; // Mark this hob as invalid\r
} else {\r
- mCapsuleTotalNumber++;\r
+ if (IsCapsuleNameCapsule((VOID *)(UINTN)HobPointer.Capsule->BaseAddress)) {\r
+ CapsuleNameCapsuleTotalNumber++;\r
+ } else {\r
+ mCapsuleTotalNumber++;\r
+ }\r
}\r
HobPointer.Raw = GET_NEXT_HOB (HobPointer);\r
}\r
}\r
SetMemN (mCapsuleStatusArray, sizeof (EFI_STATUS) * mCapsuleTotalNumber, EFI_NOT_READY);\r
\r
+ CapsuleNameCapsulePtr = (VOID **) AllocateZeroPool (sizeof (VOID *) * CapsuleNameCapsuleTotalNumber);\r
+ if (CapsuleNameCapsulePtr == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "Allocate CapsuleNameCapsulePtr fail!\n"));\r
+ FreePool (mCapsulePtr);\r
+ FreePool (mCapsuleStatusArray);\r
+ mCapsulePtr = NULL;\r
+ mCapsuleStatusArray = NULL;\r
+ mCapsuleTotalNumber = 0;\r
+ return ;\r
+ }\r
+\r
//\r
// Find all capsule images from hob\r
//\r
HobPointer.Raw = GetHobList ();\r
- Index = 0;\r
+ Index = 0;\r
+ Index2 = 0;\r
while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) {\r
- mCapsulePtr [Index++] = (VOID *) (UINTN) HobPointer.Capsule->BaseAddress;\r
+ if (IsCapsuleNameCapsule ((VOID *) (UINTN) HobPointer.Capsule->BaseAddress)) {\r
+ CapsuleNameCapsulePtr [Index2++] = (VOID *) (UINTN) HobPointer.Capsule->BaseAddress;\r
+ } else {\r
+ mCapsulePtr [Index++] = (VOID *) (UINTN) HobPointer.Capsule->BaseAddress;\r
+ }\r
HobPointer.Raw = GET_NEXT_HOB (HobPointer);\r
}\r
+\r
+ //\r
+ // Find Capsule On Disk Names\r
+ //\r
+ for (Index = 0; Index < CapsuleNameCapsuleTotalNumber; Index ++) {\r
+ CapsuleNameAddress = ValidateCapsuleNameCapsuleIntegrity (CapsuleNameCapsulePtr[Index], &CapsuleNameNumber);\r
+ if (CapsuleNameAddress != NULL ) {\r
+ CapsuleNameTotalNumber += CapsuleNameNumber;\r
+ }\r
+ }\r
+\r
+ if (CapsuleNameTotalNumber == mCapsuleTotalNumber) {\r
+ mCapsuleNamePtr = (CHAR16 **) AllocateZeroPool (sizeof (CHAR16 *) * mCapsuleTotalNumber);\r
+ if (mCapsuleNamePtr == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "Allocate mCapsuleNamePtr fail!\n"));\r
+ FreePool (mCapsulePtr);\r
+ FreePool (mCapsuleStatusArray);\r
+ FreePool (CapsuleNameCapsulePtr);\r
+ mCapsulePtr = NULL;\r
+ mCapsuleStatusArray = NULL;\r
+ mCapsuleTotalNumber = 0;\r
+ return ;\r
+ }\r
+\r
+ for (Index = 0, Index3 = 0; Index < CapsuleNameCapsuleTotalNumber; Index ++) {\r
+ CapsuleNameAddress = ValidateCapsuleNameCapsuleIntegrity (CapsuleNameCapsulePtr[Index], &CapsuleNameNumber);\r
+ if (CapsuleNameAddress != NULL ) {\r
+ for (Index2 = 0; Index2 < CapsuleNameNumber; Index2 ++) {\r
+ mCapsuleNamePtr[Index3 ++] = (CHAR16 *)(UINTN) CapsuleNameAddress[Index2];\r
+ }\r
+ }\r
+ }\r
+ } else {\r
+ mCapsuleNamePtr = NULL;\r
+ }\r
+\r
+ FreePool (CapsuleNameCapsulePtr);\r
}\r
\r
/**\r
ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;\r
UINT16 EmbeddedDriverCount;\r
BOOLEAN ResetRequired;\r
+ CHAR16 *CapsuleName;\r
\r
REPORT_STATUS_CODE(EFI_PROGRESS_CODE, (EFI_SOFTWARE | PcdGet32(PcdStatusCodeSubClassCapsule) | PcdGet32(PcdCapsuleStatusCodeProcessCapsulesBegin)));\r
\r
// We didn't find a hob, so had no errors.\r
//\r
DEBUG ((DEBUG_ERROR, "We can not find capsule data in capsule update boot mode.\n"));\r
+ mNeedReset = TRUE;\r
return EFI_SUCCESS;\r
}\r
\r
//\r
for (Index = 0; Index < mCapsuleTotalNumber; Index++) {\r
CapsuleHeader = (EFI_CAPSULE_HEADER*) mCapsulePtr [Index];\r
+ CapsuleName = (mCapsuleNamePtr == NULL) ? NULL : mCapsuleNamePtr[Index];\r
if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {\r
DEBUG ((DEBUG_INFO, "ProcessThisCapsuleImage (Ux) - 0x%x\n", CapsuleHeader));\r
DEBUG ((DEBUG_INFO, "Display logo capsule is found.\n"));\r
- Status = ProcessThisCapsuleImage (CapsuleHeader, NULL);\r
+ Status = ProcessThisCapsuleImage (CapsuleHeader, CapsuleName, NULL);\r
mCapsuleStatusArray [Index] = EFI_SUCCESS;\r
DEBUG((DEBUG_INFO, "ProcessThisCapsuleImage (Ux) - %r\n", Status));\r
break;\r
continue;\r
}\r
CapsuleHeader = (EFI_CAPSULE_HEADER*) mCapsulePtr [Index];\r
+ CapsuleName = (mCapsuleNamePtr == NULL) ? NULL : mCapsuleNamePtr[Index];\r
if (!CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {\r
//\r
// Call capsule library to process capsule image.\r
if ((!FirstRound) || (EmbeddedDriverCount == 0)) {\r
DEBUG((DEBUG_INFO, "ProcessThisCapsuleImage - 0x%x\n", CapsuleHeader));\r
ResetRequired = FALSE;\r
- Status = ProcessThisCapsuleImage (CapsuleHeader, &ResetRequired);\r
+ Status = ProcessThisCapsuleImage (CapsuleHeader, CapsuleName, &ResetRequired);\r
mCapsuleStatusArray [Index] = Status;\r
DEBUG((DEBUG_INFO, "ProcessThisCapsuleImage - %r\n", Status));\r
\r
Caution: This function may receive untrusted input.\r
\r
The capsules reported in EFI_HOB_UEFI_CAPSULE are processed.\r
- If there is no EFI_HOB_UEFI_CAPSULE, this routine does nothing.\r
+ If there is no EFI_HOB_UEFI_CAPSULE, it means error occurs, force reset to\r
+ normal boot path.\r
\r
This routine should be called twice in BDS.\r
1) The first call must be before EndOfDxe. The system capsules is processed.\r