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 <mmaurer@google.com> Co-developed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Tested-by: Gatlin Newhouse <gatlin.newhouse@gmail.com> Acked-by: Kees Cook <kees@kernel.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20240801-kcfi-v2-2-c93caed3d121@google.com [ Replaced `!FINEIBT` requirement with `!CALL_PADDING` to prevent a build error on older Rust compilers. Fixed typo. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
ce4a262098
commit
ca627e6365
7
Makefile
7
Makefile
@ -957,6 +957,13 @@ CC_FLAGS_CFI := -fsanitize=kcfi
|
|||||||
ifdef CONFIG_CFI_ICALL_NORMALIZE_INTEGERS
|
ifdef CONFIG_CFI_ICALL_NORMALIZE_INTEGERS
|
||||||
CC_FLAGS_CFI += -fsanitize-cfi-icall-experimental-normalize-integers
|
CC_FLAGS_CFI += -fsanitize-cfi-icall-experimental-normalize-integers
|
||||||
endif
|
endif
|
||||||
|
ifdef CONFIG_RUST
|
||||||
|
# Always pass -Zsanitizer-cfi-normalize-integers as CONFIG_RUST selects
|
||||||
|
# CONFIG_CFI_ICALL_NORMALIZE_INTEGERS.
|
||||||
|
RUSTC_FLAGS_CFI := -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
|
||||||
|
KBUILD_RUSTFLAGS += $(RUSTC_FLAGS_CFI)
|
||||||
|
export RUSTC_FLAGS_CFI
|
||||||
|
endif
|
||||||
KBUILD_CFLAGS += $(CC_FLAGS_CFI)
|
KBUILD_CFLAGS += $(CC_FLAGS_CFI)
|
||||||
export CC_FLAGS_CFI
|
export CC_FLAGS_CFI
|
||||||
endif
|
endif
|
||||||
|
@ -242,6 +242,10 @@ ifdef CONFIG_CALL_PADDING
|
|||||||
PADDING_CFLAGS := -fpatchable-function-entry=$(CONFIG_FUNCTION_PADDING_BYTES),$(CONFIG_FUNCTION_PADDING_BYTES)
|
PADDING_CFLAGS := -fpatchable-function-entry=$(CONFIG_FUNCTION_PADDING_BYTES),$(CONFIG_FUNCTION_PADDING_BYTES)
|
||||||
KBUILD_CFLAGS += $(PADDING_CFLAGS)
|
KBUILD_CFLAGS += $(PADDING_CFLAGS)
|
||||||
export PADDING_CFLAGS
|
export PADDING_CFLAGS
|
||||||
|
|
||||||
|
PADDING_RUSTFLAGS := -Zpatchable-function-entry=$(CONFIG_FUNCTION_PADDING_BYTES),$(CONFIG_FUNCTION_PADDING_BYTES)
|
||||||
|
KBUILD_RUSTFLAGS += $(PADDING_RUSTFLAGS)
|
||||||
|
export PADDING_RUSTFLAGS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE)
|
KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE)
|
||||||
|
@ -1905,11 +1905,13 @@ config RUST
|
|||||||
bool "Rust support"
|
bool "Rust support"
|
||||||
depends on HAVE_RUST
|
depends on HAVE_RUST
|
||||||
depends on RUST_IS_AVAILABLE
|
depends on RUST_IS_AVAILABLE
|
||||||
depends on !CFI_CLANG
|
|
||||||
depends on !MODVERSIONS
|
depends on !MODVERSIONS
|
||||||
depends on !GCC_PLUGIN_RANDSTRUCT
|
depends on !GCC_PLUGIN_RANDSTRUCT
|
||||||
depends on !RANDSTRUCT
|
depends on !RANDSTRUCT
|
||||||
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
|
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
|
||||||
|
depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
|
||||||
|
select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG
|
||||||
|
depends on !CALL_PADDING || RUSTC_VERSION >= 108000
|
||||||
help
|
help
|
||||||
Enables Rust support in the kernel.
|
Enables Rust support in the kernel.
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers/helpers.c FORCE
|
|||||||
quiet_cmd_exports = EXPORTS $@
|
quiet_cmd_exports = EXPORTS $@
|
||||||
cmd_exports = \
|
cmd_exports = \
|
||||||
$(NM) -p --defined-only $< \
|
$(NM) -p --defined-only $< \
|
||||||
| awk '/ (T|R|D) / {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@
|
| awk '$$2~/(T|R|D)/ && $$3!~/__cfi/ {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@
|
||||||
|
|
||||||
$(obj)/exports_core_generated.h: $(obj)/core.o FORCE
|
$(obj)/exports_core_generated.h: $(obj)/core.o FORCE
|
||||||
$(call if_changed,exports)
|
$(call if_changed,exports)
|
||||||
|
@ -207,6 +207,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
ts.push("features", features);
|
ts.push("features", features);
|
||||||
ts.push("llvm-target", "x86_64-linux-gnu");
|
ts.push("llvm-target", "x86_64-linux-gnu");
|
||||||
|
ts.push("supported-sanitizers", ["kcfi"]);
|
||||||
ts.push("target-pointer-width", "64");
|
ts.push("target-pointer-width", "64");
|
||||||
} else if cfg.has("X86_32") {
|
} else if cfg.has("X86_32") {
|
||||||
// This only works on UML, as i386 otherwise needs regparm support in rustc
|
// This only works on UML, as i386 otherwise needs regparm support in rustc
|
||||||
|
Loading…
Reference in New Issue
Block a user