EFI_SECTION_TYPE SectionType;\r
UINT32 AuthenticationStatus;\r
VOID *Buffer;\r
+ VOID *AlignedBuffer;\r
UINTN BufferSize;\r
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
+ UINT32 FvAlignment; \r
\r
//\r
// Read the first (and only the first) firmware volume section\r
//\r
SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;\r
+ FvHeader = NULL;\r
+ FvAlignment = 0;\r
Buffer = NULL;\r
BufferSize = 0;\r
+ AlignedBuffer = NULL;\r
Status = Fv->ReadSection (\r
Fv, \r
DriverName, \r
);\r
if (!EFI_ERROR (Status)) {\r
//\r
- // Produce a FVB protocol for the file\r
+ // FvImage should be at its required alignment.\r
//\r
- Status = ProduceFVBProtocolOnBuffer (\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,\r
- (UINT64)BufferSize,\r
- FvHandle,\r
- NULL\r
- );\r
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;\r
+ FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+ //\r
+ // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
+ // \r
+ if (FvAlignment < 8) {\r
+ FvAlignment = 8;\r
+ }\r
+ \r
+ AlignedBuffer = AllocateAlignedPool ((UINTN) BufferSize, (UINTN) FvAlignment);\r
+ if (AlignedBuffer == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ //\r
+ // Move FvImage into the aligned buffer and release the original buffer.\r
+ //\r
+ CopyMem (AlignedBuffer, Buffer, BufferSize);\r
+ CoreFreePool (Buffer);\r
+ Buffer = NULL;\r
+ //\r
+ // Produce a FVB protocol for the file\r
+ //\r
+ Status = ProduceFVBProtocolOnBuffer (\r
+ (EFI_PHYSICAL_ADDRESS) (UINTN) AlignedBuffer,\r
+ (UINT64)BufferSize,\r
+ FvHandle,\r
+ NULL\r
+ );\r
+ }\r
}\r
\r
- if (EFI_ERROR (Status) && (Buffer != NULL)) { \r
- //\r
- // ReadSection or Produce FVB failed, Free data buffer\r
- //\r
- CoreFreePool (Buffer); \r
-\r
+ if (EFI_ERROR (Status)) { \r
+ //\r
+ // ReadSection or Produce FVB failed, Free data buffer\r
+ //\r
+ if (Buffer != NULL) {\r
+ CoreFreePool (Buffer); \r
+ }\r
+ \r
+ if (AlignedBuffer != NULL) {\r
+ FreeAlignedPool (AlignedBuffer);\r
+ }\r
}\r
\r
return Status;\r
UINTN BlockIndex;\r
UINTN BlockIndex2;\r
UINTN LinearOffset;\r
+ UINT32 FvAlignment;\r
EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;\r
-\r
+ \r
+ FvAlignment = 0;\r
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;\r
//\r
// Validate FV Header, if not as expected, return\r
return EFI_VOLUME_CORRUPTED;\r
}\r
//\r
+ // Get FvHeader alignment\r
+ //\r
+ FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+ if (FvAlignment < 8) {\r
+ FvAlignment = 8;\r
+ }\r
+ if ((UINTN)BaseAddress % FvAlignment != 0) {\r
+ //\r
+ // FvImage buffer is not at its required alignment.\r
+ //\r
+ return EFI_VOLUME_CORRUPTED;\r
+ }\r
+ //\r
// Allocate EFI_FW_VOL_BLOCK_DEVICE \r
//\r
FvbDev = CoreAllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);\r