aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike McTernan <mikemcternan@google.com>2024-03-14 17:14:02 +0000
committerMike McTernan <mikemcternan@google.com>2024-03-25 20:47:20 +0000
commitdad07f8a151a0ce4ff026e51f55627f8f1ad00f8 (patch)
tree6c439524fc0246a8f4f22f3feac77e21f642a4b0
parent935889691ac6b52962bba7e1ec1a1ce35ee85a59 (diff)
downloadcommon-dad07f8a151a0ce4ff026e51f55627f8f1ad00f8.tar.gz
trusty:mmu: Make writable mappings non-executable
Bug: 328206729 Test: build.py qemu-generic-arm64-test-debug Change-Id: If3a73046f3b60454bc6edc78f1c2ed5befc30d2e
-rw-r--r--arch/arm64/mmu.c6
-rw-r--r--dev/interrupt/arm_gic/arm_gic.c3
-rw-r--r--dev/virtio/virtio.c4
-rw-r--r--kernel/vm/vmm.c3
4 files changed, 13 insertions, 3 deletions
diff --git a/arch/arm64/mmu.c b/arch/arm64/mmu.c
index 38b3ff67..160e1923 100644
--- a/arch/arm64/mmu.c
+++ b/arch/arm64/mmu.c
@@ -80,12 +80,18 @@ static bool mmu_flags_to_pte_attr(const uint aspace_flags, const uint flags, pte
DEBUG_ASSERT((aspace_flags & ~ARCH_ASPACE_FLAG_ALL) == 0);
+ /* Enforce that executable mappings are not also writable */
+ if ((flags & (ARCH_MMU_FLAG_PERM_RO | ARCH_MMU_FLAG_PERM_NO_EXECUTE)) == 0) {
+ return false;
+ }
+
if (flags & ARCH_MMU_FLAG_TAGGED) {
if ((flags & ARCH_MMU_FLAG_CACHE_MASK) & ~ARCH_MMU_FLAG_CACHED) {
/* only normal memory can be tagged */
return false;
}
}
+
switch (flags & ARCH_MMU_FLAG_CACHE_MASK) {
case ARCH_MMU_FLAG_CACHED:
if (flags & ARCH_MMU_FLAG_TAGGED) {
diff --git a/dev/interrupt/arm_gic/arm_gic.c b/dev/interrupt/arm_gic/arm_gic.c
index 340fd6e1..7101a65c 100644
--- a/dev/interrupt/arm_gic/arm_gic.c
+++ b/dev/interrupt/arm_gic/arm_gic.c
@@ -353,7 +353,8 @@ static void arm_map_regs(const char* name,
}
ret = vmm_alloc_physical(vmm_get_kernel_aspace(), "gic", size, &vaddrp, 0,
- paddr, 0, ARCH_MMU_FLAG_UNCACHED_DEVICE);
+ paddr, 0, ARCH_MMU_FLAG_UNCACHED_DEVICE |
+ ARCH_MMU_FLAG_PERM_NO_EXECUTE);
if (ret) {
panic("%s: failed %d\n", __func__, ret);
}
diff --git a/dev/virtio/virtio.c b/dev/virtio/virtio.c
index 0a306a85..3ce0687b 100644
--- a/dev/virtio/virtio.c
+++ b/dev/virtio/virtio.c
@@ -343,7 +343,9 @@ status_t virtio_alloc_ring(struct virtio_device *dev, uint index, uint16_t len)
#if WITH_KERNEL_VM
void *vptr;
- status_t err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), "virtio_ring", size, &vptr, 0, 0, ARCH_MMU_FLAG_UNCACHED_DEVICE);
+ status_t err = vmm_alloc_contiguous(vmm_get_kernel_aspace(), "virtio_ring", size, &vptr,
+ 0, 0, ARCH_MMU_FLAG_UNCACHED_DEVICE |
+ ARCH_MMU_FLAG_PERM_NO_EXECUTE);
if (err < 0)
return ERR_NO_MEMORY;
diff --git a/kernel/vm/vmm.c b/kernel/vm/vmm.c
index 27821d8d..f6d99353 100644
--- a/kernel/vm/vmm.c
+++ b/kernel/vm/vmm.c
@@ -1715,7 +1715,8 @@ static int cmd_vmm(int argc, const cmd_args* argv) {
void* ptr = (void*)0x99;
status_t err = vmm_alloc_physical(test_aspace, "physical test",
argv[3].u, &ptr, argv[4].u, argv[2].u,
- 0, ARCH_MMU_FLAG_UNCACHED_DEVICE);
+ 0, ARCH_MMU_FLAG_UNCACHED_DEVICE |
+ ARCH_MMU_FLAG_PERM_NO_EXECUTE);
printf("vmm_alloc_physical returns %d, ptr %p\n", err, ptr);
} else if (!strcmp(argv[1].str, "alloc_contig")) {
if (argc < 4)