From 51593dd0c6cf1f69b813ba9c507f74f3641bdc68 Mon Sep 17 00:00:00 2001 From: Harshit Sharma Date: Sat, 8 Aug 2020 17:51:59 -0700 Subject: arch/x86: Add support for ASan to memory functions Compiler's instrumentation cannot insert asan memory checks in case of memory functions like memset, memcpy and memmove as they are written in assembly. So, we need to manually check the memory state before performing each of these operations to ensure that ASan is triggered in case of bad access. Change-Id: I2030437636c77aea7cccda8efe050df4b77c15c7 Signed-off-by: Harshit Sharma Reviewed-on: https://review.coreboot.org/c/coreboot/+/44307 Tested-by: build bot (Jenkins) Reviewed-by: Werner Zeh --- src/arch/x86/memcpy.c | 8 ++++++++ src/arch/x86/memmove.c | 8 ++++++++ src/arch/x86/memset.c | 7 +++++++ 3 files changed, 23 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/memcpy.c b/src/arch/x86/memcpy.c index 2f23219de5..1cfdf89175 100644 --- a/src/arch/x86/memcpy.c +++ b/src/arch/x86/memcpy.c @@ -1,11 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include +#include void *memcpy(void *dest, const void *src, size_t n) { unsigned long d0, d1, d2; +#if (ENV_ROMSTAGE && CONFIG(ASAN_IN_ROMSTAGE)) || \ + (ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE)) + check_memory_region((unsigned long)src, n, false, _RET_IP_); + check_memory_region((unsigned long)dest, n, true, _RET_IP_); +#endif + asm volatile( #ifdef __x86_64__ "rep ; movsd\n\t" diff --git a/src/arch/x86/memmove.c b/src/arch/x86/memmove.c index cdd1e8dc70..3ec50b26ae 100644 --- a/src/arch/x86/memmove.c +++ b/src/arch/x86/memmove.c @@ -4,12 +4,20 @@ */ #include +#include +#include void *memmove(void *dest, const void *src, size_t n) { int d0, d1, d2, d3, d4, d5; char *ret = dest; +#if (ENV_ROMSTAGE && CONFIG(ASAN_IN_ROMSTAGE)) || \ + (ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE)) + check_memory_region((unsigned long)src, n, false, _RET_IP_); + check_memory_region((unsigned long)dest, n, true, _RET_IP_); +#endif + __asm__ __volatile__( /* Handle more 16bytes in loop */ "cmp $0x10, %0\n\t" diff --git a/src/arch/x86/memset.c b/src/arch/x86/memset.c index 17963426c0..fc09a9bd52 100644 --- a/src/arch/x86/memset.c +++ b/src/arch/x86/memset.c @@ -4,6 +4,8 @@ #include #include +#include +#include typedef uint32_t op_t; @@ -12,6 +14,11 @@ void *memset(void *dstpp, int c, size_t len) int d0; unsigned long int dstp = (unsigned long int) dstpp; +#if (ENV_ROMSTAGE && CONFIG(ASAN_IN_ROMSTAGE)) || \ + (ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE)) + check_memory_region((unsigned long)dstpp, len, true, _RET_IP_); +#endif + /* This explicit register allocation improves code very much indeed. */ register op_t x asm("ax"); -- cgit v1.2.3