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)
