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; }
