mm/kasan: Using arrays instead of linked lists

1. Modify the Kasan global variable script to support array storage of region addresses
2. Due to the lack of formatting in the previous attempt, a formatting script was created

Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
This commit is contained in:
wangmingrong1 2024-09-12 11:24:54 +08:00 committed by Xiang Xiao
parent 7796161ee2
commit 5c511443fe
4 changed files with 59 additions and 75 deletions

View File

@ -293,6 +293,10 @@ config MM_KASAN_ALL
to check. Enabling this option will get image size increased
and performance decreased significantly.
config MM_KASAN_REGIONS
int "Kasan region count"
default 8
config MM_KASAN_WATCHPOINT
int "Kasan watchpoint maximum number"
default 0

View File

@ -52,13 +52,7 @@
(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
/****************************************************************************
@ -67,7 +61,6 @@
struct kasan_region_s
{
FAR struct kasan_region_s *next;
uintptr_t begin;
uintptr_t end;
uintptr_t shadow[1];
@ -77,15 +70,16 @@ struct kasan_region_s
* Private Data
****************************************************************************/
static FAR struct kasan_region_s *g_region[CONFIG_MM_KASAN_REGIONS];
static size_t g_region_count;
static spinlock_t g_lock;
static FAR struct kasan_region_s *g_region;
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef CONFIG_MM_KASAN_GLOBAL
extern const unsigned char g_globals_region[];
extern const struct kasan_region_s *g_global_region[];
#endif
/****************************************************************************
@ -96,35 +90,35 @@ static inline_function FAR uintptr_t *
kasan_mem_to_shadow(FAR const void *ptr, size_t size,
FAR unsigned int *bit, FAR size_t *align)
{
FAR struct kasan_region_s *region;
uintptr_t addr = (uintptr_t)ptr;
size_t i;
for (region = g_region; region != NULL; region = region->next)
for (i = 0; i < g_region_count; i++)
{
if (addr >= region->begin && addr < region->end)
if (addr >= g_region[i]->begin && addr < g_region[i]->end)
{
DEBUGASSERT(addr + size <= region->end);
addr -= region->begin;
DEBUGASSERT(addr + size <= g_region[i]->end);
addr -= g_region[i]->begin;
*align = KASAN_SHADOW_SCALE;
addr /= KASAN_SHADOW_SCALE;
*bit = addr % KASAN_BITS_PER_WORD;
return &region->shadow[addr / KASAN_BITS_PER_WORD];
return &g_region[i]->shadow[addr / KASAN_BITS_PER_WORD];
}
}
#ifdef CONFIG_MM_KASAN_GLOBAL
for (region = (FAR struct kasan_region_s *)g_globals_region;
region->next;
region = KASAN_GLOBAL_NEXT_REGION(region))
for (i = 0; g_global_region[i]; i++)
{
if (addr >= region->begin && addr < region->end)
if (addr >= g_global_region[i]->begin
&& addr < g_global_region[i]->end)
{
DEBUGASSERT(addr + size <= region->end);
addr -= region->begin;
DEBUGASSERT(addr + size <= g_global_region[i]->end);
addr -= g_global_region[i]->begin;
*align = KASAN_GLOBAL_SHADOW_SCALE;
addr /= KASAN_GLOBAL_SHADOW_SCALE;
*bit = addr % KASAN_BITS_PER_WORD;
return &region->shadow[addr / KASAN_BITS_PER_WORD];
return (FAR uintptr_t *)
&g_global_region[i]->shadow[addr / KASAN_BITS_PER_WORD];
}
}
#endif
@ -270,8 +264,10 @@ void kasan_register(FAR void *addr, FAR size_t *size)
region->end = region->begin + *size;
flags = spin_lock_irqsave(&g_lock);
region->next = g_region;
g_region = region;
DEBUGASSERT(g_region_count <= CONFIG_MM_KASAN_REGIONS);
g_region[g_region_count++] = region;
spin_unlock_irqrestore(&g_lock, flags);
kasan_start();
@ -281,28 +277,19 @@ void kasan_register(FAR void *addr, FAR size_t *size)
void kasan_unregister(FAR void *addr)
{
FAR struct kasan_region_s *prev = NULL;
FAR struct kasan_region_s *region;
irqstate_t flags;
size_t i;
flags = spin_lock_irqsave(&g_lock);
for (region = g_region; region != NULL; region = region->next)
for (i = 0; i < g_region_count; i++)
{
if (region->begin == (uintptr_t)addr)
if (g_region[i]->begin == (uintptr_t)addr)
{
if (region == g_region)
{
g_region = region->next;
}
else
{
prev->next = region->next;
}
g_region_count--;
memmove(&g_region[i], &g_region[i + 1],
(g_region_count - i) * sizeof(g_region[0]));
break;
}
prev = region;
}
spin_unlock_irqrestore(&g_lock, flags);

View File

@ -58,7 +58,6 @@
struct kasan_region_s
{
FAR struct kasan_region_s *next;
uintptr_t begin;
uintptr_t end;
uint8_t shadow[1];
@ -68,8 +67,9 @@ struct kasan_region_s
* Private Data
****************************************************************************/
static FAR struct kasan_region_s *g_region[CONFIG_MM_KASAN_REGIONS];
static int g_region_count;
static spinlock_t g_lock;
static FAR struct kasan_region_s *g_region;
/****************************************************************************
* Private Functions
@ -78,18 +78,18 @@ static FAR struct kasan_region_s *g_region;
static inline_function FAR uint8_t *
kasan_mem_to_shadow(FAR const void *ptr, size_t size)
{
FAR struct kasan_region_s *region;
uintptr_t addr;
int i;
addr = (uintptr_t)kasan_reset_tag(ptr);
for (region = g_region; region != NULL; region = region->next)
for (i = 0; i < g_region_count; i++)
{
if (addr >= region->begin && addr < region->end)
if (addr >= g_region[i]->begin && addr < g_region[i]->end)
{
DEBUGASSERT(addr + size <= region->end);
addr -= region->begin;
return &region->shadow[addr / KASAN_SHADOW_SCALE];
DEBUGASSERT(addr + size <= g_region[i]->end);
addr -= g_region[i]->begin;
return &g_region[i]->shadow[addr / KASAN_SHADOW_SCALE];
}
}
@ -179,8 +179,10 @@ void kasan_register(FAR void *addr, FAR size_t *size)
region->end = region->begin + *size;
flags = spin_lock_irqsave(&g_lock);
region->next = g_region;
g_region = region;
DEBUGASSERT(g_region_count <= CONFIG_MM_KASAN_REGIONS);
g_region[g_region_count++] = region;
spin_unlock_irqrestore(&g_lock, flags);
kasan_start();
@ -190,28 +192,19 @@ void kasan_register(FAR void *addr, FAR size_t *size)
void kasan_unregister(FAR void *addr)
{
FAR struct kasan_region_s *prev = NULL;
FAR struct kasan_region_s *region;
irqstate_t flags;
size_t i;
flags = spin_lock_irqsave(&g_lock);
for (region = g_region; region != NULL; region = region->next)
for (i = 0; i < g_region_count; i++)
{
if (region->begin == (uintptr_t)addr)
if (g_region[i]->begin == (uintptr_t)addr)
{
if (region == g_region)
{
g_region = region->next;
}
else
{
prev->next = region->next;
}
g_region_count--;
memmove(&g_region[i], &g_region[i + 1],
(g_region_count - i) * sizeof(g_region[0]));
break;
}
prev = region;
}
spin_unlock_irqrestore(&g_lock, flags);

View File

@ -196,24 +196,20 @@ def long_to_bytestring(bitwides, endian, value: int) -> str:
def create_kasan_file(config: Config, region_list=[]):
region: KASanRegion = None
with open(config.outpath, "w") as file:
file.write("const unsigned char\ng_globals_region[] = {\n")
# Write the kasan region array
for i in range(len(region_list)):
file.write("static const unsigned char\nglobals_region%d[] = {\n" % (i))
region = region_list[i]
# Fill the array of regions
# The filling order is as follows, from mm/kasan/generic.c
# The data set to 0 is assigned by the program body
# 1. FAR struct kasan_region_s *next;
# This type will be used to record the size of the shadow area
# This type will be used to record the size of the shadow area
# to facilitate the program to traverse the array.
# 2. uintptr_t begin;
# 3. uintptr_t end;
# 4. uintptr_t shadow[1];
file.write(
"%s\n"
% (long_to_bytestring(config.bitwides, config.endian, region.size))
)
file.write(
"%s\n"
% (long_to_bytestring(config.bitwides, config.endian, region.start))
@ -228,9 +224,13 @@ def create_kasan_file(config: Config, region_list=[]):
file.write("\n")
file.write("0x%02x, " % (region.shadow[j]))
file.write("\n")
file.write("0x00, 0x00, 0x00, 0x00,0x00, 0x00,0x00, 0x00\n")
file.write("\n};")
file.write("\n};")
# Record kasan region pointer location
file.write("\nconst unsigned long g_global_region[] = {\n")
for i in range(len(region_list)):
file.write("\n(const unsigned long)&globals_region%d," % (i))
file.write("0x00\n};")
# Error extraction section processing to enable the program to compile successfully