Skip to content

Commit e311740

Browse files
maurerojeda
authored andcommitted
kbuild: rust: Enable KASAN support
Rust supports KASAN via LLVM, but prior to this patch, the flags aren't set properly. Suggested-by: Miguel Ojeda <[email protected]> Signed-off-by: Matthew Maurer <[email protected]> Reviewed-by: Andrey Konovalov <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Applied "SW_TAGS KASAN" nit. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent f64e2f3 commit e311740

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

scripts/Makefile.kasan

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ endif
1212
KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
1313

1414
cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1)))
15+
rustc-param = $(call rustc-option, -Cllvm-args=-$(1),)
16+
17+
check-args = $(foreach arg,$(2),$(call $(1),$(arg)))
18+
19+
kasan_params :=
1520

1621
ifdef CONFIG_KASAN_STACK
1722
stack_enable := 1
@@ -41,39 +46,59 @@ CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
4146
$(call cc-option, -fsanitize=kernel-address \
4247
-mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET)))
4348

44-
# Now, add other parameters enabled similarly in both GCC and Clang.
45-
# As some of them are not supported by older compilers, use cc-param.
46-
CFLAGS_KASAN += $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \
47-
$(call cc-param,asan-stack=$(stack_enable)) \
48-
$(call cc-param,asan-instrument-allocas=1) \
49-
$(call cc-param,asan-globals=1)
49+
# The minimum supported `rustc` version has a minimum supported LLVM
50+
# version late enough that we can assume support for -asan-mapping-offset.
51+
RUSTFLAGS_KASAN := -Zsanitizer=kernel-address \
52+
-Zsanitizer-recover=kernel-address \
53+
-Cllvm-args=-asan-mapping-offset=$(KASAN_SHADOW_OFFSET)
54+
55+
# Now, add other parameters enabled similarly in GCC, Clang, and rustc.
56+
# As some of them are not supported by older compilers, these will be filtered
57+
# through `cc-param` or `rust-param` as applicable.
58+
kasan_params += asan-instrumentation-with-call-threshold=$(call_threshold) \
59+
asan-stack=$(stack_enable) \
60+
asan-instrument-allocas=1 \
61+
asan-globals=1
5062

5163
# Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*()
5264
# instead. With compilers that don't support this option, compiler-inserted
5365
# memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures.
54-
CFLAGS_KASAN += $(call cc-param,asan-kernel-mem-intrinsic-prefix=1)
66+
kasan_params += asan-kernel-mem-intrinsic-prefix=1
5567

5668
endif # CONFIG_KASAN_GENERIC
5769

5870
ifdef CONFIG_KASAN_SW_TAGS
5971

72+
CFLAGS_KASAN := -fsanitize=kernel-hwaddress
73+
74+
# This sets flags that will enable SW_TAGS KASAN once enabled in Rust. These
75+
# will not work today, and is guarded against in dependencies for CONFIG_RUST.
76+
RUSTFLAGS_KASAN := -Zsanitizer=kernel-hwaddress \
77+
-Zsanitizer-recover=kernel-hwaddress
78+
6079
ifdef CONFIG_KASAN_INLINE
61-
instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET))
80+
kasan_params += hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)
6281
else
63-
instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1)
82+
kasan_params += hwasan-instrument-with-calls=1
6483
endif
6584

66-
CFLAGS_KASAN := -fsanitize=kernel-hwaddress \
67-
$(call cc-param,hwasan-instrument-stack=$(stack_enable)) \
68-
$(call cc-param,hwasan-use-short-granules=0) \
69-
$(call cc-param,hwasan-inline-all-checks=0) \
70-
$(instrumentation_flags)
85+
kasan_params += hwasan-instrument-stack=$(stack_enable) \
86+
hwasan-use-short-granules=0 \
87+
hwasan-inline-all-checks=0
7188

7289
# Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*().
7390
ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y)
74-
CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1)
91+
kasan_params += hwasan-kernel-mem-intrinsic-prefix=1
7592
endif
7693

7794
endif # CONFIG_KASAN_SW_TAGS
7895

79-
export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE
96+
# Add all as-supported KASAN LLVM parameters requested by the configuration.
97+
CFLAGS_KASAN += $(call check-args, cc-param, $(kasan_params))
98+
99+
ifdef CONFIG_RUST
100+
# Avoid calling `rustc-param` unless Rust is enabled.
101+
RUSTFLAGS_KASAN += $(call check-args, rustc-param, $(kasan_params))
102+
endif # CONFIG_RUST
103+
104+
export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE RUSTFLAGS_KASAN

scripts/Makefile.lib

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ ifneq ($(CONFIG_KASAN_HW_TAGS),y)
167167
_c_flags += $(if $(patsubst n%,, \
168168
$(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \
169169
$(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
170+
_rust_flags += $(if $(patsubst n%,, \
171+
$(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)$(is-kernel-object)), \
172+
$(RUSTFLAGS_KASAN))
170173
endif
171174
endif
172175

scripts/generate_rust_target.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +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"]);
210+
ts.push("supported-sanitizers", ["kcfi", "kernel-address"]);
211211
ts.push("target-pointer-width", "64");
212212
} else if cfg.has("X86_32") {
213213
// This only works on UML, as i386 otherwise needs regparm support in rustc

0 commit comments

Comments
 (0)