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 e2e5ed6a53b39cdc3d56ae258dcf8bd0412bf3c1
Author: wangmingrong1 <[email protected]>
AuthorDate: Wed Jan 21 15:02:43 2026 +0800

    kasan: Use atomic to increment g_region_count
    
    An error occurs when `g_region_count` is incremented, but the data is not 
updated in time when other cores in SMP iterate through `g_region`, causing the 
error.
    
    Signed-off-by: wangmingrong1 <[email protected]>
---
 mm/kasan/generic.c | 15 ++++++++++-----
 mm/kasan/sw_tags.c | 15 ++++++++++-----
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index 3510c2b39aa..ddeba0158d5 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -67,7 +67,7 @@ struct kasan_region_s
  ****************************************************************************/
 
 static FAR struct kasan_region_s *g_region[CONFIG_MM_KASAN_REGIONS];
-static size_t g_region_count;
+static atomic_t g_region_count;
 static spinlock_t g_lock;
 
 /****************************************************************************
@@ -78,10 +78,11 @@ static inline_function FAR uintptr_t *
 kasan_mem_to_shadow(FAR const void *ptr, size_t size,
                     FAR unsigned int *bit)
 {
+  size_t count = atomic_read(&g_region_count);
   uintptr_t addr = (uintptr_t)ptr;
   size_t i;
 
-  for (i = 0; i < g_region_count; i++)
+  for (i = 0; i < count; i++)
     {
       if (addr >= g_region[i]->begin && addr < g_region[i]->end)
         {
@@ -239,6 +240,7 @@ void kasan_register(FAR void *addr, FAR size_t *size)
 {
   FAR struct kasan_region_s *region;
   irqstate_t flags;
+  size_t idx;
 
   region = (FAR struct kasan_region_s *)
     ((FAR char *)addr + *size - KASAN_REGION_SIZE(*size));
@@ -248,8 +250,10 @@ void kasan_register(FAR void *addr, FAR size_t *size)
 
   flags = spin_lock_irqsave_notrace(&g_lock);
 
-  DEBUGASSERT(g_region_count < CONFIG_MM_KASAN_REGIONS);
-  g_region[g_region_count++] = region;
+  idx = atomic_read(&g_region_count);
+  DEBUGASSERT(idx < CONFIG_MM_KASAN_REGIONS);
+  g_region[idx] = region;
+  atomic_add(&g_region_count, 1);
 
   spin_unlock_irqrestore_notrace(&g_lock, flags);
 
@@ -270,7 +274,8 @@ void kasan_unregister(FAR void *addr)
         {
           size_t size = g_region[i]->end - g_region[i]->begin;
 
-          g_region_count--;
+          atomic_sub(&g_region_count, 1);
+          g_region[i] = NULL;
           memmove(&g_region[i], &g_region[i + 1],
                   (g_region_count - i) * sizeof(g_region[0]));
           spin_unlock_irqrestore_notrace(&g_lock, flags);
diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c
index c5640412f8f..90dbbd9fa98 100644
--- a/mm/kasan/sw_tags.c
+++ b/mm/kasan/sw_tags.c
@@ -61,7 +61,7 @@ struct kasan_region_s
  ****************************************************************************/
 
 static FAR struct kasan_region_s *g_region[CONFIG_MM_KASAN_REGIONS];
-static int g_region_count;
+static atomic_t g_region_count;
 static spinlock_t g_lock;
 
 /****************************************************************************
@@ -71,12 +71,13 @@ static spinlock_t g_lock;
 static inline_function FAR uint8_t *
 kasan_mem_to_shadow(FAR const void *ptr, size_t size)
 {
+  size_t count = atomic_read(&g_region_count);
   uintptr_t addr;
   int i;
 
   addr = (uintptr_t)kasan_clear_tag(ptr);
 
-  for (i = 0; i < g_region_count; i++)
+  for (i = 0; i < count; i++)
     {
       if (addr >= g_region[i]->begin && addr < g_region[i]->end)
         {
@@ -188,6 +189,7 @@ void kasan_register(FAR void *addr, FAR size_t *size)
 {
   FAR struct kasan_region_s *region;
   irqstate_t flags;
+  size_t idx;
 
   region = (FAR struct kasan_region_s *)
     ((FAR char *)addr + *size - KASAN_REGION_SIZE(*size));
@@ -197,8 +199,10 @@ void kasan_register(FAR void *addr, FAR size_t *size)
 
   flags = spin_lock_irqsave(&g_lock);
 
-  DEBUGASSERT(g_region_count < CONFIG_MM_KASAN_REGIONS);
-  g_region[g_region_count++] = region;
+  idx = atomic_read(&g_region_count);
+  DEBUGASSERT(idx < CONFIG_MM_KASAN_REGIONS);
+  g_region[idx] = region;
+  atomic_add(&g_region_count, 1);
 
   spin_unlock_irqrestore(&g_lock, flags);
 
@@ -219,7 +223,8 @@ void kasan_unregister(FAR void *addr)
         {
           size_t size = g_region[i]->end - g_region[i]->begin;
 
-          g_region_count--;
+          atomic_sub(&g_region_count, 1);
+          g_region[i] = NULL;
           memmove(&g_region[i], &g_region[i + 1],
                   (g_region_count - i) * sizeof(g_region[0]));
           spin_unlock_irqrestore(&g_lock, flags);

Reply via email to