kasan: Implementing global variable out of bounds detection

Extracting global variable information using scripts:
kasan_global.py:
1. Extract the global variable information provided by the -- param asan globals=1 option
2. Generate shadow regions for global variable out of bounds detection
Makefile:
1. Implement multiple links, embed the shadow area into the program, and call it by the Kasan module

Signed-off-by: W-M-R <mike_0528@163.com>
This commit is contained in:
W-M-R
2024-04-07 18:20:17 +08:00
committed by Xiang Xiao
parent 2fd73bd82f
commit 0ede3fc377
16 changed files with 566 additions and 48 deletions
+15
View File
@@ -281,6 +281,21 @@ config MM_KASAN_DISABLE_WRITES_CHECK
---help---
This option disable kasan writes check.
config MM_KASAN_GLOBAL
bool "Enable global data check"
depends on MM_KASAN
default n
---help---
This option enables KASan global data check.
It's used to extract segments in the linker script.
Two new segments need to be created, one being
".kasan.unused: { *(.data..LASANLOC*) }",
used to eliminate excess data generated.
One is ".kasan.global:{
KEEP ( *(. data.. LASAN0))
KEEP ( *(. data. rel. local.. LASAN0))
}", used to extract data generated by the compiler
config MM_UBSAN
bool "Undefined Behavior Sanitizer"
default n
+49 -3
View File
@@ -50,6 +50,16 @@
#define KASAN_REGION_SIZE(size) \
(sizeof(struct kasan_region_s) + KASAN_SHADOW_SIZE(size))
#ifdef CONFIG_MM_KASAN_GLOBAL
# define KASAN_GLOBAL_SHADOW_SCALE (32)
# define KASAN_GLOBAL_NEXT_REGION(region) \
(FAR struct kasan_region_s *) \
((FAR char *)region->shadow + (size_t)region->next)
#endif
#define KASAN_INIT_VALUE 0xDEADCAFE
/****************************************************************************
@@ -59,9 +69,9 @@
struct kasan_region_s
{
FAR struct kasan_region_s *next;
uintptr_t begin;
uintptr_t end;
uintptr_t shadow[1];
uintptr_t begin;
uintptr_t end;
uintptr_t shadow[1];
};
/****************************************************************************
@@ -72,6 +82,14 @@ static spinlock_t g_lock;
static FAR struct kasan_region_s *g_region;
static uint32_t g_region_init;
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef CONFIG_MM_KASAN_GLOBAL
extern const unsigned char g_globals_region[];
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -99,6 +117,22 @@ static FAR uintptr_t *kasan_mem_to_shadow(FAR const void *ptr, size_t size,
}
}
#ifdef CONFIG_MM_KASAN_GLOBAL
for (region = (FAR struct kasan_region_s *)g_globals_region;
region->next;
region = KASAN_GLOBAL_NEXT_REGION(region))
{
if (addr >= region->begin && addr < region->end)
{
DEBUGASSERT(addr + size <= region->end);
addr -= region->begin;
addr /= KASAN_GLOBAL_SHADOW_SCALE;
*bit = addr % KASAN_BITS_PER_WORD;
return &region->shadow[addr / KASAN_BITS_PER_WORD];
}
}
#endif
return NULL;
}
@@ -314,3 +348,15 @@ DEFINE_ASAN_LOAD_STORE(2)
DEFINE_ASAN_LOAD_STORE(4)
DEFINE_ASAN_LOAD_STORE(8)
DEFINE_ASAN_LOAD_STORE(16)
#ifdef CONFIG_MM_KASAN_GLOBAL
void __asan_register_globals(void *ptr, ssize_t size)
{
/* Shut up compiler complaints */
}
void __asan_unregister_globals(void *ptr, ssize_t size)
{
/* Shut up compiler complaints */
}
#endif