]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
security: apply NX by default to all user mappings (C2)
authorTulio A M Mendes <[email protected]>
Tue, 26 May 2026 04:54:19 +0000 (01:54 -0300)
committerTulio A M Mendes <[email protected]>
Wed, 3 Jun 2026 05:52:15 +0000 (02:52 -0300)
src/arch/x86/ap_trampoline.S
src/drivers/vbe.c
src/kernel/shm.c
src/kernel/syscall.c

index 5cb0f4e7ce3fe9f3365a31b7c63b5ba3b8a2b589..990208cb6119555c1f151272231931d3b9310801 100644 (file)
@@ -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
index 93f2aec3af4dbd13f5c94f83b8d6e90ac89058dd..97dc2b94a4976319aeb82b7f476661cacdac166e 100644 (file)
@@ -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;
index 5365089897d32f3b9749f1370c0713332bb8bc11..42ccda5a86409d985a63e9855126d982217c312c 100644 (file)
@@ -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 */
index 51adc05d68417b0ed46da309ac376ef39cfcb84e..f6c51f6bab8bcdae63b1edb73d6ee6b422476901 100644 (file)
@@ -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;
         }