Skip to content

Commit

Permalink
rust: support for shadow call stack sanitizer
Browse files Browse the repository at this point in the history
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
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.

At the time of writing, all released rustc versions up to and including
1.81 incorrectly think that the Rust targets aarch64-unknown-none and
riscv64-unknown-none-elf don't support -Zsanitizer=shadow-call-stack, so
the build will fail if you enable shadow call stack in non-dynamic mode.
See [1] for the relevant feature request. To avoid this compilation
failure, Kconfig is set up to reject such configurations.

Note that because these configurations are rejected, this patch only
allows SCS to be used with arm64 and not on riscv. However, once [1] is
implemented, I will submit a follow-up patch that allows configurations
without UNWIND_PATCH_PAC_INTO_SCS on sufficiently new compilers. That
patch will implicitly allow SCS to be enabled on riscv, but this is okay
because unlike arm64, riscv does not need any flags for rustc beyond
-Zsanitizer=shadow-call-stack.

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 `depends on` clause is placed on `config 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.

Link: rust-lang/rust#121972 [1]
Signed-off-by: Alice Ryhl <[email protected]>
  • Loading branch information
Darksonn committed Aug 6, 2024
1 parent 5953fd8 commit 518f30a
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 1 deletion.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions arch/arm64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1909,7 +1909,7 @@ config RUST
depends on !MODVERSIONS
depends on !GCC_PLUGINS
depends on !RANDSTRUCT
depends on !SHADOW_CALL_STACK
depends on !SHADOW_CALL_STACK || RUSTC_VERSION >= 108000 && UNWIND_PATCH_PAC_INTO_SCS
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
help
Enables Rust support in the kernel.
Expand Down

0 comments on commit 518f30a

Please sign in to comment.