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 6d457f14ae2eef3382b24d0e13359ed35d04b898
Author: wangmingrong1 <[email protected]>
AuthorDate: Fri Jun 6 14:48:10 2025 +0800

    kasan: kasan bypass move outside the lock
    
    Move kasan_bypass calls outside mm_lock/mm_unlock to avoid recursive
    issues when kasan itself uses the heap.
    
    Signed-off-by: wangmingrong1 <[email protected]>
---
 mm/mm_heap/mm_extend.c     |  4 ++++
 mm/mm_heap/mm_foreach.c    |  4 ++++
 mm/mm_heap/mm_free.c       |  6 ++++++
 mm/mm_heap/mm_initialize.c |  6 ++++++
 mm/mm_heap/mm_lock.c       | 26 ++------------------------
 mm/mm_heap/mm_malloc.c     |  4 ++++
 mm/mm_heap/mm_memalign.c   |  2 ++
 mm/mm_heap/mm_realloc.c    |  6 ++++++
 8 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/mm/mm_heap/mm_extend.c b/mm/mm_heap/mm_extend.c
index ee6943c3bf8..bac73f8d9e8 100644
--- a/mm/mm_heap/mm_extend.c
+++ b/mm/mm_heap/mm_extend.c
@@ -28,6 +28,7 @@
 
 #include <assert.h>
 
+#include <nuttx/mm/kasan.h>
 #include <nuttx/mm/mm.h>
 
 #include "mm_heap/mm.h"
@@ -80,6 +81,7 @@ void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, 
size_t size,
   /* Take the memory manager mutex */
 
   DEBUGVERIFY(mm_lock(heap));
+  kasan_bypass(true);
 
   /* Get the terminal node in the old heap.  The block to extend must
    * immediately follow this node.
@@ -111,6 +113,8 @@ void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, 
size_t size,
   /* Finally, increase the total heap size accordingly */
 
   heap->mm_heapsize += size;
+
+  kasan_bypass(false);
   mm_unlock(heap);
 
   /* Finally "free" the new block of memory where the old terminal node was
diff --git a/mm/mm_heap/mm_foreach.c b/mm/mm_heap/mm_foreach.c
index 3fb56aef1f7..b310170827a 100644
--- a/mm/mm_heap/mm_foreach.c
+++ b/mm/mm_heap/mm_foreach.c
@@ -29,6 +29,7 @@
 #include <assert.h>
 #include <nuttx/debug.h>
 
+#include <nuttx/mm/kasan.h>
 #include <nuttx/mm/mm.h>
 
 #include "mm_heap/mm.h"
@@ -77,6 +78,8 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t 
handler,
           return;
         }
 
+      kasan_bypass(true);
+
       for (node = heap->mm_heapstart[region];
            node < heap->mm_heapend[region];
            node = (FAR struct mm_allocnode_s *)((FAR char *)node + nodesize))
@@ -100,6 +103,7 @@ void mm_foreach(FAR struct mm_heap_s *heap, 
mm_node_handler_t handler,
       DEBUGASSERT(node == heap->mm_heapend[region]);
       handler(node, arg);
 
+      kasan_bypass(false);
       mm_unlock(heap);
     }
 #undef region
diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c
index 4297527dfb4..3ec17f9dfe2 100644
--- a/mm/mm_heap/mm_free.c
+++ b/mm/mm_heap/mm_free.c
@@ -50,6 +50,7 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR 
void *mem)
   /* Delay the deallocation until a more appropriate time. */
 
   flags = mm_lock_irq(heap);
+  kasan_bypass(true);
 
 #  ifdef CONFIG_DEBUG_ASSERTIONS
   FAR struct mm_freenode_s *node;
@@ -65,6 +66,7 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR 
void *mem)
   heap->mm_delaycount[this_cpu()]++;
 #endif
 
+  kasan_bypass(false);
   mm_unlock_irq(heap, flags);
 #endif
 }
@@ -100,6 +102,7 @@ void mm_delayfree(FAR struct mm_heap_s *heap, FAR void 
*mem, bool delay)
       return;
     }
 
+  kasan_bypass(true);
   nodesize = mm_malloc_size(heap, mem);
 #ifdef CONFIG_MM_FILL_ALLOCATIONS
 #if CONFIG_MM_FREE_DELAYCOUNT_MAX > 0
@@ -120,6 +123,7 @@ void mm_delayfree(FAR struct mm_heap_s *heap, FAR void 
*mem, bool delay)
 
   if (delay)
     {
+      kasan_bypass(false);
       mm_unlock(heap);
       add_delaylist(heap, mem);
       return;
@@ -217,6 +221,8 @@ void mm_delayfree(FAR struct mm_heap_s *heap, FAR void 
*mem, bool delay)
   /* Add the merged node to the nodelist */
 
   mm_addfreechunk(heap, node);
+
+  kasan_bypass(false);
   mm_unlock(heap);
 }
 
diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c
index bf25814beaa..6bb815dcd2e 100644
--- a/mm/mm_heap/mm_initialize.c
+++ b/mm/mm_heap/mm_initialize.c
@@ -110,6 +110,8 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void 
*heapstart,
   int idx;
 
   DEBUGVERIFY(mm_lock(heap));
+  kasan_bypass(true);
+
   idx = heap->mm_nregions;
 
   /* Writing past CONFIG_MM_REGIONS would have catastrophic consequences */
@@ -117,6 +119,7 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void 
*heapstart,
   DEBUGASSERT(idx < CONFIG_MM_REGIONS);
   if (idx >= CONFIG_MM_REGIONS)
     {
+      kasan_bypass(false);
       mm_unlock(heap);
       return;
     }
@@ -124,6 +127,7 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void 
*heapstart,
 #else
 #  define idx 0
   DEBUGVERIFY(mm_lock(heap));
+  kasan_bypass(true);
 #endif
 
 #if defined(CONFIG_MM_SMALL) && !defined(CONFIG_SMALL_MEMORY)
@@ -211,6 +215,8 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void 
*heapstart,
   heap->mm_curused += 2 * MM_SIZEOF_ALLOCNODE;
   sched_note_heap(NOTE_HEAP_ADD, heap, heapstart, heapsize,
                   heap->mm_curused);
+
+  kasan_bypass(false);
   mm_unlock(heap);
 }
 
diff --git a/mm/mm_heap/mm_lock.c b/mm/mm_heap/mm_lock.c
index 2776ee3e121..431b68ba92a 100644
--- a/mm/mm_heap/mm_lock.c
+++ b/mm/mm_heap/mm_lock.c
@@ -32,7 +32,6 @@
 #include <nuttx/debug.h>
 
 #include <nuttx/arch.h>
-#include <nuttx/mm/kasan.h>
 #include <nuttx/mm/mm.h>
 
 #include "mm_heap/mm.h"
@@ -70,16 +69,7 @@ int mm_lock(FAR struct mm_heap_s *heap)
        * Or, touch the heap internal data directly.
        */
 
-      if (nxmutex_is_locked(&heap->mm_lock))
-        {
-          return -EAGAIN;
-        }
-      else
-        {
-          kasan_bypass(true);
-          return 0;
-        }
-
+      return nxmutex_is_locked(&heap->mm_lock) ? -EAGAIN : 0;
 #  else
       /* Can't take mutex in SMP interrupt handler */
 
@@ -114,11 +104,6 @@ int mm_lock(FAR struct mm_heap_s *heap)
         }
       while (ret == -EINTR);
 
-      if (ret >= 0)
-        {
-          kasan_bypass(true);
-        }
-
       return ret;
     }
 }
@@ -136,12 +121,10 @@ void mm_unlock(FAR struct mm_heap_s *heap)
 #if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
   if (up_interrupt_context())
     {
-      kasan_bypass(false);
       return;
     }
 #endif
 
-  kasan_bypass(false);
   DEBUGVERIFY(nxmutex_unlock(&heap->mm_lock));
 }
 
