mm/kasan: add kasan watch point implementation
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
parent
e154c6d071
commit
87dc91b588
@ -30,6 +30,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -193,6 +195,28 @@ void kasan_start(void);
|
|||||||
|
|
||||||
void kasan_stop(void);
|
void kasan_stop(void);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: kasan_debugpoint
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Monitor the memory range for invalid access check
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* type - DEBUGPOINT_NONE : remove
|
||||||
|
* DEBUGPOINT_WATCHPOINT_RO: read
|
||||||
|
* DEBUGPOINT_WATCHPOINT_WO: write
|
||||||
|
* DEBUGPOINT_WATCHPOINT_RW: read/write
|
||||||
|
* addr - range start address
|
||||||
|
* size - range size
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* If the setting is successful, it returns 0, otherwise it
|
||||||
|
* returns an error code.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int kasan_debugpoint(int type, FAR void *addr, size_t size);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
11
mm/Kconfig
11
mm/Kconfig
@ -264,6 +264,11 @@ choice
|
|||||||
prompt "KAsan Mode"
|
prompt "KAsan Mode"
|
||||||
default MM_KASAN_GENERIC
|
default MM_KASAN_GENERIC
|
||||||
|
|
||||||
|
config MM_KASAN_NONE
|
||||||
|
bool "KAsan disable"
|
||||||
|
---help---
|
||||||
|
Disable KASan check
|
||||||
|
|
||||||
config MM_KASAN_GENERIC
|
config MM_KASAN_GENERIC
|
||||||
bool "KAsan generic mode"
|
bool "KAsan generic mode"
|
||||||
---help---
|
---help---
|
||||||
@ -288,6 +293,12 @@ config MM_KASAN_ALL
|
|||||||
to check. Enabling this option will get image size increased
|
to check. Enabling this option will get image size increased
|
||||||
and performance decreased significantly.
|
and performance decreased significantly.
|
||||||
|
|
||||||
|
config MM_KASAN_WATCHPOINT
|
||||||
|
int "Kasan watchpoint maximum number"
|
||||||
|
default 0
|
||||||
|
---help---
|
||||||
|
The maximum number of watchpoints that can be set by KASan.
|
||||||
|
|
||||||
config MM_KASAN_DISABLE_NULL_POINTER_CHECK
|
config MM_KASAN_DISABLE_NULL_POINTER_CHECK
|
||||||
bool "Disable null pointer access check"
|
bool "Disable null pointer access check"
|
||||||
default n
|
default n
|
||||||
|
124
mm/kasan/hook.c
124
mm/kasan/hook.c
@ -83,12 +83,33 @@
|
|||||||
# define MM_KASAN_DISABLE_WRITE_PANIC 0
|
# define MM_KASAN_DISABLE_WRITE_PANIC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MM_KASAN_WATCHPOINT
|
||||||
|
# define MM_KASAN_WATCHPOINT CONFIG_MM_KASAN_WATCHPOINT
|
||||||
|
#else
|
||||||
|
# define MM_KASAN_WATCHPOINT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define KASAN_INIT_VALUE 0xdeadcafe
|
#define KASAN_INIT_VALUE 0xdeadcafe
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct kasan_watchpoint_s
|
||||||
|
{
|
||||||
|
FAR void *addr;
|
||||||
|
size_t size;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if MM_KASAN_WATCHPOINT > 0
|
||||||
|
static struct kasan_watchpoint_s g_watchpoint[MM_KASAN_WATCHPOINT];
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint32_t g_region_init;
|
static uint32_t g_region_init;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -164,6 +185,37 @@ static void kasan_report(FAR const void *addr, size_t size,
|
|||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MM_KASAN_WATCHPOINT > 0
|
||||||
|
static void kasan_check_watchpoint(FAR const void *addr, size_t size,
|
||||||
|
bool is_write,
|
||||||
|
FAR void *return_address)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MM_KASAN_WATCHPOINT; i++)
|
||||||
|
{
|
||||||
|
FAR struct kasan_watchpoint_s *watchpoint = &g_watchpoint[i];
|
||||||
|
|
||||||
|
if (watchpoint->type == DEBUGPOINT_NONE)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr + size <= watchpoint->addr ||
|
||||||
|
addr > watchpoint->addr + watchpoint->size)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((is_write && (watchpoint->type & DEBUGPOINT_WATCHPOINT_WO)) ||
|
||||||
|
(!is_write && (watchpoint->type & DEBUGPOINT_WATCHPOINT_RO)))
|
||||||
|
{
|
||||||
|
kasan_report(addr, size, is_write, return_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void kasan_check_report(FAR const void *addr, size_t size,
|
static inline void kasan_check_report(FAR const void *addr, size_t size,
|
||||||
bool is_write,
|
bool is_write,
|
||||||
FAR void *return_address)
|
FAR void *return_address)
|
||||||
@ -180,10 +232,16 @@ static inline void kasan_check_report(FAR const void *addr, size_t size,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_MM_KASAN_NONE
|
||||||
if (kasan_is_poisoned(addr, size))
|
if (kasan_is_poisoned(addr, size))
|
||||||
{
|
{
|
||||||
kasan_report(addr, size, is_write, return_address);
|
kasan_report(addr, size, is_write, return_address);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MM_KASAN_WATCHPOINT > 0
|
||||||
|
kasan_check_watchpoint(addr, size, is_write, return_address);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -200,6 +258,72 @@ void kasan_stop(void)
|
|||||||
g_region_init = 0;
|
g_region_init = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: kasan_debugpoint
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Monitor the memory range for invalid access check
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* type - DEBUGPOINT_NONE : remove
|
||||||
|
* DEBUGPOINT_WATCHPOINT_RO: read
|
||||||
|
* DEBUGPOINT_WATCHPOINT_WO: write
|
||||||
|
* DEBUGPOINT_WATCHPOINT_RW: read/write
|
||||||
|
* addr - range start address
|
||||||
|
* size - range size
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* If the setting is successful, it returns 0, otherwise it
|
||||||
|
* returns an error code.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if MM_KASAN_WATCHPOINT > 0
|
||||||
|
int kasan_debugpoint(int type, FAR void *addr, size_t size)
|
||||||
|
{
|
||||||
|
FAR struct kasan_watchpoint_s *watchpoint;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (addr == NULL || size == 0)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MM_KASAN_WATCHPOINT; i++)
|
||||||
|
{
|
||||||
|
watchpoint = &g_watchpoint[i];
|
||||||
|
if (watchpoint->type == DEBUGPOINT_NONE || watchpoint->addr == addr)
|
||||||
|
{
|
||||||
|
if (type != DEBUGPOINT_NONE)
|
||||||
|
{
|
||||||
|
watchpoint->addr = addr;
|
||||||
|
watchpoint->size = size;
|
||||||
|
watchpoint->type = type;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = MM_KASAN_WATCHPOINT - 1; j > i; j--)
|
||||||
|
{
|
||||||
|
if (g_watchpoint[j].type != DEBUGPOINT_NONE)
|
||||||
|
{
|
||||||
|
watchpoint->addr = g_watchpoint[j].addr;
|
||||||
|
watchpoint->size = g_watchpoint[j].size;
|
||||||
|
watchpoint->type = g_watchpoint[j].type;
|
||||||
|
watchpoint = &g_watchpoint[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watchpoint->type = DEBUGPOINT_NONE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void __asan_before_dynamic_init(FAR const void *module_name)
|
void __asan_before_dynamic_init(FAR const void *module_name)
|
||||||
{
|
{
|
||||||
/* Shut up compiler complaints */
|
/* Shut up compiler complaints */
|
||||||
|
Loading…
Reference in New Issue
Block a user