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);
 }
 
 /****************************************************************************

Reply via email to