From: Eric Dong Date: Tue, 25 Mar 2014 05:04:21 +0000 (+0000) Subject: Support load 64 bit image from 32 bit core. X-Git-Tag: edk2-stable201903~11591 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=a8d8d430510db36bc421dd0cb9f9d6d45f5907ac 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 Reviewed-by: Jiewen, Yao Reviewed-by: Liming, Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15387 6f19259b-4bc3-4df7-8a09-765794883524 --- 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.