Re: [PATCH v6] rust: support for shadow call stack sanitizer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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?

> +       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.

>  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.

>  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,




[Index of Archives]     [Linux&nblp;USB Development]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite Secrets]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux