This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit f1bff30ae8d5ef51bbfeb794e06ca2d83dc51e85
Author: Royyan Zahir <[email protected]>
AuthorDate: Wed Sep 30 09:25:22 2026 +0400

    arch/arm64: map nothing of the kernel over user space
    
    access_ok() trusts the user address range, so a kernel mapping inside it
    would pass as user memory. Refuse such a mapping: at boot the kernel
    stops, arm64_mmu_set_memregion() returns -EINVAL.
    
    Signed-off-by: Royyan Zahir <[email protected]>
---
 arch/arm64/src/common/arm64_mmu.c | 46 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/src/common/arm64_mmu.c 
b/arch/arm64/src/common/arm64_mmu.c
index 8792517b2a4..53a123dc491 100644
--- a/arch/arm64/src/common/arm64_mmu.c
+++ b/arch/arm64/src/common/arm64_mmu.c
@@ -39,6 +39,10 @@
 #include "arm64_fatal.h"
 #include "arm64_mmu.h"
 
+#ifdef CONFIG_BUILD_KERNEL
+#  include "addrenv.h"
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -458,6 +462,27 @@ static void split_pte_block_desc(uint64_t *pte, int level)
   set_pte_table_desc(pte, new_table, level);
 }
 
+#ifdef CONFIG_BUILD_KERNEL
+static bool is_user_overlap(uintptr_t virt, size_t size)
+{
+  uintptr_t last = virt + size - 1;
+
+  if (virt <= ARCH_ADDRENV_VEND && last >= ARCH_ADDRENV_VBASE)
+    {
+      return true;
+    }
+
+#ifdef CONFIG_ARCH_VMA_MAPPING
+  if (virt <= ARCH_SHM_VEND && last >= CONFIG_ARCH_SHM_VBASE)
+    {
+      return true;
+    }
+#endif
+
+  return false;
+}
+#endif
+
 /* Create/Populate translation table(s) for given region */
 
 static void init_xlat_tables(const struct arm_mmu_region *region)
@@ -475,6 +500,13 @@ static void init_xlat_tables(const struct arm_mmu_region 
*region)
   sinfo("mmap: virt %lux phys %lux size %lux\n", virt, phys, size);
 #endif
 
+#ifdef CONFIG_BUILD_KERNEL
+  if (size > 0 && is_user_overlap(virt, size))
+    {
+      PANIC();
+    }
+#endif
+
   /* check minimum alignment requirement for given mmap region */
 
   __MMU_ASSERT(((virt & (PAGE_SIZE - 1)) == 0) &&
@@ -648,17 +680,21 @@ int arm64_mmu_set_memregion(const struct arm_mmu_region 
*region)
   uint64_t virt = region->base_va;
   uint64_t size = region->size;
 
-  if (((virt & (PAGE_SIZE - 1)) == 0) &&
-      ((size & (PAGE_SIZE - 1)) == 0))
+  if (((virt & (PAGE_SIZE - 1)) != 0) ||
+      ((size & (PAGE_SIZE - 1)) != 0))
     {
-      init_xlat_tables(region);
+      sinfo("address/size are not page aligned\n");
+      return -EINVAL;
     }
-  else
+
+#ifdef CONFIG_BUILD_KERNEL
+  if (size > 0 && is_user_overlap(virt, size))
     {
-      sinfo("address/size are not page aligned\n");
       return -EINVAL;
     }
+#endif
 
+  init_xlat_tables(region);
   return 0;
 }
 

Reply via email to