From 8be4bca3ebdd7f2b3e6f35bbdae649c2baef1bee Mon Sep 17 00:00:00 2001 From: ligd Date: Wed, 2 Nov 2022 23:19:02 +0800 Subject: [PATCH] kasan: fix kasan race-condition Change-Id: I1c729b8a85422a1f4326785e5d52cb0fc60d4822 Signed-off-by: ligd --- mm/kasan/kasan.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c index aec0e20c2b..bff7a998f6 100644 --- a/mm/kasan/kasan.c +++ b/mm/kasan/kasan.c @@ -22,7 +22,7 @@ * Included Files ****************************************************************************/ -#include +#include #include #include @@ -68,7 +68,7 @@ struct kasan_region_s * Private Data ****************************************************************************/ -static mutex_t g_lock = NXMUTEX_INITIALIZER; +static spinlock_t g_lock; static FAR struct kasan_region_s *g_region; static uint32_t g_region_init; @@ -133,6 +133,9 @@ static void kasan_set_poison(FAR const void *addr, size_t size, unsigned int bit; unsigned int nbit; uintptr_t mask; + int flags; + + flags = spin_lock_irqsave(&g_lock); p = kasan_mem_to_shadow(addr, size, &bit); DEBUGASSERT(p != NULL); @@ -171,6 +174,8 @@ static void kasan_set_poison(FAR const void *addr, size_t size, *p &= ~mask; } } + + spin_unlock_irqrestore(&g_lock, flags); } /**************************************************************************** @@ -192,6 +197,7 @@ void kasan_unpoison(FAR const void *addr, size_t size) void kasan_register(FAR void *addr, FAR size_t *size) { FAR struct kasan_region_s *region; + int flags; region = (FAR struct kasan_region_s *) ((FAR char *)addr + *size - KASAN_REGION_SIZE(*size)); @@ -199,11 +205,11 @@ void kasan_register(FAR void *addr, FAR size_t *size) region->begin = (uintptr_t)addr; region->end = region->begin + *size; - nxmutex_lock(&g_lock); + flags = spin_lock_irqsave(&g_lock); region->next = g_region; g_region = region; g_region_init = KASAN_INIT_VALUE; - nxmutex_unlock(&g_lock); + spin_unlock_irqrestore(&g_lock, flags); kasan_poison(addr, *size); *size -= KASAN_REGION_SIZE(*size);