On Wed, 28 Aug 2024 at 16:42, Alice Ryhl <aliceryhl@xxxxxxxxxx> wrote: > > On Wed, Aug 28, 2024 at 3:48 PM Ard Biesheuvel <ardb@xxxxxxxxxx> wrote: > > > > On Mon, 26 Aug 2024 at 16:23, Alice Ryhl <aliceryhl@xxxxxxxxxx> wrote: > > > > > > This patch adds all of the flags that are needed to support the shadow > > > call stack (SCS) sanitizer with Rust, and updates Kconfig to allow only > > > configurations that work. > > > > > > The -Zfixed-x18 flag is required to use SCS on arm64, and requires rustc > > > version 1.80.0 or greater. This restriction is reflected in Kconfig. > > > > > > When CONFIG_DYNAMIC_SCS is enabled, the build will be configured to > > > include unwind tables in the build artifacts. Dynamic SCS uses the > > > unwind tables at boot to find all places that need to be patched. The > > > -Cforce-unwind-tables=y flag ensures that unwind tables are available > > > for Rust code. > > > > > > In non-dynamic mode, the -Zsanitizer=shadow-call-stack flag is what > > > enables the SCS sanitizer. Using this flag requires rustc version 1.82.0 > > > or greater on the targets used by Rust in the kernel. This restriction > > > is reflected in Kconfig. > > > > > > It is possible to avoid the requirement of rustc 1.80.0 by using > > > -Ctarget-feature=+reserve-x18 instead of -Zfixed-x18. However, this flag > > > emits a warning during the build, so this patch does not add support for > > > using it and instead requires 1.80.0 or greater. > > > > > > The dependency is placed on `select HAVE_RUST` to avoid a situation > > > where enabling Rust silently turns off the sanitizer. Instead, turning > > > on the sanitizer results in Rust being disabled. We generally do not > > > want changes to CONFIG_RUST to result in any mitigations being changed > > > or turned off. > > > > > > At the time of writing, rustc 1.82.0 only exists via the nightly release > > > channel. There is a chance that the -Zsanitizer=shadow-call-stack flag > > > will end up needing 1.83.0 instead, but I think it is small. > > > > > > Signed-off-by: Alice Ryhl <aliceryhl@xxxxxxxxxx> > > > --- > > > Link: https://lore.kernel.org/rust-for-linux/20240808221138.873750-1-ojeda@xxxxxxxxxx/ [1] > > > --- > > > Changes in v6: > > > - Move Kconfig requirements into arch/*/Kconfig. > > > - List non-dynamic SCS as supported on 1.82. This reflects newly added > > > things in rustc. > > > - Link to v5: https://lore.kernel.org/r/20240806-shadow-call-stack-v5-1-26dccb829154@xxxxxxxxxx > > > > > > Changes in v5: > > > - Rebase series on v6.11-rc2. > > > - The first patch is no longer included as it was merged in v6.11-rc2. > > > - The commit message is rewritten from scratch. > > > - Link to v4: https://lore.kernel.org/r/20240729-shadow-call-stack-v4-0-2a664b082ea4@xxxxxxxxxx > > > > > > Changes in v4: > > > - Move `depends on` to CONFIG_RUST. > > > - Rewrite commit messages to include more context. > > > - Link to v3: https://lore.kernel.org/r/20240704-shadow-call-stack-v3-0-d11c7a6ebe30@xxxxxxxxxx > > > > > > Changes in v3: > > > - Use -Zfixed-x18. > > > - Add logic to reject unsupported rustc versions. > > > - Also include a fix to be backported. > > > - Link to v2: https://lore.kernel.org/rust-for-linux/20240305-shadow-call-stack-v2-1-c7b4a3f4d616@xxxxxxxxxx/ > > > > > > Changes in v2: > > > - Add -Cforce-unwind-tables flag. > > > - Link to v1: https://lore.kernel.org/rust-for-linux/20240304-shadow-call-stack-v1-1-f055eaf40a2c@xxxxxxxxxx/ > > > --- > > > Makefile | 1 + > > > arch/arm64/Kconfig | 7 ++++++- > > > arch/arm64/Makefile | 3 +++ > > > arch/riscv/Kconfig | 7 ++++++- > > > init/Kconfig | 1 - > > > 5 files changed, 16 insertions(+), 3 deletions(-) > > > > > > diff --git a/Makefile b/Makefile > > > index 44c02a6f60a1..eb01a26d8354 100644 > > > --- a/Makefile > > > +++ b/Makefile > > > @@ -927,6 +927,7 @@ ifdef CONFIG_SHADOW_CALL_STACK > > > ifndef CONFIG_DYNAMIC_SCS > > > CC_FLAGS_SCS := -fsanitize=shadow-call-stack > > > KBUILD_CFLAGS += $(CC_FLAGS_SCS) > > > +KBUILD_RUSTFLAGS += -Zsanitizer=shadow-call-stack > > > endif > > > export CC_FLAGS_SCS > > > endif > > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > > > index a2f8ff354ca6..28c4a3035331 100644 > > > --- a/arch/arm64/Kconfig > > > +++ b/arch/arm64/Kconfig > > > @@ -231,7 +231,7 @@ config ARM64 > > > select HAVE_FUNCTION_ARG_ACCESS_API > > > select MMU_GATHER_RCU_TABLE_FREE > > > select HAVE_RSEQ > > > - select HAVE_RUST if CPU_LITTLE_ENDIAN > > > + select HAVE_RUST if RUSTC_SUPPORTS_ARM64 > > > select HAVE_STACKPROTECTOR > > > select HAVE_SYSCALL_TRACEPOINTS > > > select HAVE_KPROBES > > > @@ -265,6 +265,11 @@ config ARM64 > > > help > > > ARM 64-bit (AArch64) Linux support. > > > > > > +config RUSTC_SUPPORTS_ARM64 > > > > Nit: could we choose a better name here? ARCH_HAVE_RUST perhaps? > > This is the name suggested by Will Deacon in the previous version. I'm > happy to change it if you prefer, but I'm wondering if that name is > too close to HAVE_RUST? Perhaps ARCH_SUPPORTS_RUST? Ultimately I think > that the current name is okay. > Fair enough. Let's leave it as-is. > > > + def_bool y > > > + depends on CPU_LITTLE_ENDIAN > > > + depends on !SHADOW_CALL_STACK || RUSTC_VERSION >= 108200 || RUSTC_VERSION >= 108000 && UNWIND_PATCH_PAC_INTO_SCS > > > + > > > > This is a bit opaque, so I'd prefer to have a comment here, explaining > > that rustc 1.82 supports emitting the instrumentation statically, but > > 1.80 is needed to get the X18 reservation, which the DWARF based > > patching logic relies on. > > Hmm. I tried a few different wordings and ended on this: > > config RUSTC_SUPPORTS_ARM64 > def_bool y > depends on CPU_LITTLE_ENDIAN > # Shadow call stack is only supported on some versions of rustc. > # > # When using the UNWIND_PATCH_PAC_INTO_SCS option, rustc version 1.80+ is > # required due to use of the -Zfixed-x18 flag. > # > # Otherwise, rustc version 1.82+ is required due to use of the > # -Zsanitizer=shadow-call-stack flag. > depends on !SHADOW_CALL_STACK || RUSTC_VERSION >= 108200 || > RUSTC_VERSION >= 108000 && UNWIND_PATCH_PAC_INTO_SCS > > This wording avoids getting into the weeds of how SCS works. Do you > prefer something that gets into more detail than this? > This looks fine to me. > > > config CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS > > > def_bool CC_IS_CLANG > > > # https://github.com/ClangBuiltLinux/linux/issues/1507 > > > diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile > > > index f6bc3da1ef11..b058c4803efb 100644 > > > --- a/arch/arm64/Makefile > > > +++ b/arch/arm64/Makefile > > > @@ -57,9 +57,11 @@ KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) > > > ifneq ($(CONFIG_UNWIND_TABLES),y) > > > KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables > > > KBUILD_AFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables > > > +KBUILD_RUSTFLAGS += -Cforce-unwind-tables=n > > > else > > > KBUILD_CFLAGS += -fasynchronous-unwind-tables > > > KBUILD_AFLAGS += -fasynchronous-unwind-tables > > > +KBUILD_RUSTFLAGS += -Cforce-unwind-tables=y -Zuse-sync-unwind=n > > > endif > > > > > > ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) > > > @@ -114,6 +116,7 @@ endif > > > > > > ifeq ($(CONFIG_SHADOW_CALL_STACK), y) > > > KBUILD_CFLAGS += -ffixed-x18 > > > +KBUILD_RUSTFLAGS += -Zfixed-x18 > > > endif > > > > > > ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) > > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > > > index 0f3cd7c3a436..476e38ed9c00 100644 > > > --- a/arch/riscv/Kconfig > > > +++ b/arch/riscv/Kconfig > > > @@ -172,7 +172,7 @@ config RISCV > > > select HAVE_REGS_AND_STACK_ACCESS_API > > > select HAVE_RETHOOK if !XIP_KERNEL > > > select HAVE_RSEQ > > > - select HAVE_RUST if 64BIT > > > + select HAVE_RUST if RUSTC_SUPPORTS_RISCV > > > select HAVE_SAMPLE_FTRACE_DIRECT > > > select HAVE_SAMPLE_FTRACE_DIRECT_MULTI > > > select HAVE_STACKPROTECTOR > > > @@ -202,6 +202,11 @@ config RISCV > > > select UACCESS_MEMCPY if !MMU > > > select ZONE_DMA32 if 64BIT > > > > > > +config RUSTC_SUPPORTS_RISCV > > > + def_bool y > > > + depends on 64BIT > > > + depends on !SHADOW_CALL_STACK || RUSTC_VERSION >= 108200 > > > + > > > > Same nit as above. Also, if this enables shadow call stack on RISC-V > > too, please mention it in the commit log more clearly, as it only > > mentions arm64 by name. > > Same question as above. I came up with: > > config RUSTC_SUPPORTS_RISCV > def_bool y > depends on 64BIT > # Shadow call stack requires rustc version 1.82+ due to use of the > # -Zsanitizer=shadow-call-stack flag. > depends on !SHADOW_CALL_STACK || RUSTC_VERSION >= 108200 > Fine too. > > > config CLANG_SUPPORTS_DYNAMIC_FTRACE > > > def_bool CC_IS_CLANG > > > # https://github.com/ClangBuiltLinux/linux/issues/1817 > > > diff --git a/init/Kconfig b/init/Kconfig > > > index fe76c5d0a72e..e095e94eb9db 100644 > > > --- a/init/Kconfig > > > +++ b/init/Kconfig > > > @@ -1909,7 +1909,6 @@ config RUST > > > depends on !MODVERSIONS > > > depends on !GCC_PLUGINS > > > depends on !RANDSTRUCT > > > - depends on !SHADOW_CALL_STACK > > > depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE > > > help > > > Enables Rust support in the kernel. > > > > > > --- > > > base-commit: 5953fd808fca8116a91678ee5fac00fc198ad93d > > > change-id: 20240304-shadow-call-stack-9c197a4361d9 > > > > > > > With the comments addressed (or refuted) > > > > Reviewed-by: Ard Biesheuvel <ardb@xxxxxxxxxx> > > Thanks for the review! > > Alice >