Commit | Line | Data |
---|---|---|
f80be457 AP |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * KMSAN hooks for kernel subsystems. | |
4 | * | |
5 | * These functions handle creation of KMSAN metadata for memory allocations. | |
6 | * | |
7 | * Copyright (C) 2018-2022 Google LLC | |
8 | * Author: Alexander Potapenko <glider@google.com> | |
9 | * | |
10 | */ | |
11 | ||
12 | #include <linux/cacheflush.h> | |
13 | #include <linux/gfp.h> | |
14 | #include <linux/mm.h> | |
15 | #include <linux/mm_types.h> | |
16 | #include <linux/slab.h> | |
17 | #include <linux/uaccess.h> | |
18 | ||
19 | #include "../internal.h" | |
20 | #include "../slab.h" | |
21 | #include "kmsan.h" | |
22 | ||
23 | /* | |
24 | * Instrumented functions shouldn't be called under | |
25 | * kmsan_enter_runtime()/kmsan_leave_runtime(), because this will lead to | |
26 | * skipping effects of functions like memset() inside instrumented code. | |
27 | */ | |
28 | ||
29 | /* Functions from kmsan-checks.h follow. */ | |
30 | void kmsan_poison_memory(const void *address, size_t size, gfp_t flags) | |
31 | { | |
32 | if (!kmsan_enabled || kmsan_in_runtime()) | |
33 | return; | |
34 | kmsan_enter_runtime(); | |
35 | /* The users may want to poison/unpoison random memory. */ | |
36 | kmsan_internal_poison_memory((void *)address, size, flags, | |
37 | KMSAN_POISON_NOCHECK); | |
38 | kmsan_leave_runtime(); | |
39 | } | |
40 | EXPORT_SYMBOL(kmsan_poison_memory); | |
41 | ||
42 | void kmsan_unpoison_memory(const void *address, size_t size) | |
43 | { | |
44 | unsigned long ua_flags; | |
45 | ||
46 | if (!kmsan_enabled || kmsan_in_runtime()) | |
47 | return; | |
48 | ||
49 | ua_flags = user_access_save(); | |
50 | kmsan_enter_runtime(); | |
51 | /* The users may want to poison/unpoison random memory. */ | |
52 | kmsan_internal_unpoison_memory((void *)address, size, | |
53 | KMSAN_POISON_NOCHECK); | |
54 | kmsan_leave_runtime(); | |
55 | user_access_restore(ua_flags); | |
56 | } | |
57 | EXPORT_SYMBOL(kmsan_unpoison_memory); | |
58 | ||
59 | void kmsan_check_memory(const void *addr, size_t size) | |
60 | { | |
61 | if (!kmsan_enabled) | |
62 | return; | |
63 | return kmsan_internal_check_memory((void *)addr, size, /*user_addr*/ 0, | |
64 | REASON_ANY); | |
65 | } | |
66 | EXPORT_SYMBOL(kmsan_check_memory); |