xref: /openbmc/linux/Documentation/dev-tools/kmsan.rst (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
193858ae7SAlexander Potapenko.. SPDX-License-Identifier: GPL-2.0
293858ae7SAlexander Potapenko.. Copyright (C) 2022, Google LLC.
393858ae7SAlexander Potapenko
493858ae7SAlexander Potapenko===================================
593858ae7SAlexander PotapenkoThe Kernel Memory Sanitizer (KMSAN)
693858ae7SAlexander Potapenko===================================
793858ae7SAlexander Potapenko
893858ae7SAlexander PotapenkoKMSAN is a dynamic error detector aimed at finding uses of uninitialized
993858ae7SAlexander Potapenkovalues. It is based on compiler instrumentation, and is quite similar to the
1093858ae7SAlexander Potapenkouserspace `MemorySanitizer tool`_.
1193858ae7SAlexander Potapenko
1293858ae7SAlexander PotapenkoAn important note is that KMSAN is not intended for production use, because it
1393858ae7SAlexander Potapenkodrastically increases kernel memory footprint and slows the whole system down.
1493858ae7SAlexander Potapenko
1593858ae7SAlexander PotapenkoUsage
1693858ae7SAlexander Potapenko=====
1793858ae7SAlexander Potapenko
1893858ae7SAlexander PotapenkoBuilding the kernel
1993858ae7SAlexander Potapenko-------------------
2093858ae7SAlexander Potapenko
2193858ae7SAlexander PotapenkoIn order to build a kernel with KMSAN you will need a fresh Clang (14.0.6+).
2293858ae7SAlexander PotapenkoPlease refer to `LLVM documentation`_ for the instructions on how to build Clang.
2393858ae7SAlexander Potapenko
2493858ae7SAlexander PotapenkoNow configure and build the kernel with CONFIG_KMSAN enabled.
2593858ae7SAlexander Potapenko
2693858ae7SAlexander PotapenkoExample report
2793858ae7SAlexander Potapenko--------------
2893858ae7SAlexander Potapenko
2993858ae7SAlexander PotapenkoHere is an example of a KMSAN report::
3093858ae7SAlexander Potapenko
3193858ae7SAlexander Potapenko  =====================================================
3293858ae7SAlexander Potapenko  BUG: KMSAN: uninit-value in test_uninit_kmsan_check_memory+0x1be/0x380 [kmsan_test]
3393858ae7SAlexander Potapenko   test_uninit_kmsan_check_memory+0x1be/0x380 mm/kmsan/kmsan_test.c:273
3493858ae7SAlexander Potapenko   kunit_run_case_internal lib/kunit/test.c:333
3593858ae7SAlexander Potapenko   kunit_try_run_case+0x206/0x420 lib/kunit/test.c:374
3693858ae7SAlexander Potapenko   kunit_generic_run_threadfn_adapter+0x6d/0xc0 lib/kunit/try-catch.c:28
3793858ae7SAlexander Potapenko   kthread+0x721/0x850 kernel/kthread.c:327
3893858ae7SAlexander Potapenko   ret_from_fork+0x1f/0x30 ??:?
3993858ae7SAlexander Potapenko
4093858ae7SAlexander Potapenko  Uninit was stored to memory at:
4193858ae7SAlexander Potapenko   do_uninit_local_array+0xfa/0x110 mm/kmsan/kmsan_test.c:260
4293858ae7SAlexander Potapenko   test_uninit_kmsan_check_memory+0x1a2/0x380 mm/kmsan/kmsan_test.c:271
4393858ae7SAlexander Potapenko   kunit_run_case_internal lib/kunit/test.c:333
4493858ae7SAlexander Potapenko   kunit_try_run_case+0x206/0x420 lib/kunit/test.c:374
4593858ae7SAlexander Potapenko   kunit_generic_run_threadfn_adapter+0x6d/0xc0 lib/kunit/try-catch.c:28
4693858ae7SAlexander Potapenko   kthread+0x721/0x850 kernel/kthread.c:327
4793858ae7SAlexander Potapenko   ret_from_fork+0x1f/0x30 ??:?
4893858ae7SAlexander Potapenko
4993858ae7SAlexander Potapenko  Local variable uninit created at:
5093858ae7SAlexander Potapenko   do_uninit_local_array+0x4a/0x110 mm/kmsan/kmsan_test.c:256
5193858ae7SAlexander Potapenko   test_uninit_kmsan_check_memory+0x1a2/0x380 mm/kmsan/kmsan_test.c:271
5293858ae7SAlexander Potapenko
5393858ae7SAlexander Potapenko  Bytes 4-7 of 8 are uninitialized
5493858ae7SAlexander Potapenko  Memory access of size 8 starts at ffff888083fe3da0
5593858ae7SAlexander Potapenko
5693858ae7SAlexander Potapenko  CPU: 0 PID: 6731 Comm: kunit_try_catch Tainted: G    B       E     5.16.0-rc3+ #104
5793858ae7SAlexander Potapenko  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
5893858ae7SAlexander Potapenko  =====================================================
5993858ae7SAlexander Potapenko
6093858ae7SAlexander PotapenkoThe report says that the local variable ``uninit`` was created uninitialized in
6193858ae7SAlexander Potapenko``do_uninit_local_array()``. The third stack trace corresponds to the place
6293858ae7SAlexander Potapenkowhere this variable was created.
6393858ae7SAlexander Potapenko
6493858ae7SAlexander PotapenkoThe first stack trace shows where the uninit value was used (in
6593858ae7SAlexander Potapenko``test_uninit_kmsan_check_memory()``). The tool shows the bytes which were left
6693858ae7SAlexander Potapenkouninitialized in the local variable, as well as the stack where the value was
6793858ae7SAlexander Potapenkocopied to another memory location before use.
6893858ae7SAlexander Potapenko
6993858ae7SAlexander PotapenkoA use of uninitialized value ``v`` is reported by KMSAN in the following cases:
70*436fa4a6SAlexander Potapenko
7193858ae7SAlexander Potapenko - in a condition, e.g. ``if (v) { ... }``;
7293858ae7SAlexander Potapenko - in an indexing or pointer dereferencing, e.g. ``array[v]`` or ``*v``;
7393858ae7SAlexander Potapenko - when it is copied to userspace or hardware, e.g. ``copy_to_user(..., &v, ...)``;
7493858ae7SAlexander Potapenko - when it is passed as an argument to a function, and
7593858ae7SAlexander Potapenko   ``CONFIG_KMSAN_CHECK_PARAM_RETVAL`` is enabled (see below).
7693858ae7SAlexander Potapenko
7793858ae7SAlexander PotapenkoThe mentioned cases (apart from copying data to userspace or hardware, which is
7893858ae7SAlexander Potapenkoa security issue) are considered undefined behavior from the C11 Standard point
7993858ae7SAlexander Potapenkoof view.
8093858ae7SAlexander Potapenko
8193858ae7SAlexander PotapenkoDisabling the instrumentation
8293858ae7SAlexander Potapenko-----------------------------
8393858ae7SAlexander Potapenko
8493858ae7SAlexander PotapenkoA function can be marked with ``__no_kmsan_checks``. Doing so makes KMSAN
8593858ae7SAlexander Potapenkoignore uninitialized values in that function and mark its output as initialized.
8693858ae7SAlexander PotapenkoAs a result, the user will not get KMSAN reports related to that function.
8793858ae7SAlexander Potapenko
8893858ae7SAlexander PotapenkoAnother function attribute supported by KMSAN is ``__no_sanitize_memory``.
8993858ae7SAlexander PotapenkoApplying this attribute to a function will result in KMSAN not instrumenting
9093858ae7SAlexander Potapenkoit, which can be helpful if we do not want the compiler to interfere with some
9193858ae7SAlexander Potapenkolow-level code (e.g. that marked with ``noinstr`` which implicitly adds
9293858ae7SAlexander Potapenko``__no_sanitize_memory``).
9393858ae7SAlexander Potapenko
9493858ae7SAlexander PotapenkoThis however comes at a cost: stack allocations from such functions will have
9593858ae7SAlexander Potapenkoincorrect shadow/origin values, likely leading to false positives. Functions
9693858ae7SAlexander Potapenkocalled from non-instrumented code may also receive incorrect metadata for their
9793858ae7SAlexander Potapenkoparameters.
9893858ae7SAlexander Potapenko
9993858ae7SAlexander PotapenkoAs a rule of thumb, avoid using ``__no_sanitize_memory`` explicitly.
10093858ae7SAlexander Potapenko
10193858ae7SAlexander PotapenkoIt is also possible to disable KMSAN for a single file (e.g. main.o)::
10293858ae7SAlexander Potapenko
10393858ae7SAlexander Potapenko  KMSAN_SANITIZE_main.o := n
10493858ae7SAlexander Potapenko
10593858ae7SAlexander Potapenkoor for the whole directory::
10693858ae7SAlexander Potapenko
10793858ae7SAlexander Potapenko  KMSAN_SANITIZE := n
10893858ae7SAlexander Potapenko
10993858ae7SAlexander Potapenkoin the Makefile. Think of this as applying ``__no_sanitize_memory`` to every
11093858ae7SAlexander Potapenkofunction in the file or directory. Most users won't need KMSAN_SANITIZE, unless
11193858ae7SAlexander Potapenkotheir code gets broken by KMSAN (e.g. runs at early boot time).
11293858ae7SAlexander Potapenko
11393858ae7SAlexander PotapenkoSupport
11493858ae7SAlexander Potapenko=======
11593858ae7SAlexander Potapenko
11693858ae7SAlexander PotapenkoIn order for KMSAN to work the kernel must be built with Clang, which so far is
11793858ae7SAlexander Potapenkothe only compiler that has KMSAN support. The kernel instrumentation pass is
11893858ae7SAlexander Potapenkobased on the userspace `MemorySanitizer tool`_.
11993858ae7SAlexander Potapenko
12093858ae7SAlexander PotapenkoThe runtime library only supports x86_64 at the moment.
12193858ae7SAlexander Potapenko
12293858ae7SAlexander PotapenkoHow KMSAN works
12393858ae7SAlexander Potapenko===============
12493858ae7SAlexander Potapenko
12593858ae7SAlexander PotapenkoKMSAN shadow memory
12693858ae7SAlexander Potapenko-------------------
12793858ae7SAlexander Potapenko
12893858ae7SAlexander PotapenkoKMSAN associates a metadata byte (also called shadow byte) with every byte of
12993858ae7SAlexander Potapenkokernel memory. A bit in the shadow byte is set iff the corresponding bit of the
13093858ae7SAlexander Potapenkokernel memory byte is uninitialized. Marking the memory uninitialized (i.e.
13193858ae7SAlexander Potapenkosetting its shadow bytes to ``0xff``) is called poisoning, marking it
13293858ae7SAlexander Potapenkoinitialized (setting the shadow bytes to ``0x00``) is called unpoisoning.
13393858ae7SAlexander Potapenko
13493858ae7SAlexander PotapenkoWhen a new variable is allocated on the stack, it is poisoned by default by
13593858ae7SAlexander Potapenkoinstrumentation code inserted by the compiler (unless it is a stack variable
13693858ae7SAlexander Potapenkothat is immediately initialized). Any new heap allocation done without
13793858ae7SAlexander Potapenko``__GFP_ZERO`` is also poisoned.
13893858ae7SAlexander Potapenko
13993858ae7SAlexander PotapenkoCompiler instrumentation also tracks the shadow values as they are used along
14093858ae7SAlexander Potapenkothe code. When needed, instrumentation code invokes the runtime library in
14193858ae7SAlexander Potapenko``mm/kmsan/`` to persist shadow values.
14293858ae7SAlexander Potapenko
14393858ae7SAlexander PotapenkoThe shadow value of a basic or compound type is an array of bytes of the same
14493858ae7SAlexander Potapenkolength. When a constant value is written into memory, that memory is unpoisoned.
14593858ae7SAlexander PotapenkoWhen a value is read from memory, its shadow memory is also obtained and
14693858ae7SAlexander Potapenkopropagated into all the operations which use that value. For every instruction
14793858ae7SAlexander Potapenkothat takes one or more values the compiler generates code that calculates the
14893858ae7SAlexander Potapenkoshadow of the result depending on those values and their shadows.
14993858ae7SAlexander Potapenko
15093858ae7SAlexander PotapenkoExample::
15193858ae7SAlexander Potapenko
15293858ae7SAlexander Potapenko  int a = 0xff;  // i.e. 0x000000ff
15393858ae7SAlexander Potapenko  int b;
15493858ae7SAlexander Potapenko  int c = a | b;
15593858ae7SAlexander Potapenko
15693858ae7SAlexander PotapenkoIn this case the shadow of ``a`` is ``0``, shadow of ``b`` is ``0xffffffff``,
15793858ae7SAlexander Potapenkoshadow of ``c`` is ``0xffffff00``. This means that the upper three bytes of
15893858ae7SAlexander Potapenko``c`` are uninitialized, while the lower byte is initialized.
15993858ae7SAlexander Potapenko
16093858ae7SAlexander PotapenkoOrigin tracking
16193858ae7SAlexander Potapenko---------------
16293858ae7SAlexander Potapenko
16393858ae7SAlexander PotapenkoEvery four bytes of kernel memory also have a so-called origin mapped to them.
16493858ae7SAlexander PotapenkoThis origin describes the point in program execution at which the uninitialized
16593858ae7SAlexander Potapenkovalue was created. Every origin is associated with either the full allocation
16693858ae7SAlexander Potapenkostack (for heap-allocated memory), or the function containing the uninitialized
16793858ae7SAlexander Potapenkovariable (for locals).
16893858ae7SAlexander Potapenko
16993858ae7SAlexander PotapenkoWhen an uninitialized variable is allocated on stack or heap, a new origin
17093858ae7SAlexander Potapenkovalue is created, and that variable's origin is filled with that value. When a
17193858ae7SAlexander Potapenkovalue is read from memory, its origin is also read and kept together with the
17293858ae7SAlexander Potapenkoshadow. For every instruction that takes one or more values, the origin of the
17393858ae7SAlexander Potapenkoresult is one of the origins corresponding to any of the uninitialized inputs.
17493858ae7SAlexander PotapenkoIf a poisoned value is written into memory, its origin is written to the
17593858ae7SAlexander Potapenkocorresponding storage as well.
17693858ae7SAlexander Potapenko
17793858ae7SAlexander PotapenkoExample 1::
17893858ae7SAlexander Potapenko
17993858ae7SAlexander Potapenko  int a = 42;
18093858ae7SAlexander Potapenko  int b;
18193858ae7SAlexander Potapenko  int c = a + b;
18293858ae7SAlexander Potapenko
18393858ae7SAlexander PotapenkoIn this case the origin of ``b`` is generated upon function entry, and is
18493858ae7SAlexander Potapenkostored to the origin of ``c`` right before the addition result is written into
18593858ae7SAlexander Potapenkomemory.
18693858ae7SAlexander Potapenko
18793858ae7SAlexander PotapenkoSeveral variables may share the same origin address, if they are stored in the
18893858ae7SAlexander Potapenkosame four-byte chunk. In this case every write to either variable updates the
18993858ae7SAlexander Potapenkoorigin for all of them. We have to sacrifice precision in this case, because
19093858ae7SAlexander Potapenkostoring origins for individual bits (and even bytes) would be too costly.
19193858ae7SAlexander Potapenko
19293858ae7SAlexander PotapenkoExample 2::
19393858ae7SAlexander Potapenko
19493858ae7SAlexander Potapenko  int combine(short a, short b) {
19593858ae7SAlexander Potapenko    union ret_t {
19693858ae7SAlexander Potapenko      int i;
19793858ae7SAlexander Potapenko      short s[2];
19893858ae7SAlexander Potapenko    } ret;
19993858ae7SAlexander Potapenko    ret.s[0] = a;
20093858ae7SAlexander Potapenko    ret.s[1] = b;
20193858ae7SAlexander Potapenko    return ret.i;
20293858ae7SAlexander Potapenko  }
20393858ae7SAlexander Potapenko
20493858ae7SAlexander PotapenkoIf ``a`` is initialized and ``b`` is not, the shadow of the result would be
20593858ae7SAlexander Potapenko0xffff0000, and the origin of the result would be the origin of ``b``.
20693858ae7SAlexander Potapenko``ret.s[0]`` would have the same origin, but it will never be used, because
20793858ae7SAlexander Potapenkothat variable is initialized.
20893858ae7SAlexander Potapenko
20993858ae7SAlexander PotapenkoIf both function arguments are uninitialized, only the origin of the second
21093858ae7SAlexander Potapenkoargument is preserved.
21193858ae7SAlexander Potapenko
21293858ae7SAlexander PotapenkoOrigin chaining
21393858ae7SAlexander Potapenko~~~~~~~~~~~~~~~
21493858ae7SAlexander Potapenko
21593858ae7SAlexander PotapenkoTo ease debugging, KMSAN creates a new origin for every store of an
21693858ae7SAlexander Potapenkouninitialized value to memory. The new origin references both its creation stack
21793858ae7SAlexander Potapenkoand the previous origin the value had. This may cause increased memory
21893858ae7SAlexander Potapenkoconsumption, so we limit the length of origin chains in the runtime.
21993858ae7SAlexander Potapenko
22093858ae7SAlexander PotapenkoClang instrumentation API
22193858ae7SAlexander Potapenko-------------------------
22293858ae7SAlexander Potapenko
22393858ae7SAlexander PotapenkoClang instrumentation pass inserts calls to functions defined in
22493858ae7SAlexander Potapenko``mm/kmsan/nstrumentation.c`` into the kernel code.
22593858ae7SAlexander Potapenko
22693858ae7SAlexander PotapenkoShadow manipulation
22793858ae7SAlexander Potapenko~~~~~~~~~~~~~~~~~~~
22893858ae7SAlexander Potapenko
22993858ae7SAlexander PotapenkoFor every memory access the compiler emits a call to a function that returns a
23093858ae7SAlexander Potapenkopair of pointers to the shadow and origin addresses of the given memory::
23193858ae7SAlexander Potapenko
23293858ae7SAlexander Potapenko  typedef struct {
23393858ae7SAlexander Potapenko    void *shadow, *origin;
23493858ae7SAlexander Potapenko  } shadow_origin_ptr_t
23593858ae7SAlexander Potapenko
23693858ae7SAlexander Potapenko  shadow_origin_ptr_t __msan_metadata_ptr_for_load_{1,2,4,8}(void *addr)
23793858ae7SAlexander Potapenko  shadow_origin_ptr_t __msan_metadata_ptr_for_store_{1,2,4,8}(void *addr)
23893858ae7SAlexander Potapenko  shadow_origin_ptr_t __msan_metadata_ptr_for_load_n(void *addr, uintptr_t size)
23993858ae7SAlexander Potapenko  shadow_origin_ptr_t __msan_metadata_ptr_for_store_n(void *addr, uintptr_t size)
24093858ae7SAlexander Potapenko
24193858ae7SAlexander PotapenkoThe function name depends on the memory access size.
24293858ae7SAlexander Potapenko
24393858ae7SAlexander PotapenkoThe compiler makes sure that for every loaded value its shadow and origin
24493858ae7SAlexander Potapenkovalues are read from memory. When a value is stored to memory, its shadow and
24593858ae7SAlexander Potapenkoorigin are also stored using the metadata pointers.
24693858ae7SAlexander Potapenko
24793858ae7SAlexander PotapenkoHandling locals
24893858ae7SAlexander Potapenko~~~~~~~~~~~~~~~
24993858ae7SAlexander Potapenko
25093858ae7SAlexander PotapenkoA special function is used to create a new origin value for a local variable and
25193858ae7SAlexander Potapenkoset the origin of that variable to that value::
25293858ae7SAlexander Potapenko
25393858ae7SAlexander Potapenko  void __msan_poison_alloca(void *addr, uintptr_t size, char *descr)
25493858ae7SAlexander Potapenko
25593858ae7SAlexander PotapenkoAccess to per-task data
25693858ae7SAlexander Potapenko~~~~~~~~~~~~~~~~~~~~~~~
25793858ae7SAlexander Potapenko
25893858ae7SAlexander PotapenkoAt the beginning of every instrumented function KMSAN inserts a call to
25993858ae7SAlexander Potapenko``__msan_get_context_state()``::
26093858ae7SAlexander Potapenko
26193858ae7SAlexander Potapenko  kmsan_context_state *__msan_get_context_state(void)
26293858ae7SAlexander Potapenko
26393858ae7SAlexander Potapenko``kmsan_context_state`` is declared in ``include/linux/kmsan.h``::
26493858ae7SAlexander Potapenko
26593858ae7SAlexander Potapenko  struct kmsan_context_state {
26693858ae7SAlexander Potapenko    char param_tls[KMSAN_PARAM_SIZE];
26793858ae7SAlexander Potapenko    char retval_tls[KMSAN_RETVAL_SIZE];
26893858ae7SAlexander Potapenko    char va_arg_tls[KMSAN_PARAM_SIZE];
26993858ae7SAlexander Potapenko    char va_arg_origin_tls[KMSAN_PARAM_SIZE];
27093858ae7SAlexander Potapenko    u64 va_arg_overflow_size_tls;
27193858ae7SAlexander Potapenko    char param_origin_tls[KMSAN_PARAM_SIZE];
27293858ae7SAlexander Potapenko    depot_stack_handle_t retval_origin_tls;
27393858ae7SAlexander Potapenko  };
27493858ae7SAlexander Potapenko
27593858ae7SAlexander PotapenkoThis structure is used by KMSAN to pass parameter shadows and origins between
27693858ae7SAlexander Potapenkoinstrumented functions (unless the parameters are checked immediately by
27793858ae7SAlexander Potapenko``CONFIG_KMSAN_CHECK_PARAM_RETVAL``).
27893858ae7SAlexander Potapenko
27993858ae7SAlexander PotapenkoPassing uninitialized values to functions
28093858ae7SAlexander Potapenko~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28193858ae7SAlexander Potapenko
28293858ae7SAlexander PotapenkoClang's MemorySanitizer instrumentation has an option,
28393858ae7SAlexander Potapenko``-fsanitize-memory-param-retval``, which makes the compiler check function
28493858ae7SAlexander Potapenkoparameters passed by value, as well as function return values.
28593858ae7SAlexander Potapenko
28693858ae7SAlexander PotapenkoThe option is controlled by ``CONFIG_KMSAN_CHECK_PARAM_RETVAL``, which is
28793858ae7SAlexander Potapenkoenabled by default to let KMSAN report uninitialized values earlier.
28893858ae7SAlexander PotapenkoPlease refer to the `LKML discussion`_ for more details.
28993858ae7SAlexander Potapenko
29093858ae7SAlexander PotapenkoBecause of the way the checks are implemented in LLVM (they are only applied to
29193858ae7SAlexander Potapenkoparameters marked as ``noundef``), not all parameters are guaranteed to be
29293858ae7SAlexander Potapenkochecked, so we cannot give up the metadata storage in ``kmsan_context_state``.
29393858ae7SAlexander Potapenko
29493858ae7SAlexander PotapenkoString functions
29593858ae7SAlexander Potapenko~~~~~~~~~~~~~~~~
29693858ae7SAlexander Potapenko
29793858ae7SAlexander PotapenkoThe compiler replaces calls to ``memcpy()``/``memmove()``/``memset()`` with the
29893858ae7SAlexander Potapenkofollowing functions. These functions are also called when data structures are
29993858ae7SAlexander Potapenkoinitialized or copied, making sure shadow and origin values are copied alongside
30093858ae7SAlexander Potapenkowith the data::
30193858ae7SAlexander Potapenko
30293858ae7SAlexander Potapenko  void *__msan_memcpy(void *dst, void *src, uintptr_t n)
30393858ae7SAlexander Potapenko  void *__msan_memmove(void *dst, void *src, uintptr_t n)
30493858ae7SAlexander Potapenko  void *__msan_memset(void *dst, int c, uintptr_t n)
30593858ae7SAlexander Potapenko
30693858ae7SAlexander PotapenkoError reporting
30793858ae7SAlexander Potapenko~~~~~~~~~~~~~~~
30893858ae7SAlexander Potapenko
30993858ae7SAlexander PotapenkoFor each use of a value the compiler emits a shadow check that calls
31093858ae7SAlexander Potapenko``__msan_warning()`` in the case that value is poisoned::
31193858ae7SAlexander Potapenko
31293858ae7SAlexander Potapenko  void __msan_warning(u32 origin)
31393858ae7SAlexander Potapenko
31493858ae7SAlexander Potapenko``__msan_warning()`` causes KMSAN runtime to print an error report.
31593858ae7SAlexander Potapenko
31693858ae7SAlexander PotapenkoInline assembly instrumentation
31793858ae7SAlexander Potapenko~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31893858ae7SAlexander Potapenko
31993858ae7SAlexander PotapenkoKMSAN instruments every inline assembly output with a call to::
32093858ae7SAlexander Potapenko
32193858ae7SAlexander Potapenko  void __msan_instrument_asm_store(void *addr, uintptr_t size)
32293858ae7SAlexander Potapenko
32393858ae7SAlexander Potapenko, which unpoisons the memory region.
32493858ae7SAlexander Potapenko
32593858ae7SAlexander PotapenkoThis approach may mask certain errors, but it also helps to avoid a lot of
32693858ae7SAlexander Potapenkofalse positives in bitwise operations, atomics etc.
32793858ae7SAlexander Potapenko
32893858ae7SAlexander PotapenkoSometimes the pointers passed into inline assembly do not point to valid memory.
32993858ae7SAlexander PotapenkoIn such cases they are ignored at runtime.
33093858ae7SAlexander Potapenko
33193858ae7SAlexander Potapenko
33293858ae7SAlexander PotapenkoRuntime library
33393858ae7SAlexander Potapenko---------------
33493858ae7SAlexander Potapenko
33593858ae7SAlexander PotapenkoThe code is located in ``mm/kmsan/``.
33693858ae7SAlexander Potapenko
33793858ae7SAlexander PotapenkoPer-task KMSAN state
33893858ae7SAlexander Potapenko~~~~~~~~~~~~~~~~~~~~
33993858ae7SAlexander Potapenko
34093858ae7SAlexander PotapenkoEvery task_struct has an associated KMSAN task state that holds the KMSAN
34193858ae7SAlexander Potapenkocontext (see above) and a per-task flag disallowing KMSAN reports::
34293858ae7SAlexander Potapenko
34393858ae7SAlexander Potapenko  struct kmsan_context {
34493858ae7SAlexander Potapenko    ...
34593858ae7SAlexander Potapenko    bool allow_reporting;
34693858ae7SAlexander Potapenko    struct kmsan_context_state cstate;
34793858ae7SAlexander Potapenko    ...
34893858ae7SAlexander Potapenko  }
34993858ae7SAlexander Potapenko
35093858ae7SAlexander Potapenko  struct task_struct {
35193858ae7SAlexander Potapenko    ...
35293858ae7SAlexander Potapenko    struct kmsan_context kmsan;
35393858ae7SAlexander Potapenko    ...
35493858ae7SAlexander Potapenko  }
35593858ae7SAlexander Potapenko
35693858ae7SAlexander PotapenkoKMSAN contexts
35793858ae7SAlexander Potapenko~~~~~~~~~~~~~~
35893858ae7SAlexander Potapenko
35993858ae7SAlexander PotapenkoWhen running in a kernel task context, KMSAN uses ``current->kmsan.cstate`` to
36093858ae7SAlexander Potapenkohold the metadata for function parameters and return values.
36193858ae7SAlexander Potapenko
36293858ae7SAlexander PotapenkoBut in the case the kernel is running in the interrupt, softirq or NMI context,
36393858ae7SAlexander Potapenkowhere ``current`` is unavailable, KMSAN switches to per-cpu interrupt state::
36493858ae7SAlexander Potapenko
36593858ae7SAlexander Potapenko  DEFINE_PER_CPU(struct kmsan_ctx, kmsan_percpu_ctx);
36693858ae7SAlexander Potapenko
36793858ae7SAlexander PotapenkoMetadata allocation
36893858ae7SAlexander Potapenko~~~~~~~~~~~~~~~~~~~
36993858ae7SAlexander Potapenko
37093858ae7SAlexander PotapenkoThere are several places in the kernel for which the metadata is stored.
37193858ae7SAlexander Potapenko
37293858ae7SAlexander Potapenko1. Each ``struct page`` instance contains two pointers to its shadow and
37393858ae7SAlexander Potapenkoorigin pages::
37493858ae7SAlexander Potapenko
37593858ae7SAlexander Potapenko  struct page {
37693858ae7SAlexander Potapenko    ...
37793858ae7SAlexander Potapenko    struct page *shadow, *origin;
37893858ae7SAlexander Potapenko    ...
37993858ae7SAlexander Potapenko  };
38093858ae7SAlexander Potapenko
38193858ae7SAlexander PotapenkoAt boot-time, the kernel allocates shadow and origin pages for every available
38293858ae7SAlexander Potapenkokernel page. This is done quite late, when the kernel address space is already
38393858ae7SAlexander Potapenkofragmented, so normal data pages may arbitrarily interleave with the metadata
38493858ae7SAlexander Potapenkopages.
38593858ae7SAlexander Potapenko
38693858ae7SAlexander PotapenkoThis means that in general for two contiguous memory pages their shadow/origin
38793858ae7SAlexander Potapenkopages may not be contiguous. Consequently, if a memory access crosses the
38893858ae7SAlexander Potapenkoboundary of a memory block, accesses to shadow/origin memory may potentially
38993858ae7SAlexander Potapenkocorrupt other pages or read incorrect values from them.
39093858ae7SAlexander Potapenko
39193858ae7SAlexander PotapenkoIn practice, contiguous memory pages returned by the same ``alloc_pages()``
39293858ae7SAlexander Potapenkocall will have contiguous metadata, whereas if these pages belong to two
39393858ae7SAlexander Potapenkodifferent allocations their metadata pages can be fragmented.
39493858ae7SAlexander Potapenko
39593858ae7SAlexander PotapenkoFor the kernel data (``.data``, ``.bss`` etc.) and percpu memory regions
39693858ae7SAlexander Potapenkothere also are no guarantees on metadata contiguity.
39793858ae7SAlexander Potapenko
39893858ae7SAlexander PotapenkoIn the case ``__msan_metadata_ptr_for_XXX_YYY()`` hits the border between two
39993858ae7SAlexander Potapenkopages with non-contiguous metadata, it returns pointers to fake shadow/origin regions::
40093858ae7SAlexander Potapenko
40193858ae7SAlexander Potapenko  char dummy_load_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
40293858ae7SAlexander Potapenko  char dummy_store_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
40393858ae7SAlexander Potapenko
40493858ae7SAlexander Potapenko``dummy_load_page`` is zero-initialized, so reads from it always yield zeroes.
40593858ae7SAlexander PotapenkoAll stores to ``dummy_store_page`` are ignored.
40693858ae7SAlexander Potapenko
40793858ae7SAlexander Potapenko2. For vmalloc memory and modules, there is a direct mapping between the memory
40893858ae7SAlexander Potapenkorange, its shadow and origin. KMSAN reduces the vmalloc area by 3/4, making only
40993858ae7SAlexander Potapenkothe first quarter available to ``vmalloc()``. The second quarter of the vmalloc
41093858ae7SAlexander Potapenkoarea contains shadow memory for the first quarter, the third one holds the
41193858ae7SAlexander Potapenkoorigins. A small part of the fourth quarter contains shadow and origins for the
41293858ae7SAlexander Potapenkokernel modules. Please refer to ``arch/x86/include/asm/pgtable_64_types.h`` for
41393858ae7SAlexander Potapenkomore details.
41493858ae7SAlexander Potapenko
41593858ae7SAlexander PotapenkoWhen an array of pages is mapped into a contiguous virtual memory space, their
41693858ae7SAlexander Potapenkoshadow and origin pages are similarly mapped into contiguous regions.
41793858ae7SAlexander Potapenko
41893858ae7SAlexander PotapenkoReferences
41993858ae7SAlexander Potapenko==========
42093858ae7SAlexander Potapenko
42193858ae7SAlexander PotapenkoE. Stepanov, K. Serebryany. `MemorySanitizer: fast detector of uninitialized
42293858ae7SAlexander Potapenkomemory use in C++
42393858ae7SAlexander Potapenko<https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43308.pdf>`_.
42493858ae7SAlexander PotapenkoIn Proceedings of CGO 2015.
42593858ae7SAlexander Potapenko
42693858ae7SAlexander Potapenko.. _MemorySanitizer tool: https://clang.llvm.org/docs/MemorySanitizer.html
42793858ae7SAlexander Potapenko.. _LLVM documentation: https://llvm.org/docs/GettingStarted.html
42893858ae7SAlexander Potapenko.. _LKML discussion: https://lore.kernel.org/all/20220614144853.3693273-1-glider@google.com/
429