forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
For each memory location KernelMemorySanitizer maintains two types of metadata: 1. The so-called shadow of that location - а byte:byte mapping describing whether or not individual bits of memory are initialized (shadow is 0) or not (shadow is 1). 2. The origins of that location - а 4-byte:4-byte mapping containing 4-byte IDs of the stack traces where uninitialized values were created. Each struct page now contains pointers to two struct pages holding KMSAN metadata (shadow and origins) for the original struct page. Utility routines in mm/kmsan/core.c and mm/kmsan/shadow.c handle the metadata creation, addressing, copying and checking. mm/kmsan/report.c performs error reporting in the cases an uninitialized value is used in a way that leads to undefined behavior. KMSAN compiler instrumentation is responsible for tracking the metadata along with the kernel memory. mm/kmsan/instrumentation.c provides the implementation for instrumentation hooks that are called from files compiled with -fsanitize=kernel-memory. To aid parameter passing (also done at instrumentation level), each task_struct now contains a struct kmsan_task_state used to track the metadata of function parameters and return values for that task. Finally, this patch provides CONFIG_KMSAN that enables KMSAN, and declares CFLAGS_KMSAN, which are applied to files compiled with KMSAN. The KMSAN_SANITIZE:=n Makefile directive can be used to completely disable KMSAN instrumentation for certain files. Similarly, KMSAN_ENABLE_CHECKS:=n disables KMSAN checks and makes newly created stack memory initialized. Users can also use functions from include/linux/kmsan-checks.h to mark certain memory regions as uninitialized or initialized (this is called "poisoning" and "unpoisoning") or check that a particular region is initialized. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Alexander Potapenko <[email protected]> Acked-by: Marco Elver <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Andrey Konovalov <[email protected]> Cc: Andrey Konovalov <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: David Rientjes <[email protected]> Cc: Dmitry Vyukov <[email protected]> Cc: Eric Biggers <[email protected]> Cc: Eric Biggers <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Herbert Xu <[email protected]> Cc: Ilya Leoshkevich <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Joonsoo Kim <[email protected]> Cc: Kees Cook <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Michael S. Tsirkin <[email protected]> Cc: Pekka Enberg <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Petr Mladek <[email protected]> Cc: Stephen Rothwell <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vasily Gorbik <[email protected]> Cc: Vegard Nossum <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
- Loading branch information
1 parent
6e9f05d
commit f80be45
Showing
17 changed files
with
1,592 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* KMSAN checks to be used for one-off annotations in subsystems. | ||
* | ||
* Copyright (C) 2017-2022 Google LLC | ||
* Author: Alexander Potapenko <[email protected]> | ||
* | ||
*/ | ||
|
||
#ifndef _LINUX_KMSAN_CHECKS_H | ||
#define _LINUX_KMSAN_CHECKS_H | ||
|
||
#include <linux/types.h> | ||
|
||
#ifdef CONFIG_KMSAN | ||
|
||
/** | ||
* kmsan_poison_memory() - Mark the memory range as uninitialized. | ||
* @address: address to start with. | ||
* @size: size of buffer to poison. | ||
* @flags: GFP flags for allocations done by this function. | ||
* | ||
* Until other data is written to this range, KMSAN will treat it as | ||
* uninitialized. Error reports for this memory will reference the call site of | ||
* kmsan_poison_memory() as origin. | ||
*/ | ||
void kmsan_poison_memory(const void *address, size_t size, gfp_t flags); | ||
|
||
/** | ||
* kmsan_unpoison_memory() - Mark the memory range as initialized. | ||
* @address: address to start with. | ||
* @size: size of buffer to unpoison. | ||
* | ||
* Until other data is written to this range, KMSAN will treat it as | ||
* initialized. | ||
*/ | ||
void kmsan_unpoison_memory(const void *address, size_t size); | ||
|
||
/** | ||
* kmsan_check_memory() - Check the memory range for being initialized. | ||
* @address: address to start with. | ||
* @size: size of buffer to check. | ||
* | ||
* If any piece of the given range is marked as uninitialized, KMSAN will report | ||
* an error. | ||
*/ | ||
void kmsan_check_memory(const void *address, size_t size); | ||
|
||
#else | ||
|
||
static inline void kmsan_poison_memory(const void *address, size_t size, | ||
gfp_t flags) | ||
{ | ||
} | ||
static inline void kmsan_unpoison_memory(const void *address, size_t size) | ||
{ | ||
} | ||
static inline void kmsan_check_memory(const void *address, size_t size) | ||
{ | ||
} | ||
|
||
#endif | ||
|
||
#endif /* _LINUX_KMSAN_CHECKS_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* A minimal header declaring types added by KMSAN to existing kernel structs. | ||
* | ||
* Copyright (C) 2017-2022 Google LLC | ||
* Author: Alexander Potapenko <[email protected]> | ||
* | ||
*/ | ||
#ifndef _LINUX_KMSAN_TYPES_H | ||
#define _LINUX_KMSAN_TYPES_H | ||
|
||
/* These constants are defined in the MSan LLVM instrumentation pass. */ | ||
#define KMSAN_RETVAL_SIZE 800 | ||
#define KMSAN_PARAM_SIZE 800 | ||
|
||
struct kmsan_context_state { | ||
char param_tls[KMSAN_PARAM_SIZE]; | ||
char retval_tls[KMSAN_RETVAL_SIZE]; | ||
char va_arg_tls[KMSAN_PARAM_SIZE]; | ||
char va_arg_origin_tls[KMSAN_PARAM_SIZE]; | ||
u64 va_arg_overflow_size_tls; | ||
char param_origin_tls[KMSAN_PARAM_SIZE]; | ||
u32 retval_origin_tls; | ||
}; | ||
|
||
#undef KMSAN_PARAM_SIZE | ||
#undef KMSAN_RETVAL_SIZE | ||
|
||
struct kmsan_ctx { | ||
struct kmsan_context_state cstate; | ||
int kmsan_in_runtime; | ||
bool allow_reporting; | ||
}; | ||
|
||
#endif /* _LINUX_KMSAN_TYPES_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
config HAVE_ARCH_KMSAN | ||
bool | ||
|
||
config HAVE_KMSAN_COMPILER | ||
# Clang versions <14.0.0 also support -fsanitize=kernel-memory, but not | ||
# all the features necessary to build the kernel with KMSAN. | ||
depends on CC_IS_CLANG && CLANG_VERSION >= 140000 | ||
def_bool $(cc-option,-fsanitize=kernel-memory -mllvm -msan-disable-checks=1) | ||
|
||
config KMSAN | ||
bool "KMSAN: detector of uninitialized values use" | ||
depends on HAVE_ARCH_KMSAN && HAVE_KMSAN_COMPILER | ||
depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN | ||
select STACKDEPOT | ||
select STACKDEPOT_ALWAYS_INIT | ||
help | ||
KernelMemorySanitizer (KMSAN) is a dynamic detector of uses of | ||
uninitialized values in the kernel. It is based on compiler | ||
instrumentation provided by Clang and thus requires Clang to build. | ||
|
||
An important note is that KMSAN is not intended for production use, | ||
because it drastically increases kernel memory footprint and slows | ||
the whole system down. | ||
|
||
See <file:Documentation/dev-tools/kmsan.rst> for more details. | ||
|
||
if KMSAN | ||
|
||
config HAVE_KMSAN_PARAM_RETVAL | ||
# -fsanitize-memory-param-retval is supported only by Clang >= 14. | ||
depends on HAVE_KMSAN_COMPILER | ||
def_bool $(cc-option,-fsanitize=kernel-memory -fsanitize-memory-param-retval) | ||
|
||
config KMSAN_CHECK_PARAM_RETVAL | ||
bool "Check for uninitialized values passed to and returned from functions" | ||
default y | ||
depends on HAVE_KMSAN_PARAM_RETVAL | ||
help | ||
If the compiler supports -fsanitize-memory-param-retval, KMSAN will | ||
eagerly check every function parameter passed by value and every | ||
function return value. | ||
|
||
Disabling KMSAN_CHECK_PARAM_RETVAL will result in tracking shadow for | ||
function parameters and return values across function borders. This | ||
is a more relaxed mode, but it generates more instrumentation code and | ||
may potentially report errors in corner cases when non-instrumented | ||
functions call instrumented ones. | ||
|
||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
# | ||
# Makefile for KernelMemorySanitizer (KMSAN). | ||
# | ||
# | ||
obj-y := core.o instrumentation.o hooks.o report.o shadow.o | ||
|
||
KMSAN_SANITIZE := n | ||
KCOV_INSTRUMENT := n | ||
UBSAN_SANITIZE := n | ||
|
||
# Disable instrumentation of KMSAN runtime with other tools. | ||
CC_FLAGS_KMSAN_RUNTIME := -fno-stack-protector | ||
CC_FLAGS_KMSAN_RUNTIME += $(call cc-option,-fno-conserve-stack) | ||
CC_FLAGS_KMSAN_RUNTIME += -DDISABLE_BRANCH_PROFILING | ||
|
||
CFLAGS_REMOVE.o = $(CC_FLAGS_FTRACE) | ||
|
||
CFLAGS_core.o := $(CC_FLAGS_KMSAN_RUNTIME) | ||
CFLAGS_hooks.o := $(CC_FLAGS_KMSAN_RUNTIME) | ||
CFLAGS_instrumentation.o := $(CC_FLAGS_KMSAN_RUNTIME) | ||
CFLAGS_report.o := $(CC_FLAGS_KMSAN_RUNTIME) | ||
CFLAGS_shadow.o := $(CC_FLAGS_KMSAN_RUNTIME) |
Oops, something went wrong.