Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit ca627e6

Browse files
maurerojeda
authored andcommitted
rust: cfi: add support for CFI_CLANG with Rust
Make it possible to use the Control Flow Integrity (CFI) sanitizer when Rust is enabled. Enabling CFI with Rust requires that CFI is configured to normalize integer types so that all integer types of the same size and signedness are compatible under CFI. Rust and C use the same LLVM backend for code generation, so Rust KCFI is compatible with the KCFI used in the kernel for C. In the case of FineIBT, CFI also depends on -Zpatchable-function-entry for rewriting the function prologue, so we set that flag for Rust as well. The flag for FineIBT requires rustc 1.80.0 or later, so include a Kconfig requirement for that. Enabling Rust will select CFI_ICALL_NORMALIZE_INTEGERS because the flag is required to use Rust with CFI. Using select rather than `depends on` avoids the case where Rust is not visible in menuconfig due to CFI_ICALL_NORMALIZE_INTEGERS not being enabled. One disadvantage of select is that RUST must `depends on` all of the things that CFI_ICALL_NORMALIZE_INTEGERS depends on to avoid invalid configurations. Alice has been using KCFI on her phone for several months, so it is reasonably well tested on arm64. Signed-off-by: Matthew Maurer <[email protected]> Co-developed-by: Alice Ryhl <[email protected]> Signed-off-by: Alice Ryhl <[email protected]> Reviewed-by: Sami Tolvanen <[email protected]> Tested-by: Gatlin Newhouse <[email protected]> Acked-by: Kees Cook <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Replaced `!FINEIBT` requirement with `!CALL_PADDING` to prevent a build error on older Rust compilers. Fixed typo. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent ce4a262 commit ca627e6

File tree

5 files changed

+16
-2
lines changed

5 files changed

+16
-2
lines changed

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,13 @@ CC_FLAGS_CFI := -fsanitize=kcfi
957957
ifdef CONFIG_CFI_ICALL_NORMALIZE_INTEGERS
958958
CC_FLAGS_CFI += -fsanitize-cfi-icall-experimental-normalize-integers
959959
endif
960+
ifdef CONFIG_RUST
961+
# Always pass -Zsanitizer-cfi-normalize-integers as CONFIG_RUST selects
962+
# CONFIG_CFI_ICALL_NORMALIZE_INTEGERS.
963+
RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
964+
KBUILD_RUSTFLAGS += $(RUSTC_FLAGS_CFI)
965+
export RUSTC_FLAGS_CFI
966+
endif
960967
KBUILD_CFLAGS += $(CC_FLAGS_CFI)
961968
export CC_FLAGS_CFI
962969
endif

arch/x86/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ ifdef CONFIG_CALL_PADDING
242242
PADDING_CFLAGS := -fpatchable-function-entry=$(CONFIG_FUNCTION_PADDING_BYTES),$(CONFIG_FUNCTION_PADDING_BYTES)
243243
KBUILD_CFLAGS += $(PADDING_CFLAGS)
244244
export PADDING_CFLAGS
245+
246+
PADDING_RUSTFLAGS := -Zpatchable-function-entry=$(CONFIG_FUNCTION_PADDING_BYTES),$(CONFIG_FUNCTION_PADDING_BYTES)
247+
KBUILD_RUSTFLAGS += $(PADDING_RUSTFLAGS)
248+
export PADDING_RUSTFLAGS
245249
endif
246250

247251
KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE)

init/Kconfig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1905,11 +1905,13 @@ config RUST
19051905
bool "Rust support"
19061906
depends on HAVE_RUST
19071907
depends on RUST_IS_AVAILABLE
1908-
depends on !CFI_CLANG
19091908
depends on !MODVERSIONS
19101909
depends on !GCC_PLUGIN_RANDSTRUCT
19111910
depends on !RANDSTRUCT
19121911
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
1912+
depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
1913+
select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG
1914+
depends on !CALL_PADDING || RUSTC_VERSION >= 108000
19131915
help
19141916
Enables Rust support in the kernel.
19151917

rust/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers/helpers.c FORCE
306306
quiet_cmd_exports = EXPORTS $@
307307
cmd_exports = \
308308
$(NM) -p --defined-only $< \
309-
| awk '/ (T|R|D) / {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@
309+
| awk '$$2~/(T|R|D)/ && $$3!~/__cfi/ {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@
310310

311311
$(obj)/exports_core_generated.h: $(obj)/core.o FORCE
312312
$(call if_changed,exports)

scripts/generate_rust_target.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ fn main() {
207207
}
208208
ts.push("features", features);
209209
ts.push("llvm-target", "x86_64-linux-gnu");
210+
ts.push("supported-sanitizers", ["kcfi"]);
210211
ts.push("target-pointer-width", "64");
211212
} else if cfg.has("X86_32") {
212213
// This only works on UML, as i386 otherwise needs regparm support in rustc

0 commit comments

Comments
 (0)