From: Tulio A M Mendes Date: Tue, 26 May 2026 04:54:19 +0000 (-0300) Subject: security: apply NX by default to all user mappings (C2) X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=e7321d9837be65d8a21b436db6c11f69f9f85a0d;p=AdrOS.git security: apply NX by default to all user mappings (C2) --- diff --git a/src/arch/x86/ap_trampoline.S b/src/arch/x86/ap_trampoline.S index 5cb0f4e7..990208cb 100644 --- a/src/arch/x86/ap_trampoline.S +++ b/src/arch/x86/ap_trampoline.S @@ -70,6 +70,21 @@ ap_pm_entry: or $0x20, %eax /* CR4.PAE = bit 5 */ mov %eax, %cr4 + /* Enable NXE in IA32_EFER on this AP if the CPU supports NX. */ + mov $0x80000000, %eax + cpuid + cmp $0x80000001, %eax + jb 1f + mov $0x80000001, %eax + cpuid + bt $20, %edx + jnc 1f + mov $0xC0000080, %ecx + rdmsr + or $0x800, %eax + wrmsr +1: + /* Load CR3 (PDPT physical address) from data area */ mov (AP_DATA_BASE + 8), %eax mov %eax, %cr3 diff --git a/src/drivers/vbe.c b/src/drivers/vbe.c index 93f2aec3..97dc2b94 100644 --- a/src/drivers/vbe.c +++ b/src/drivers/vbe.c @@ -170,10 +170,28 @@ static int fb0_ioctl(fs_node_t* node, uint32_t cmd, void* arg) { return -1; } +/* Local PROT_* definitions for fb0_mmap */ +enum { + PROT_NONE = 0x0, + PROT_READ = 0x1, + PROT_WRITE = 0x2, + PROT_EXEC = 0x4, +}; + static uintptr_t fb0_mmap(fs_node_t* node, uintptr_t addr, uint32_t length, uint32_t prot, uint32_t offset) { - (void)node; (void)prot; (void)offset; + (void)node; (void)offset; if (!g_vbe_ready) return 0; + /* Respect prot argument - deny execution, apply NX by default */ + if (prot & PROT_EXEC) return 0; /* Framebuffer is not executable */ + + uint32_t vmm_flags = VMM_FLAG_PRESENT | VMM_FLAG_USER | VMM_FLAG_NOCACHE; + if (prot & PROT_WRITE) vmm_flags |= VMM_FLAG_RW; + else if (prot & PROT_READ) vmm_flags |= VMM_FLAG_RW; /* No RO flag in VMM, use RW for read */ + else vmm_flags |= VMM_FLAG_RW; /* Default to RW if no prot specified */ + /* NX by default */ + vmm_flags |= VMM_FLAG_NX; + uint32_t aligned_len = (length + 0xFFFU) & ~(uint32_t)0xFFFU; if (aligned_len > ((g_vbe.size + 0xFFFU) & ~(uint32_t)0xFFFU)) aligned_len = (g_vbe.size + 0xFFFU) & ~(uint32_t)0xFFFU; @@ -181,7 +199,7 @@ static uintptr_t fb0_mmap(fs_node_t* node, uintptr_t addr, uint32_t length, uint for (uint32_t i = 0; i < aligned_len; i += 0x1000U) { vmm_map_page((uint64_t)(g_vbe.phys_addr + i), (uint64_t)(addr + i), - VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER | VMM_FLAG_NOCACHE); + vmm_flags); } return addr; diff --git a/src/kernel/shm.c b/src/kernel/shm.c index 53650898..42ccda5a 100644 --- a/src/kernel/shm.c +++ b/src/kernel/shm.c @@ -188,11 +188,11 @@ void* shm_at(int shmid, uintptr_t shmaddr) { /* Map physical pages into user address space. * vmm_map_page signature: (phys, virt, flags) - * K24: NX flag deferred until IA32_EFER.NXE MSR is enabled (A01) */ + * NX by default - IA32_EFER.NXE MSR is now enabled (A01 completed) */ for (uint32_t i = 0; i < seg->npages; i++) { vmm_map_page((uint64_t)seg->pages[i], (uint64_t)(vaddr + i * PAGE_SIZE), - VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER); + VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER | VMM_FLAG_NX); } /* Record mapping in process mmap table with shmid for detach lookup */ diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 51adc05d..f6c51f6b 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -3112,6 +3112,8 @@ static uintptr_t syscall_mmap_impl(uintptr_t addr, uint32_t length, uint32_t pro /* Anonymous mmap: allocate fresh zeroed pages */ uint32_t vmm_flags = VMM_FLAG_PRESENT | VMM_FLAG_USER; if (prot & PROT_WRITE) vmm_flags |= VMM_FLAG_RW; + /* NX by default, remove only if PROT_EXEC is explicitly requested */ + if (!(prot & PROT_EXEC)) vmm_flags |= VMM_FLAG_NX; uintptr_t mapped_va[1024]; int mapped_count = 0; @@ -3209,7 +3211,7 @@ static uintptr_t syscall_brk_impl(uintptr_t addr) { } vmm_as_map_page(current_process->addr_space, (uint64_t)(uintptr_t)frame, (uint64_t)va, - VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER); + VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER | VMM_FLAG_NX); memset((void*)va, 0, 0x1000U); if (mapped_count < 1024) mapped_va[mapped_count++] = va; }