diff options
author | Eric Dong <eric.dong@intel.com> | 2014-03-25 05:04:21 +0000 |
---|---|---|
committer | ydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524> | 2014-03-25 05:04:21 +0000 |
commit | a8d8d430510db36bc421dd0cb9f9d6d45f5907ac (patch) | |
tree | a805ad5900f58f78696de47c49a42f557c99702c /MdePkg/Library/BasePeCoffLib | |
parent | 5070befc3b9b013f36062c7cc08320c87c02f972 (diff) | |
download | edk2-a8d8d430510db36bc421dd0cb9f9d6d45f5907ac.tar.gz edk2-a8d8d430510db36bc421dd0cb9f9d6d45f5907ac.tar.bz2 edk2-a8d8d430510db36bc421dd0cb9f9d6d45f5907ac.zip |
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
Diffstat (limited to 'MdePkg/Library/BasePeCoffLib')
-rw-r--r-- | MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c index d9e8809e55..33cad23a01 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c @@ -941,6 +941,7 @@ PeCoffLoaderRelocateImage ( EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
EFI_IMAGE_DATA_DIRECTORY *RelocDir;
UINT64 Adjust;
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseOrg;
EFI_IMAGE_BASE_RELOCATION *RelocBase;
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
UINT16 *Reloc;
@@ -1041,7 +1042,8 @@ PeCoffLoaderRelocateImage ( RelocDir->VirtualAddress + RelocDir->Size - 1,
TeStrippedOffset
);
- if (RelocBase == NULL || RelocBaseEnd == NULL) {
+ if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
return RETURN_LOAD_ERROR;
}
} else {
@@ -1050,6 +1052,7 @@ PeCoffLoaderRelocateImage ( //
RelocBase = RelocBaseEnd = NULL;
}
+ RelocBaseOrg = RelocBase;
//
// If Adjust is not zero, then apply fix ups to the image
@@ -1065,14 +1068,23 @@ PeCoffLoaderRelocateImage ( //
// 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;
return RETURN_LOAD_ERROR;
}
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);
if (FixupBase == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
return RETURN_LOAD_ERROR;
}
@@ -1080,8 +1092,11 @@ PeCoffLoaderRelocateImage ( // Run this relocation record
//
while (Reloc < RelocEnd) {
-
- Fixup = FixupBase + (*Reloc & 0xFFF);
+ Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);
+ if (Fixup == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
switch ((*Reloc) >> 12) {
case EFI_IMAGE_REL_BASED_ABSOLUTE:
break;
@@ -1148,6 +1163,7 @@ PeCoffLoaderRelocateImage ( //
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
}
+ ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);
//
// 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];
}
+ //
+ // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.
+ //
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
- ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);
} else {
ImageContext->FixupDataSize = 0;
}
} else {
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.
|