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:
parent
7796161ee2
commit
5c511443fe
@ -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
|
||||
|
@ -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 ®ion->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 ®ion->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);
|
||||
|
@ -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 ®ion->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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user