@@ -155,12 +138,8 @@ void mm_unlock(FAR struct mm_heap_s *heap)
 
 irqstate_t mm_lock_irq(FAR struct mm_heap_s *heap)
 {
-  irqstate_t flags = up_irq_save();
-
   UNUSED(heap);
-  kasan_bypass(true);
-
-  return flags;
+  return up_irq_save();
 }
 
 /****************************************************************************
@@ -174,6 +153,5 @@ irqstate_t mm_lock_irq(FAR struct mm_heap_s *heap)
 void mm_unlock_irq(FAR struct mm_heap_s *heap, irqstate_t state)
 {
   UNUSED(heap);
-  kasan_bypass(false);
   up_irq_restore(state);
 }
diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c
index 6e5cab9d2e5..a91b4e6bd3c 100644
--- a/mm/mm_heap/mm_malloc.c
+++ b/mm/mm_heap/mm_malloc.c
@@ -66,6 +66,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool 
force)
   /* Move the delay list to local */
 
   flags = mm_lock_irq(heap);
+  kasan_bypass(true);
 
   tmp = heap->mm_delaylist[this_cpu()];
 
@@ -83,6 +84,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool 
force)
 
   heap->mm_delaylist[this_cpu()] = NULL;
 
+  kasan_bypass(false);
   mm_unlock_irq(heap, flags);
 
   /* Test if the delayed is empty */
@@ -213,6 +215,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
   /* We need to hold the MM mutex while we muck with the nodelist. */
 
   DEBUGVERIFY(mm_lock(heap));
+  kasan_bypass(true);
 
   /* Convert the request size into a nodelist index */
 
@@ -328,6 +331,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
                       heap->mm_curused);
     }
 
+  kasan_bypass(false);
   mm_unlock(heap);
 
   if (ret)
diff --git a/mm/mm_heap/mm_memalign.c b/mm/mm_heap/mm_memalign.c
index 99fb74f70ea..f5ed76b1801 100644
--- a/mm/mm_heap/mm_memalign.c
+++ b/mm/mm_heap/mm_memalign.c
@@ -159,6 +159,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t 
alignment,
    */
 
   DEBUGVERIFY(mm_lock(heap));
+  kasan_bypass(true);
 
   /* Get the node associated with the allocation and the next node after
    * the allocation.
@@ -291,6 +292,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t 
alignment,
   sched_note_heap(NOTE_HEAP_ALLOC, heap, (FAR void *)alignedchunk, size,
                   heap->mm_curused);
 
+  kasan_bypass(false);
   mm_unlock(heap);
 
   MM_ADD_BACKTRACE(heap, node);
diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c
index c1c7dac53ae..9317138cb9a 100644
--- a/mm/mm_heap/mm_realloc.c
+++ b/mm/mm_heap/mm_realloc.c
@@ -137,6 +137,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void 
*oldmem,
   /* We need to hold the MM mutex while we muck with the nodelist. */
 
   DEBUGVERIFY(mm_lock(heap));
+  kasan_bypass(true);
+
   DEBUGASSERT(MM_NODE_IS_ALLOC(oldnode));
 
   /* Check if this is a request to reduce the size of the allocation. */
@@ -159,6 +161,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void 
*oldmem,
 
       /* Then return the original address */
 
+      kasan_bypass(false);
       mm_unlock(heap);
       MM_ADD_BACKTRACE(heap, oldnode);
 
@@ -390,6 +393,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void 
*oldmem,
                       heap->mm_curused);
 
       size = MM_SIZEOF_NODE(oldnode);
+
+      kasan_bypass(false);
       mm_unlock(heap);
       MM_ADD_BACKTRACE(heap, (FAR char *)newmem - MM_SIZEOF_ALLOCNODE);
 
@@ -419,6 +424,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void 
*oldmem,
        * leave the original memory in place.
        */
 
+      kasan_bypass(false);
       mm_unlock(heap);
       newmem = mm_malloc(heap, size);
       if (newmem)

Reply via email to