diff --git a/Documentation/guides/index.rst b/Documentation/guides/index.rst index 11e43cc421..b19c8027e9 100644 --- a/Documentation/guides/index.rst +++ b/Documentation/guides/index.rst @@ -19,6 +19,7 @@ Guides customapps.rst citests.rst zerolatencyinterrupts.rst + kasan.rst nestedinterrupts.rst cortexmhardfaults.rst coredump.rst diff --git a/Documentation/guides/kasan.rst b/Documentation/guides/kasan.rst index 3f3b1aeb04..ba669ee3b0 100644 --- a/Documentation/guides/kasan.rst +++ b/Documentation/guides/kasan.rst @@ -8,17 +8,23 @@ Overview Kernel Address Sanitizer (KASAN) is a dynamic memory safety error detector designed to find out-of-bounds and use-after-free bugs. -The current version of NuttX has one modes: +The current version of NuttX has two modes: 1. Generic KASAN +2. Software Tag-Based KASAN -Generic KASAN, enabled with CONFIG_MM_KASAN, is the mode intended for +Generic KASAN, enabled with CONFIG_MM_KASAN_GENERIC, is the mode intended for debugging, similar to linux user level ASan. This mode is supported on many CPU architectures, but it has significant performance and memory overheads. The current NuttX Generic KASAN can support memory out of bounds detection allocated by the default NuttX heap allocator,which depends on CONFIG_MM_DEFAULT_MANAGER or CONFIG_MM_TLSF_MANAGER, and detection of out of bounds with global variables. +Software Tag-Based KASAN or SW_TAGS KASAN, enabled with CONFIG_MM_KASAN_SW_TAGS, +can be used for both debugging, This mode is only supported for arm64, +but its moderate memory overhead allows using it for testing on +memory-restricted devices with real workloads. + Support ------- @@ -27,20 +33,33 @@ Architectures Generic KASAN is supported on x86_64, arm, arm64, riscv, xtensa and so on. +Software Tag-Based KASAN modes are supported only on arm64. + Usage ----- To enable Generic KASAN, configure the kernel with:: + CONFIG_MM_KASAN=y CONFIG_MM_KASAN_ALL=y + CONFIG_MM_KASAN_GENERIC=y If you want to enable global variable out of bounds detection, you can add configurations based on the above:: + CONFIG_MM_KASAN_GLOBAL=y +To enable Software Tag-Based KASAN, configure the kernel with:: + + CONFIG_MM_KASAN=y + CONFIG_MM_KASAN_ALL=y + CONFIG_MM_KASAN_SW_TAGS=y + Implementation details ---------------------- +Generic KASAN: + Compile with param -fsanitize=kernel-address, Compile-time instrumentation is used to insert memory access checks. Compiler inserts function calls (``__asan_load*(addr)``, ``__asan_store*(addr)``) before @@ -94,6 +113,26 @@ The data generated by the compiler will be placed in a non-existent memory block After the compilation is completed, this segment will be deleted and will not be copied to the bin file of the final burned board. +Software Tag-Based KASAN: + +Software Tag-Based KASAN uses a software memory tagging approach to checking +access validity. It is currently only implemented for the arm64 architecture. + +Software Tag-Based KASAN uses the Top Byte Ignore (TBI) feature of arm64 CPUs +to store a pointer tag in the top byte of kernel pointers. It uses shadow memory +to store memory tags associated with each heap allocated memory cell (therefore, it +dedicates 1/8 th of the kernel memory for shadow memory). + +On each memory allocation, Software Tag-Based KASAN generates a random tag, tags +the allocated memory with this tag, and embeds the same tag into the returned +pointer. + +Software Tag-Based KASAN uses compile-time instrumentation to insert checks +before each memory access. These checks make sure that the tag of the memory +that is being accessed is equal to the tag of the pointer that is used to access +this memory. In case of a tag mismatch, Software Tag-Based KASAN prints a bug +report. + For developers -------------- @@ -102,4 +141,6 @@ Ignoring accesses If you want the module you are writing to not be inserted by the compiler, you can add the option 'CFLAGS += -fno-sanitize=kernel-address' to a single module. -If it is a file, you can write it this way, special_file.o: CFLAGS = -fno-sanitize=kernel-address +If it is a file, you can write it this way, +special_file.o: CFLAGS = -fno-sanitize=kernel-address +or : special_file.o: CFLAGS = -fno-sanitize=kernel-hwaddress diff --git a/arch/arm64/src/Toolchain.defs b/arch/arm64/src/Toolchain.defs index 162d4fd411..a8485ad697 100644 --- a/arch/arm64/src/Toolchain.defs +++ b/arch/arm64/src/Toolchain.defs @@ -79,7 +79,11 @@ ifeq ($(CONFIG_MM_UBSAN_TRAP_ON_ERROR),y) endif ifeq ($(CONFIG_MM_KASAN_ALL),y) - ARCHOPTIMIZATION += -fsanitize=kernel-address + ifeq ($(CONFIG_MM_KASAN_GENERIC),y) + ARCHOPTIMIZATION += -fsanitize=kernel-address + else ifeq ($(CONFIG_MM_KASAN_SW_TAGS),y) + ARCHOPTIMIZATION += -fsanitize=kernel-hwaddress + endif endif ifeq ($(CONFIG_MM_KASAN_GLOBAL),y) diff --git a/arch/arm64/src/common/arm64_mmu.c b/arch/arm64/src/common/arm64_mmu.c index bd1283a637..d1645f5912 100644 --- a/arch/arm64/src/common/arm64_mmu.c +++ b/arch/arm64/src/common/arm64_mmu.c @@ -153,6 +153,12 @@ #define TCR_PS_BITS TCR_PS_BITS_4GB #endif +#ifdef CONFIG_MM_KASAN_SW_TAGS +#define TCR_KASAN_SW_FLAGS (TCR_TBI0 | TCR_TBI1 | TCR_ASID_8) +#else +#define TCR_KASAN_SW_FLAGS 0 +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -254,7 +260,8 @@ static uint64_t get_tcr(int el) * inner shareable */ - tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA; + tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | + TCR_IRGN_WBWA | TCR_KASAN_SW_FLAGS; return tcr; } diff --git a/arch/arm64/src/common/arm64_mmu.h b/arch/arm64/src/common/arm64_mmu.h index 80bd75301f..2f16e726cd 100644 --- a/arch/arm64/src/common/arm64_mmu.h +++ b/arch/arm64/src/common/arm64_mmu.h @@ -149,6 +149,12 @@ #define TCR_TG0_16K (2ULL << 14) #define TCR_EPD1_DISABLE (1ULL << 23) +#define TCR_AS_SHIFT 36U +#define TCR_ASID_8 (0ULL << TCR_AS_SHIFT) +#define TCR_ASID_16 (1ULL << TCR_AS_SHIFT) +#define TCR_TBI0 (1ULL << 37) +#define TCR_TBI1 (1ULL << 38) + #define TCR_PS_BITS_4GB 0x0ULL #define TCR_PS_BITS_64GB 0x1ULL #define TCR_PS_BITS_1TB 0x2ULL diff --git a/include/nuttx/mm/kasan.h b/include/nuttx/mm/kasan.h index 6cea24d4f7..4b1654c53e 100644 --- a/include/nuttx/mm/kasan.h +++ b/include/nuttx/mm/kasan.h @@ -37,9 +37,10 @@ #ifndef CONFIG_MM_KASAN # define kasan_is_poisoned(addr, size) false # define kasan_poison(addr, size) -# define kasan_unpoison(addr, size) +# define kasan_unpoison(addr, size) addr # define kasan_register(addr, size) # define kasan_init_early() +# define kasan_reset_tag(addr) addr #else /**************************************************************************** @@ -99,11 +100,11 @@ void kasan_poison(FAR const void *addr, size_t size); * size - range size * * Returned Value: - * None. + * Return tagged address * ****************************************************************************/ -void kasan_unpoison(FAR const void *addr, size_t size); +FAR void *kasan_unpoison(FAR const void *addr, size_t size); /**************************************************************************** * Name: kasan_register @@ -143,6 +144,19 @@ void kasan_register(FAR void *addr, FAR size_t *size); void kasan_init_early(void); +/**************************************************************************** + * Name: kasan_reset_tag + * + * Input Parameters: + * addr - The address of the memory to reset the tag. + * + * Returned Value: + * Unlabeled address + * + ****************************************************************************/ + +FAR void *kasan_reset_tag(FAR const void *addr); + #undef EXTERN #ifdef __cplusplus } diff --git a/mm/Kconfig b/mm/Kconfig index cfb2a5e539..a817a29673 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -258,6 +258,25 @@ config MM_KASAN bugs in native code. After turn on this option, Please add -fsanitize=kernel-address to CFLAGS/CXXFLAGS too. +if MM_KASAN + +choice + prompt "KAsan Mode" + default MM_KASAN_GENERIC + +config MM_KASAN_GENERIC + bool "KAsan generic mode" + ---help--- + KASan generic mode that does not require hardware support at all + +config MM_KASAN_SW_TAGS + bool "KAsan SW tags" + depends on ARCH_ARM64 + ---help--- + KAsan based on software tags + +endchoice + config MM_KASAN_ALL bool "Enable KASan for the entire image" depends on MM_KASAN @@ -288,7 +307,7 @@ config MM_KASAN_DISABLE_WRITES_CHECK config MM_KASAN_GLOBAL bool "Enable global data check" - depends on MM_KASAN + depends on MM_KASAN_GENERIC default n ---help--- This option enables KASan global data check. diff --git a/mm/kasan/Make.defs b/mm/kasan/Make.defs index 4b1b8b3d25..a2a15b6a03 100644 --- a/mm/kasan/Make.defs +++ b/mm/kasan/Make.defs @@ -23,16 +23,24 @@ CSRCS += hook.c ifeq ($(CONFIG_MM_KASAN),y) -CSRCS += generic.c - -# Disable kernel-address in mm subsystem ifeq ($(CONFIG_ARCH_TOOLCHAIN_GNU),y) - CFLAGS += -fno-sanitize=kernel-address + + ifeq ($(CONFIG_MM_KASAN_GENERIC),y) + CSRCS += generic.c + CFLAGS += -fno-sanitize=kernel-address + endif + + ifeq ($(CONFIG_MM_KASAN_SW_TAGS),y) + CSRCS += sw_tags.c + CFLAGS += -fno-sanitize=kernel-hwaddress + endif + ifeq ($(CONFIG_LTO_NONE),n) CFLAGS += -fno-lto endif + endif endif # Add the core heap directory to the build diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index a300e66eb5..98c94f5e02 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -139,10 +139,10 @@ static void kasan_set_poison(FAR const void *addr, size_t size, bool poisoned) { FAR uintptr_t *p; + irqstate_t flags; unsigned int bit; unsigned int nbit; uintptr_t mask; - int flags; p = kasan_mem_to_shadow(addr, size, &bit); if (p == NULL) @@ -193,6 +193,11 @@ static void kasan_set_poison(FAR const void *addr, size_t size, * Public Functions ****************************************************************************/ +FAR void *kasan_reset_tag(FAR const void *addr) +{ + return (FAR void *)addr; +} + bool kasan_is_poisoned(FAR const void *addr, size_t size) { FAR uintptr_t *p; @@ -207,9 +212,10 @@ void kasan_poison(FAR const void *addr, size_t size) kasan_set_poison(addr, size, true); } -void kasan_unpoison(FAR const void *addr, size_t size) +FAR void *kasan_unpoison(FAR const void *addr, size_t size) { kasan_set_poison(addr, size, false); + return (FAR void *)addr; } void kasan_register(FAR void *addr, FAR size_t *size) diff --git a/mm/kasan/hook.c b/mm/kasan/hook.c index db1c792f8f..8db71f5d84 100644 --- a/mm/kasan/hook.c +++ b/mm/kasan/hook.c @@ -31,6 +31,46 @@ #include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DEFINE_ASAN_LOAD_STORE(size) \ + void __asan_report_load##size##_noabort(FAR void *addr) \ + { \ + kasan_report(addr, size, false, return_address(0)); \ + } \ + void __asan_report_store##size##_noabort(FAR void *addr) \ + { \ + kasan_report(addr, size, true, return_address(0)); \ + } \ + void __asan_load##size##_noabort(FAR void *addr) \ + { \ + kasan_check_report(addr, size, false, return_address(0)); \ + } \ + void __asan_store##size##_noabort(FAR void *addr) \ + { \ + kasan_check_report(addr, size, true, return_address(0)); \ + } \ + void __asan_load##size(FAR void *addr) \ + { \ + kasan_check_report(addr, size, false, return_address(0)); \ + } \ + void __asan_store##size(FAR void *addr) \ + { \ + kasan_check_report(addr, size, true, return_address(0)); \ + } + +#define DEFINE_HWASAN_LOAD_STORE(size) \ + void __hwasan_load##size##_noabort(void *addr) \ + { \ + kasan_check_report(addr, size, false, return_address(0)); \ + } \ + void __hwasan_store##size##_noabort(void *addr) \ + { \ + kasan_check_report(addr, size, true, return_address(0)); \ + } + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -181,34 +221,28 @@ void __asan_storeN(FAR void *addr, size_t size) kasan_check_report(addr, size, true, return_address(0)); } -#define DEFINE_ASAN_LOAD_STORE(size) \ - void __asan_report_load##size##_noabort(FAR void *addr) \ - { \ - kasan_report(addr, size, false, return_address(0)); \ - } \ - void __asan_report_store##size##_noabort(FAR void *addr) \ - { \ - kasan_report(addr, size, true, return_address(0)); \ - } \ - void __asan_load##size##_noabort(FAR void *addr) \ - { \ - kasan_check_report(addr, size, false, return_address(0)); \ - } \ - void __asan_store##size##_noabort(FAR void *addr) \ - { \ - kasan_check_report(addr, size, true, return_address(0)); \ - } \ - void __asan_load##size(FAR void *addr) \ - { \ - kasan_check_report(addr, size, false, return_address(0)); \ - } \ - void __asan_store##size(FAR void *addr) \ - { \ - kasan_check_report(addr, size, true, return_address(0)); \ - } +/* Generic KASan will instrument the following functions */ DEFINE_ASAN_LOAD_STORE(1) DEFINE_ASAN_LOAD_STORE(2) DEFINE_ASAN_LOAD_STORE(4) DEFINE_ASAN_LOAD_STORE(8) DEFINE_ASAN_LOAD_STORE(16) + +/* Soft tags KASan will instrument the following functions */ + +void __hwasan_loadN_noabort(FAR void *addr, size_t size) +{ + kasan_check_report(addr, size, false, return_address(0)); +} + +void __hwasan_storeN_noabort(FAR void *addr, size_t size) +{ + kasan_check_report(addr, size, true, return_address(0)); +} + +DEFINE_HWASAN_LOAD_STORE(1) +DEFINE_HWASAN_LOAD_STORE(2) +DEFINE_HWASAN_LOAD_STORE(4) +DEFINE_HWASAN_LOAD_STORE(8) +DEFINE_HWASAN_LOAD_STORE(16) diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c new file mode 100644 index 0000000000..1313e7b4a3 --- /dev/null +++ b/mm/kasan/sw_tags.c @@ -0,0 +1,199 @@ +/**************************************************************************** + * mm/kasan/sw_tags.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define KASAN_TAG_SHIFT 56 + +#define kasan_get_tag(addr) \ + ((uint8_t)((uint64_t)(addr) >> KASAN_TAG_SHIFT)) + +#define kasan_set_tag(addr, tag) \ + (FAR void *)((((uint64_t)(addr)) & ~((uint64_t)0xff << KASAN_TAG_SHIFT)) | \ + (((uint64_t)(tag)) << KASAN_TAG_SHIFT)) + +#define kasan_random_tag() (rand() % ((1 << (64 - KASAN_TAG_SHIFT)) - 1)) + +#define KASAN_SHADOW_SCALE (sizeof(uintptr_t)) + +#define KASAN_SHADOW_SIZE(size) \ + ((size) + KASAN_SHADOW_SCALE - 1) / KASAN_SHADOW_SCALE +#define KASAN_REGION_SIZE(size) \ + (sizeof(struct kasan_region_s) + KASAN_SHADOW_SIZE(size)) + +#define KASAN_INIT_VALUE 0xdeadcafe + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct kasan_region_s +{ + FAR struct kasan_region_s *next; + uintptr_t begin; + uintptr_t end; + uint8_t shadow[1]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static spinlock_t g_lock; +static FAR struct kasan_region_s *g_region; +static uint32_t g_region_init; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static FAR uint8_t *kasan_mem_to_shadow(FAR const void *ptr, size_t size) +{ + FAR struct kasan_region_s *region; + uintptr_t addr; + + addr = (uintptr_t)kasan_reset_tag(ptr); + if (size == 0 || g_region_init != KASAN_INIT_VALUE) + { + return NULL; + } + + for (region = g_region; region != NULL; region = region->next) + { + if (addr >= region->begin && addr < region->end) + { + DEBUGASSERT(addr + size <= region->end); + addr -= region->begin; + return ®ion->shadow[addr / KASAN_SHADOW_SCALE]; + } + } + + return NULL; +} + +static void kasan_set_poison(FAR const void *addr, + size_t size, uint8_t value) +{ + irqstate_t flags; + FAR uint8_t *p; + + addr = kasan_reset_tag(addr); + p = kasan_mem_to_shadow(addr, size); + if (p == NULL) + { + return; + } + + size = KASAN_SHADOW_SIZE(size); + flags = spin_lock_irqsave(&g_lock); + + while (size--) + { + p[size] = value; + } + + spin_unlock_irqrestore(&g_lock, flags); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +FAR void *kasan_reset_tag(FAR const void *addr) +{ + return (FAR void *) + (((uint64_t)(addr)) & ~((uint64_t)0xff << KASAN_TAG_SHIFT)); +} + +bool kasan_is_poisoned(FAR const void *addr, size_t size) +{ + FAR uint8_t *p; + uint8_t tag; + + tag = kasan_get_tag(addr); + p = kasan_mem_to_shadow(addr, size); + if (p == NULL) + { + return false; + } + + size = KASAN_SHADOW_SIZE(size); + while (size--) + { + if (p[size] != tag) + { + return true; + } + } + + return false; +} + +void kasan_poison(FAR const void *addr, size_t size) +{ + kasan_set_poison(addr, size, 0xff); +} + +FAR void *kasan_unpoison(FAR const void *addr, size_t size) +{ + uint8_t tag = kasan_random_tag(); + + kasan_set_poison(addr, size, tag); + return kasan_set_tag(addr, tag); +} + +void kasan_register(FAR void *addr, FAR size_t *size) +{ + FAR struct kasan_region_s *region; + irqstate_t flags; + + region = (FAR struct kasan_region_s *) + ((FAR char *)addr + *size - KASAN_REGION_SIZE(*size)); + + region->begin = (uintptr_t)addr; + region->end = region->begin + *size; + + flags = spin_lock_irqsave(&g_lock); + region->next = g_region; + g_region = region; + spin_unlock_irqrestore(&g_lock, flags); + + g_region_init = KASAN_INIT_VALUE; + kasan_poison(addr, *size); + *size -= KASAN_REGION_SIZE(*size); +} + +void kasan_init_early(void) +{ + g_region_init = 0; +} diff --git a/mm/mempool/mempool.c b/mm/mempool/mempool.c index 1251d46aa5..7b5363f301 100644 --- a/mm/mempool/mempool.c +++ b/mm/mempool/mempool.c @@ -406,7 +406,7 @@ retry: pool->nalloc++; spin_unlock_irqrestore(&pool->lock, flags); - kasan_unpoison(blk, pool->blocksize); + blk = kasan_unpoison(blk, pool->blocksize); #ifdef CONFIG_MM_FILL_ALLOCATIONS memset(blk, MM_ALLOC_MAGIC, pool->blocksize); #endif @@ -648,7 +648,7 @@ int mempool_deinit(FAR struct mempool_s *pool) { blk = (FAR sq_entry_t *)((FAR char *)blk - count * blocksize); - kasan_unpoison(blk, count * blocksize + sizeof(sq_entry_t)); + blk = kasan_unpoison(blk, count * blocksize + sizeof(sq_entry_t)); pool->free(pool, blk); if (pool->expandsize >= blocksize + sizeof(sq_entry_t)) { @@ -658,8 +658,8 @@ int mempool_deinit(FAR struct mempool_s *pool) if (pool->ibase) { - kasan_unpoison(pool->ibase, - pool->interruptsize / blocksize * blocksize); + pool->ibase = kasan_unpoison(pool->ibase, + pool->interruptsize / blocksize * blocksize); pool->free(pool, pool->ibase); } diff --git a/mm/mm_heap/mm_heapmember.c b/mm/mm_heap/mm_heapmember.c index 239bdf5050..51d385f6b3 100644 --- a/mm/mm_heap/mm_heapmember.c +++ b/mm/mm_heap/mm_heapmember.c @@ -30,6 +30,7 @@ #include #include +#include #include "mm_heap/mm.h" @@ -56,6 +57,7 @@ bool mm_heapmember(FAR struct mm_heap_s *heap, FAR void *mem) { + mem = kasan_reset_tag(mem); #if CONFIG_MM_REGIONS > 1 int i; diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c index 0f81081d11..96adef1a48 100644 --- a/mm/mm_heap/mm_malloc.c +++ b/mm/mm_heap/mm_malloc.c @@ -324,7 +324,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) if (ret) { MM_ADD_BACKTRACE(heap, node); - kasan_unpoison(ret, mm_malloc_size(heap, ret)); + ret = kasan_unpoison(ret, mm_malloc_size(heap, ret)); #ifdef CONFIG_MM_FILL_ALLOCATIONS memset(ret, MM_ALLOC_MAGIC, alignsize - MM_ALLOCNODE_OVERHEAD); #endif diff --git a/mm/mm_heap/mm_memalign.c b/mm/mm_heap/mm_memalign.c index 218ce4e6f5..0aa449f296 100644 --- a/mm/mm_heap/mm_memalign.c +++ b/mm/mm_heap/mm_memalign.c @@ -277,8 +277,10 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, MM_ADD_BACKTRACE(heap, node); - kasan_unpoison((FAR void *)alignedchunk, - mm_malloc_size(heap, (FAR void *)alignedchunk)); + alignedchunk = (uintptr_t)kasan_unpoison + ((FAR const void *)alignedchunk, + mm_malloc_size(heap, + (FAR void *)alignedchunk)); DEBUGASSERT(alignedchunk % alignment == 0); return (FAR void *)alignedchunk; diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c index d18d910a3d..7125a71f04 100644 --- a/mm/mm_heap/mm_realloc.c +++ b/mm/mm_heap/mm_realloc.c @@ -385,8 +385,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, mm_unlock(heap); MM_ADD_BACKTRACE(heap, (FAR char *)newmem - MM_SIZEOF_ALLOCNODE); - kasan_unpoison(newmem, mm_malloc_size(heap, newmem)); - if (newmem != oldmem) + newmem = kasan_unpoison(newmem, mm_malloc_size(heap, newmem)); + if (kasan_reset_tag(newmem) != kasan_reset_tag(oldmem)) { /* Now we have to move the user contents 'down' in memory. memcpy * should be safe for this. diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c index b8056c0a86..d6241a4c5d 100644 --- a/mm/tlsf/mm_tlsf.c +++ b/mm/tlsf/mm_tlsf.c @@ -1183,7 +1183,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size) memdump_backtrace(heap, buf); #endif - kasan_unpoison(ret, mm_malloc_size(heap, ret)); + ret = kasan_unpoison(ret, mm_malloc_size(heap, ret)); #ifdef CONFIG_MM_FILL_ALLOCATIONS memset(ret, 0xaa, nodesize); @@ -1260,7 +1260,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment, memdump_backtrace(heap, buf); #endif - kasan_unpoison(ret, mm_malloc_size(heap, ret)); + ret = kasan_unpoison(ret, mm_malloc_size(heap, ret)); } #if CONFIG_MM_FREE_DELAYCOUNT_MAX > 0