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