kasan: add builtin_return_address(0) to kasan

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2023-09-19 10:52:17 +08:00 committed by Xiang Xiao
parent 03e220a271
commit cb94f825af
2 changed files with 35 additions and 22 deletions

View File

@ -157,6 +157,7 @@
*/ */
# define offsetof(a, b) __builtin_offsetof(a, b) # define offsetof(a, b) __builtin_offsetof(a, b)
# define return_address(x) __builtin_return_address(x)
/* Attributes /* Attributes
* *
@ -632,6 +633,7 @@
# undef CONFIG_HAVE_LONG_DOUBLE # undef CONFIG_HAVE_LONG_DOUBLE
# define offsetof(a, b) ((size_t)(&(((a *)(0))->b))) # define offsetof(a, b) ((size_t)(&(((a *)(0))->b)))
# define return_address(x) 0
# define no_builtin(n) # define no_builtin(n)
@ -773,6 +775,7 @@
# undef CONFIG_HAVE_LONG_DOUBLE # undef CONFIG_HAVE_LONG_DOUBLE
# define offsetof(a, b) ((size_t)(&(((a *)(0))->b))) # define offsetof(a, b) ((size_t)(&(((a *)(0))->b)))
# define return_address(x) 0
# define no_builtin(n) # define no_builtin(n)
@ -843,6 +846,7 @@
# define CONFIG_HAVE_FLOAT 1 # define CONFIG_HAVE_FLOAT 1
# define offsetof(a, b) ((size_t)(&(((a *)(0))->b))) # define offsetof(a, b) ((size_t)(&(((a *)(0))->b)))
# define return_address(x) 0
# define no_builtin(n) # define no_builtin(n)
@ -920,6 +924,7 @@
# define UNUSED(a) ((void)(1 || &(a))) # define UNUSED(a) ((void)(1 || &(a)))
# define offsetof(a, b) ((size_t)(&(((a *)(0))->b))) # define offsetof(a, b) ((size_t)(&(((a *)(0))->b)))
# define return_address(x) 0
# define no_builtin(n) # define no_builtin(n)
@ -988,6 +993,7 @@
# define UNUSED(a) ((void)(1 || &(a))) # define UNUSED(a) ((void)(1 || &(a)))
# define offsetof(a, b) ((size_t)(&(((a *)(0))->b))) # define offsetof(a, b) ((size_t)(&(((a *)(0))->b)))
# define return_address(x) 0
# define no_builtin(n) # define no_builtin(n)

View File

@ -102,15 +102,18 @@ static FAR uintptr_t *kasan_mem_to_shadow(FAR const void *ptr, size_t size,
return NULL; return NULL;
} }
static void kasan_report(FAR const void *addr, size_t size, bool is_write) static void kasan_report(FAR const void *addr, size_t size,
bool is_write,
FAR void *return_address)
{ {
static int recursion; static int recursion;
if (++recursion == 1) if (++recursion == 1)
{ {
_alert("kasan detected a %s access error, address at %0#"PRIxPTR _alert("kasan detected a %s access error, address at %p,"
", size is %zu\n", is_write ? "write" : "read", "size is %zu, return address: %p\n",
(uintptr_t)addr, size); is_write ? "write" : "read",
addr, size, return_address);
PANIC(); PANIC();
} }
@ -178,6 +181,16 @@ static void kasan_set_poison(FAR const void *addr, size_t size,
spin_unlock_irqrestore(&g_lock, flags); spin_unlock_irqrestore(&g_lock, flags);
} }
static inline void kasan_check_report(FAR const void *addr, size_t size,
bool is_write,
FAR void *return_address)
{
if (kasan_is_poisoned(addr, size))
{
kasan_report(addr, size, false, return_address);
}
}
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -242,64 +255,58 @@ void __asan_handle_no_return(void)
void __asan_report_load_n_noabort(FAR void *addr, size_t size) void __asan_report_load_n_noabort(FAR void *addr, size_t size)
{ {
kasan_report(addr, size, false); kasan_report(addr, size, false, return_address(0));
} }
void __asan_report_store_n_noabort(FAR void *addr, size_t size) void __asan_report_store_n_noabort(FAR void *addr, size_t size)
{ {
kasan_report(addr, size, true); kasan_report(addr, size, true, return_address(0));
} }
void __asan_loadN_noabort(FAR void *addr, size_t size) void __asan_loadN_noabort(FAR void *addr, size_t size)
{ {
if (kasan_is_poisoned(addr, size)) kasan_check_report(addr, size, false, return_address(0));
{
kasan_report(addr, size, false);
}
} }
void __asan_storeN_noabort(FAR void * addr, size_t size) void __asan_storeN_noabort(FAR void * addr, size_t size)
{ {
if (kasan_is_poisoned(addr, size)) kasan_check_report(addr, size, true, return_address(0));
{
kasan_report(addr, size, true);
}
} }
void __asan_loadN(FAR void *addr, size_t size) void __asan_loadN(FAR void *addr, size_t size)
{ {
__asan_loadN_noabort(addr, size); kasan_check_report(addr, size, false, return_address(0));
} }
void __asan_storeN(FAR void *addr, size_t size) void __asan_storeN(FAR void *addr, size_t size)
{ {
__asan_storeN_noabort(addr, size); kasan_check_report(addr, size, true, return_address(0));
} }
#define DEFINE_ASAN_LOAD_STORE(size) \ #define DEFINE_ASAN_LOAD_STORE(size) \
void __asan_report_load##size##_noabort(FAR void *addr) \ void __asan_report_load##size##_noabort(FAR void *addr) \
{ \ { \
__asan_report_load_n_noabort(addr, size); \ kasan_report(addr, size, false, return_address(0)); \
} \ } \
void __asan_report_store##size##_noabort(FAR void *addr) \ void __asan_report_store##size##_noabort(FAR void *addr) \
{ \ { \
__asan_report_store_n_noabort(addr, size); \ kasan_report(addr, size, true, return_address(0)); \
} \ } \
void __asan_load##size##_noabort(FAR void *addr) \ void __asan_load##size##_noabort(FAR void *addr) \
{ \ { \
__asan_loadN_noabort(addr, size); \ kasan_check_report(addr, size, false, return_address(0)); \
} \ } \
void __asan_store##size##_noabort(FAR void *addr) \ void __asan_store##size##_noabort(FAR void *addr) \
{ \ { \
__asan_storeN_noabort(addr, size); \ kasan_check_report(addr, size, true, return_address(0)); \
} \ } \
void __asan_load##size(FAR void *addr) \ void __asan_load##size(FAR void *addr) \
{ \ { \
__asan_load##size##_noabort(addr); \ kasan_check_report(addr, size, false, return_address(0)); \
} \ } \
void __asan_store##size(FAR void *addr) \ void __asan_store##size(FAR void *addr) \
{ \ { \
__asan_store##size##_noabort(addr); \ kasan_check_report(addr, size, true, return_address(0)); \
} }
DEFINE_ASAN_LOAD_STORE(1) DEFINE_ASAN_LOAD_STORE(1)