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