2 .\" Copyright (c) 2021 The FreeBSD Foundation
4 .\" This documentation was written by Mark Johnston under sponsorship from
5 .\" the FreeBSD Foundation.
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
10 .\" 1. Redistributions of source code must retain the above copyright
11 .\" notice, this list of conditions and the following disclaimer.
12 .\" 2. Redistributions in binary form must reproduce the above copyright
13 .\" notice, this list of conditions and the following disclaimer in the
14 .\" documentation and/or other materials provided with the distribution.
16 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 .Nd Kernel Memory SANitizer
37 kernel configuration can be used to compile a KMSAN-enabled kernel using
39 as a base configuration.
40 Alternately, to compile KMSAN into the kernel, place the following line in your
41 kernel configuration file:
42 .Bd -ragged -offset indent
48 .Fn kmsan_mark "const void *addr" "size_t size" "uint8_t code"
50 .Fn kmsan_orig "const void *addr" "size_t size" "int type" "uintptr_t pc"
52 .Fn kmsan_check "const void *addr" "size_t size" "const char *descr"
54 .Fn kmsan_check_bio "const struct bio *" "const char *descr"
56 .Fn kmsan_check_ccb "const union ccb *" "const char *descr"
58 .Fn kmsan_check_mbuf "const struct mbuf *" "const char *descr"
61 is a subsystem which leverages compiler instrumentation to detect uses of
62 uninitialized memory in the kernel.
63 Currently it is implemented only on the amd64 platform.
67 is compiled into the kernel, the compiler is configured to emit function
68 calls preceding memory accesses.
69 The functions are implemented by the
71 runtime component and use hidden, byte-granular shadow state to determine
72 whether the source operand has been initialized.
73 When uninitialized memory is used as a source operand in certain operations,
74 such as control flow expressions or memory accesses, the runtime reports
76 Otherwise, the shadow state is propagated to destination operand.
78 variable assignment or a
80 call which copies uninitialized memory will cause the destination buffer or
81 variable to be marked uninitialized.
83 To report an error, the
85 runtime will either trigger a kernel panic or print a message to the console,
86 depending on the value of the
87 .Sy debug.kmsan.panic_on_violation
89 In both cases, a stack trace and information about the origin of the
90 uninitialized memory is included.
92 In addition to compiler-detected uses of uninitialized memory,
97 perform validation of the input's shadow state and will raise an error if
98 any uninitialized bytes are detected.
102 option imposes a significant performance penalty.
103 Kernel code typically runs two or three times slower, and each byte mapped in
104 the kernel map requires two bytes of shadow state.
107 should be used only for kernel testing and development.
108 It is not recommended to enable
110 in systems with less than 8GB of physical RAM.
120 marks an address range as valid or invalid according to the value of the
123 The valid values for this parameter are
124 .Dv KMSAN_STATE_INITED
126 .Dv KMSAN_STATE_UNINIT ,
127 which mark the range as initialized and uninitialized, respectively.
128 For example, when a piece of memory is freed to a kernel allocator, it will
129 typically have been marked initialized; before the memory is reused for a new
130 allocation, the allocator should mark it as uninitialized.
131 As another example, writes to host memory performed by devices, e.g., via DMA,
132 are not intercepted by the sanitizer; to avoid false positives, drivers should
133 mark device-written memory as initialized.
134 For many drivers this is handled internally by the
143 In particular, it associates a given uninitialized buffer with a memory type
147 runtime to track the source of uninitialized memory and is only for debugging
150 .Sx IMPLEMENTATION NOTES
155 function and its sub-typed siblings validate the shadow state of the region(s)
156 of kernel memory passed as input parameters.
157 If any byte of the input is marked as uninitialized, the runtime will generate
159 These functions are useful during debugging, as they can be strategically
160 inserted into code paths to narrow down the source of uninitialized memory.
161 They are also used to perform validation in various kernel I/O paths, helping
162 ensure that, for example, packets transmitted over a network do not contain
163 uninitialized kernel memory.
165 and related functions also take a
167 parameter which is inserted into any reports raised by the check.
168 .Sh IMPLEMENTATION NOTES
172 runtime makes use of two shadows of the kernel map.
173 Each address in the kernel map has a linear mapping to addresses in the
175 The first, simply called the shadow map, tracks the state of the corresponding
177 A non-zero byte in the shadow map indicates that the corresponding byte of
178 kernel memory is uninitialized.
181 instrumentation automatically propagates shadow state as the contents of kernel
182 memory are transformed and copied.
184 The second shadow is called the origin map, and exists only to help debug
185 reports from the sanitizer.
186 To avoid false positives,
188 does not raise reports for certain operations on uninitialized memory, such
189 as copying or arithmetic.
190 Thus, operations on uninitialized state which raise a report may be far removed
191 from the source of the bug, complicating debugging.
192 The origin map contains information which can help pinpoint the root cause of
195 report; when generating a report, the runtime uses state from the origin map
196 to provide extra details.
198 Unlike the shadow map, the origin map is not byte-granular, but consists of 4-byte
200 Each cell describes the corresponding four bytes of mapped kernel memory and
201 holds a type and compressed code address.
202 When kernel memory is allocated for some purpose, its origin is initialized
203 either by the compiler instrumentation or by runtime hooks in the allocator.
204 The type indicates the specific allocator, e.g.,
206 and the address provides the location in the kernel code where the memory was
211 is configured, the compiler will only emit instrumentation for C code.
212 Files containing assembly code are left un-instrumented.
213 In some cases this is handled by the sanitizer runtime, which defines
214 wrappers for subroutines implemented in assembly.
215 These wrappers are referred to as interceptors and handle updating
216 shadow state to reflect the operations performed by the original
218 In other cases, C code which calls assembly code or is called from
219 assembly code may need to use
221 to manually update shadow state.
222 This is typically only necessary in machine-dependent code.
224 Inline assembly is instrumented by the compiler to update shadow state
225 based on the output operands of the code, and thus does not usually
226 require any special handling to avoid false positives.
227 .Ss Interrupts and Exceptions
228 In addition to the shadow maps, the sanitizer requires some thread-local
229 storage (TLS) to track initialization and origin state for function
230 parameters and return values.
231 The sanitizer instrumentation will automatically fetch, update and
233 In particular, this storage block has a layout defined by the sanitizer
236 Most kernel code runs in a context where interrupts or exceptions may
237 redirect the CPU to begin execution of unrelated code.
238 To ensure that thread-local sanitizer state remains consistent, the
239 runtime maintains a stack of TLS blocks for each thread.
240 When machine-dependent interrupt and exception handlers begin execution,
241 they push a new entry onto the stack before calling into any C code, and
242 pop the stack before resuming execution of the interrupted code.
243 These operations are performed by the
247 functions in the sanitizer runtime.
249 The following contrived example demonstrates some of the types of bugs
250 that are automatically detected by
252 .Bd -literal -offset indent
259 /* A 2-byte hole is here. */
266 * This will raise a report since "sz" is uninitialized
267 * here. If it is initialized, and "osz" was left uninitialized
268 * by the caller, a report would also be raised.
273 buf = malloc(32, M_TEMP, M_WAITOK);
276 * This will raise a report since "buf" has not been
277 * initialized and contains whatever data is left over from the
278 * previous use of that memory.
280 for (i = 0; i < 32; i++)
286 * This will raise a report since the pad bytes in "foo" have
287 * not been initialized, e.g., by memset(), and this call will
288 * thus copy uninitialized kernel stack memory into userspace.
290 copyout(&foo, uaddr, sizeof(foo));
293 * This line itself will not raise a report, but may trigger
294 * a report in the caller depending on how the return value is
308 .%A Konstantin Serebryany
309 .%T MemorySanitizer: fast detector of uninitialized memory use in C++
310 .%J 2015 IEEE/ACM International Symposium on Code Generation and Optimization (CGO)
317 and first appeared in
320 Accesses to kernel memory outside of the kernel map are ignored by the
323 In particular, memory accesses via the direct map are not validated.
324 When memory is copied from outside the kernel map into the kernel map,
325 that region of the kernel map is marked as initialized.
328 is configured, kernel memory allocators are configured to use the kernel map,
329 and filesystems are configured to always map data buffers into the kernel map,
330 so usage of the direct map is minimized.
331 However, some uses of the direct map remain.
332 This is a conservative policy which aims to avoid false positives, but it will
333 mask bug in some kernel subsystems.
335 On amd64, global variables and the physical page array
338 This is intentional, as it reduces memory usage by avoiding creating
339 shadows of large regions of the kernel map.
340 However, this can allow bugs to go undetected by
343 Some kernel memory allocators provide type-stable objects, and code which uses
344 them frequently depends on object data being preserved across allocations.
345 Such allocations cannot be sanitized by
347 However, in some cases it may be possible to use
349 to manually annotate fields which are known to contain invalid data upon