Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/mm/kmsan/report.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* KMSAN error reporting routines.
4
*
5
* Copyright (C) 2019-2022 Google LLC
6
* Author: Alexander Potapenko <[email protected]>
7
*
8
*/
9
10
#include <linux/console.h>
11
#include <linux/kmsan.h>
12
#include <linux/moduleparam.h>
13
#include <linux/stackdepot.h>
14
#include <linux/stacktrace.h>
15
#include <linux/uaccess.h>
16
17
#include "kmsan.h"
18
19
static DEFINE_RAW_SPINLOCK(kmsan_report_lock);
20
#define DESCR_SIZE 128
21
/* Protected by kmsan_report_lock */
22
static char report_local_descr[DESCR_SIZE];
23
int panic_on_kmsan __read_mostly;
24
EXPORT_SYMBOL_GPL(panic_on_kmsan);
25
26
#ifdef MODULE_PARAM_PREFIX
27
#undef MODULE_PARAM_PREFIX
28
#endif
29
#define MODULE_PARAM_PREFIX "kmsan."
30
module_param_named(panic, panic_on_kmsan, int, 0);
31
32
/*
33
* Skip internal KMSAN frames.
34
*/
35
static int get_stack_skipnr(const unsigned long stack_entries[],
36
int num_entries)
37
{
38
int len, skip;
39
char buf[64];
40
41
for (skip = 0; skip < num_entries; ++skip) {
42
len = scnprintf(buf, sizeof(buf), "%ps",
43
(void *)stack_entries[skip]);
44
45
/* Never show __msan_* or kmsan_* functions. */
46
if ((strnstr(buf, "__msan_", len) == buf) ||
47
(strnstr(buf, "kmsan_", len) == buf))
48
continue;
49
50
/*
51
* No match for runtime functions -- @skip entries to skip to
52
* get to first frame of interest.
53
*/
54
break;
55
}
56
57
return skip;
58
}
59
60
/*
61
* Currently the descriptions of locals generated by Clang look as follows:
62
* ----local_name@function_name
63
* We want to print only the name of the local, as other information in that
64
* description can be confusing.
65
* The meaningful part of the description is copied to a global buffer to avoid
66
* allocating memory.
67
*/
68
static char *pretty_descr(char *descr)
69
{
70
int pos = 0, len = strlen(descr);
71
72
for (int i = 0; i < len; i++) {
73
if (descr[i] == '@')
74
break;
75
if (descr[i] == '-')
76
continue;
77
report_local_descr[pos] = descr[i];
78
if (pos + 1 == DESCR_SIZE)
79
break;
80
pos++;
81
}
82
report_local_descr[pos] = 0;
83
return report_local_descr;
84
}
85
86
void kmsan_print_origin(depot_stack_handle_t origin)
87
{
88
unsigned long *entries = NULL, *chained_entries = NULL;
89
unsigned int nr_entries, chained_nr_entries, skipnr;
90
void *pc1 = NULL, *pc2 = NULL;
91
depot_stack_handle_t head;
92
unsigned long magic;
93
char *descr = NULL;
94
unsigned int depth;
95
96
if (!origin)
97
return;
98
99
while (true) {
100
nr_entries = stack_depot_fetch(origin, &entries);
101
depth = kmsan_depth_from_eb(stack_depot_get_extra_bits(origin));
102
magic = nr_entries ? entries[0] : 0;
103
if ((nr_entries == 4) && (magic == KMSAN_ALLOCA_MAGIC_ORIGIN)) {
104
descr = (char *)entries[1];
105
pc1 = (void *)entries[2];
106
pc2 = (void *)entries[3];
107
pr_err("Local variable %s created at:\n",
108
pretty_descr(descr));
109
if (pc1)
110
pr_err(" %pSb\n", pc1);
111
if (pc2)
112
pr_err(" %pSb\n", pc2);
113
break;
114
}
115
if ((nr_entries == 3) && (magic == KMSAN_CHAIN_MAGIC_ORIGIN)) {
116
/*
117
* Origin chains deeper than KMSAN_MAX_ORIGIN_DEPTH are
118
* not stored, so the output may be incomplete.
119
*/
120
if (depth == KMSAN_MAX_ORIGIN_DEPTH)
121
pr_err("<Zero or more stacks not recorded to save memory>\n\n");
122
head = entries[1];
123
origin = entries[2];
124
pr_err("Uninit was stored to memory at:\n");
125
chained_nr_entries =
126
stack_depot_fetch(head, &chained_entries);
127
kmsan_internal_unpoison_memory(
128
chained_entries,
129
chained_nr_entries * sizeof(*chained_entries),
130
/*checked*/ false);
131
skipnr = get_stack_skipnr(chained_entries,
132
chained_nr_entries);
133
stack_trace_print(chained_entries + skipnr,
134
chained_nr_entries - skipnr, 0);
135
pr_err("\n");
136
continue;
137
}
138
pr_err("Uninit was created at:\n");
139
if (nr_entries) {
140
skipnr = get_stack_skipnr(entries, nr_entries);
141
stack_trace_print(entries + skipnr, nr_entries - skipnr,
142
0);
143
} else {
144
pr_err("(stack is not available)\n");
145
}
146
break;
147
}
148
}
149
150
void kmsan_report(depot_stack_handle_t origin, void *address, int size,
151
int off_first, int off_last, const void __user *user_addr,
152
enum kmsan_bug_reason reason)
153
{
154
unsigned long stack_entries[KMSAN_STACK_DEPTH];
155
int num_stack_entries, skipnr;
156
char *bug_type = NULL;
157
unsigned long ua_flags;
158
bool is_uaf;
159
160
if (!kmsan_enabled || kmsan_in_runtime())
161
return;
162
if (current->kmsan_ctx.depth)
163
return;
164
if (!origin)
165
return;
166
167
kmsan_enter_runtime();
168
ua_flags = user_access_save();
169
raw_spin_lock(&kmsan_report_lock);
170
pr_err("=====================================================\n");
171
is_uaf = kmsan_uaf_from_eb(stack_depot_get_extra_bits(origin));
172
switch (reason) {
173
case REASON_ANY:
174
bug_type = is_uaf ? "use-after-free" : "uninit-value";
175
break;
176
case REASON_COPY_TO_USER:
177
bug_type = is_uaf ? "kernel-infoleak-after-free" :
178
"kernel-infoleak";
179
break;
180
case REASON_SUBMIT_URB:
181
bug_type = is_uaf ? "kernel-usb-infoleak-after-free" :
182
"kernel-usb-infoleak";
183
break;
184
}
185
186
num_stack_entries =
187
stack_trace_save(stack_entries, KMSAN_STACK_DEPTH, 1);
188
skipnr = get_stack_skipnr(stack_entries, num_stack_entries);
189
190
pr_err("BUG: KMSAN: %s in %pSb\n", bug_type,
191
(void *)stack_entries[skipnr]);
192
stack_trace_print(stack_entries + skipnr, num_stack_entries - skipnr,
193
0);
194
pr_err("\n");
195
196
kmsan_print_origin(origin);
197
198
if (size) {
199
pr_err("\n");
200
if (off_first == off_last)
201
pr_err("Byte %d of %d is uninitialized\n", off_first,
202
size);
203
else
204
pr_err("Bytes %d-%d of %d are uninitialized\n",
205
off_first, off_last, size);
206
}
207
if (address)
208
pr_err("Memory access of size %d starts at %px\n", size,
209
address);
210
if (user_addr && reason == REASON_COPY_TO_USER)
211
pr_err("Data copied to user address %px\n", user_addr);
212
pr_err("\n");
213
dump_stack_print_info(KERN_ERR);
214
pr_err("=====================================================\n");
215
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
216
raw_spin_unlock(&kmsan_report_lock);
217
if (panic_on_kmsan)
218
panic("kmsan.panic set ...\n");
219
user_access_restore(ua_flags);
220
kmsan_leave_runtime();
221
}
222
223