This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 91f3d832cdee46345a7f6ccb70f1fbf89bca5ac9 Author: Marco Casaroli <[email protected]> AuthorDate: Tue Oct 20 10:55:19 2026 +0200 arch: Compare the last address of a region with <=. ARCH_ADDRENV_VEND, ARCH_SHM_VEND and ARCH_KMAP_VEND are the last address of their region (base + size - 1), but all users compared with "vaddr < VEND". The last byte of each region was outside it. The current callers pass page aligned addresses, so they get the same result, but a check of any other address in the last page was wrong. Compare with "<=" in arm (armv7-a), arm64, risc-v, x86_64 and mm/kmap, and say in the comments that these ends are inclusive. ARCH_SCRATCH_VBASE was ARCH_SHM_VEND, the last byte of the shared memory region; it is now the first address after the region. Nothing uses it. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- arch/arm/src/armv7-a/arm_addrenv_shm.c | 4 ++-- arch/arm/src/armv7-a/pgalloc.h | 2 +- arch/arm64/src/common/addrenv.h | 2 +- arch/arm64/src/common/arm64_addrenv_mmu.c | 2 +- arch/arm64/src/common/arm64_addrenv_pgmap.c | 4 ++-- arch/arm64/src/common/arm64_addrenv_shm.c | 4 ++-- arch/arm64/src/common/pgalloc.h | 4 ++-- arch/risc-v/src/common/addrenv.h | 2 +- arch/risc-v/src/common/pgalloc.h | 4 ++-- arch/risc-v/src/common/riscv_addrenv.c | 2 +- arch/risc-v/src/common/riscv_addrenv_pgmap.c | 4 ++-- arch/risc-v/src/common/riscv_addrenv_shm.c | 4 ++-- arch/x86_64/src/common/addrenv.h | 2 +- arch/x86_64/src/common/pgalloc.h | 4 ++-- include/nuttx/addrenv.h | 4 +++- mm/kmap/kmm_map.c | 2 +- 16 files changed, 26 insertions(+), 24 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_addrenv_shm.c b/arch/arm/src/armv7-a/arm_addrenv_shm.c index ae0466b4569..bc54a7d63e8 100644 --- a/arch/arm/src/armv7-a/arm_addrenv_shm.c +++ b/arch/arm/src/armv7-a/arm_addrenv_shm.c @@ -77,7 +77,7 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr) /* Sanity checks */ DEBUGASSERT(pages && npages > 0 && tcb && tcb->addrenv_own); - DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Loop until all pages have been mapped into the caller's address space. */ @@ -183,7 +183,7 @@ int up_shmdt(uintptr_t vaddr, unsigned int npages) /* Sanity checks */ DEBUGASSERT(npages > 0 && tcb && tcb->addrenv_own); - DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Loop until all pages have been unmapped from the caller's address diff --git a/arch/arm/src/armv7-a/pgalloc.h b/arch/arm/src/armv7-a/pgalloc.h index 7fe3a92aed4..5a7f7810682 100644 --- a/arch/arm/src/armv7-a/pgalloc.h +++ b/arch/arm/src/armv7-a/pgalloc.h @@ -95,7 +95,7 @@ static inline bool arm_uservaddr(uintptr_t vaddr) || (vaddr >= CONFIG_ARCH_STACK_VBASE && vaddr < ARCH_STACK_VEND) #endif #ifdef CONFIG_ARCH_VMA_MAPPING - || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND) + || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND) #endif ); } diff --git a/arch/arm64/src/common/addrenv.h b/arch/arm64/src/common/addrenv.h index 8aa1241e1a9..e015a04964b 100644 --- a/arch/arm64/src/common/addrenv.h +++ b/arch/arm64/src/common/addrenv.h @@ -52,7 +52,7 @@ #define ARCH_ADDRENV_MAX_SIZE (0x40000000) -/* User address environment end */ +/* User address environment end (the last address) */ #define ARCH_ADDRENV_VEND (ARCH_ADDRENV_VBASE + ARCH_ADDRENV_MAX_SIZE - 1) diff --git a/arch/arm64/src/common/arm64_addrenv_mmu.c b/arch/arm64/src/common/arm64_addrenv_mmu.c index e25548bda7d..784b2d79f6d 100644 --- a/arch/arm64/src/common/arm64_addrenv_mmu.c +++ b/arch/arm64/src/common/arm64_addrenv_mmu.c @@ -375,7 +375,7 @@ static int create_region(arch_addrenv_t *addrenv, uintptr_t vaddr, static inline bool vaddr_is_shm(uintptr_t vaddr) { #if defined (CONFIG_ARCH_SHM_VBASE) && defined(ARCH_SHM_VEND) - return vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND; + return vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND; #else UNUSED(vaddr); return false; diff --git a/arch/arm64/src/common/arm64_addrenv_pgmap.c b/arch/arm64/src/common/arm64_addrenv_pgmap.c index 8989545c889..5eb8c58afc4 100644 --- a/arch/arm64/src/common/arm64_addrenv_pgmap.c +++ b/arch/arm64/src/common/arm64_addrenv_pgmap.c @@ -254,7 +254,7 @@ int up_addrenv_kmap_pages(void **pages, unsigned int npages, uintptr_t vaddr, /* Sanity checks */ DEBUGASSERT(pages != NULL && npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr < ARCH_KMAP_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr <= ARCH_KMAP_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* The access is either RO or RW, read access cannot be revoked */ @@ -316,7 +316,7 @@ int up_addrenv_kunmap_pages(uintptr_t vaddr, unsigned int npages) /* Sanity checks */ DEBUGASSERT(npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr < ARCH_KMAP_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr <= ARCH_KMAP_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Let arm64_unmap_pages do the work */ diff --git a/arch/arm64/src/common/arm64_addrenv_shm.c b/arch/arm64/src/common/arm64_addrenv_shm.c index 2b4851796ca..225f8e056fa 100644 --- a/arch/arm64/src/common/arm64_addrenv_shm.c +++ b/arch/arm64/src/common/arm64_addrenv_shm.c @@ -76,7 +76,7 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr) DEBUGASSERT(tcb && tcb->addrenv_own); DEBUGASSERT(pages != NULL && npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Let arm64_map_pages do the work */ @@ -110,7 +110,7 @@ int up_shmdt(uintptr_t vaddr, unsigned int npages) DEBUGASSERT(tcb && tcb->addrenv_own); DEBUGASSERT(npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Let arm64_unmap_pages do the work */ diff --git a/arch/arm64/src/common/pgalloc.h b/arch/arm64/src/common/pgalloc.h index 54ae504b023..7f1b9d434a7 100644 --- a/arch/arm64/src/common/pgalloc.h +++ b/arch/arm64/src/common/pgalloc.h @@ -101,9 +101,9 @@ static inline bool arm64_uservaddr(uintptr_t vaddr) * heap, or stack regions. */ - return ((vaddr >= ARCH_ADDRENV_VBASE && vaddr < ARCH_ADDRENV_VEND) + return ((vaddr >= ARCH_ADDRENV_VBASE && vaddr <= ARCH_ADDRENV_VEND) #ifdef CONFIG_ARCH_VMA_MAPPING - || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND) + || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND) #endif ); } diff --git a/arch/risc-v/src/common/addrenv.h b/arch/risc-v/src/common/addrenv.h index ec4557311ff..888632f35bf 100644 --- a/arch/risc-v/src/common/addrenv.h +++ b/arch/risc-v/src/common/addrenv.h @@ -52,7 +52,7 @@ #define ARCH_ADDRENV_MAX_SIZE (0x40000000) -/* User address environment end */ +/* User address environment end (the last address) */ #define ARCH_ADDRENV_VEND (ARCH_ADDRENV_VBASE + ARCH_ADDRENV_MAX_SIZE - 1) diff --git a/arch/risc-v/src/common/pgalloc.h b/arch/risc-v/src/common/pgalloc.h index 8a772c104cb..217abe5d2e6 100644 --- a/arch/risc-v/src/common/pgalloc.h +++ b/arch/risc-v/src/common/pgalloc.h @@ -101,9 +101,9 @@ static inline bool riscv_uservaddr(uintptr_t vaddr) * heap, or stack regions. */ - return ((vaddr >= ARCH_ADDRENV_VBASE && vaddr < ARCH_ADDRENV_VEND) + return ((vaddr >= ARCH_ADDRENV_VBASE && vaddr <= ARCH_ADDRENV_VEND) #ifdef CONFIG_ARCH_VMA_MAPPING - || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND) + || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND) #endif ); } diff --git a/arch/risc-v/src/common/riscv_addrenv.c b/arch/risc-v/src/common/riscv_addrenv.c index f5d056cd945..cb740938245 100644 --- a/arch/risc-v/src/common/riscv_addrenv.c +++ b/arch/risc-v/src/common/riscv_addrenv.c @@ -335,7 +335,7 @@ static int create_region(arch_addrenv_t *addrenv, uintptr_t vaddr, static inline bool vaddr_is_shm(uintptr_t vaddr) { #if defined (CONFIG_ARCH_SHM_VBASE) && defined(ARCH_SHM_VEND) - return vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND; + return vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND; #else UNUSED(vaddr); return false; diff --git a/arch/risc-v/src/common/riscv_addrenv_pgmap.c b/arch/risc-v/src/common/riscv_addrenv_pgmap.c index 61ad38e7db1..d25bacafd9c 100644 --- a/arch/risc-v/src/common/riscv_addrenv_pgmap.c +++ b/arch/risc-v/src/common/riscv_addrenv_pgmap.c @@ -250,7 +250,7 @@ int up_addrenv_kmap_pages(void **pages, unsigned int npages, uintptr_t vaddr, /* Sanity checks */ DEBUGASSERT(pages != NULL && npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr < ARCH_KMAP_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr <= ARCH_KMAP_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Convert access right flags to MMU flags */ @@ -303,7 +303,7 @@ int up_addrenv_kunmap_pages(uintptr_t vaddr, unsigned int npages) /* Sanity checks */ DEBUGASSERT(npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr < ARCH_KMAP_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr <= ARCH_KMAP_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Let riscv_unmap_pages do the work */ diff --git a/arch/risc-v/src/common/riscv_addrenv_shm.c b/arch/risc-v/src/common/riscv_addrenv_shm.c index 9ad2840b771..2f1a756d4ed 100644 --- a/arch/risc-v/src/common/riscv_addrenv_shm.c +++ b/arch/risc-v/src/common/riscv_addrenv_shm.c @@ -76,7 +76,7 @@ int up_shmat(uintptr_t *pages, unsigned int npages, uintptr_t vaddr) DEBUGASSERT(tcb && tcb->addrenv_own); DEBUGASSERT(pages != NULL && npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Let riscv_map_pages do the work */ @@ -110,7 +110,7 @@ int up_shmdt(uintptr_t vaddr, unsigned int npages) DEBUGASSERT(tcb && tcb->addrenv_own); DEBUGASSERT(npages > 0); - DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND); + DEBUGASSERT(vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND); DEBUGASSERT(MM_ISALIGNED(vaddr)); /* Let riscv_unmap_pages do the work */ diff --git a/arch/x86_64/src/common/addrenv.h b/arch/x86_64/src/common/addrenv.h index e9ddee927f8..26628b95d93 100644 --- a/arch/x86_64/src/common/addrenv.h +++ b/arch/x86_64/src/common/addrenv.h @@ -52,7 +52,7 @@ #define ARCH_ADDRENV_MAX_SIZE (0x40000000) -/* User address environment end */ +/* User address environment end (the last address) */ #define ARCH_ADDRENV_VEND (ARCH_ADDRENV_VBASE + ARCH_ADDRENV_MAX_SIZE - 1) diff --git a/arch/x86_64/src/common/pgalloc.h b/arch/x86_64/src/common/pgalloc.h index 3d95e2df368..d05e6a3990f 100644 --- a/arch/x86_64/src/common/pgalloc.h +++ b/arch/x86_64/src/common/pgalloc.h @@ -111,9 +111,9 @@ static inline bool x86_64_uservaddr(uintptr_t vaddr) * heap, or stack regions. */ - return ((vaddr >= ARCH_ADDRENV_VBASE && vaddr < ARCH_ADDRENV_VEND) + return ((vaddr >= ARCH_ADDRENV_VBASE && vaddr <= ARCH_ADDRENV_VEND) #ifdef CONFIG_ARCH_VMA_MAPPING - || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr < ARCH_SHM_VEND) + || (vaddr >= CONFIG_ARCH_SHM_VBASE && vaddr <= ARCH_SHM_VEND) #endif ); } diff --git a/include/nuttx/addrenv.h b/include/nuttx/addrenv.h index 91c2eaa28d4..4c479fe511e 100644 --- a/include/nuttx/addrenv.h +++ b/include/nuttx/addrenv.h @@ -200,10 +200,12 @@ # define CONFIG_ARCH_SHM_NPAGES 1 # endif +/* ARCH_SHM_VEND and ARCH_KMAP_VEND are the last address of the region */ + # define ARCH_SHM_SIZE (CONFIG_ARCH_SHM_NPAGES * CONFIG_MM_PGSIZE) # define ARCH_SHM_VEND (CONFIG_ARCH_SHM_VBASE + ARCH_SHM_SIZE - 1) -# define ARCH_SCRATCH_VBASE ARCH_SHM_VEND +# define ARCH_SCRATCH_VBASE (ARCH_SHM_VEND + 1) # else # define ARCH_SCRATCH_VBASE __ARCH_SHM_VBASE # endif diff --git a/mm/kmap/kmm_map.c b/mm/kmap/kmm_map.c index 7e80c06c935..4c5466f31ff 100644 --- a/mm/kmap/kmm_map.c +++ b/mm/kmap/kmm_map.c @@ -233,7 +233,7 @@ static FAR void *map_single_page(uintptr_t page) static bool is_kmap_vaddr(uintptr_t vaddr) { - return (vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr < ARCH_KMAP_VEND); + return (vaddr >= CONFIG_ARCH_KMAP_VBASE && vaddr <= ARCH_KMAP_VEND); } /****************************************************************************
