Skip to content

Commit 9df3f50

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64: avoid redundant PAC stripping in __builtin_return_address()
In old versions of GCC and Clang, __builtin_return_address() did not strip the PAC. This was not the behaviour we desired, and so we wrapped this with code to strip the PAC in commit: 689eae4 ("arm64: mask PAC bits of __builtin_return_address") Since then, both GCC and Clang decided that __builtin_return_address() *should* strip the PAC, and the existing behaviour was a bug. GCC was fixed in 11.1.0, with those fixes backported to 10.2.0, 9.4.0, 8.5.0, but not earlier: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94891 Clang was fixed in 12.0.0, though this was not backported: https://reviews.llvm.org/D75044 When using a compiler whose __builtin_return_address() strips the PAC, our wrapper to strip the PAC is redundant. Similarly, when pointer authentication is not in use within the kernel pointers will not have a PAC, and so there's no point stripping those pointers. To avoid this redundant work, this patch updates the __builtin_return_address() wrapper to only be used when in-kernel pointer authentication is configured and the compiler's __builtin_return_address() does not strip the PAC. This is a cleanup/optimization, and not a fix that requires backporting. Stripping a PAC should be an idempotent operation, and so redundantly stripping the PAC is not harmful. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <[email protected]> Cc: Amit Daniel Kachhap <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: James Morse <[email protected]> Cc: Kristina Martsenko <[email protected]> Cc: Will Deacon <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent b5ecc19 commit 9df3f50

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

arch/arm64/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,20 @@ config ARCH_PROC_KCORE_TEXT
362362
config BROKEN_GAS_INST
363363
def_bool !$(as-instr,1:\n.inst 0\n.rept . - 1b\n\nnop\n.endr\n)
364364

365+
config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
366+
bool
367+
# Clang's __builtin_return_adddress() strips the PAC since 12.0.0
368+
# https://reviews.llvm.org/D75044
369+
default y if CC_IS_CLANG && (CLANG_VERSION >= 120000)
370+
# GCC's __builtin_return_address() strips the PAC since 11.1.0,
371+
# and this was backported to 10.2.0, 9.4.0, 8.5.0, but not earlier
372+
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94891
373+
default y if CC_IS_GCC && (GCC_VERSION >= 110100)
374+
default y if CC_IS_GCC && (GCC_VERSION >= 100200) && (GCC_VERSION < 110000)
375+
default y if CC_IS_GCC && (GCC_VERSION >= 90400) && (GCC_VERSION < 100000)
376+
default y if CC_IS_GCC && (GCC_VERSION >= 80500) && (GCC_VERSION < 90000)
377+
default n
378+
365379
config KASAN_SHADOW_OFFSET
366380
hex
367381
depends on KASAN_GENERIC || KASAN_SW_TAGS

arch/arm64/include/asm/compiler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
((ptr & BIT_ULL(55)) ? (ptr | ptrauth_kernel_pac_mask()) : \
2121
(ptr & ~ptrauth_user_pac_mask()))
2222

23+
#if defined(CONFIG_ARM64_PTR_AUTH_KERNEL) && \
24+
!defined(CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC)
2325
#define __builtin_return_address(val) \
2426
(void *)(ptrauth_clear_pac((unsigned long)__builtin_return_address(val)))
27+
#endif
2528

2629
#endif /* __ASM_COMPILER_H */

0 commit comments

Comments
 (0)