[edk2] [PATCH v4 3/7] MdeModulePkg/EbcDxe: use EfiBootServicesCode memory for thunks

Ard Biesheuvel posted 7 patches 7 years, 8 months ago
[edk2] [PATCH v4 3/7] MdeModulePkg/EbcDxe: use EfiBootServicesCode memory for thunks
Posted by Ard Biesheuvel 7 years, 8 months ago
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 services 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>
---
 MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c |  2 +-
 MdeModulePkg/Universal/EbcDxe/EbcInt.c             | 23 ++++++++++++++++++++
 MdeModulePkg/Universal/EbcDxe/EbcInt.h             | 14 ++++++++++++
 MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c    |  2 +-
 MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c     |  2 +-
 MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c     |  2 +-
 6 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c
index ade47c4d0622..7c13ce12a38b 100644
--- a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c
+++ b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c
@@ -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;
   }
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.c b/MdeModulePkg/Universal/EbcDxe/EbcInt.c
index 6fd2aaf5af27..727ba8bcae44 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c
+++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c
@@ -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;
+}
diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.h b/MdeModulePkg/Universal/EbcDxe/EbcInt.h
index 75017a23e75e..8aa7a4abbd63 100644
--- a/MdeModulePkg/Universal/EbcDxe/EbcInt.h
+++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.h
@@ -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_
diff --git a/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c
index 8e660b93ad64..a825846f89c3 100644
--- a/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c
+++ b/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c
@@ -484,7 +484,7 @@ EbcCreateThunks (
 
   ThunkSize = sizeof(mInstructionBufferTemplate);
 
-  Ptr = AllocatePool (sizeof(mInstructionBufferTemplate));
+  Ptr = EbcAllocatePoolForThunk (sizeof(mInstructionBufferTemplate));
 
   if (Ptr == NULL) {
     return EFI_OUT_OF_RESOURCES;
diff --git a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c
index 95837cb67865..f99348f181a9 100644
--- a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c
+++ b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c
@@ -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;
diff --git a/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c
index 4325e2e52710..33a174917b69 100644
--- a/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c
+++ b/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c
@@ -441,7 +441,7 @@ EbcCreateThunks (
 
   ThunkSize = sizeof(mInstructionBufferTemplate);
 
-  Ptr = AllocatePool (sizeof(mInstructionBufferTemplate));
+  Ptr = EbcAllocatePoolForThunk (sizeof(mInstructionBufferTemplate));
 
   if (Ptr == NULL) {
     return EFI_OUT_OF_RESOURCES;
-- 
2.7.4

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel