Files
linux-stable-mirror/scripts/Makefile.kasan
T
Alice Ryhl 72d33b8bfe rust: kasan: add support for Software Tag-Based KASAN
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>
2026-05-27 01:54:22 +02:00

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