MdeModulePkg/EbcDxe: use EfiBootServicesCode memory for thunks

The EBC driver emits thunks for native to EBC calls, which are short
instructions sequences that bridge the gap between the native execution
environment and the EBC virtual machine.

Since these thunks are allocated using MemoryAllocationLib::AllocatePool(),
they are emitted into EfiBootServicesData regions, which does not reflect
the nature of these thunks accurately, and interferes with strict memory
protection policies that map data regions non-executable.

So instead, create a new helper EbcAllocatePoolForThunk() that invokes the
AllocatePool() boot service directly to allocate EfiBootServicesCode pool
memory explicitly, and wire up this helper for the various architecture
specific thunk generation routines.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Ard Biesheuvel 2017-02-26 16:45:24 +00:00
parent a0ffd7a9ee
commit 16dc5b68fc
6 changed files with 41 additions and 4 deletions

View File

@ -383,7 +383,7 @@ EbcCreateThunks (
return EFI_INVALID_PARAMETER;
}
InstructionBuffer = AllocatePool (sizeof (EBC_INSTRUCTION_BUFFER));
InstructionBuffer = EbcAllocatePoolForThunk (sizeof (EBC_INSTRUCTION_BUFFER));
if (InstructionBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}

View File

@ -1410,3 +1410,26 @@ EbcVmTestUnsupported (
return EFI_UNSUPPORTED;
}
/**
Allocates a buffer of type EfiBootServicesCode.
@param AllocationSize The number of bytes to allocate.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
EFIAPI
EbcAllocatePoolForThunk (
IN UINTN AllocationSize
)
{
VOID *Buffer;
EFI_STATUS Status;
Status = gBS->AllocatePool (EfiBootServicesCode, AllocationSize, &Buffer);
if (EFI_ERROR (Status)) {
return NULL;
}
return Buffer;
}

View File

@ -246,4 +246,18 @@ typedef struct {
CR(a, EBC_PROTOCOL_PRIVATE_DATA, EbcProtocol, EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE)
/**
Allocates a buffer of type EfiBootServicesCode.
@param AllocationSize The number of bytes to allocate.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
EFIAPI
EbcAllocatePoolForThunk (
IN UINTN AllocationSize
);
#endif // #ifndef _EBC_INT_H_

View File

@ -484,7 +484,7 @@ EbcCreateThunks (
ThunkSize = sizeof(mInstructionBufferTemplate);
Ptr = AllocatePool (sizeof(mInstructionBufferTemplate));
Ptr = EbcAllocatePoolForThunk (sizeof(mInstructionBufferTemplate));
if (Ptr == NULL) {
return EFI_OUT_OF_RESOURCES;

View File

@ -403,7 +403,7 @@ EbcCreateThunks (
//
Size = EBC_THUNK_SIZE + EBC_THUNK_ALIGNMENT - 1;
ThunkSize = Size;
Ptr = AllocatePool (Size);
Ptr = EbcAllocatePoolForThunk (Size);
if (Ptr == NULL) {
return EFI_OUT_OF_RESOURCES;

View File

@ -441,7 +441,7 @@ EbcCreateThunks (
ThunkSize = sizeof(mInstructionBufferTemplate);
Ptr = AllocatePool (sizeof(mInstructionBufferTemplate));
Ptr = EbcAllocatePoolForThunk (sizeof(mInstructionBufferTemplate));
if (Ptr == NULL) {
return EFI_OUT_OF_RESOURCES;