This series prepares the powerpc Kconfig and Kbuild files for clang's per-task stack protector support. clang requires '-mstack-protector-guard-offset' to always be passed with the other '-mstack-protector-guard' flags, which does not always happen with the powerpc implementation, unlike arm, arm64, and riscv implementations. This series brings powerpc in line with those other architectures, which allows clang's support to work right away when it is merged. Additionally, there is one other fix needed for the Kconfig test to work correctly when targeting 32-bit.
I have tested this series in QEMU against LKDTM's REPORT_STACK_CANARY with ppc64le_guest_defconfig and pmac32_defconfig built with a toolchain that contains Keith's in-progress pull request, which should land for LLVM 20:
https://github.com/llvm/llvm-project/pull/110928
--- Changes in v2: - Combined patch 1 and 3, as they are fixing the same test for similar reasons; adjust commit message accordingly (Christophe) - Moved stack protector guard flags on one line in Makefile (Christophe) - Add 'Cc: stable' targeting 6.1 and newer for the sake of simplicity, as it is the oldest stable release where this series applies cleanly (folks who want it on earlier releases can request or perform a backport separately). - Pick up Keith's Reviewed-by and Tested-by on both patches. - Add a blurb to commit message of patch 1 explaining why clang's register selection behavior differs from GCC. - Link to v1: https://lore.kernel.org/r/20241007-powerpc-fix-stackprotector-test-clang-v1-...
--- Nathan Chancellor (2): powerpc: Fix stack protector Kconfig test for clang powerpc: Adjust adding stack protector flags to KBUILD_CLAGS for clang
arch/powerpc/Kconfig | 4 ++-- arch/powerpc/Makefile | 13 ++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) --- base-commit: 8cf0b93919e13d1e8d4466eb4080a4c4d9d66d7b change-id: 20241004-powerpc-fix-stackprotector-test-clang-84e67ed82f62
Best regards,
Clang's in-progress per-task stack protector support [1] does not work with the current Kconfig checks because '-mstack-protector-guard-offset' is not provided, unlike all other architecture Kconfig checks.
$ fd Kconfig -x rg -l mstack-protector-guard-offset ./arch/arm/Kconfig ./arch/riscv/Kconfig ./arch/arm64/Kconfig
This produces an error from clang, which is interpreted as the flags not being supported at all when they really are.
$ clang --target=powerpc64-linux-gnu \ -mstack-protector-guard=tls \ -mstack-protector-guard-reg=r13 \ -c -o /dev/null -x c /dev/null clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default
This argument will always be provided by the build system, so mirror other architectures and use '-mstack-protector-guard-offset=0' for testing support, which fixes the issue for clang and does not regress support with GCC.
Even with the first problem addressed, the 32-bit test continues to fail because Kbuild uses the powerpc64le-linux-gnu target for clang and nothing flips the target to 32-bit, resulting in an error about an invalid register valid:
$ clang --target=powerpc64le-linux-gnu \ -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \ -mstack-protector-guard-offset=0 \ -x c -c -o /dev/null /dev/null clang: error: invalid value 'r2' in 'mstack-protector-guard-reg=', expected one of: r13
While GCC allows arbitrary registers, the implementation of '-mstack-protector-guard=tls' in LLVM shares the same code path as the user space thread local storage implementation, which uses a fixed register (2 for 32-bit and 13 for 62-bit), so the command line parsing enforces this limitation.
Use the Kconfig macro '$(m32-flag)', which expands to '-m32' when supported, in the stack protector support cc-option call to properly switch the target to a 32-bit one, which matches what happens in Kbuild. While the 64-bit macro does not strictly need it, add the equivalent 64-bit option for symmetry.
Cc: stable@vger.kernel.org # 6.1+ Link: https://github.com/llvm/llvm-project/pull/110928 [1] Reviewed-by: Keith Packard keithp@keithp.com Tested-by: Keith Packard keithp@keithp.com Signed-off-by: Nathan Chancellor nathan@kernel.org --- arch/powerpc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8094a01974cca1d27002720e706f66bec2a2d035..6aaca48955a34b2a38af1415bfa36f74f35c3f3e 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -275,8 +275,8 @@ config PPC select HAVE_RSEQ select HAVE_SETUP_PER_CPU_AREA if PPC64 select HAVE_SOFTIRQ_ON_OWN_STACK - select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2) - select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) + select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,$(m32-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 -mstack-protector-guard-offset=0) + select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,$(m64-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 -mstack-protector-guard-offset=0) select HAVE_STATIC_CALL if PPC32 select HAVE_SYSCALL_TRACEPOINTS select HAVE_VIRT_CPU_ACCOUNTING
After fixing the HAVE_STACKPROTECTER checks for clang's in-progress per-task stack protector support [1], the build fails during prepare0 because '-mstack-protector-guard-offset' has not been added to KBUILD_CFLAGS yet but the other '-mstack-protector-guard' flags have.
clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default make[4]: *** [scripts/Makefile.build:229: scripts/mod/empty.o] Error 1 make[4]: *** [scripts/Makefile.build:102: scripts/mod/devicetable-offsets.s] Error 1
Mirror other architectures and add all '-mstack-protector-guard' flags to KBUILD_CFLAGS atomically during stack_protector_prepare, which resolves the issue and allows clang's implementation to fully work with the kernel.
Cc: stable@vger.kernel.org # 6.1+ Link: https://github.com/llvm/llvm-project/pull/110928 [1] Reviewed-by: Keith Packard keithp@keithp.com Tested-by: Keith Packard keithp@keithp.com Signed-off-by: Nathan Chancellor nathan@kernel.org --- arch/powerpc/Makefile | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index bbfe4a1f06ef9db9b2f2e48e02096b1e0500a14b..cbb353ddacb7adc5de28cd1fde893de3efdd8272 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -100,13 +100,6 @@ KBUILD_AFLAGS += -m$(BITS) KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION) endif
-cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard=tls -ifdef CONFIG_PPC64 -cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r13 -else -cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r2 -endif - LDFLAGS_vmlinux-y := -Bstatic LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) += -z notext @@ -402,9 +395,11 @@ prepare: stack_protector_prepare PHONY += stack_protector_prepare stack_protector_prepare: prepare0 ifdef CONFIG_PPC64 - $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \ + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) else - $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) + $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \ + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) endif endif
On Wed, 09 Oct 2024 12:26:07 -0700, Nathan Chancellor wrote:
This series prepares the powerpc Kconfig and Kbuild files for clang's per-task stack protector support. clang requires '-mstack-protector-guard-offset' to always be passed with the other '-mstack-protector-guard' flags, which does not always happen with the powerpc implementation, unlike arm, arm64, and riscv implementations. This series brings powerpc in line with those other architectures, which allows clang's support to work right away when it is merged. Additionally, there is one other fix needed for the Kconfig test to work correctly when targeting 32-bit.
[...]
Applied to powerpc/next.
[1/2] powerpc: Fix stack protector Kconfig test for clang https://git.kernel.org/powerpc/c/46e1879deea22eed31e9425d58635895fc0e8040 [2/2] powerpc: Adjust adding stack protector flags to KBUILD_CLAGS for clang https://git.kernel.org/powerpc/c/bee08a9e6ab03caf14481d97b35a258400ffab8f
cheers
linux-stable-mirror@lists.linaro.org