mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-01 06:39:05 +00:00
kasan: update documentation
Do assorted clean-ups and improvements to KASAN documentation, including: - Describe each mode in a dedicated paragraph. - Split out a Support section that describes in details which compilers, architectures and memory types each mode requires/supports. - Capitalize the first letter in the names of each KASAN mode. [andreyknvl@google.com: rewording, per Marco] Link: https://lkml.kernel.org/r/896b2d914d6b50d677fd7b38f76967cc705c01ba.1652203271.git.andreyknvl@google.com Link: https://lkml.kernel.org/r/5bd58ebebf066593ce0e1d265d60278b5f5a1874.1652123204.git.andreyknvl@google.com Signed-off-by: Andrey Konovalov <andreyknvl@google.com> Reviewed-by: Marco Elver <elver@google.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com> Cc: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
06bc4cf6cd
commit
c2ec0c8f68
@ -4,39 +4,76 @@ The Kernel Address Sanitizer (KASAN)
|
|||||||
Overview
|
Overview
|
||||||
--------
|
--------
|
||||||
|
|
||||||
KernelAddressSANitizer (KASAN) is a dynamic memory safety error detector
|
Kernel Address Sanitizer (KASAN) is a dynamic memory safety error detector
|
||||||
designed to find out-of-bound and use-after-free bugs. KASAN has three modes:
|
designed to find out-of-bounds and use-after-free bugs.
|
||||||
|
|
||||||
1. generic KASAN (similar to userspace ASan),
|
KASAN has three modes:
|
||||||
2. software tag-based KASAN (similar to userspace HWASan),
|
|
||||||
3. hardware tag-based KASAN (based on hardware memory tagging).
|
|
||||||
|
|
||||||
Generic KASAN is mainly used for debugging due to a large memory overhead.
|
1. Generic KASAN
|
||||||
Software tag-based KASAN can be used for dogfood testing as it has a lower
|
2. Software Tag-Based KASAN
|
||||||
memory overhead that allows using it with real workloads. Hardware tag-based
|
3. Hardware Tag-Based KASAN
|
||||||
KASAN comes with low memory and performance overheads and, therefore, can be
|
|
||||||
used in production. Either as an in-field memory bug detector or as a security
|
|
||||||
mitigation.
|
|
||||||
|
|
||||||
Software KASAN modes (#1 and #2) use compile-time instrumentation to insert
|
Generic KASAN, enabled with CONFIG_KASAN_GENERIC, is the mode intended for
|
||||||
validity checks before every memory access and, therefore, require a compiler
|
debugging, similar to userspace ASan. This mode is supported on many CPU
|
||||||
version that supports that.
|
architectures, but it has significant performance and memory overheads.
|
||||||
|
|
||||||
Generic KASAN is supported in GCC and Clang. With GCC, it requires version
|
Software Tag-Based KASAN or SW_TAGS KASAN, enabled with CONFIG_KASAN_SW_TAGS,
|
||||||
8.3.0 or later. Any supported Clang version is compatible, but detection of
|
can be used for both debugging and dogfood testing, similar to userspace HWASan.
|
||||||
out-of-bounds accesses for global variables is only supported since Clang 11.
|
This mode is only supported for arm64, but its moderate memory overhead allows
|
||||||
|
using it for testing on memory-restricted devices with real workloads.
|
||||||
|
|
||||||
Software tag-based KASAN mode is only supported in Clang.
|
Hardware Tag-Based KASAN or HW_TAGS KASAN, enabled with CONFIG_KASAN_HW_TAGS,
|
||||||
|
is the mode intended to be used as an in-field memory bug detector or as a
|
||||||
|
security mitigation. This mode only works on arm64 CPUs that support MTE
|
||||||
|
(Memory Tagging Extension), but it has low memory and performance overheads and
|
||||||
|
thus can be used in production.
|
||||||
|
|
||||||
The hardware KASAN mode (#3) relies on hardware to perform the checks but
|
For details about the memory and performance impact of each KASAN mode, see the
|
||||||
still requires a compiler version that supports memory tagging instructions.
|
descriptions of the corresponding Kconfig options.
|
||||||
This mode is supported in GCC 10+ and Clang 12+.
|
|
||||||
|
|
||||||
Both software KASAN modes work with SLUB and SLAB memory allocators,
|
The Generic and the Software Tag-Based modes are commonly referred to as the
|
||||||
while the hardware tag-based KASAN currently only supports SLUB.
|
software modes. The Software Tag-Based and the Hardware Tag-Based modes are
|
||||||
|
referred to as the tag-based modes.
|
||||||
|
|
||||||
Currently, generic KASAN is supported for the x86_64, arm, arm64, xtensa, s390,
|
Support
|
||||||
and riscv architectures, and tag-based KASAN modes are supported only for arm64.
|
-------
|
||||||
|
|
||||||
|
Architectures
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Generic KASAN is supported on x86_64, arm, arm64, powerpc, riscv, s390, and
|
||||||
|
xtensa, and the tag-based KASAN modes are supported only on arm64.
|
||||||
|
|
||||||
|
Compilers
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
Software KASAN modes use compile-time instrumentation to insert validity checks
|
||||||
|
before every memory access and thus require a compiler version that provides
|
||||||
|
support for that. The Hardware Tag-Based mode relies on hardware to perform
|
||||||
|
these checks but still requires a compiler version that supports the memory
|
||||||
|
tagging instructions.
|
||||||
|
|
||||||
|
Generic KASAN requires GCC version 8.3.0 or later
|
||||||
|
or any Clang version supported by the kernel.
|
||||||
|
|
||||||
|
Software Tag-Based KASAN requires GCC 11+
|
||||||
|
or any Clang version supported by the kernel.
|
||||||
|
|
||||||
|
Hardware Tag-Based KASAN requires GCC 10+ or Clang 12+.
|
||||||
|
|
||||||
|
Memory types
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Generic KASAN supports finding bugs in all of slab, page_alloc, vmap, vmalloc,
|
||||||
|
stack, and global memory.
|
||||||
|
|
||||||
|
Software Tag-Based KASAN supports slab, page_alloc, vmalloc, and stack memory.
|
||||||
|
|
||||||
|
Hardware Tag-Based KASAN supports slab, page_alloc, and non-executable vmalloc
|
||||||
|
memory.
|
||||||
|
|
||||||
|
For slab, both software KASAN modes support SLUB and SLAB allocators, while
|
||||||
|
Hardware Tag-Based KASAN only supports SLUB.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
@ -45,13 +82,13 @@ To enable KASAN, configure the kernel with::
|
|||||||
|
|
||||||
CONFIG_KASAN=y
|
CONFIG_KASAN=y
|
||||||
|
|
||||||
and choose between ``CONFIG_KASAN_GENERIC`` (to enable generic KASAN),
|
and choose between ``CONFIG_KASAN_GENERIC`` (to enable Generic KASAN),
|
||||||
``CONFIG_KASAN_SW_TAGS`` (to enable software tag-based KASAN), and
|
``CONFIG_KASAN_SW_TAGS`` (to enable Software Tag-Based KASAN), and
|
||||||
``CONFIG_KASAN_HW_TAGS`` (to enable hardware tag-based KASAN).
|
``CONFIG_KASAN_HW_TAGS`` (to enable Hardware Tag-Based KASAN).
|
||||||
|
|
||||||
For software modes, also choose between ``CONFIG_KASAN_OUTLINE`` and
|
For the software modes, also choose between ``CONFIG_KASAN_OUTLINE`` and
|
||||||
``CONFIG_KASAN_INLINE``. Outline and inline are compiler instrumentation types.
|
``CONFIG_KASAN_INLINE``. Outline and inline are compiler instrumentation types.
|
||||||
The former produces a smaller binary while the latter is 1.1-2 times faster.
|
The former produces a smaller binary while the latter is up to 2 times faster.
|
||||||
|
|
||||||
To include alloc and free stack traces of affected slab objects into reports,
|
To include alloc and free stack traces of affected slab objects into reports,
|
||||||
enable ``CONFIG_STACKTRACE``. To include alloc and free stack traces of affected
|
enable ``CONFIG_STACKTRACE``. To include alloc and free stack traces of affected
|
||||||
@ -146,7 +183,7 @@ is either 8 or 16 aligned bytes depending on KASAN mode. Each number in the
|
|||||||
memory state section of the report shows the state of one of the memory
|
memory state section of the report shows the state of one of the memory
|
||||||
granules that surround the accessed address.
|
granules that surround the accessed address.
|
||||||
|
|
||||||
For generic KASAN, the size of each memory granule is 8. The state of each
|
For Generic KASAN, the size of each memory granule is 8. The state of each
|
||||||
granule is encoded in one shadow byte. Those 8 bytes can be accessible,
|
granule is encoded in one shadow byte. Those 8 bytes can be accessible,
|
||||||
partially accessible, freed, or be a part of a redzone. KASAN uses the following
|
partially accessible, freed, or be a part of a redzone. KASAN uses the following
|
||||||
encoding for each shadow byte: 00 means that all 8 bytes of the corresponding
|
encoding for each shadow byte: 00 means that all 8 bytes of the corresponding
|
||||||
@ -181,14 +218,14 @@ By default, KASAN prints a bug report only for the first invalid memory access.
|
|||||||
With ``kasan_multi_shot``, KASAN prints a report on every invalid access. This
|
With ``kasan_multi_shot``, KASAN prints a report on every invalid access. This
|
||||||
effectively disables ``panic_on_warn`` for KASAN reports.
|
effectively disables ``panic_on_warn`` for KASAN reports.
|
||||||
|
|
||||||
Alternatively, independent of ``panic_on_warn`` the ``kasan.fault=`` boot
|
Alternatively, independent of ``panic_on_warn``, the ``kasan.fault=`` boot
|
||||||
parameter can be used to control panic and reporting behaviour:
|
parameter can be used to control panic and reporting behaviour:
|
||||||
|
|
||||||
- ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN
|
- ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN
|
||||||
report or also panic the kernel (default: ``report``). The panic happens even
|
report or also panic the kernel (default: ``report``). The panic happens even
|
||||||
if ``kasan_multi_shot`` is enabled.
|
if ``kasan_multi_shot`` is enabled.
|
||||||
|
|
||||||
Hardware tag-based KASAN mode (see the section about various modes below) is
|
Hardware Tag-Based KASAN mode (see the section about various modes below) is
|
||||||
intended for use in production as a security mitigation. Therefore, it supports
|
intended for use in production as a security mitigation. Therefore, it supports
|
||||||
additional boot parameters that allow disabling KASAN or controlling features:
|
additional boot parameters that allow disabling KASAN or controlling features:
|
||||||
|
|
||||||
@ -250,49 +287,46 @@ outline-instrumented kernel.
|
|||||||
Generic KASAN is the only mode that delays the reuse of freed objects via
|
Generic KASAN is the only mode that delays the reuse of freed objects via
|
||||||
quarantine (see mm/kasan/quarantine.c for implementation).
|
quarantine (see mm/kasan/quarantine.c for implementation).
|
||||||
|
|
||||||
Software tag-based KASAN
|
Software Tag-Based KASAN
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Software tag-based KASAN uses a software memory tagging approach to checking
|
Software Tag-Based KASAN uses a software memory tagging approach to checking
|
||||||
access validity. It is currently only implemented for the arm64 architecture.
|
access validity. It is currently only implemented for the arm64 architecture.
|
||||||
|
|
||||||
Software tag-based KASAN uses the Top Byte Ignore (TBI) feature of arm64 CPUs
|
Software Tag-Based KASAN uses the Top Byte Ignore (TBI) feature of arm64 CPUs
|
||||||
to store a pointer tag in the top byte of kernel pointers. It uses shadow memory
|
to store a pointer tag in the top byte of kernel pointers. It uses shadow memory
|
||||||
to store memory tags associated with each 16-byte memory cell (therefore, it
|
to store memory tags associated with each 16-byte memory cell (therefore, it
|
||||||
dedicates 1/16th of the kernel memory for shadow memory).
|
dedicates 1/16th of the kernel memory for shadow memory).
|
||||||
|
|
||||||
On each memory allocation, software tag-based KASAN generates a random tag, tags
|
On each memory allocation, Software Tag-Based KASAN generates a random tag, tags
|
||||||
the allocated memory with this tag, and embeds the same tag into the returned
|
the allocated memory with this tag, and embeds the same tag into the returned
|
||||||
pointer.
|
pointer.
|
||||||
|
|
||||||
Software tag-based KASAN uses compile-time instrumentation to insert checks
|
Software Tag-Based KASAN uses compile-time instrumentation to insert checks
|
||||||
before each memory access. These checks make sure that the tag of the memory
|
before each memory access. These checks make sure that the tag of the memory
|
||||||
that is being accessed is equal to the tag of the pointer that is used to access
|
that is being accessed is equal to the tag of the pointer that is used to access
|
||||||
this memory. In case of a tag mismatch, software tag-based KASAN prints a bug
|
this memory. In case of a tag mismatch, Software Tag-Based KASAN prints a bug
|
||||||
report.
|
report.
|
||||||
|
|
||||||
Software tag-based KASAN also has two instrumentation modes (outline, which
|
Software Tag-Based KASAN also has two instrumentation modes (outline, which
|
||||||
emits callbacks to check memory accesses; and inline, which performs the shadow
|
emits callbacks to check memory accesses; and inline, which performs the shadow
|
||||||
memory checks inline). With outline instrumentation mode, a bug report is
|
memory checks inline). With outline instrumentation mode, a bug report is
|
||||||
printed from the function that performs the access check. With inline
|
printed from the function that performs the access check. With inline
|
||||||
instrumentation, a ``brk`` instruction is emitted by the compiler, and a
|
instrumentation, a ``brk`` instruction is emitted by the compiler, and a
|
||||||
dedicated ``brk`` handler is used to print bug reports.
|
dedicated ``brk`` handler is used to print bug reports.
|
||||||
|
|
||||||
Software tag-based KASAN uses 0xFF as a match-all pointer tag (accesses through
|
Software Tag-Based KASAN uses 0xFF as a match-all pointer tag (accesses through
|
||||||
pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
|
pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
|
||||||
reserved to tag freed memory regions.
|
reserved to tag freed memory regions.
|
||||||
|
|
||||||
Software tag-based KASAN currently only supports tagging of slab, page_alloc,
|
Hardware Tag-Based KASAN
|
||||||
and vmalloc memory.
|
|
||||||
|
|
||||||
Hardware tag-based KASAN
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Hardware tag-based KASAN is similar to the software mode in concept but uses
|
Hardware Tag-Based KASAN is similar to the software mode in concept but uses
|
||||||
hardware memory tagging support instead of compiler instrumentation and
|
hardware memory tagging support instead of compiler instrumentation and
|
||||||
shadow memory.
|
shadow memory.
|
||||||
|
|
||||||
Hardware tag-based KASAN is currently only implemented for arm64 architecture
|
Hardware Tag-Based KASAN is currently only implemented for arm64 architecture
|
||||||
and based on both arm64 Memory Tagging Extension (MTE) introduced in ARMv8.5
|
and based on both arm64 Memory Tagging Extension (MTE) introduced in ARMv8.5
|
||||||
Instruction Set Architecture and Top Byte Ignore (TBI).
|
Instruction Set Architecture and Top Byte Ignore (TBI).
|
||||||
|
|
||||||
@ -302,21 +336,18 @@ access, hardware makes sure that the tag of the memory that is being accessed is
|
|||||||
equal to the tag of the pointer that is used to access this memory. In case of a
|
equal to the tag of the pointer that is used to access this memory. In case of a
|
||||||
tag mismatch, a fault is generated, and a report is printed.
|
tag mismatch, a fault is generated, and a report is printed.
|
||||||
|
|
||||||
Hardware tag-based KASAN uses 0xFF as a match-all pointer tag (accesses through
|
Hardware Tag-Based KASAN uses 0xFF as a match-all pointer tag (accesses through
|
||||||
pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
|
pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
|
||||||
reserved to tag freed memory regions.
|
reserved to tag freed memory regions.
|
||||||
|
|
||||||
Hardware tag-based KASAN currently only supports tagging of slab, page_alloc,
|
If the hardware does not support MTE (pre ARMv8.5), Hardware Tag-Based KASAN
|
||||||
and VM_ALLOC-based vmalloc memory.
|
|
||||||
|
|
||||||
If the hardware does not support MTE (pre ARMv8.5), hardware tag-based KASAN
|
|
||||||
will not be enabled. In this case, all KASAN boot parameters are ignored.
|
will not be enabled. In this case, all KASAN boot parameters are ignored.
|
||||||
|
|
||||||
Note that enabling CONFIG_KASAN_HW_TAGS always results in in-kernel TBI being
|
Note that enabling CONFIG_KASAN_HW_TAGS always results in in-kernel TBI being
|
||||||
enabled. Even when ``kasan.mode=off`` is provided or when the hardware does not
|
enabled. Even when ``kasan.mode=off`` is provided or when the hardware does not
|
||||||
support MTE (but supports TBI).
|
support MTE (but supports TBI).
|
||||||
|
|
||||||
Hardware tag-based KASAN only reports the first found bug. After that, MTE tag
|
Hardware Tag-Based KASAN only reports the first found bug. After that, MTE tag
|
||||||
checking gets disabled.
|
checking gets disabled.
|
||||||
|
|
||||||
Shadow memory
|
Shadow memory
|
||||||
@ -414,19 +445,18 @@ generic ``noinstr`` one.
|
|||||||
Note that disabling compiler instrumentation (either on a per-file or a
|
Note that disabling compiler instrumentation (either on a per-file or a
|
||||||
per-function basis) makes KASAN ignore the accesses that happen directly in
|
per-function basis) makes KASAN ignore the accesses that happen directly in
|
||||||
that code for software KASAN modes. It does not help when the accesses happen
|
that code for software KASAN modes. It does not help when the accesses happen
|
||||||
indirectly (through calls to instrumented functions) or with the hardware
|
indirectly (through calls to instrumented functions) or with Hardware
|
||||||
tag-based mode that does not use compiler instrumentation.
|
Tag-Based KASAN, which does not use compiler instrumentation.
|
||||||
|
|
||||||
For software KASAN modes, to disable KASAN reports in a part of the kernel code
|
For software KASAN modes, to disable KASAN reports in a part of the kernel code
|
||||||
for the current task, annotate this part of the code with a
|
for the current task, annotate this part of the code with a
|
||||||
``kasan_disable_current()``/``kasan_enable_current()`` section. This also
|
``kasan_disable_current()``/``kasan_enable_current()`` section. This also
|
||||||
disables the reports for indirect accesses that happen through function calls.
|
disables the reports for indirect accesses that happen through function calls.
|
||||||
|
|
||||||
For tag-based KASAN modes (include the hardware one), to disable access
|
For tag-based KASAN modes, to disable access checking, use
|
||||||
checking, use ``kasan_reset_tag()`` or ``page_kasan_tag_reset()``. Note that
|
``kasan_reset_tag()`` or ``page_kasan_tag_reset()``. Note that temporarily
|
||||||
temporarily disabling access checking via ``page_kasan_tag_reset()`` requires
|
disabling access checking via ``page_kasan_tag_reset()`` requires saving and
|
||||||
saving and restoring the per-page KASAN tag via
|
restoring the per-page KASAN tag via ``page_kasan_tag``/``page_kasan_tag_set``.
|
||||||
``page_kasan_tag``/``page_kasan_tag_set``.
|
|
||||||
|
|
||||||
Tests
|
Tests
|
||||||
~~~~~
|
~~~~~
|
||||||
|
Loading…
Reference in New Issue
Block a user