xref: /freebsd/share/man/man9/kmsan.9 (revision f5b549d09878c8dcd2382f3d3867f7b3671d908e)
1ce260994SMark Johnston.\"-
2ce260994SMark Johnston.\" Copyright (c) 2021 The FreeBSD Foundation
3ce260994SMark Johnston.\"
4ce260994SMark Johnston.\" This documentation was written by Mark Johnston under sponsorship from
5ce260994SMark Johnston.\" the FreeBSD Foundation.
6ce260994SMark Johnston.\"
7ce260994SMark Johnston.\" Redistribution and use in source and binary forms, with or without
8ce260994SMark Johnston.\" modification, are permitted provided that the following conditions
9ce260994SMark Johnston.\" are met:
10ce260994SMark Johnston.\" 1. Redistributions of source code must retain the above copyright
11ce260994SMark Johnston.\"    notice, this list of conditions and the following disclaimer.
12ce260994SMark Johnston.\" 2. Redistributions in binary form must reproduce the above copyright
13ce260994SMark Johnston.\"    notice, this list of conditions and the following disclaimer in the
14ce260994SMark Johnston.\"    documentation and/or other materials provided with the distribution.
15ce260994SMark Johnston.\"
16ce260994SMark Johnston.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17ce260994SMark Johnston.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18ce260994SMark Johnston.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ce260994SMark Johnston.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20ce260994SMark Johnston.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ce260994SMark Johnston.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22ce260994SMark Johnston.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23ce260994SMark Johnston.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24ce260994SMark Johnston.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25ce260994SMark Johnston.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26ce260994SMark Johnston.\" SUCH DAMAGE.
27ce260994SMark Johnston.\"
28*f5b549d0SMark Johnston.Dd January 11, 2024
29ce260994SMark Johnston.Dt KMSAN 9
30ce260994SMark Johnston.Os
31ce260994SMark Johnston.Sh NAME
32ce260994SMark Johnston.Nm KMSAN
33ce260994SMark Johnston.Nd Kernel Memory SANitizer
34ce260994SMark Johnston.Sh SYNOPSIS
35ce260994SMark JohnstonThe
36ce260994SMark Johnston.Pa GENERIC-KMSAN
37ce260994SMark Johnstonkernel configuration can be used to compile a KMSAN-enabled kernel using
38ce260994SMark Johnston.Pa GENERIC
39ce260994SMark Johnstonas a base configuration.
40ce260994SMark JohnstonAlternately, to compile KMSAN into the kernel, place the following line in your
41ce260994SMark Johnstonkernel configuration file:
42ce260994SMark Johnston.Bd -ragged -offset indent
43ce260994SMark Johnston.Cd "options KMSAN"
44ce260994SMark Johnston.Ed
45ce260994SMark Johnston.Pp
46ce260994SMark Johnston.In sys/msan.h
47ce260994SMark Johnston.Ft void
48ce260994SMark Johnston.Fn kmsan_mark "const void *addr" "size_t size" "uint8_t code"
49ce260994SMark Johnston.Ft void
50ce260994SMark Johnston.Fn kmsan_orig "const void *addr" "size_t size" "int type" "uintptr_t pc"
51ce260994SMark Johnston.Ft void
52ce260994SMark Johnston.Fn kmsan_check "const void *addr" "size_t size" "const char *descr"
53ce260994SMark Johnston.Ft void
54ce260994SMark Johnston.Fn kmsan_check_bio "const struct bio *" "const char *descr"
55ce260994SMark Johnston.Ft void
56ce260994SMark Johnston.Fn kmsan_check_ccb "const union ccb *" "const char *descr"
57ce260994SMark Johnston.Ft void
58ce260994SMark Johnston.Fn kmsan_check_mbuf "const struct mbuf *" "const char *descr"
59be5464aeSMark Johnston.Ft void
60be5464aeSMark Johnston.Fn kmsan_check_uio "const struct uio *" "const char *descr"
61ce260994SMark Johnston.Sh DESCRIPTION
62ce260994SMark Johnston.Nm
63ce260994SMark Johnstonis a subsystem which leverages compiler instrumentation to detect uses of
64ce260994SMark Johnstonuninitialized memory in the kernel.
65*f5b549d0SMark JohnstonCurrently it is implemented only on the amd64 and arm64 platforms.
66ce260994SMark Johnston.Pp
67ce260994SMark JohnstonWhen
68ce260994SMark Johnston.Nm
69ce260994SMark Johnstonis compiled into the kernel, the compiler is configured to emit function
70ce260994SMark Johnstoncalls preceding memory accesses.
71ce260994SMark JohnstonThe functions are implemented by the
72ce260994SMark Johnston.Nm
73ce260994SMark Johnstonruntime component and use hidden, byte-granular shadow state to determine
74ce260994SMark Johnstonwhether the source operand has been initialized.
75ce260994SMark JohnstonWhen uninitialized memory is used as a source operand in certain operations,
76ce260994SMark Johnstonsuch as control flow expressions or memory accesses, the runtime reports
77ce260994SMark Johnstonan error.
78ce260994SMark JohnstonOtherwise, the shadow state is propagated to destination operand.
79ce260994SMark JohnstonFor example, a
80ce260994SMark Johnstonvariable assignment or a
81ce260994SMark Johnston.Fn memcpy
82ce260994SMark Johnstoncall which copies uninitialized memory will cause the destination buffer or
83ce260994SMark Johnstonvariable to be marked uninitialized.
84ce260994SMark Johnston.Pp
85ce260994SMark JohnstonTo report an error, the
86ce260994SMark Johnston.Nm
87ce260994SMark Johnstonruntime will either trigger a kernel panic or print a message to the console,
88ce260994SMark Johnstondepending on the value of the
89ce260994SMark Johnston.Sy debug.kmsan.panic_on_violation
90ce260994SMark Johnstonsysctl.
91ce260994SMark JohnstonIn both cases, a stack trace and information about the origin of the
92ce260994SMark Johnstonuninitialized memory is included.
93ce260994SMark Johnston.Pp
94ce260994SMark JohnstonIn addition to compiler-detected uses of uninitialized memory,
95ce260994SMark Johnstonvarious kernel I/O
96ce260994SMark Johnston.Dq exit points ,
97ce260994SMark Johnstonsuch as
98ce260994SMark Johnston.Xr copyout 9 ,
99ce260994SMark Johnstonperform validation of the input's shadow state and will raise an error if
100ce260994SMark Johnstonany uninitialized bytes are detected.
101ce260994SMark Johnston.Pp
102ce260994SMark JohnstonThe
103ce260994SMark Johnston.Nm
104ce260994SMark Johnstonoption imposes a significant performance penalty.
105ce260994SMark JohnstonKernel code typically runs two or three times slower, and each byte mapped in
106ce260994SMark Johnstonthe kernel map requires two bytes of shadow state.
107ce260994SMark JohnstonAs a result,
108ce260994SMark Johnston.Nm
109ce260994SMark Johnstonshould be used only for kernel testing and development.
110ce260994SMark JohnstonIt is not recommended to enable
111ce260994SMark Johnston.Nm
112ce260994SMark Johnstonin systems with less than 8GB of physical RAM.
1137ca90db2SZhenlei Huang.Pp
1147ca90db2SZhenlei HuangThe sanitizer in a KMSAN-configured kernel can be disabled by setting the loader
1157ca90db2SZhenlei Huangtunable
1167ca90db2SZhenlei Huang.Sy debug.kmsan.disable=1 .
117ce260994SMark Johnston.Sh FUNCTIONS
118ce260994SMark JohnstonThe
119ce260994SMark Johnston.Fn kmsan_mark
120ce260994SMark Johnstonand
121ce260994SMark Johnston.Fn kmsan_orig
122ce260994SMark Johnstonfunctions update
123ce260994SMark Johnston.Nm
124ce260994SMark Johnstonshadow state.
125ce260994SMark Johnston.Fn kmsan_mark
126ce260994SMark Johnstonmarks an address range as valid or invalid according to the value of the
127ce260994SMark Johnston.Va code
128ce260994SMark Johnstonparameter.
129ce260994SMark JohnstonThe valid values for this parameter are
130ce260994SMark Johnston.Dv KMSAN_STATE_INITED
131ce260994SMark Johnstonand
132ce260994SMark Johnston.Dv KMSAN_STATE_UNINIT ,
133ce260994SMark Johnstonwhich mark the range as initialized and uninitialized, respectively.
134ce260994SMark JohnstonFor example, when a piece of memory is freed to a kernel allocator, it will
135ce260994SMark Johnstontypically have been marked initialized; before the memory is reused for a new
136ce260994SMark Johnstonallocation, the allocator should mark it as uninitialized.
137ce260994SMark JohnstonAs another example, writes to host memory performed by devices, e.g., via DMA,
138ce260994SMark Johnstonare not intercepted by the sanitizer; to avoid false positives, drivers should
139ce260994SMark Johnstonmark device-written memory as initialized.
140ce260994SMark JohnstonFor many drivers this is handled internally by the
141ce260994SMark Johnston.Xr busdma 9
142ce260994SMark Johnstonsubsystem.
143ce260994SMark Johnston.Pp
144ce260994SMark JohnstonThe
145ce260994SMark Johnston.Fn kmsan_orig
146ce260994SMark Johnstonfunction updates
147ce260994SMark Johnston.Dq origin
148ce260994SMark Johnstonshadow state.
149ce260994SMark JohnstonIn particular, it associates a given uninitialized buffer with a memory type
150ce260994SMark Johnstonand code address.
151ce260994SMark JohnstonThis is used by the
152ce260994SMark Johnston.Nm
153ce260994SMark Johnstonruntime to track the source of uninitialized memory and is only for debugging
154ce260994SMark Johnstonpurposes.
155ce260994SMark JohnstonSee
156ce260994SMark Johnston.Sx IMPLEMENTATION NOTES
157ce260994SMark Johnstonfor more details.
158ce260994SMark Johnston.Pp
159ce260994SMark JohnstonThe
160ce260994SMark Johnston.Fn kmsan_check
161ce260994SMark Johnstonfunction and its sub-typed siblings validate the shadow state of the region(s)
162ce260994SMark Johnstonof kernel memory passed as input parameters.
163ce260994SMark JohnstonIf any byte of the input is marked as uninitialized, the runtime will generate
164ce260994SMark Johnstona report.
165ce260994SMark JohnstonThese functions are useful during debugging, as they can be strategically
166ce260994SMark Johnstoninserted into code paths to narrow down the source of uninitialized memory.
167ce260994SMark JohnstonThey are also used to perform validation in various kernel I/O paths, helping
168ce260994SMark Johnstonensure that, for example, packets transmitted over a network do not contain
169ce260994SMark Johnstonuninitialized kernel memory.
170ce260994SMark Johnston.Fn kmsan_check
171ce260994SMark Johnstonand related functions also take a
172ce260994SMark Johnston.Fa descr
173ce260994SMark Johnstonparameter which is inserted into any reports raised by the check.
174ce260994SMark Johnston.Sh IMPLEMENTATION NOTES
175ce260994SMark Johnston.Ss Shadow Maps
176ce260994SMark JohnstonThe
177ce260994SMark Johnston.Nm
178ce260994SMark Johnstonruntime makes use of two shadows of the kernel map.
179ce260994SMark JohnstonEach address in the kernel map has a linear mapping to addresses in the
180ce260994SMark Johnstontwo shadows.
181ce260994SMark JohnstonThe first, simply called the shadow map, tracks the state of the corresponding
182ce260994SMark Johnstonkernel memory.
183ce260994SMark JohnstonA non-zero byte in the shadow map indicates that the corresponding byte of
184ce260994SMark Johnstonkernel memory is uninitialized.
185ce260994SMark JohnstonThe
186ce260994SMark Johnston.Nm
187ce260994SMark Johnstoninstrumentation automatically propagates shadow state as the contents of kernel
188ce260994SMark Johnstonmemory are transformed and copied.
189ce260994SMark Johnston.Pp
190ce260994SMark JohnstonThe second shadow is called the origin map, and exists only to help debug
191ce260994SMark Johnstonreports from the sanitizer.
192ce260994SMark JohnstonTo avoid false positives,
193ce260994SMark Johnston.Nm
194ce260994SMark Johnstondoes not raise reports for certain operations on uninitialized memory, such
195ce260994SMark Johnstonas copying or arithmetic.
196ce260994SMark JohnstonThus, operations on uninitialized state which raise a report may be far removed
197ce260994SMark Johnstonfrom the source of the bug, complicating debugging.
198ce260994SMark JohnstonThe origin map contains information which can help pinpoint the root cause of
199ce260994SMark Johnstona particular
200ce260994SMark Johnston.Nm
201ce260994SMark Johnstonreport; when generating a report, the runtime uses state from the origin map
202ce260994SMark Johnstonto provide extra details.
203ce260994SMark Johnston.Pp
204ce260994SMark JohnstonUnlike the shadow map, the origin map is not byte-granular, but consists of 4-byte
205ce260994SMark Johnston.Dq cells .
206ce260994SMark JohnstonEach cell describes the corresponding four bytes of mapped kernel memory and
207ce260994SMark Johnstonholds a type and compressed code address.
208ce260994SMark JohnstonWhen kernel memory is allocated for some purpose, its origin is initialized
209ce260994SMark Johnstoneither by the compiler instrumentation or by runtime hooks in the allocator.
210ce260994SMark JohnstonThe type indicates the specific allocator, e.g.,
211ce260994SMark Johnston.Xr uma 9 ,
212ce260994SMark Johnstonand the address provides the location in the kernel code where the memory was
213ce260994SMark Johnstonallocated.
214ce260994SMark Johnston.Ss Assembly Code
215ce260994SMark JohnstonWhen
216ce260994SMark Johnston.Nm
217ce260994SMark Johnstonis configured, the compiler will only emit instrumentation for C code.
218ce260994SMark JohnstonFiles containing assembly code are left un-instrumented.
219ce260994SMark JohnstonIn some cases this is handled by the sanitizer runtime, which defines
220ce260994SMark Johnstonwrappers for subroutines implemented in assembly.
221ce260994SMark JohnstonThese wrappers are referred to as interceptors and handle updating
222ce260994SMark Johnstonshadow state to reflect the operations performed by the original
223ce260994SMark Johnstonsubroutines.
224ce260994SMark JohnstonIn other cases, C code which calls assembly code or is called from
225ce260994SMark Johnstonassembly code may need to use
226ce260994SMark Johnston.Fn kmsan_mark
227ce260994SMark Johnstonto manually update shadow state.
228ce260994SMark JohnstonThis is typically only necessary in machine-dependent code.
229ce260994SMark Johnston.Pp
230ce260994SMark JohnstonInline assembly is instrumented by the compiler to update shadow state
231ce260994SMark Johnstonbased on the output operands of the code, and thus does not usually
232ce260994SMark Johnstonrequire any special handling to avoid false positives.
233ce260994SMark Johnston.Ss Interrupts and Exceptions
234ce260994SMark JohnstonIn addition to the shadow maps, the sanitizer requires some thread-local
235ce260994SMark Johnstonstorage (TLS) to track initialization and origin state for function
236ce260994SMark Johnstonparameters and return values.
237ce260994SMark JohnstonThe sanitizer instrumentation will automatically fetch, update and
238ce260994SMark Johnstonverify this state.
239ce260994SMark JohnstonIn particular, this storage block has a layout defined by the sanitizer
240ce260994SMark JohnstonABI.
241ce260994SMark Johnston.Pp
242ce260994SMark JohnstonMost kernel code runs in a context where interrupts or exceptions may
243ce260994SMark Johnstonredirect the CPU to begin execution of unrelated code.
244ce260994SMark JohnstonTo ensure that thread-local sanitizer state remains consistent, the
245ce260994SMark Johnstonruntime maintains a stack of TLS blocks for each thread.
246ce260994SMark JohnstonWhen machine-dependent interrupt and exception handlers begin execution,
247ce260994SMark Johnstonthey push a new entry onto the stack before calling into any C code, and
248ce260994SMark Johnstonpop the stack before resuming execution of the interrupted code.
249ce260994SMark JohnstonThese operations are performed by the
250ce260994SMark Johnston.Fn kmsan_intr_enter
251ce260994SMark Johnstonand
252ce260994SMark Johnston.Fn kmsan_intr_leave
253ce260994SMark Johnstonfunctions in the sanitizer runtime.
254ce260994SMark Johnston.Sh EXAMPLES
255ce260994SMark JohnstonThe following contrived example demonstrates some of the types of bugs
256ce260994SMark Johnstonthat are automatically detected by
257ce260994SMark Johnston.Nm :
258ce260994SMark Johnston.Bd -literal -offset indent
259ce260994SMark Johnstonint
260ce260994SMark Johnstonf(size_t osz)
261ce260994SMark Johnston{
262ce260994SMark Johnston	struct {
263ce260994SMark Johnston		uint32_t bar;
264ce260994SMark Johnston		uint16_t baz;
265ce260994SMark Johnston		/* A 2-byte hole is here. */
266ce260994SMark Johnston	} foo;
267ce260994SMark Johnston	char *buf;
268ce260994SMark Johnston	size_t sz;
269ce260994SMark Johnston	int error;
270ce260994SMark Johnston
271ce260994SMark Johnston	/*
272ce260994SMark Johnston	 * This will raise a report since "sz" is uninitialized
273ce260994SMark Johnston	 * here.  If it is initialized, and "osz" was left uninitialized
274ce260994SMark Johnston	 * by the caller, a report would also be raised.
275ce260994SMark Johnston	 */
276ce260994SMark Johnston	if (sz < osz)
277ce260994SMark Johnston		return (1);
278ce260994SMark Johnston
279ce260994SMark Johnston	buf = malloc(32, M_TEMP, M_WAITOK);
280ce260994SMark Johnston
281ce260994SMark Johnston	/*
282ce260994SMark Johnston	 * This will raise a report since "buf" has not been
283ce260994SMark Johnston	 * initialized and contains whatever data is left over from the
284ce260994SMark Johnston	 * previous use of that memory.
285ce260994SMark Johnston	 */
286ce260994SMark Johnston	for (i = 0; i < 32; i++)
287ce260994SMark Johnston		if (buf[i] != '\0')
288ce260994SMark Johnston			foo.bar++;
289ce260994SMark Johnston	foo.baz = 0;
290ce260994SMark Johnston
291ce260994SMark Johnston	/*
292ce260994SMark Johnston	 * This will raise a report since the pad bytes in "foo" have
293ce260994SMark Johnston	 * not been initialized, e.g., by memset(), and this call will
294ce260994SMark Johnston	 * thus copy uninitialized kernel stack memory into userspace.
295ce260994SMark Johnston	 */
296ce260994SMark Johnston	copyout(&foo, uaddr, sizeof(foo));
297ce260994SMark Johnston
298ce260994SMark Johnston	/*
299ce260994SMark Johnston	 * This line itself will not raise a report, but may trigger
300ce260994SMark Johnston	 * a report in the caller depending on how the return value is
301ce260994SMark Johnston	 * used.
302ce260994SMark Johnston	 */
303ce260994SMark Johnston	return (error);
304ce260994SMark Johnston}
305ce260994SMark Johnston.Ed
306ce260994SMark Johnston.Sh SEE ALSO
307ce260994SMark Johnston.Xr build 7 ,
308ce260994SMark Johnston.Xr busdma 9 ,
309ce260994SMark Johnston.Xr copyout 9 ,
310ce260994SMark Johnston.Xr KASAN 9 ,
311be5464aeSMark Johnston.Xr uio 9 ,
312ce260994SMark Johnston.Xr uma 9
313ce260994SMark Johnston.Rs
314ce260994SMark Johnston.%A Evgeniy Stepanov
315ce260994SMark Johnston.%A Konstantin Serebryany
316ce260994SMark Johnston.%T MemorySanitizer: fast detector of uninitialized memory use in C++
317ce260994SMark Johnston.%J 2015 IEEE/ACM International Symposium on Code Generation and Optimization (CGO)
318ce260994SMark Johnston.%D 2015
319ce260994SMark Johnston.Re
320ce260994SMark Johnston.Sh HISTORY
321ce260994SMark Johnston.Nm
322ce260994SMark Johnstonwas ported from
323ce260994SMark Johnston.Nx
324ce260994SMark Johnstonand first appeared in
325ce260994SMark Johnston.Fx 14.0 .
326ce260994SMark Johnston.Sh BUGS
327ce260994SMark JohnstonAccesses to kernel memory outside of the kernel map are ignored by the
328ce260994SMark Johnston.Nm
329ce260994SMark Johnstonruntime.
330ce260994SMark JohnstonIn particular, memory accesses via the direct map are not validated.
331ce260994SMark JohnstonWhen memory is copied from outside the kernel map into the kernel map,
332ce260994SMark Johnstonthat region of the kernel map is marked as initialized.
333ce260994SMark JohnstonWhen
334ce260994SMark Johnston.Nm
335ce260994SMark Johnstonis configured, kernel memory allocators are configured to use the kernel map,
336ce260994SMark Johnstonand filesystems are configured to always map data buffers into the kernel map,
337ce260994SMark Johnstonso usage of the direct map is minimized.
338ce260994SMark JohnstonHowever, some uses of the direct map remain.
339ce260994SMark JohnstonThis is a conservative policy which aims to avoid false positives, but it will
340ce260994SMark Johnstonmask bug in some kernel subsystems.
341ce260994SMark Johnston.Pp
342ce260994SMark JohnstonOn amd64, global variables and the physical page array
343ce260994SMark Johnston.Va vm_page_array
344ce260994SMark Johnstonare not sanitized.
345ce260994SMark JohnstonThis is intentional, as it reduces memory usage by avoiding creating
346ce260994SMark Johnstonshadows of large regions of the kernel map.
347ce260994SMark JohnstonHowever, this can allow bugs to go undetected by
348ce260994SMark Johnston.Nm .
349ce260994SMark Johnston.Pp
350ce260994SMark JohnstonSome kernel memory allocators provide type-stable objects, and code which uses
351ce260994SMark Johnstonthem frequently depends on object data being preserved across allocations.
352ce260994SMark JohnstonSuch allocations cannot be sanitized by
353ce260994SMark Johnston.Nm .
354ce260994SMark JohnstonHowever, in some cases it may be possible to use
355ce260994SMark Johnston.Fn kmsan_mark
356ce260994SMark Johnstonto manually annotate fields which are known to contain invalid data upon
357ce260994SMark Johnstonallocation.
358