mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-21 15:43:21 +02:00
72d33b8bfe
This adds support for Software Tag-Based KASAN (KASAN_SW_TAGS) when CONFIG_RUST is enabled. This requires that rustc includes support for the kernel-hwaddress sanitizer, which is available since 1.96.0 [1]. Unlike with clang, we need to pass -Zsanitizer-recover in addition to -Zsanitizer because the option is not implied automatically. The kasan makefile uses different names for the flags depending on whether CC is clang or gcc, but as we require that CC is clang when using KASAN, we do not need to try to handle mixed gcc/llvm builds when Rust is enabled. Link: https://github.com/rust-lang/rust/pull/153049 [1] Reviewed-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260408-kasan-rust-sw-tags-v3-2-e07964d14363@google.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
107 lines
3.6 KiB
Makefile
107 lines
3.6 KiB
Makefile
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
|
|
# Safe for compiler to generate meminstrinsic calls in uninstrumented files.
|
|
CFLAGS_KASAN_NOSANITIZE :=
|
|
else
|
|
# Don't let compiler generate memintrinsic calls in uninstrumented files
|
|
# because they are instrumented.
|
|
CFLAGS_KASAN_NOSANITIZE := -fno-builtin
|
|
endif
|
|
|
|
KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
|
|
|
|
cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1)))
|
|
rustc-param = $(call rustc-option, -Cllvm-args=-$(1),)
|
|
|
|
check-args = $(foreach arg,$(2),$(call $(1),$(arg)))
|
|
|
|
kasan_params :=
|
|
|
|
ifdef CONFIG_KASAN_STACK
|
|
stack_enable := 1
|
|
else
|
|
stack_enable := 0
|
|
endif
|
|
|
|
ifdef CONFIG_KASAN_GENERIC
|
|
|
|
ifdef CONFIG_KASAN_INLINE
|
|
# When the number of memory accesses in a function is less than this
|
|
# call threshold number, the compiler will use inline instrumentation.
|
|
# 10000 is chosen offhand as a sufficiently large number to make all
|
|
# kernel functions to be instrumented inline.
|
|
call_threshold := 10000
|
|
else
|
|
call_threshold := 0
|
|
endif
|
|
|
|
# First, enable -fsanitize=kernel-address together with providing the shadow
|
|
# mapping offset, as for GCC, -fasan-shadow-offset fails without -fsanitize
|
|
# (GCC accepts the shadow mapping offset via -fasan-shadow-offset instead of
|
|
# a --param like the other KASAN parameters).
|
|
# Instead of ifdef-checking the compiler, rely on cc-option.
|
|
CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
|
|
-fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \
|
|
$(call cc-option, -fsanitize=kernel-address \
|
|
-mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET)))
|
|
|
|
# The minimum supported `rustc` version has a minimum supported LLVM
|
|
# version late enough that we can assume support for -asan-mapping-offset.
|
|
RUSTFLAGS_KASAN := -Zsanitizer=kernel-address \
|
|
-Zsanitizer-recover=kernel-address \
|
|
-Cllvm-args=-asan-mapping-offset=$(KASAN_SHADOW_OFFSET)
|
|
|
|
# Now, add other parameters enabled similarly in GCC, Clang, and rustc.
|
|
# As some of them are not supported by older compilers, these will be filtered
|
|
# through `cc-param` or `rust-param` as applicable.
|
|
kasan_params += asan-instrumentation-with-call-threshold=$(call_threshold) \
|
|
asan-stack=$(stack_enable) \
|
|
asan-instrument-allocas=1 \
|
|
asan-globals=1
|
|
|
|
# Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*()
|
|
# instead. With compilers that don't support this option, compiler-inserted
|
|
# memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures.
|
|
kasan_params += asan-kernel-mem-intrinsic-prefix=1
|
|
|
|
endif # CONFIG_KASAN_GENERIC
|
|
|
|
ifdef CONFIG_KASAN_SW_TAGS
|
|
|
|
CFLAGS_KASAN := -fsanitize=kernel-hwaddress
|
|
|
|
RUSTFLAGS_KASAN := -Zsanitizer=kernel-hwaddress \
|
|
-Zsanitizer-recover=kernel-hwaddress
|
|
|
|
ifdef CONFIG_KASAN_INLINE
|
|
kasan_params += hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)
|
|
else
|
|
kasan_params += hwasan-instrument-with-calls=1
|
|
endif
|
|
|
|
kasan_params += hwasan-instrument-stack=$(stack_enable) \
|
|
hwasan-use-short-granules=0 \
|
|
hwasan-inline-all-checks=0
|
|
|
|
# Instrument memcpy/memset/memmove calls by using instrumented __(hw)asan_mem*().
|
|
ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
|
|
ifdef CONFIG_CC_IS_GCC
|
|
kasan_params += asan-kernel-mem-intrinsic-prefix=1
|
|
else
|
|
kasan_params += hwasan-kernel-mem-intrinsic-prefix=1
|
|
endif
|
|
endif # CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX
|
|
|
|
endif # CONFIG_KASAN_SW_TAGS
|
|
|
|
# Add all as-supported KASAN LLVM parameters requested by the configuration.
|
|
CFLAGS_KASAN += $(call check-args, cc-param, $(kasan_params))
|
|
|
|
ifdef CONFIG_RUST
|
|
# Avoid calling `rustc-param` unless Rust is enabled.
|
|
RUSTFLAGS_KASAN += $(call check-args, rustc-param, $(kasan_params))
|
|
endif # CONFIG_RUST
|
|
|
|
export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE RUSTFLAGS_KASAN
|