kernel/arm: set PXN for user memory

* set PXN for all page tables below KERNEL_BASE
* also set PXN for physical page mapper

PXN, Privileged execute-never

When the PXN bit is 1, a Permission fault is generated if the processor
is executing at PL1 and attempts to execute an instruction fetched from
the corresponding memory region.

Change-Id: I3056cbed151004ac9edfbc81ebeada328aeb603c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5607
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
David Karoly 2022-09-01 22:49:48 +02:00 committed by waddlesplash
parent c0a7601219
commit 3d79cd3332
3 changed files with 7 additions and 8 deletions

View File

@ -38,6 +38,7 @@
// 31 10 9 8 5 432 10
// | page table address |0| domain |000|01|
#define ARM_MMU_L1_FLAG_PXN 0x00000004
// the domain is not used so and the ? is implementation specified... have not
// found it in the cortex A8 reference... so I set t to 0

View File

@ -240,8 +240,7 @@ ARMPagingMethod32Bit::PhysicalPageSlotPool::AllocatePool(
int32 index = VADDR_TO_PDENT((addr_t)virtualBase);
page_directory_entry* entry
= &map->PagingStructures32Bit()->pgdir_virt[index];
PutPageTableInPageDir(entry, physicalTable,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
PutPageTableInPageDir(entry, physicalTable, ARM_MMU_L1_FLAG_PXN);
ARMPagingStructures32Bit::UpdateAllPageDirs(index, *entry);
// init the pool structure
@ -400,7 +399,8 @@ ARMPagingMethod32Bit::MapEarly(kernel_args* args, addr_t virtualAddress,
// put it in the pgdir
e = &fKernelVirtualPageDirectory[index];
PutPageTableInPageDir(e, pgtable_phys, attributes);
PutPageTableInPageDir(e, pgtable_phys,
(virtualAddress < KERNEL_BASE) ? ARM_MMU_L1_FLAG_PXN : 0);
}
phys_addr_t ptEntryPhys = fKernelVirtualPageDirectory[index] & ARM_PDE_ADDRESS_MASK;
@ -494,7 +494,7 @@ ARMPagingMethod32Bit::PutPageTableInPageDir(page_directory_entry* entry,
{
dsb();
*entry = (pgtablePhysical & ARM_PDE_ADDRESS_MASK) | ARM_MMU_L1_TYPE_COARSE;
*entry = (pgtablePhysical & ARM_PDE_ADDRESS_MASK) | ARM_MMU_L1_TYPE_COARSE | attributes;
dsb();
isb();
@ -549,7 +549,7 @@ ARMPagingMethod32Bit::_EarlyPreparePageTables(page_table_entry* pageTables,
page_directory_entry* entry = method->KernelVirtualPageDirectory()
+ VADDR_TO_PDENT(address) + i;
PutPageTableInPageDir(entry, physicalTable,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
(address < KERNEL_BASE) ? ARM_MMU_L1_FLAG_PXN : 0);
}
}
}

View File

@ -187,9 +187,7 @@ ARMVMTranslationMap32Bit::Map(addr_t va, phys_addr_t pa, uint32 attributes,
// put it in the pgdir
ARMPagingMethod32Bit::PutPageTableInPageDir(&pd[index], pgtable,
attributes
| ((attributes & B_USER_PROTECTION) != 0
? B_WRITE_AREA : B_KERNEL_WRITE_AREA));
(va < KERNEL_BASE) ? ARM_MMU_L1_FLAG_PXN : 0);
// update any other page directories, if it maps kernel space
if (index >= FIRST_KERNEL_PGDIR_ENT