7aed6a2c51
Syzbot reports a KASAN failure early during boot on arm64 when building with GCC 12.2.0 and using the Software Tag-Based KASAN mode: | BUG: KASAN: invalid-access in smp_build_mpidr_hash arch/arm64/kernel/setup.c:133 [inline] | BUG: KASAN: invalid-access in setup_arch+0x984/0xd60 arch/arm64/kernel/setup.c:356 | Write of size 4 at addr 03ff800086867e00 by task swapper/0 | Pointer tag: [03], memory tag: [fe] Initial triage indicates that the report is a false positive and a thorough investigation of the crash by Mark Rutland revealed the root cause to be a bug in GCC: > When GCC is passed `-fsanitize=hwaddress` or > `-fsanitize=kernel-hwaddress` it ignores > `__attribute__((no_sanitize_address))`, and instruments functions > we require are not instrumented. > > [...] > > All versions [of GCC] I tried were broken, from 11.3.0 to 14.2.0 > inclusive. > > I think we have to disable KASAN_SW_TAGS with GCC until this is > fixed Disable Software Tag-Based KASAN when building with GCC by making CC_HAS_KASAN_SW_TAGS depend on !CC_IS_GCC. Cc: Andrey Konovalov <andreyknvl@gmail.com> Suggested-by: Mark Rutland <mark.rutland@arm.com> Reported-by: syzbot+908886656a02769af987@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/000000000000f362e80620e27859@google.com Link: https://lore.kernel.org/r/ZvFGwKfoC4yVjN_X@J2N7QTR9R3 Link: https://bugzilla.kernel.org/show_bug.cgi?id=218854 Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/r/20241014161100.18034-1-will@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
230 lines
7.7 KiB
Plaintext
230 lines
7.7 KiB
Plaintext
# SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
# This config refers to the generic KASAN mode.
|
|
config HAVE_ARCH_KASAN
|
|
bool
|
|
|
|
config HAVE_ARCH_KASAN_SW_TAGS
|
|
bool
|
|
|
|
config HAVE_ARCH_KASAN_HW_TAGS
|
|
bool
|
|
|
|
config HAVE_ARCH_KASAN_VMALLOC
|
|
bool
|
|
|
|
config ARCH_DISABLE_KASAN_INLINE
|
|
bool
|
|
help
|
|
Disables both inline and stack instrumentation. Selected by
|
|
architectures that do not support these instrumentation types.
|
|
|
|
config CC_HAS_KASAN_GENERIC
|
|
def_bool $(cc-option, -fsanitize=kernel-address)
|
|
|
|
# GCC appears to ignore no_sanitize_address when -fsanitize=kernel-hwaddress
|
|
# is passed. See https://bugzilla.kernel.org/show_bug.cgi?id=218854 (and
|
|
# the linked LKML thread) for more details.
|
|
config CC_HAS_KASAN_SW_TAGS
|
|
def_bool !CC_IS_GCC && $(cc-option, -fsanitize=kernel-hwaddress)
|
|
|
|
# This option is only required for software KASAN modes.
|
|
# Old GCC versions do not have proper support for no_sanitize_address.
|
|
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89124 for details.
|
|
config CC_HAS_WORKING_NOSANITIZE_ADDRESS
|
|
def_bool !CC_IS_GCC || GCC_VERSION >= 80300
|
|
|
|
menuconfig KASAN
|
|
bool "KASAN: dynamic memory safety error detector"
|
|
depends on (((HAVE_ARCH_KASAN && CC_HAS_KASAN_GENERIC) || \
|
|
(HAVE_ARCH_KASAN_SW_TAGS && CC_HAS_KASAN_SW_TAGS)) && \
|
|
CC_HAS_WORKING_NOSANITIZE_ADDRESS) || \
|
|
HAVE_ARCH_KASAN_HW_TAGS
|
|
depends on SYSFS && !SLUB_TINY
|
|
select STACKDEPOT_ALWAYS_INIT
|
|
help
|
|
Enables KASAN (Kernel Address Sanitizer) - a dynamic memory safety
|
|
error detector designed to find out-of-bounds and use-after-free bugs.
|
|
|
|
See Documentation/dev-tools/kasan.rst for details.
|
|
|
|
For better error reports, also enable CONFIG_STACKTRACE.
|
|
|
|
if KASAN
|
|
|
|
config CC_HAS_KASAN_MEMINTRINSIC_PREFIX
|
|
def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=kernel-address -mllvm -asan-kernel-mem-intrinsic-prefix=1)) || \
|
|
(CC_IS_GCC && $(cc-option,-fsanitize=kernel-address --param asan-kernel-mem-intrinsic-prefix=1))
|
|
# Don't define it if we don't need it: compilation of the test uses
|
|
# this variable to decide how the compiler should treat builtins.
|
|
depends on !KASAN_HW_TAGS
|
|
help
|
|
The compiler is able to prefix memintrinsics with __asan or __hwasan.
|
|
|
|
choice
|
|
prompt "KASAN mode"
|
|
default KASAN_GENERIC
|
|
help
|
|
KASAN has three modes:
|
|
|
|
1. Generic KASAN (supported by many architectures, enabled with
|
|
CONFIG_KASAN_GENERIC, similar to userspace ASan),
|
|
2. Software Tag-Based KASAN (arm64 only, based on software memory
|
|
tagging, enabled with CONFIG_KASAN_SW_TAGS, similar to userspace
|
|
HWASan), and
|
|
3. Hardware Tag-Based KASAN (arm64 only, based on hardware memory
|
|
tagging, enabled with CONFIG_KASAN_HW_TAGS).
|
|
|
|
See Documentation/dev-tools/kasan.rst for details about each mode.
|
|
|
|
config KASAN_GENERIC
|
|
bool "Generic KASAN"
|
|
depends on HAVE_ARCH_KASAN && CC_HAS_KASAN_GENERIC
|
|
depends on CC_HAS_WORKING_NOSANITIZE_ADDRESS
|
|
select SLUB_DEBUG
|
|
select CONSTRUCTORS
|
|
help
|
|
Enables Generic KASAN.
|
|
|
|
Requires GCC 8.3.0+ or Clang.
|
|
|
|
Consumes about 1/8th of available memory at kernel start and adds an
|
|
overhead of ~50% for dynamic allocations.
|
|
The performance slowdown is ~x3.
|
|
|
|
config KASAN_SW_TAGS
|
|
bool "Software Tag-Based KASAN"
|
|
depends on HAVE_ARCH_KASAN_SW_TAGS && CC_HAS_KASAN_SW_TAGS
|
|
depends on CC_HAS_WORKING_NOSANITIZE_ADDRESS
|
|
select SLUB_DEBUG
|
|
select CONSTRUCTORS
|
|
help
|
|
Enables Software Tag-Based KASAN.
|
|
|
|
Requires Clang.
|
|
|
|
Supported only on arm64 CPUs and relies on Top Byte Ignore.
|
|
|
|
Consumes about 1/16th of available memory at kernel start and
|
|
add an overhead of ~20% for dynamic allocations.
|
|
|
|
May potentially introduce problems related to pointer casting and
|
|
comparison, as it embeds a tag into the top byte of each pointer.
|
|
|
|
config KASAN_HW_TAGS
|
|
bool "Hardware Tag-Based KASAN"
|
|
depends on HAVE_ARCH_KASAN_HW_TAGS
|
|
help
|
|
Enables Hardware Tag-Based KASAN.
|
|
|
|
Requires GCC 10+ or Clang 12+.
|
|
|
|
Supported only on arm64 CPUs starting from ARMv8.5 and relies on
|
|
Memory Tagging Extension and Top Byte Ignore.
|
|
|
|
Consumes about 1/32nd of available memory.
|
|
|
|
May potentially introduce problems related to pointer casting and
|
|
comparison, as it embeds a tag into the top byte of each pointer.
|
|
|
|
endchoice
|
|
|
|
choice
|
|
prompt "Instrumentation type"
|
|
depends on KASAN_GENERIC || KASAN_SW_TAGS
|
|
default KASAN_INLINE if !ARCH_DISABLE_KASAN_INLINE
|
|
|
|
config KASAN_OUTLINE
|
|
bool "Outline instrumentation"
|
|
help
|
|
Makes the compiler insert function calls that check whether the memory
|
|
is accessible before each memory access. Slower than KASAN_INLINE, but
|
|
does not bloat the size of the kernel's .text section so much.
|
|
|
|
config KASAN_INLINE
|
|
bool "Inline instrumentation"
|
|
depends on !ARCH_DISABLE_KASAN_INLINE
|
|
help
|
|
Makes the compiler directly insert memory accessibility checks before
|
|
each memory access. Faster than KASAN_OUTLINE (gives ~x2 boost for
|
|
some workloads), but makes the kernel's .text size much bigger.
|
|
|
|
endchoice
|
|
|
|
config KASAN_STACK
|
|
bool "Stack instrumentation (unsafe)" if CC_IS_CLANG && !COMPILE_TEST
|
|
depends on KASAN_GENERIC || KASAN_SW_TAGS
|
|
depends on !ARCH_DISABLE_KASAN_INLINE
|
|
default y if CC_IS_GCC
|
|
help
|
|
Disables stack instrumentation and thus KASAN's ability to detect
|
|
out-of-bounds bugs in stack variables.
|
|
|
|
With Clang, stack instrumentation has a problem that causes excessive
|
|
stack usage, see https://llvm.org/pr38809. Thus,
|
|
with Clang, this option is deemed unsafe.
|
|
|
|
This option is always disabled when compile-testing with Clang to
|
|
avoid cluttering the log with stack overflow warnings.
|
|
|
|
With GCC, enabling stack instrumentation is assumed to be safe.
|
|
|
|
If the architecture disables inline instrumentation via
|
|
ARCH_DISABLE_KASAN_INLINE, stack instrumentation gets disabled
|
|
as well, as it adds inline-style instrumentation that is run
|
|
unconditionally.
|
|
|
|
config KASAN_VMALLOC
|
|
bool "Check accesses to vmalloc allocations"
|
|
depends on HAVE_ARCH_KASAN_VMALLOC
|
|
help
|
|
Makes KASAN check the validity of accesses to vmalloc allocations.
|
|
|
|
With software KASAN modes, all types vmalloc allocations are
|
|
checked. Enabling this option leads to higher memory usage.
|
|
|
|
With Hardware Tag-Based KASAN, only non-executable VM_ALLOC mappings
|
|
are checked. There is no additional memory usage.
|
|
|
|
config KASAN_KUNIT_TEST
|
|
tristate "KUnit-compatible tests of KASAN bug detection capabilities" if !KUNIT_ALL_TESTS
|
|
depends on KASAN && KUNIT && TRACEPOINTS
|
|
default KUNIT_ALL_TESTS
|
|
help
|
|
A KUnit-based KASAN test suite. Triggers different kinds of
|
|
out-of-bounds and use-after-free accesses. Useful for testing whether
|
|
KASAN can detect certain bug types.
|
|
|
|
For more information on KUnit and unit tests in general, please refer
|
|
to the KUnit documentation in Documentation/dev-tools/kunit/.
|
|
|
|
config KASAN_MODULE_TEST
|
|
tristate "KUnit-incompatible tests of KASAN bug detection capabilities"
|
|
depends on m && KASAN && !KASAN_HW_TAGS
|
|
help
|
|
A part of the KASAN test suite that is not integrated with KUnit.
|
|
Incompatible with Hardware Tag-Based KASAN.
|
|
|
|
config KASAN_EXTRA_INFO
|
|
bool "Record and report more information"
|
|
depends on KASAN
|
|
help
|
|
Record and report more information to help us find the cause of the
|
|
bug and to help us correlate the error with other system events.
|
|
|
|
Currently, the CPU number and timestamp are additionally
|
|
recorded for each heap block at allocation and free time, and
|
|
8 bytes will be added to each metadata structure that records
|
|
allocation or free information.
|
|
|
|
In Generic KASAN, each kmalloc-8 and kmalloc-16 object will add
|
|
16 bytes of additional memory consumption, and each kmalloc-32
|
|
object will add 8 bytes of additional memory consumption, not
|
|
affecting other larger objects.
|
|
|
|
In SW_TAGS KASAN and HW_TAGS KASAN, depending on the stack_ring_size
|
|
boot parameter, it will add 8 * stack_ring_size bytes of additional
|
|
memory consumption.
|
|
|
|
endif # KASAN
|