Skip to content

Commit d077242

Browse files
Darksonnojeda
authored andcommitted
rust: support for shadow call stack sanitizer
Add 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. Reviewed-by: Sami Tolvanen <[email protected]> Reviewed-by: Ard Biesheuvel <[email protected]> Reviewed-by: Kees Cook <[email protected]> Acked-by: Will Deacon <[email protected]> Signed-off-by: Alice Ryhl <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Fixed indentation using spaces. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 93dc3be commit d077242

File tree

5 files changed

+25
-3
lines changed

5 files changed

+25
-3
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ ifdef CONFIG_SHADOW_CALL_STACK
929929
ifndef CONFIG_DYNAMIC_SCS
930930
CC_FLAGS_SCS := -fsanitize=shadow-call-stack
931931
KBUILD_CFLAGS += $(CC_FLAGS_SCS)
932+
KBUILD_RUSTFLAGS += -Zsanitizer=shadow-call-stack
932933
endif
933934
export CC_FLAGS_SCS
934935
endif

arch/arm64/Kconfig

+13-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ config ARM64
231231
select HAVE_FUNCTION_ARG_ACCESS_API
232232
select MMU_GATHER_RCU_TABLE_FREE
233233
select HAVE_RSEQ
234-
select HAVE_RUST if CPU_LITTLE_ENDIAN
234+
select HAVE_RUST if RUSTC_SUPPORTS_ARM64
235235
select HAVE_STACKPROTECTOR
236236
select HAVE_SYSCALL_TRACEPOINTS
237237
select HAVE_KPROBES
@@ -265,6 +265,18 @@ config ARM64
265265
help
266266
ARM 64-bit (AArch64) Linux support.
267267

268+
config RUSTC_SUPPORTS_ARM64
269+
def_bool y
270+
depends on CPU_LITTLE_ENDIAN
271+
# Shadow call stack is only supported on certain rustc versions.
272+
#
273+
# When using the UNWIND_PATCH_PAC_INTO_SCS option, rustc version 1.80+ is
274+
# required due to use of the -Zfixed-x18 flag.
275+
#
276+
# Otherwise, rustc version 1.82+ is required due to use of the
277+
# -Zsanitizer=shadow-call-stack flag.
278+
depends on !SHADOW_CALL_STACK || RUSTC_VERSION >= 108200 || RUSTC_VERSION >= 108000 && UNWIND_PATCH_PAC_INTO_SCS
279+
268280
config CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS
269281
def_bool CC_IS_CLANG
270282
# https://github.com/ClangBuiltLinux/linux/issues/1507

arch/arm64/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ KBUILD_AFLAGS += $(call cc-option,-mabi=lp64)
5757
ifneq ($(CONFIG_UNWIND_TABLES),y)
5858
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
5959
KBUILD_AFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
60+
KBUILD_RUSTFLAGS += -Cforce-unwind-tables=n
6061
else
6162
KBUILD_CFLAGS += -fasynchronous-unwind-tables
6263
KBUILD_AFLAGS += -fasynchronous-unwind-tables
64+
KBUILD_RUSTFLAGS += -Cforce-unwind-tables=y -Zuse-sync-unwind=n
6365
endif
6466

6567
ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y)
@@ -114,6 +116,7 @@ endif
114116

115117
ifeq ($(CONFIG_SHADOW_CALL_STACK), y)
116118
KBUILD_CFLAGS += -ffixed-x18
119+
KBUILD_RUSTFLAGS += -Zfixed-x18
117120
endif
118121

119122
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)

arch/riscv/Kconfig

+8-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ config RISCV
172172
select HAVE_REGS_AND_STACK_ACCESS_API
173173
select HAVE_RETHOOK if !XIP_KERNEL
174174
select HAVE_RSEQ
175-
select HAVE_RUST if 64BIT
175+
select HAVE_RUST if RUSTC_SUPPORTS_RISCV
176176
select HAVE_SAMPLE_FTRACE_DIRECT
177177
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
178178
select HAVE_STACKPROTECTOR
@@ -202,6 +202,13 @@ config RISCV
202202
select UACCESS_MEMCPY if !MMU
203203
select ZONE_DMA32 if 64BIT
204204

205+
config RUSTC_SUPPORTS_RISCV
206+
def_bool y
207+
depends on 64BIT
208+
# Shadow call stack requires rustc version 1.82+ due to use of the
209+
# -Zsanitizer=shadow-call-stack flag.
210+
depends on !SHADOW_CALL_STACK || RUSTC_VERSION >= 108200
211+
205212
config CLANG_SUPPORTS_DYNAMIC_FTRACE
206213
def_bool CC_IS_CLANG
207214
# https://github.com/ClangBuiltLinux/linux/issues/1817

init/Kconfig

-1
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,6 @@ config RUST
19091909
depends on !MODVERSIONS
19101910
depends on !GCC_PLUGIN_RANDSTRUCT
19111911
depends on !RANDSTRUCT
1912-
depends on !SHADOW_CALL_STACK
19131912
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
19141913
help
19151914
Enables Rust support in the kernel.

0 commit comments

Comments
 (0)