mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 16:22:29 +00:00
[metal] Allow more fine-grained control over page permissions (#663)
- use PAGE_RSRV bit (originally only for blinkenlights), rather than PAGE_V bit, to indicate that a virtual address page has been reserved — this should allow a program to create & reserve inaccessible "guard pages" - mark page table entries for non-code pages with PAGE_XD bit, which should be supported on (circa) post-2004 x86-64 CPUs
This commit is contained in:
parent
0f89140882
commit
d38700687a
5 changed files with 25 additions and 14 deletions
|
@ -43,7 +43,7 @@ noasan struct DirectMap sys_mmap_metal(void *paddr, size_t size, int prot,
|
|||
addr = 4096;
|
||||
for (i = 0; i < size; i += 4096) {
|
||||
pte = __get_virtual(mm, pml4t, addr + i, false);
|
||||
if (pte && (*pte & PAGE_V)) {
|
||||
if (pte && (*pte & (PAGE_V | PAGE_RSRV))) {
|
||||
addr = MAX(addr, sys_mmap_metal_break) + i + 4096;
|
||||
i = 0;
|
||||
}
|
||||
|
@ -55,7 +55,13 @@ noasan struct DirectMap sys_mmap_metal(void *paddr, size_t size, int prot,
|
|||
pte = __get_virtual(mm, pml4t, addr + i, true);
|
||||
if (pte && page) {
|
||||
__clear_page(BANE + page);
|
||||
*pte = page | ((prot & PROT_WRITE) ? PAGE_RW : 0) | PAGE_U | PAGE_V;
|
||||
page |= PAGE_RSRV | PAGE_U;
|
||||
if ((prot & PROT_WRITE))
|
||||
page |= PAGE_V | PAGE_RW;
|
||||
else if ((prot & (PROT_READ | PROT_EXEC)))
|
||||
page |= PAGE_V;
|
||||
if (!(prot & PROT_EXEC)) page |= PAGE_XD;
|
||||
*pte = page;
|
||||
} else {
|
||||
addr = -1;
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue