mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-21 12:44:50 +02:00
Support load 64 bit image from 32 bit core.
Add more enhancement to check invalid PE format. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Jiewen, Yao <jiewen.yao@intel.com> Reviewed-by: Liming, Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15387 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
5070befc3b
commit
a8d8d43051
@ -941,6 +941,7 @@ PeCoffLoaderRelocateImage (
|
|||||||
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
||||||
EFI_IMAGE_DATA_DIRECTORY *RelocDir;
|
EFI_IMAGE_DATA_DIRECTORY *RelocDir;
|
||||||
UINT64 Adjust;
|
UINT64 Adjust;
|
||||||
|
EFI_IMAGE_BASE_RELOCATION *RelocBaseOrg;
|
||||||
EFI_IMAGE_BASE_RELOCATION *RelocBase;
|
EFI_IMAGE_BASE_RELOCATION *RelocBase;
|
||||||
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
|
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
|
||||||
UINT16 *Reloc;
|
UINT16 *Reloc;
|
||||||
@ -1041,7 +1042,8 @@ PeCoffLoaderRelocateImage (
|
|||||||
RelocDir->VirtualAddress + RelocDir->Size - 1,
|
RelocDir->VirtualAddress + RelocDir->Size - 1,
|
||||||
TeStrippedOffset
|
TeStrippedOffset
|
||||||
);
|
);
|
||||||
if (RelocBase == NULL || RelocBaseEnd == NULL) {
|
if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
|
||||||
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
return RETURN_LOAD_ERROR;
|
return RETURN_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1050,6 +1052,7 @@ PeCoffLoaderRelocateImage (
|
|||||||
//
|
//
|
||||||
RelocBase = RelocBaseEnd = NULL;
|
RelocBase = RelocBaseEnd = NULL;
|
||||||
}
|
}
|
||||||
|
RelocBaseOrg = RelocBase;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If Adjust is not zero, then apply fix ups to the image
|
// If Adjust is not zero, then apply fix ups to the image
|
||||||
@ -1065,14 +1068,23 @@ PeCoffLoaderRelocateImage (
|
|||||||
//
|
//
|
||||||
// Add check for RelocBase->SizeOfBlock field.
|
// Add check for RelocBase->SizeOfBlock field.
|
||||||
//
|
//
|
||||||
if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {
|
if (RelocBase->SizeOfBlock == 0) {
|
||||||
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
|
return RETURN_LOAD_ERROR;
|
||||||
|
}
|
||||||
|
if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) {
|
||||||
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
return RETURN_LOAD_ERROR;
|
return RETURN_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
|
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
|
||||||
|
if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) {
|
||||||
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
|
return RETURN_LOAD_ERROR;
|
||||||
|
}
|
||||||
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);
|
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);
|
||||||
if (FixupBase == NULL) {
|
if (FixupBase == NULL) {
|
||||||
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
return RETURN_LOAD_ERROR;
|
return RETURN_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1080,8 +1092,11 @@ PeCoffLoaderRelocateImage (
|
|||||||
// Run this relocation record
|
// Run this relocation record
|
||||||
//
|
//
|
||||||
while (Reloc < RelocEnd) {
|
while (Reloc < RelocEnd) {
|
||||||
|
Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);
|
||||||
Fixup = FixupBase + (*Reloc & 0xFFF);
|
if (Fixup == NULL) {
|
||||||
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
|
return RETURN_LOAD_ERROR;
|
||||||
|
}
|
||||||
switch ((*Reloc) >> 12) {
|
switch ((*Reloc) >> 12) {
|
||||||
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
||||||
break;
|
break;
|
||||||
@ -1148,6 +1163,7 @@ PeCoffLoaderRelocateImage (
|
|||||||
//
|
//
|
||||||
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
|
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
|
||||||
}
|
}
|
||||||
|
ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Adjust the EntryPoint to match the linked-to address
|
// Adjust the EntryPoint to match the linked-to address
|
||||||
@ -1444,14 +1460,17 @@ PeCoffLoaderLoadImage (
|
|||||||
DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.
|
||||||
|
//
|
||||||
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
||||||
ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
|
ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);
|
||||||
} else {
|
} else {
|
||||||
ImageContext->FixupDataSize = 0;
|
ImageContext->FixupDataSize = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DirectoryEntry = &Hdr.Te->DataDirectory[0];
|
DirectoryEntry = &Hdr.Te->DataDirectory[0];
|
||||||
ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
|
ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Consumer must allocate a buffer for the relocation fixup log.
|
// Consumer must allocate a buffer for the relocation fixup log.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user