summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2018-04-06 19:09:06 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2018-04-06 19:09:06 +0000
commit68744a33e1b6bcd838736f8b858ee47e60a12bfa (patch)
treec411ed29a319aa6dcb3b2c27ab7c7357c35bc279 /sys/arch
parent5ae64a7e9b370cdb4d071f05e2ebbe01402ecd28 (diff)
Sadly some UEFI frimware writes to mappings marked as runtime code so we can't
enforce W^X for runtime services. Do respect the bits that indicate that mappings can be non-readable, non-executable or read-only though. ok patrick@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/arm64/dev/efi.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/arch/arm64/dev/efi.c b/sys/arch/arm64/dev/efi.c
index 9a84863046f..cecaecf03d1 100644
--- a/sys/arch/arm64/dev/efi.c
+++ b/sys/arch/arm64/dev/efi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efi.c,v 1.3 2018/01/12 14:52:55 kettenis Exp $ */
+/* $OpenBSD: efi.c,v 1.4 2018/04/06 19:09:05 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
@@ -125,7 +125,7 @@ efi_attach(struct device *parent, struct device *self, void *aux)
vaddr_t va = desc->VirtualStart;
paddr_t pa = desc->PhysicalStart;
int npages = desc->NumberOfPages;
- vm_prot_t prot = PROT_READ;
+ vm_prot_t prot = PROT_READ | PROT_WRITE;
#ifdef EFI_DEBUG
printf("type 0x%x pa 0x%llx va 0x%llx pages 0x%llx attr 0x%llx\n",
@@ -142,10 +142,20 @@ efi_attach(struct device *parent, struct device *self, void *aux)
if ((desc->Attribute & EFI_MEMORY_WB) == 0)
pa |= PMAP_DEVICE;
+ /*
+ * Only make pages marked as runtime service code
+ * executable. This violates the standard but it
+ * seems we can get away with it.
+ */
if (desc->Type == EfiRuntimeServicesCode)
prot |= PROT_EXEC;
- else
- prot |= PROT_WRITE;
+
+ if (desc->Attribute & EFI_MEMORY_RP)
+ prot &= ~PROT_READ;
+ if (desc->Attribute & EFI_MEMORY_XP)
+ prot &= ~PROT_EXEC;
+ if (desc->Attribute & EFI_MEMORY_RO)
+ prot &= ~PROT_WRITE;
while (npages--) {
pmap_enter(sc->sc_pm, va, pa, prot,