EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
UINT64 Adjust;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseOrg;\r
EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
UINT16 *Reloc;\r
RelocDir->VirtualAddress + RelocDir->Size - 1,\r
TeStrippedOffset\r
);\r
- if (RelocBase == NULL || RelocBaseEnd == NULL) {\r
+ if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
return RETURN_LOAD_ERROR;\r
}\r
} else {\r
//\r
RelocBase = RelocBaseEnd = NULL; \r
}\r
+ RelocBaseOrg = RelocBase;\r
\r
//\r
// If Adjust is not zero, then apply fix ups to the image\r
//\r
// Add check for RelocBase->SizeOfBlock field.\r
//\r
- if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {\r
+ if (RelocBase->SizeOfBlock == 0) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+ if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) {\r
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
return RETURN_LOAD_ERROR;\r
}\r
\r
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
+ if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);\r
if (FixupBase == NULL) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
return RETURN_LOAD_ERROR;\r
} \r
\r
// Run this relocation record\r
//\r
while (Reloc < RelocEnd) {\r
-\r
- Fixup = FixupBase + (*Reloc & 0xFFF);\r
+ Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);\r
+ if (Fixup == NULL) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
switch ((*Reloc) >> 12) {\r
case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
break;\r
//\r
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
}\r
+ ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);\r
\r
//\r
// Adjust the EntryPoint to match the linked-to address\r
DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
}\r
\r
+ //\r
+ // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.\r
+ //\r
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
- ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);\r
} else {\r
ImageContext->FixupDataSize = 0;\r
}\r
} else {\r
DirectoryEntry = &Hdr.Te->DataDirectory[0];\r
- ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);\r
}\r
//\r
// Consumer must allocate a buffer for the relocation fixup log.\r