]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
security: remove hardcoded fixed VAs, use hal_mm_kernel_virt_base() (Fase 2)
authorTulio A M Mendes <[email protected]>
Tue, 26 May 2026 05:13:17 +0000 (02:13 -0300)
committerTulio A M Mendes <[email protected]>
Wed, 3 Jun 2026 05:52:27 +0000 (02:52 -0300)
include/hal/mm.h
src/arch/x86/sysenter.S
src/kernel/syscall.c

index ff14f79e2005cbef0fb41f8556000625b350b02a..52133ea943cff5ec5600c1be1aeab13d694992b4 100644 (file)
@@ -14,6 +14,9 @@
 
 #define HAL_MM_MAP_RW  (1u << 0)
 
+/* User space address bounds (architecture-specific) */
+#define HAL_MM_USER_MIN_ADDR  0x08000000U  /* Conservative lower bound for user mappings */
+
 int hal_mm_map_physical_range(uintptr_t phys_start, uintptr_t phys_end, uint32_t flags, uintptr_t* out_virt);
 
 uintptr_t hal_mm_phys_to_virt(uintptr_t phys);
index 81a3c38731b4ffd77dbf9669ba615fff821d9050..c8cd9902814a710c1d7f9591cad4d51da7c7f9eb 100644 (file)
@@ -82,10 +82,11 @@ sysenter_entry:
      *   real arg2 = *(ECX + 8)
      *
      * SECURITY: validate ECX is in user space before dereferencing.
-     * If ECX >= 0xC0000000 (kernel base), it could leak kernel data.
+     * Use hal_mm_kernel_virt_base() to get dynamic kernel base.
      * Also check ECX is at least 8 bytes from kernel boundary.
      */
-    cmpl $0xC0000000, %ecx
+    call hal_mm_kernel_virt_base
+    cmpl %eax, %ecx
     jae  1f
     cmpl $8, %ecx        /* ECX must be at least 8 bytes from kernel boundary */
     jb   1f
index ed85615b06355b910250f6c2b3a99b18b70e2484..2ec485e206cecf5777b17334fb6dc3bf97492ab2 100644 (file)
@@ -411,7 +411,8 @@ static int syscall_dlopen_impl(const char* user_path) {
         /* Detect 32-bit overflow in p_vaddr + base */
         if (p_vaddr > (UINT32_MAX - base)) continue;
         uint32_t vaddr = p_vaddr + base;
-        if (vaddr >= 0xC0000000U) continue;
+        uintptr_t kern_base = hal_mm_kernel_virt_base();
+        if (kern_base && vaddr >= kern_base) continue;
 
         /* Detect 32-bit overflow in vaddr + p_memsz */
         if (p_memsz > (UINT32_MAX - vaddr)) continue;
@@ -497,7 +498,8 @@ static int syscall_dlopen_impl(const char* user_path) {
 
     /* Read symbol count from DT_HASH if available: hash[1] = nchain = nsyms */
     uint32_t nsyms = 0;
-    if (hash_va && hash_va < 0xC0000000U) {
+    uintptr_t kern_base = hal_mm_kernel_virt_base();
+    if (hash_va && kern_base && hash_va < kern_base) {
         nsyms = *(uint32_t*)(hash_va + 4);
     }
 
@@ -4367,10 +4369,10 @@ void syscall_handler(struct registers* regs) {
             if (kern_base && end > kern_base) { sc_ret(regs) = (uint32_t)-ENOMEM; return; }
         }
 
-        /* Check stack region (user stack is below 0xC0000000, typically around 0xBFxxxxxx) */
+        /* Check stack region (user stack is below kernel base, typically around 0xBFxxxxxx) */
         if (!owned) {
             uintptr_t kern_base = hal_mm_kernel_virt_base();
-            if (kern_base && addr < kern_base && addr >= 0x08000000U)
+            if (kern_base && addr < kern_base && addr >= HAL_MM_USER_MIN_ADDR)
                 owned = 1;  /* Conservative: allow for text/data/bss/stack regions */
         }