diff options
Diffstat (limited to 'mm/kasan/shadow.c')
-rw-r--r-- | mm/kasan/shadow.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c index 15cfb34d16a1..c8b86f3273b5 100644 --- a/mm/kasan/shadow.c +++ b/mm/kasan/shadow.c @@ -38,6 +38,15 @@ bool __kasan_check_write(const volatile void *p, unsigned int size) } EXPORT_SYMBOL(__kasan_check_write); +#if !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) && !defined(CONFIG_GENERIC_ENTRY) +/* + * CONFIG_GENERIC_ENTRY relies on compiler emitted mem*() calls to not be + * instrumented. KASAN enabled toolchains should emit __asan_mem*() functions + * for the sites they want to instrument. + * + * If we have a compiler that can instrument meminstrinsics, never override + * these, so that non-instrumented files can safely consider them as builtins. + */ #undef memset void *memset(void *addr, int c, size_t len) { @@ -68,6 +77,49 @@ void *memcpy(void *dest, const void *src, size_t len) return __memcpy(dest, src, len); } +#endif + +void *__asan_memset(void *addr, int c, size_t len) +{ + if (!kasan_check_range((unsigned long)addr, len, true, _RET_IP_)) + return NULL; + + return __memset(addr, c, len); +} +EXPORT_SYMBOL(__asan_memset); + +#ifdef __HAVE_ARCH_MEMMOVE +void *__asan_memmove(void *dest, const void *src, size_t len) +{ + if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) || + !kasan_check_range((unsigned long)dest, len, true, _RET_IP_)) + return NULL; + + return __memmove(dest, src, len); +} +EXPORT_SYMBOL(__asan_memmove); +#endif + +void *__asan_memcpy(void *dest, const void *src, size_t len) +{ + if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) || + !kasan_check_range((unsigned long)dest, len, true, _RET_IP_)) + return NULL; + + return __memcpy(dest, src, len); +} +EXPORT_SYMBOL(__asan_memcpy); + +#ifdef CONFIG_KASAN_SW_TAGS +void *__hwasan_memset(void *addr, int c, size_t len) __alias(__asan_memset); +EXPORT_SYMBOL(__hwasan_memset); +#ifdef __HAVE_ARCH_MEMMOVE +void *__hwasan_memmove(void *dest, const void *src, size_t len) __alias(__asan_memmove); +EXPORT_SYMBOL(__hwasan_memmove); +#endif +void *__hwasan_memcpy(void *dest, const void *src, size_t len) __alias(__asan_memcpy); +EXPORT_SYMBOL(__hwasan_memcpy); +#endif void kasan_poison(const void *addr, size_t size, u8 value, bool init) { |