From a6ebe08333dcc6c263b6bb8936d4883663c63798 Mon Sep 17 00:00:00 2001 From: Harshit Sharma Date: Mon, 20 Jul 2020 00:21:05 -0700 Subject: lib: Add ASan support to romstage on x86 arch This patch adds ASan support to romstage on x86 architecture. A Kconfig option is added to enable ASan in romstage. Compiler flags are updated. A memory space representing the shadow region is reserved in linker section. And a function call to asan_init() is added to initialize shadow region when romstage loads. Change-Id: I67ebfb5e8d602e865b1f5c874860861ae4e54381 Signed-off-by: Harshit Sharma Reviewed-on: https://review.coreboot.org/c/coreboot/+/43604 Tested-by: build bot (Jenkins) Reviewed-by: Werner Zeh --- src/lib/asan.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'src/lib/asan.c') diff --git a/src/lib/asan.c b/src/lib/asan.c index 0c186d62a3..11dbf7c657 100644 --- a/src/lib/asan.c +++ b/src/lib/asan.c @@ -10,18 +10,29 @@ #include #include +#include #include static inline void *asan_mem_to_shadow(const void *addr) { +#if ENV_ROMSTAGE + return (void *)((uintptr_t)&_asan_shadow + (((uintptr_t)addr - + (uintptr_t)&_car_region_start) >> ASAN_SHADOW_SCALE_SHIFT)); +#elif ENV_RAMSTAGE return (void *)((uintptr_t)&_asan_shadow + (((uintptr_t)addr - (uintptr_t)&_data) >> ASAN_SHADOW_SCALE_SHIFT)); +#endif } static inline const void *asan_shadow_to_mem(const void *shadow_addr) { +#if ENV_ROMSTAGE + return (void *)((uintptr_t)&_car_region_start + (((uintptr_t)shadow_addr - + (uintptr_t)&_asan_shadow) << ASAN_SHADOW_SCALE_SHIFT)); +#elif ENV_RAMSTAGE return (void *)((uintptr_t)&_data + (((uintptr_t)shadow_addr - (uintptr_t)&_asan_shadow) << ASAN_SHADOW_SCALE_SHIFT)); +#endif } static void asan_poison_shadow(const void *address, size_t size, u8 value) @@ -225,10 +236,15 @@ static __always_inline void check_memory_region_inline(unsigned long addr, size_t size, bool write, unsigned long ret_ip) { +#if ENV_ROMSTAGE + if (((uintptr_t)addr < (uintptr_t)&_car_region_start) || + ((uintptr_t)addr > (uintptr_t)&_ebss)) + return; +#elif ENV_RAMSTAGE if (((uintptr_t)addr < (uintptr_t)&_data) || - ((uintptr_t)addr > (uintptr_t)&_eheap)) + ((uintptr_t)addr > (uintptr_t)&_eheap)) return; - +#endif if (unlikely(size == 0)) return; @@ -252,8 +268,13 @@ static void check_memory_region(unsigned long addr, size_t size, bool write, uintptr_t __asan_shadow_offset(uintptr_t addr) { +#if ENV_ROMSTAGE + return (uintptr_t)&_asan_shadow - (((uintptr_t)&_car_region_start) >> + ASAN_SHADOW_SCALE_SHIFT); +#elif ENV_RAMSTAGE return (uintptr_t)&_asan_shadow - (((uintptr_t)&_data) >> ASAN_SHADOW_SCALE_SHIFT); +#endif } static void register_global(struct asan_global *global) @@ -285,6 +306,7 @@ void __asan_unregister_globals(struct asan_global *globals, size_t size) * to it so we could poison variable's redzone. * This function calls those constructors. */ +#if ENV_RAMSTAGE static void asan_ctors(void) { extern long __CTOR_LIST__; @@ -296,12 +318,18 @@ static void asan_ctors(void) for (; *ctor != (func_ptr) 0; ctor++) (*ctor)(); } +#endif void asan_init(void) { +#if ENV_ROMSTAGE + size_t size = (size_t)&_ebss - (size_t)&_car_region_start; + asan_unpoison_shadow((void *)&_car_region_start, size); +#elif ENV_RAMSTAGE size_t size = (size_t)&_eheap - (size_t)&_data; asan_unpoison_shadow((void *)&_data, size); asan_ctors(); +#endif } void __asan_poison_stack_memory(const void *addr, size_t size) -- cgit v1.2.3