This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 448ace47612349adaeab937f59ff92f1efeedbee Author: wangmingrong1 <wangmingro...@xiaomi.com> AuthorDate: Wed Mar 5 14:52:49 2025 +0800 kasan: fix realloc memcpy tags check error When the size of the new realloc is larger than the old one and can be expanded forward and backward, the tag of oldmem needs to be set to the same as newmem, otherwise memcpy will report a kasan error. Signed-off-by: wangmingrong1 <wangmingro...@xiaomi.com> --- include/nuttx/mm/kasan.h | 21 +++++++++++++++++++++ mm/kasan/generic.c | 10 ++++++++++ mm/kasan/sw_tags.c | 22 +++++++++++++++++++--- mm/mm_heap/mm_realloc.c | 4 +++- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/include/nuttx/mm/kasan.h b/include/nuttx/mm/kasan.h index a1c4d1745c..c066c10863 100644 --- a/include/nuttx/mm/kasan.h +++ b/include/nuttx/mm/kasan.h @@ -41,6 +41,8 @@ # define kasan_unpoison(addr, size) addr # define kasan_register(addr, size) # define kasan_unregister(addr) +# define kasan_get_tag(addr) 0 +# define kasan_set_tag(addr, tag) addr # define kasan_clear_tag(addr) addr # define kasan_start() # define kasan_stop() @@ -132,6 +134,12 @@ void kasan_register(FAR void *addr, FAR size_t *size); void kasan_unregister(FAR void *addr); +/**************************************************************************** + * Name: kasan_set_tag + ****************************************************************************/ + +FAR void *kasan_set_tag(FAR const void *addr, uint8_t tag); + /**************************************************************************** * Name: kasan_clear_tag * @@ -145,6 +153,19 @@ void kasan_unregister(FAR void *addr); FAR void *kasan_clear_tag(FAR const void *addr); +/**************************************************************************** + * Name: kasan_get_tag + * + * Input Parameters: + * addr - The address of the memory to get the tag. + * + * Returned Value: + * address tag + * + ****************************************************************************/ + +uint8_t kasan_get_tag(FAR const void *addr); + /**************************************************************************** * Name: kasan_start * diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index 4c3324ad34..e649be4bd7 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -204,6 +204,16 @@ static void kasan_set_poison(FAR const void *addr, size_t size, * Public Functions ****************************************************************************/ +uint8_t kasan_get_tag(FAR const void *addr) +{ + return 0; +} + +FAR void *kasan_set_tag(FAR const void *addr, uint8_t tag) +{ + return (FAR void *)addr; +} + FAR void *kasan_clear_tag(FAR const void *addr) { return (FAR void *)addr; diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c index 0a48209bc0..b7a155ca54 100644 --- a/mm/kasan/sw_tags.c +++ b/mm/kasan/sw_tags.c @@ -156,10 +156,10 @@ static void kasan_set_poison(FAR const void *addr, * Public Functions ****************************************************************************/ -FAR void *kasan_clear_tag(FAR const void *addr) +FAR void *kasan_set_tag(FAR const void *addr, uint8_t tag) { - return (FAR void *) - (((uint64_t)(addr)) & ~((uint64_t)0xff << KASAN_TAG_SHIFT)); + return (FAR void *)((uint64_t)kasan_clear_tag(addr) | + (((uint64_t)tag) << KASAN_TAG_SHIFT)); } void kasan_poison(FAR const void *addr, size_t size) @@ -167,6 +167,22 @@ void kasan_poison(FAR const void *addr, size_t size) kasan_set_poison(addr, size, 0xff); } +FAR void *kasan_clear_tag(FAR const void *addr) +{ + return (FAR void *) + (((uint64_t)addr) & ~((uint64_t)0xff << KASAN_TAG_SHIFT)); +} + +uint8_t kasan_get_tag(FAR const void *addr) +{ + return (uint8_t)((uint64_t)addr >> KASAN_TAG_SHIFT); +} + +bool kasan_bypass(bool state) +{ + return false; +} + FAR void *kasan_unpoison(FAR const void *addr, size_t size) { uint8_t tag = kasan_random_tag(); diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c index 1835c093cc..a91e2988ea 100644 --- a/mm/mm_heap/mm_realloc.c +++ b/mm/mm_heap/mm_realloc.c @@ -393,7 +393,9 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, newmem = kasan_unpoison(newmem, MM_SIZEOF_NODE(oldnode) - MM_ALLOCNODE_OVERHEAD); - if (kasan_reset_tag(newmem) != kasan_reset_tag(oldmem)) + + oldmem = kasan_set_tag(oldmem, kasan_get_tag(newmem)); + if (newmem != oldmem) { /* Now we have to move the user contents 'down' in memory. memcpy * should be safe for this.