1
2
3#include <linux/jiffies.h>
4#include <linux/kernel.h>
5#include <linux/lockdep.h>
6#include <linux/preempt.h>
7#include <linux/printk.h>
8#include <linux/sched.h>
9#include <linux/spinlock.h>
10#include <linux/stacktrace.h>
11
12#include "kcsan.h"
13#include "encoding.h"
14
15
16
17
18#define NUM_STACK_ENTRIES 64
19
20
21
22
23
24
25
26static struct {
27 const volatile void *ptr;
28 size_t size;
29 int access_type;
30 int task_pid;
31 int cpu_id;
32 unsigned long stack_entries[NUM_STACK_ENTRIES];
33 int num_stack_entries;
34} other_info = { .ptr = NULL };
35
36
37
38
39struct report_time {
40
41
42
43 unsigned long time;
44
45
46
47
48
49 unsigned long frame1;
50 unsigned long frame2;
51};
52
53
54
55
56
57
58
59
60
61
62
63#define REPORT_TIMES_MAX (PAGE_SIZE / sizeof(struct report_time))
64#define REPORT_TIMES_SIZE \
65 (CONFIG_KCSAN_REPORT_ONCE_IN_MS > REPORT_TIMES_MAX ? \
66 REPORT_TIMES_MAX : \
67 CONFIG_KCSAN_REPORT_ONCE_IN_MS)
68static struct report_time report_times[REPORT_TIMES_SIZE];
69
70
71
72
73
74static DEFINE_SPINLOCK(report_lock);
75
76
77
78
79
80static bool rate_limit_report(unsigned long frame1, unsigned long frame2)
81{
82 struct report_time *use_entry = &report_times[0];
83 unsigned long invalid_before;
84 int i;
85
86 BUILD_BUG_ON(CONFIG_KCSAN_REPORT_ONCE_IN_MS != 0 && REPORT_TIMES_SIZE == 0);
87
88 if (CONFIG_KCSAN_REPORT_ONCE_IN_MS == 0)
89 return false;
90
91 invalid_before = jiffies - msecs_to_jiffies(CONFIG_KCSAN_REPORT_ONCE_IN_MS);
92
93
94 for (i = 0; i < REPORT_TIMES_SIZE; ++i) {
95 struct report_time *rt = &report_times[i];
96
97
98
99
100
101
102
103 if (time_before(rt->time, use_entry->time))
104 use_entry = rt;
105
106
107
108
109
110 if (rt->time == 0)
111 break;
112
113
114 if (time_before(rt->time, invalid_before))
115 continue;
116
117
118 if ((rt->frame1 == frame1 && rt->frame2 == frame2) ||
119 (rt->frame1 == frame2 && rt->frame2 == frame1))
120 return true;
121 }
122
123 use_entry->time = jiffies;
124 use_entry->frame1 = frame1;
125 use_entry->frame2 = frame2;
126 return false;
127}
128
129
130
131
132static bool
133skip_report(enum kcsan_value_change value_change, unsigned long top_frame)
134{
135
136 WARN_ON_ONCE(value_change == KCSAN_VALUE_CHANGE_FALSE);
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 if (IS_ENABLED(CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY) &&
156 value_change == KCSAN_VALUE_CHANGE_MAYBE) {
157
158
159
160
161
162
163 char buf[64];
164
165 snprintf(buf, sizeof(buf), "%ps", (void *)top_frame);
166 if (!strnstr(buf, "rcu_", sizeof(buf)) &&
167 !strnstr(buf, "_rcu", sizeof(buf)) &&
168 !strnstr(buf, "_srcu", sizeof(buf)))
169 return true;
170 }
171
172 return kcsan_skip_report_debugfs(top_frame);
173}
174
175static const char *get_access_type(int type)
176{
177 switch (type) {
178 case 0:
179 return "read";
180 case KCSAN_ACCESS_ATOMIC:
181 return "read (marked)";
182 case KCSAN_ACCESS_WRITE:
183 return "write";
184 case KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ATOMIC:
185 return "write (marked)";
186
187
188
189
190 case KCSAN_ACCESS_ASSERT:
191 case KCSAN_ACCESS_ASSERT | KCSAN_ACCESS_ATOMIC:
192 return "assert no writes";
193 case KCSAN_ACCESS_ASSERT | KCSAN_ACCESS_WRITE:
194 case KCSAN_ACCESS_ASSERT | KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ATOMIC:
195 return "assert no accesses";
196
197 default:
198 BUG();
199 }
200}
201
202static const char *get_bug_type(int type)
203{
204 return (type & KCSAN_ACCESS_ASSERT) != 0 ? "assert: race" : "data-race";
205}
206
207
208static const char *get_thread_desc(int task_id)
209{
210 if (task_id != -1) {
211 static char buf[32];
212
213 snprintf(buf, sizeof(buf), "task %i", task_id);
214 return buf;
215 }
216 return "interrupt";
217}
218
219
220static int get_stack_skipnr(unsigned long stack_entries[], int num_entries)
221{
222 char buf[64];
223 int skip = 0;
224
225 for (; skip < num_entries; ++skip) {
226 snprintf(buf, sizeof(buf), "%ps", (void *)stack_entries[skip]);
227 if (!strnstr(buf, "csan_", sizeof(buf)) &&
228 !strnstr(buf, "tsan_", sizeof(buf)) &&
229 !strnstr(buf, "_once_size", sizeof(buf))) {
230 break;
231 }
232 }
233 return skip;
234}
235
236
237static int sym_strcmp(void *addr1, void *addr2)
238{
239 char buf1[64];
240 char buf2[64];
241
242 snprintf(buf1, sizeof(buf1), "%pS", addr1);
243 snprintf(buf2, sizeof(buf2), "%pS", addr2);
244
245 return strncmp(buf1, buf2, sizeof(buf1));
246}
247
248
249
250
251static bool print_report(const volatile void *ptr, size_t size, int access_type,
252 enum kcsan_value_change value_change, int cpu_id,
253 enum kcsan_report_type type)
254{
255 unsigned long stack_entries[NUM_STACK_ENTRIES] = { 0 };
256 int num_stack_entries = stack_trace_save(stack_entries, NUM_STACK_ENTRIES, 1);
257 int skipnr = get_stack_skipnr(stack_entries, num_stack_entries);
258 unsigned long this_frame = stack_entries[skipnr];
259 unsigned long other_frame = 0;
260 int other_skipnr = 0;
261
262
263
264
265 if (skip_report(KCSAN_VALUE_CHANGE_TRUE, stack_entries[skipnr]))
266 return false;
267
268 if (type == KCSAN_REPORT_RACE_SIGNAL) {
269 other_skipnr = get_stack_skipnr(other_info.stack_entries,
270 other_info.num_stack_entries);
271 other_frame = other_info.stack_entries[other_skipnr];
272
273
274 if (skip_report(value_change, other_frame))
275 return false;
276 }
277
278 if (rate_limit_report(this_frame, other_frame))
279 return false;
280
281
282 pr_err("==================================================================\n");
283 switch (type) {
284 case KCSAN_REPORT_RACE_SIGNAL: {
285 int cmp;
286
287
288
289
290
291 cmp = sym_strcmp((void *)other_frame, (void *)this_frame);
292 pr_err("BUG: KCSAN: %s in %ps / %ps\n",
293 get_bug_type(access_type | other_info.access_type),
294 (void *)(cmp < 0 ? other_frame : this_frame),
295 (void *)(cmp < 0 ? this_frame : other_frame));
296 } break;
297
298 case KCSAN_REPORT_RACE_UNKNOWN_ORIGIN:
299 pr_err("BUG: KCSAN: %s in %pS\n", get_bug_type(access_type),
300 (void *)this_frame);
301 break;
302
303 default:
304 BUG();
305 }
306
307 pr_err("\n");
308
309
310 switch (type) {
311 case KCSAN_REPORT_RACE_SIGNAL:
312 pr_err("%s to 0x%px of %zu bytes by %s on cpu %i:\n",
313 get_access_type(other_info.access_type), other_info.ptr,
314 other_info.size, get_thread_desc(other_info.task_pid),
315 other_info.cpu_id);
316
317
318 stack_trace_print(other_info.stack_entries + other_skipnr,
319 other_info.num_stack_entries - other_skipnr,
320 0);
321
322 pr_err("\n");
323 pr_err("%s to 0x%px of %zu bytes by %s on cpu %i:\n",
324 get_access_type(access_type), ptr, size,
325 get_thread_desc(in_task() ? task_pid_nr(current) : -1),
326 cpu_id);
327 break;
328
329 case KCSAN_REPORT_RACE_UNKNOWN_ORIGIN:
330 pr_err("race at unknown origin, with %s to 0x%px of %zu bytes by %s on cpu %i:\n",
331 get_access_type(access_type), ptr, size,
332 get_thread_desc(in_task() ? task_pid_nr(current) : -1),
333 cpu_id);
334 break;
335
336 default:
337 BUG();
338 }
339
340 stack_trace_print(stack_entries + skipnr, num_stack_entries - skipnr,
341 0);
342
343
344 pr_err("\n");
345 pr_err("Reported by Kernel Concurrency Sanitizer on:\n");
346 dump_stack_print_info(KERN_DEFAULT);
347 pr_err("==================================================================\n");
348
349 return true;
350}
351
352static void release_report(unsigned long *flags, enum kcsan_report_type type)
353{
354 if (type == KCSAN_REPORT_RACE_SIGNAL)
355 other_info.ptr = NULL;
356
357 spin_unlock_irqrestore(&report_lock, *flags);
358}
359
360
361
362
363
364
365static bool prepare_report(unsigned long *flags, const volatile void *ptr,
366 size_t size, int access_type, int cpu_id,
367 enum kcsan_report_type type)
368{
369 if (type != KCSAN_REPORT_CONSUMED_WATCHPOINT &&
370 type != KCSAN_REPORT_RACE_SIGNAL) {
371
372 spin_lock_irqsave(&report_lock, *flags);
373 return true;
374 }
375
376retry:
377 spin_lock_irqsave(&report_lock, *flags);
378
379 switch (type) {
380 case KCSAN_REPORT_CONSUMED_WATCHPOINT:
381 if (other_info.ptr != NULL)
382 break;
383
384 other_info.ptr = ptr;
385 other_info.size = size;
386 other_info.access_type = access_type;
387 other_info.task_pid = in_task() ? task_pid_nr(current) : -1;
388 other_info.cpu_id = cpu_id;
389 other_info.num_stack_entries = stack_trace_save(other_info.stack_entries, NUM_STACK_ENTRIES, 1);
390
391 spin_unlock_irqrestore(&report_lock, *flags);
392
393
394
395
396
397 return false;
398
399 case KCSAN_REPORT_RACE_SIGNAL:
400 if (other_info.ptr == NULL)
401 break;
402
403
404
405
406
407 if (!matching_access((unsigned long)other_info.ptr &
408 WATCHPOINT_ADDR_MASK,
409 other_info.size,
410 (unsigned long)ptr & WATCHPOINT_ADDR_MASK,
411 size))
412 break;
413
414 if (!matching_access((unsigned long)other_info.ptr,
415 other_info.size, (unsigned long)ptr,
416 size)) {
417
418
419
420
421 kcsan_counter_inc(
422 KCSAN_COUNTER_ENCODING_FALSE_POSITIVES);
423
424
425 release_report(flags, KCSAN_REPORT_RACE_SIGNAL);
426 return false;
427 }
428
429 access_type |= other_info.access_type;
430 if ((access_type & KCSAN_ACCESS_WRITE) == 0) {
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463 release_report(flags, KCSAN_REPORT_RACE_SIGNAL);
464 return false;
465 }
466
467
468
469
470
471
472 return true;
473
474 default:
475 BUG();
476 }
477
478 spin_unlock_irqrestore(&report_lock, *flags);
479
480 goto retry;
481}
482
483void kcsan_report(const volatile void *ptr, size_t size, int access_type,
484 enum kcsan_value_change value_change, int cpu_id,
485 enum kcsan_report_type type)
486{
487 unsigned long flags = 0;
488
489
490
491
492
493
494
495 lockdep_off();
496
497 kcsan_disable_current();
498 if (prepare_report(&flags, ptr, size, access_type, cpu_id, type)) {
499
500
501
502
503
504 bool reported = value_change != KCSAN_VALUE_CHANGE_FALSE &&
505 print_report(ptr, size, access_type, value_change, cpu_id, type);
506
507 if (reported && panic_on_warn)
508 panic("panic_on_warn set ...\n");
509
510 release_report(&flags, type);
511 }
512 kcsan_enable_current();
513
514 lockdep_on();
515}
516