Skip to content

Commit

Permalink
StandaloneMmPkg/StandaloneMmCoreEntryPoint: relocate StMM core on the…
Browse files Browse the repository at this point in the history
… fly

Apply PE/COFF fixups when starting up the standalone MM core, so that
it can execute at any address regardless of the link time address.

Note that this requires the PE/COFF image to be emitted with its
relocation section preserved. Special care is taken to ensure that
TE images are dealt with correctly as well.

Signed-off-by: Ard Biesheuvel <[email protected]>
Acked-by: Jiewen Yao <[email protected]>
Reviewed-by: Sami Mujawar <[email protected]>
Tested-by: Ilias Apalodimas <[email protected]>
  • Loading branch information
Ard Biesheuvel authored and mergify[bot] committed Jun 16, 2020
1 parent cdc6862 commit 493f2c6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (
and make further progress in the boot process.
@param ImageContext Pointer to PE/COFF image context
@param ImageBase Base of image in memory
@param SectionHeaderOffset Offset of PE/COFF image section header
@param NumberOfSections Number of Sections
@param TextUpdater Function to change code permissions
Expand All @@ -82,6 +83,7 @@ EFI_STATUS
EFIAPI
UpdateMmFoundationPeCoffPermissions (
IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_PHYSICAL_ADDRESS ImageBase,
IN UINT32 SectionHeaderOffset,
IN CONST UINT16 NumberOfSections,
IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,
Expand All @@ -98,6 +100,7 @@ UpdateMmFoundationPeCoffPermissions (
@param TeData Pointer to PE/COFF image data
@param ImageContext Pointer to PE/COFF image context
@param ImageBase Pointer to ImageBase variable
@param SectionHeaderOffset Offset of PE/COFF image section header
@param NumberOfSections Number of Sections
Expand All @@ -107,6 +110,7 @@ EFIAPI
GetStandaloneMmCorePeCoffSections (
IN VOID *TeData,
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
OUT EFI_PHYSICAL_ADDRESS *ImageBase,
IN OUT UINT32 *SectionHeaderOffset,
IN OUT UINT16 *NumberOfSections
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ EFI_STATUS
EFIAPI
UpdateMmFoundationPeCoffPermissions (
IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_PHYSICAL_ADDRESS ImageBase,
IN UINT32 SectionHeaderOffset,
IN CONST UINT16 NumberOfSections,
IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,
Expand Down Expand Up @@ -87,7 +88,7 @@ UpdateMmFoundationPeCoffPermissions (
// if it is a writeable section then mark it appropriately as well.
//
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) {
Base = ImageContext->ImageAddress + SectionHeader.VirtualAddress;
Base = ImageBase + SectionHeader.VirtualAddress;

TextUpdater (Base, SectionHeader.Misc.VirtualSize);

Expand Down Expand Up @@ -153,6 +154,7 @@ STATIC
EFI_STATUS
GetPeCoffSectionInformation (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
OUT EFI_PHYSICAL_ADDRESS *ImageBase,
OUT UINT32 *SectionHeaderOffset,
OUT UINT16 *NumberOfSections
)
Expand Down Expand Up @@ -212,6 +214,7 @@ GetPeCoffSectionInformation (
return Status;
}

*ImageBase = ImageContext->ImageAddress;
if (!ImageContext->IsTeImage) {
ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);

Expand All @@ -232,7 +235,7 @@ GetPeCoffSectionInformation (
} else {
*SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));
*NumberOfSections = Hdr.Te->NumberOfSections;
ImageContext->ImageAddress -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
*ImageBase -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
}
return RETURN_SUCCESS;
}
Expand All @@ -242,6 +245,7 @@ EFIAPI
GetStandaloneMmCorePeCoffSections (
IN VOID *TeData,
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
OUT EFI_PHYSICAL_ADDRESS *ImageBase,
IN OUT UINT32 *SectionHeaderOffset,
IN OUT UINT16 *NumberOfSections
)
Expand All @@ -255,7 +259,8 @@ GetStandaloneMmCorePeCoffSections (

DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));

Status = GetPeCoffSectionInformation (ImageContext, SectionHeaderOffset, NumberOfSections);
Status = GetPeCoffSectionInformation (ImageContext, ImageBase,
SectionHeaderOffset, NumberOfSections);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));
return Status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ _ModuleEntryPoint (
VOID *HobStart;
VOID *TeData;
UINTN TeDataSize;
EFI_PHYSICAL_ADDRESS ImageBase;

// Get Secure Partition Manager Version Information
Status = GetSpmVersion ();
Expand Down Expand Up @@ -253,6 +254,7 @@ _ModuleEntryPoint (
Status = GetStandaloneMmCorePeCoffSections (
TeData,
&ImageContext,
&ImageBase,
&SectionHeaderOffset,
&NumberOfSections
);
Expand All @@ -261,10 +263,21 @@ _ModuleEntryPoint (
goto finish;
}

//
// ImageBase may deviate from ImageContext.ImageAddress if we are dealing
// with a TE image, in which case the latter points to the actual offset
// of the image, whereas ImageBase refers to the address where the image
// would start if the stripped PE headers were still in place. In either
// case, we need to fix up ImageBase so it refers to the actual current
// load address.
//
ImageBase += (UINTN)TeData - ImageContext.ImageAddress;

// Update the memory access permissions of individual sections in the
// Standalone MM core module
Status = UpdateMmFoundationPeCoffPermissions (
&ImageContext,
ImageBase,
SectionHeaderOffset,
NumberOfSections,
ArmSetMemoryRegionNoExec,
Expand All @@ -276,6 +289,15 @@ _ModuleEntryPoint (
goto finish;
}

if (ImageContext.ImageAddress != (UINTN)TeData) {
ImageContext.ImageAddress = (UINTN)TeData;
ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);
ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);

Status = PeCoffLoaderRelocateImage (&ImageContext);
ASSERT_EFI_ERROR (Status);
}

//
// Create Hoblist based upon boot information passed by privileged software
//
Expand Down

0 comments on commit 493f2c6

Please sign in to comment.