diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2580e27e432874..b27ed9739eea58 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -7,6 +7,10 @@ config CC_HAS_ELFV2 config CC_HAS_PREFIXED def_bool PPC64 && $(cc-option, -mcpu=power10 -mprefixed) +config PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX + def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=kernel-address -mllvm -asan-kernel-mem-intrinsic-prefix=1)) || \ + (CC_IS_GCC && $(cc-option,-fsanitize=kernel-address --param asan-kernel-mem-intrinsic-prefix=1)) + config CC_HAS_PCREL # Clang has a bug (https://github.com/llvm/llvm-project/issues/62372) # where pcrel code is not generated if -msoft-float, -mno-altivec, or @@ -220,9 +224,9 @@ config PPC select HAVE_ARCH_HUGE_VMAP if PPC_RADIX_MMU || PPC_8xx select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_JUMP_LABEL_RELATIVE - select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14 - select HAVE_ARCH_KASAN if PPC_RADIX_MMU - select HAVE_ARCH_KASAN if PPC_BOOK3E_64 + select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14 && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX + select HAVE_ARCH_KASAN if PPC_RADIX_MMU && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX + select HAVE_ARCH_KASAN if PPC_BOOK3E_64 && PPC_CC_HAS_KASAN_MEMINTRINSIC_PREFIX select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN select HAVE_ARCH_KCSAN select HAVE_ARCH_KFENCE if ARCH_SUPPORTS_DEBUG_PAGEALLOC diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h index a690e7da53c279..d62756b87ba4a4 100644 --- a/arch/powerpc/include/asm/kasan.h +++ b/arch/powerpc/include/asm/kasan.h @@ -2,20 +2,9 @@ #ifndef __ASM_KASAN_H #define __ASM_KASAN_H -#if defined(CONFIG_KASAN) && !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) -#define _GLOBAL_KASAN(fn) \ - _GLOBAL(fn); \ - _GLOBAL(__##fn) -#define _GLOBAL_TOC_KASAN(fn) \ - _GLOBAL_TOC(fn); \ - _GLOBAL_TOC(__##fn) -#define EXPORT_SYMBOL_KASAN(fn) \ - EXPORT_SYMBOL(__##fn) -#else /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ #define _GLOBAL_KASAN(fn) _GLOBAL(fn) #define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(fn) #define EXPORT_SYMBOL_KASAN(fn) -#endif /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ #ifndef __ASSEMBLER__ diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index 1981bd4036b548..72b5c93a2b8486 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -29,29 +29,10 @@ extern void * memchr(const void *,int,__kernel_size_t); void memcpy_flushcache(void *dest, const void *src, size_t size); #ifdef CONFIG_KASAN -/* __mem variants are used by KASAN to implement instrumented meminstrinsics. */ -#ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX +/* Used by mm/kasan/shadow.c as raw backends to bypass KASAN checking. */ #define __memset memset #define __memcpy memcpy #define __memmove memmove -#else /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ -void *__memset(void *s, int c, __kernel_size_t count); -void *__memcpy(void *to, const void *from, __kernel_size_t n); -void *__memmove(void *to, const void *from, __kernel_size_t n); -#ifndef __SANITIZE_ADDRESS__ -/* - * For files that are not instrumented (e.g. mm/slub.c) we - * should use not instrumented version of mem* functions. - */ -#define memcpy(dst, src, len) __memcpy(dst, src, len) -#define memmove(dst, src, len) __memmove(dst, src, len) -#define memset(s, c, n) __memset(s, c, n) - -#ifndef __NO_FORTIFY -#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ -#endif -#endif /* !__SANITIZE_ADDRESS__ */ -#endif /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ #endif /* CONFIG_KASAN */ #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 6f6801da9dc1e2..233b5c650d1ebd 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -36,8 +36,12 @@ void __init set_cur_cpu_spec(struct cpu_spec *s) t = PTRRELOC(t); /* - * use memcpy() instead of *t = *s so that GCC replaces it - * by __memcpy() when KASAN is active + * Use memcpy() instead of *t = *s because t is a PTRRELOC-adjusted + * pointer and this code runs before the MMU mapping is established. + * A struct assignment is a compiler-generated aggregate copy whose + * implementation is not under our control in relocation-sensitive code; + * memcpy() ensures the adjusted pointer is explicitly passed to the + * copy routine. */ memcpy(t, s, sizeof(*t)); @@ -55,7 +59,11 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, /* * Copy everything, then do fixups. Use memcpy() instead of *t = *s - * so that GCC replaces it by __memcpy() when KASAN is active + * because t is a PTRRELOC-adjusted pointer and this code runs before + * the MMU mapping is established. A struct assignment is a + * compiler-generated aggregate copy whose implementation is not under + * our control in relocation-sensitive code; memcpy() ensures the + * adjusted pointer is explicitly passed to the copy routine. */ memcpy(t, s, sizeof(*t)); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index eb9f556b0937e3..d6d7f1ede319d6 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1363,10 +1363,12 @@ static void __init prom_check_platform_support(void) "ibm,arch-vec-5-platform-support"); /* - * First copy the architecture vec template - * - * use memcpy() instead of *vec = *vec_template so that GCC replaces it - * by __memcpy() when KASAN is active + * First copy the architecture vec template. Use memcpy() instead of + * a struct assignment because this code runs before the MMU mapping + * is established. A struct assignment is a compiler-generated + * aggregate copy whose implementation is not under our control in + * relocation-sensitive code; memcpy() ensures the adjusted pointer + * is explicitly passed to the copy routine. */ memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template, sizeof(ibm_architecture_vec));