summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg
diff options
context:
space:
mode:
authorOliver Smith-Denny <osde@microsoft.com>2023-04-26 12:04:37 -0700
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-08-29 16:11:40 +0000
commit1169122c6f22d4db3e44b7b720480522b6933a62 (patch)
treedadafdb0029f2cc1adbc6c405dc4421895f2e63d /MdeModulePkg
parent01735bbe4a46a6fb7d5d739d0fc5a14897ad18da (diff)
downloadedk2-1169122c6f22d4db3e44b7b720480522b6933a62.tar.gz
edk2-1169122c6f22d4db3e44b7b720480522b6933a62.tar.bz2
edk2-1169122c6f22d4db3e44b7b720480522b6933a62.zip
MdeModulePkg NonDiscoverablePciDeviceIo: MMIO Memory XP By Default
When allocating memory for a non-discoverable PCI device's IO, the current core code removes the XP attribute, allowing code to execute from that region. This is a security vulnerability and unneeded. This change updates to mark the region as XP when allocating memory for the non-discoverable PCI device. These allocations in this function are limited to `EfiBootServicesData` and `EfiRuntimeServicesData`, which we expect to be XP. Signed-off-by: Aaron Pop <aaronpop@microsoft.com>
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c
index e31c38deed..4daf51761b 100644
--- a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c
+++ b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c
@@ -1111,6 +1111,8 @@ NonCoherentPciIoAllocateBuffer (
NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *Alloc;
VOID *AllocAddress;
+ MemType = EFI_MEMORY_XP;
+
if (HostAddress == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -1152,9 +1154,9 @@ NonCoherentPciIoAllocateBuffer (
// Use write combining if it was requested, or if it is the only
// type supported by the region.
//
- MemType = EFI_MEMORY_WC;
+ MemType |= EFI_MEMORY_WC;
} else {
- MemType = EFI_MEMORY_UC;
+ MemType |= EFI_MEMORY_UC;
}
Alloc = AllocatePool (sizeof *Alloc);
@@ -1172,6 +1174,34 @@ NonCoherentPciIoAllocateBuffer (
//
InsertHeadList (&Dev->UncachedAllocationList, &Alloc->List);
+ //
+ // Ensure that EFI_MEMORY_XP is in the capability set
+ //
+ if ((GcdDescriptor.Capabilities & EFI_MEMORY_XP) != EFI_MEMORY_XP) {
+ Status = gDS->SetMemorySpaceCapabilities (
+ (PHYSICAL_ADDRESS)(UINTN)AllocAddress,
+ EFI_PAGES_TO_SIZE (Pages),
+ GcdDescriptor.Capabilities | EFI_MEMORY_XP
+ );
+
+ // if we were to fail setting the capability, this would indicate an internal failure of the GCD code. We should
+ // assert here to let a platform know something went crazy, but for a release build we can let the allocation occur
+ // without the EFI_MEMORY_XP bit set, as that was the existing behavior
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a failed to set EFI_MEMORY_XP capability on 0x%llx for length 0x%llx. Attempting to allocate without XP set.\n",
+ __func__,
+ AllocAddress,
+ EFI_PAGES_TO_SIZE (Pages)
+ ));
+
+ ASSERT_EFI_ERROR (Status);
+
+ MemType &= ~EFI_MEMORY_XP;
+ }
+ }
+
Status = gDS->SetMemorySpaceAttributes (
(EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress,
EFI_PAGES_TO_SIZE (Pages),