1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * This file contains common KASAN error reporting code. |
4 | * |
5 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. |
6 | * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com> |
7 | * |
8 | * Some code borrowed from https://github.com/xairy/kasan-prototype by |
9 | * Andrey Konovalov <andreyknvl@gmail.com> |
10 | */ |
11 | |
12 | #include <kunit/test.h> |
13 | #include <linux/bitops.h> |
14 | #include <linux/ftrace.h> |
15 | #include <linux/init.h> |
16 | #include <linux/kernel.h> |
17 | #include <linux/lockdep.h> |
18 | #include <linux/mm.h> |
19 | #include <linux/printk.h> |
20 | #include <linux/sched.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/stackdepot.h> |
23 | #include <linux/stacktrace.h> |
24 | #include <linux/string.h> |
25 | #include <linux/types.h> |
26 | #include <linux/kasan.h> |
27 | #include <linux/module.h> |
28 | #include <linux/sched/task_stack.h> |
29 | #include <linux/uaccess.h> |
30 | #include <trace/events/error_report.h> |
31 | |
32 | #include <asm/sections.h> |
33 | |
34 | #include "kasan.h" |
35 | #include "../slab.h" |
36 | |
37 | static unsigned long kasan_flags; |
38 | |
39 | #define KASAN_BIT_REPORTED 0 |
40 | #define KASAN_BIT_MULTI_SHOT 1 |
41 | |
42 | enum kasan_arg_fault { |
43 | KASAN_ARG_FAULT_DEFAULT, |
44 | KASAN_ARG_FAULT_REPORT, |
45 | KASAN_ARG_FAULT_PANIC, |
46 | KASAN_ARG_FAULT_PANIC_ON_WRITE, |
47 | }; |
48 | |
49 | static enum kasan_arg_fault kasan_arg_fault __ro_after_init = KASAN_ARG_FAULT_DEFAULT; |
50 | |
51 | /* kasan.fault=report/panic */ |
52 | static int __init early_kasan_fault(char *arg) |
53 | { |
54 | if (!arg) |
55 | return -EINVAL; |
56 | |
57 | if (!strcmp(arg, "report" )) |
58 | kasan_arg_fault = KASAN_ARG_FAULT_REPORT; |
59 | else if (!strcmp(arg, "panic" )) |
60 | kasan_arg_fault = KASAN_ARG_FAULT_PANIC; |
61 | else if (!strcmp(arg, "panic_on_write" )) |
62 | kasan_arg_fault = KASAN_ARG_FAULT_PANIC_ON_WRITE; |
63 | else |
64 | return -EINVAL; |
65 | |
66 | return 0; |
67 | } |
68 | early_param("kasan.fault" , early_kasan_fault); |
69 | |
70 | static int __init kasan_set_multi_shot(char *str) |
71 | { |
72 | set_bit(KASAN_BIT_MULTI_SHOT, addr: &kasan_flags); |
73 | return 1; |
74 | } |
75 | __setup("kasan_multi_shot" , kasan_set_multi_shot); |
76 | |
77 | /* |
78 | * This function is used to check whether KASAN reports are suppressed for |
79 | * software KASAN modes via kasan_disable/enable_current() critical sections. |
80 | * |
81 | * This is done to avoid: |
82 | * 1. False-positive reports when accessing slab metadata, |
83 | * 2. Deadlocking when poisoned memory is accessed by the reporting code. |
84 | * |
85 | * Hardware Tag-Based KASAN instead relies on: |
86 | * For #1: Resetting tags via kasan_reset_tag(). |
87 | * For #2: Suppression of tag checks via CPU, see report_suppress_start/end(). |
88 | */ |
89 | static bool report_suppressed_sw(void) |
90 | { |
91 | #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) |
92 | if (current->kasan_depth) |
93 | return true; |
94 | #endif |
95 | return false; |
96 | } |
97 | |
98 | static void report_suppress_start(void) |
99 | { |
100 | #ifdef CONFIG_KASAN_HW_TAGS |
101 | /* |
102 | * Disable preemption for the duration of printing a KASAN report, as |
103 | * hw_suppress_tag_checks_start() disables checks on the current CPU. |
104 | */ |
105 | preempt_disable(); |
106 | hw_suppress_tag_checks_start(); |
107 | #else |
108 | kasan_disable_current(); |
109 | #endif |
110 | } |
111 | |
112 | static void report_suppress_stop(void) |
113 | { |
114 | #ifdef CONFIG_KASAN_HW_TAGS |
115 | hw_suppress_tag_checks_stop(); |
116 | preempt_enable(); |
117 | #else |
118 | kasan_enable_current(); |
119 | #endif |
120 | } |
121 | |
122 | /* |
123 | * Used to avoid reporting more than one KASAN bug unless kasan_multi_shot |
124 | * is enabled. Note that KASAN tests effectively enable kasan_multi_shot |
125 | * for their duration. |
126 | */ |
127 | static bool report_enabled(void) |
128 | { |
129 | if (test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) |
130 | return true; |
131 | return !test_and_set_bit(KASAN_BIT_REPORTED, addr: &kasan_flags); |
132 | } |
133 | |
134 | #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST) || IS_ENABLED(CONFIG_KASAN_MODULE_TEST) |
135 | |
136 | bool kasan_save_enable_multi_shot(void) |
137 | { |
138 | return test_and_set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags); |
139 | } |
140 | EXPORT_SYMBOL_GPL(kasan_save_enable_multi_shot); |
141 | |
142 | void kasan_restore_multi_shot(bool enabled) |
143 | { |
144 | if (!enabled) |
145 | clear_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags); |
146 | } |
147 | EXPORT_SYMBOL_GPL(kasan_restore_multi_shot); |
148 | |
149 | #endif |
150 | |
151 | #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST) |
152 | |
153 | /* |
154 | * Whether the KASAN KUnit test suite is currently being executed. |
155 | * Updated in kasan_test.c. |
156 | */ |
157 | static bool kasan_kunit_executing; |
158 | |
159 | void kasan_kunit_test_suite_start(void) |
160 | { |
161 | WRITE_ONCE(kasan_kunit_executing, true); |
162 | } |
163 | EXPORT_SYMBOL_GPL(kasan_kunit_test_suite_start); |
164 | |
165 | void kasan_kunit_test_suite_end(void) |
166 | { |
167 | WRITE_ONCE(kasan_kunit_executing, false); |
168 | } |
169 | EXPORT_SYMBOL_GPL(kasan_kunit_test_suite_end); |
170 | |
171 | static bool kasan_kunit_test_suite_executing(void) |
172 | { |
173 | return READ_ONCE(kasan_kunit_executing); |
174 | } |
175 | |
176 | #else /* CONFIG_KASAN_KUNIT_TEST */ |
177 | |
178 | static inline bool kasan_kunit_test_suite_executing(void) { return false; } |
179 | |
180 | #endif /* CONFIG_KASAN_KUNIT_TEST */ |
181 | |
182 | #if IS_ENABLED(CONFIG_KUNIT) |
183 | |
184 | static void fail_non_kasan_kunit_test(void) |
185 | { |
186 | struct kunit *test; |
187 | |
188 | if (kasan_kunit_test_suite_executing()) |
189 | return; |
190 | |
191 | test = current->kunit_test; |
192 | if (test) |
193 | kunit_set_failure(test); |
194 | } |
195 | |
196 | #else /* CONFIG_KUNIT */ |
197 | |
198 | static inline void fail_non_kasan_kunit_test(void) { } |
199 | |
200 | #endif /* CONFIG_KUNIT */ |
201 | |
202 | static DEFINE_SPINLOCK(report_lock); |
203 | |
204 | static void start_report(unsigned long *flags, bool sync) |
205 | { |
206 | fail_non_kasan_kunit_test(); |
207 | /* Respect the /proc/sys/kernel/traceoff_on_warning interface. */ |
208 | disable_trace_on_warning(); |
209 | /* Do not allow LOCKDEP mangling KASAN reports. */ |
210 | lockdep_off(); |
211 | /* Make sure we don't end up in loop. */ |
212 | report_suppress_start(); |
213 | spin_lock_irqsave(&report_lock, *flags); |
214 | pr_err("==================================================================\n" ); |
215 | } |
216 | |
217 | static void end_report(unsigned long *flags, const void *addr, bool is_write) |
218 | { |
219 | if (addr) |
220 | trace_error_report_end(error_detector: ERROR_DETECTOR_KASAN, |
221 | id: (unsigned long)addr); |
222 | pr_err("==================================================================\n" ); |
223 | spin_unlock_irqrestore(lock: &report_lock, flags: *flags); |
224 | if (!test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) |
225 | check_panic_on_warn(origin: "KASAN" ); |
226 | switch (kasan_arg_fault) { |
227 | case KASAN_ARG_FAULT_DEFAULT: |
228 | case KASAN_ARG_FAULT_REPORT: |
229 | break; |
230 | case KASAN_ARG_FAULT_PANIC: |
231 | panic(fmt: "kasan.fault=panic set ...\n" ); |
232 | break; |
233 | case KASAN_ARG_FAULT_PANIC_ON_WRITE: |
234 | if (is_write) |
235 | panic(fmt: "kasan.fault=panic_on_write set ...\n" ); |
236 | break; |
237 | } |
238 | add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); |
239 | lockdep_on(); |
240 | report_suppress_stop(); |
241 | } |
242 | |
243 | static void print_error_description(struct kasan_report_info *info) |
244 | { |
245 | pr_err("BUG: KASAN: %s in %pS\n" , info->bug_type, (void *)info->ip); |
246 | |
247 | if (info->type != KASAN_REPORT_ACCESS) { |
248 | pr_err("Free of addr %px by task %s/%d\n" , |
249 | info->access_addr, current->comm, task_pid_nr(current)); |
250 | return; |
251 | } |
252 | |
253 | if (info->access_size) |
254 | pr_err("%s of size %zu at addr %px by task %s/%d\n" , |
255 | info->is_write ? "Write" : "Read" , info->access_size, |
256 | info->access_addr, current->comm, task_pid_nr(current)); |
257 | else |
258 | pr_err("%s at addr %px by task %s/%d\n" , |
259 | info->is_write ? "Write" : "Read" , |
260 | info->access_addr, current->comm, task_pid_nr(current)); |
261 | } |
262 | |
263 | static void print_track(struct kasan_track *track, const char *prefix) |
264 | { |
265 | pr_err("%s by task %u:\n" , prefix, track->pid); |
266 | if (track->stack) |
267 | stack_depot_print(stack: track->stack); |
268 | else |
269 | pr_err("(stack is not available)\n" ); |
270 | } |
271 | |
272 | static inline struct page *addr_to_page(const void *addr) |
273 | { |
274 | if (virt_addr_valid(addr)) |
275 | return virt_to_head_page(x: addr); |
276 | return NULL; |
277 | } |
278 | |
279 | static void describe_object_addr(const void *addr, struct kasan_report_info *info) |
280 | { |
281 | unsigned long access_addr = (unsigned long)addr; |
282 | unsigned long object_addr = (unsigned long)info->object; |
283 | const char *rel_type, *region_state = "" ; |
284 | int rel_bytes; |
285 | |
286 | pr_err("The buggy address belongs to the object at %px\n" |
287 | " which belongs to the cache %s of size %d\n" , |
288 | info->object, info->cache->name, info->cache->object_size); |
289 | |
290 | if (access_addr < object_addr) { |
291 | rel_type = "to the left" ; |
292 | rel_bytes = object_addr - access_addr; |
293 | } else if (access_addr >= object_addr + info->alloc_size) { |
294 | rel_type = "to the right" ; |
295 | rel_bytes = access_addr - (object_addr + info->alloc_size); |
296 | } else { |
297 | rel_type = "inside" ; |
298 | rel_bytes = access_addr - object_addr; |
299 | } |
300 | |
301 | /* |
302 | * Tag-Based modes use the stack ring to infer the bug type, but the |
303 | * memory region state description is generated based on the metadata. |
304 | * Thus, defining the region state as below can contradict the metadata. |
305 | * Fixing this requires further improvements, so only infer the state |
306 | * for the Generic mode. |
307 | */ |
308 | if (IS_ENABLED(CONFIG_KASAN_GENERIC)) { |
309 | if (strcmp(info->bug_type, "slab-out-of-bounds" ) == 0) |
310 | region_state = "allocated " ; |
311 | else if (strcmp(info->bug_type, "slab-use-after-free" ) == 0) |
312 | region_state = "freed " ; |
313 | } |
314 | |
315 | pr_err("The buggy address is located %d bytes %s of\n" |
316 | " %s%zu-byte region [%px, %px)\n" , |
317 | rel_bytes, rel_type, region_state, info->alloc_size, |
318 | (void *)object_addr, (void *)(object_addr + info->alloc_size)); |
319 | } |
320 | |
321 | static void describe_object_stacks(struct kasan_report_info *info) |
322 | { |
323 | if (info->alloc_track.stack) { |
324 | print_track(track: &info->alloc_track, prefix: "Allocated" ); |
325 | pr_err("\n" ); |
326 | } |
327 | |
328 | if (info->free_track.stack) { |
329 | print_track(track: &info->free_track, prefix: "Freed" ); |
330 | pr_err("\n" ); |
331 | } |
332 | |
333 | kasan_print_aux_stacks(cache: info->cache, object: info->object); |
334 | } |
335 | |
336 | static void describe_object(const void *addr, struct kasan_report_info *info) |
337 | { |
338 | if (kasan_stack_collection_enabled()) |
339 | describe_object_stacks(info); |
340 | describe_object_addr(addr, info); |
341 | } |
342 | |
343 | static inline bool kernel_or_module_addr(const void *addr) |
344 | { |
345 | if (is_kernel(addr: (unsigned long)addr)) |
346 | return true; |
347 | if (is_module_address(addr: (unsigned long)addr)) |
348 | return true; |
349 | return false; |
350 | } |
351 | |
352 | static inline bool init_task_stack_addr(const void *addr) |
353 | { |
354 | return addr >= (void *)&init_thread_union.stack && |
355 | (addr <= (void *)&init_thread_union.stack + |
356 | sizeof(init_thread_union.stack)); |
357 | } |
358 | |
359 | static void print_address_description(void *addr, u8 tag, |
360 | struct kasan_report_info *info) |
361 | { |
362 | struct page *page = addr_to_page(addr); |
363 | |
364 | dump_stack_lvl(KERN_ERR); |
365 | pr_err("\n" ); |
366 | |
367 | if (info->cache && info->object) { |
368 | describe_object(addr, info); |
369 | pr_err("\n" ); |
370 | } |
371 | |
372 | if (kernel_or_module_addr(addr) && !init_task_stack_addr(addr)) { |
373 | pr_err("The buggy address belongs to the variable:\n" ); |
374 | pr_err(" %pS\n" , addr); |
375 | pr_err("\n" ); |
376 | } |
377 | |
378 | if (object_is_on_stack(obj: addr)) { |
379 | /* |
380 | * Currently, KASAN supports printing frame information only |
381 | * for accesses to the task's own stack. |
382 | */ |
383 | kasan_print_address_stack_frame(addr); |
384 | pr_err("\n" ); |
385 | } |
386 | |
387 | if (is_vmalloc_addr(x: addr)) { |
388 | struct vm_struct *va = find_vm_area(addr); |
389 | |
390 | if (va) { |
391 | pr_err("The buggy address belongs to the virtual mapping at\n" |
392 | " [%px, %px) created by:\n" |
393 | " %pS\n" , |
394 | va->addr, va->addr + va->size, va->caller); |
395 | pr_err("\n" ); |
396 | |
397 | page = vmalloc_to_page(addr); |
398 | } |
399 | } |
400 | |
401 | if (page) { |
402 | pr_err("The buggy address belongs to the physical page:\n" ); |
403 | dump_page(page, reason: "kasan: bad access detected" ); |
404 | pr_err("\n" ); |
405 | } |
406 | } |
407 | |
408 | static bool meta_row_is_guilty(const void *row, const void *addr) |
409 | { |
410 | return (row <= addr) && (addr < row + META_MEM_BYTES_PER_ROW); |
411 | } |
412 | |
413 | static int meta_pointer_offset(const void *row, const void *addr) |
414 | { |
415 | /* |
416 | * Memory state around the buggy address: |
417 | * ff00ff00ff00ff00: 00 00 00 05 fe fe fe fe fe fe fe fe fe fe fe fe |
418 | * ... |
419 | * |
420 | * The length of ">ff00ff00ff00ff00: " is |
421 | * 3 + (BITS_PER_LONG / 8) * 2 chars. |
422 | * The length of each granule metadata is 2 bytes |
423 | * plus 1 byte for space. |
424 | */ |
425 | return 3 + (BITS_PER_LONG / 8) * 2 + |
426 | (addr - row) / KASAN_GRANULE_SIZE * 3 + 1; |
427 | } |
428 | |
429 | static void print_memory_metadata(const void *addr) |
430 | { |
431 | int i; |
432 | void *row; |
433 | |
434 | row = (void *)round_down((unsigned long)addr, META_MEM_BYTES_PER_ROW) |
435 | - META_ROWS_AROUND_ADDR * META_MEM_BYTES_PER_ROW; |
436 | |
437 | pr_err("Memory state around the buggy address:\n" ); |
438 | |
439 | for (i = -META_ROWS_AROUND_ADDR; i <= META_ROWS_AROUND_ADDR; i++) { |
440 | char buffer[4 + (BITS_PER_LONG / 8) * 2]; |
441 | char metadata[META_BYTES_PER_ROW]; |
442 | |
443 | snprintf(buf: buffer, size: sizeof(buffer), |
444 | fmt: (i == 0) ? ">%px: " : " %px: " , row); |
445 | |
446 | /* |
447 | * We should not pass a shadow pointer to generic |
448 | * function, because generic functions may try to |
449 | * access kasan mapping for the passed address. |
450 | */ |
451 | kasan_metadata_fetch_row(buffer: &metadata[0], row); |
452 | |
453 | print_hex_dump(KERN_ERR, prefix_str: buffer, |
454 | prefix_type: DUMP_PREFIX_NONE, META_BYTES_PER_ROW, groupsize: 1, |
455 | buf: metadata, META_BYTES_PER_ROW, ascii: 0); |
456 | |
457 | if (meta_row_is_guilty(row, addr)) |
458 | pr_err("%*c\n" , meta_pointer_offset(row, addr), '^'); |
459 | |
460 | row += META_MEM_BYTES_PER_ROW; |
461 | } |
462 | } |
463 | |
464 | static void print_report(struct kasan_report_info *info) |
465 | { |
466 | void *addr = kasan_reset_tag(addr: (void *)info->access_addr); |
467 | u8 tag = get_tag((void *)info->access_addr); |
468 | |
469 | print_error_description(info); |
470 | if (addr_has_metadata(addr)) |
471 | kasan_print_tags(addr_tag: tag, addr: info->first_bad_addr); |
472 | pr_err("\n" ); |
473 | |
474 | if (addr_has_metadata(addr)) { |
475 | print_address_description(addr, tag, info); |
476 | print_memory_metadata(addr: info->first_bad_addr); |
477 | } else { |
478 | dump_stack_lvl(KERN_ERR); |
479 | } |
480 | } |
481 | |
482 | static void complete_report_info(struct kasan_report_info *info) |
483 | { |
484 | void *addr = kasan_reset_tag(addr: (void *)info->access_addr); |
485 | struct slab *slab; |
486 | |
487 | if (info->type == KASAN_REPORT_ACCESS) |
488 | info->first_bad_addr = kasan_find_first_bad_addr( |
489 | addr: (void *)info->access_addr, size: info->access_size); |
490 | else |
491 | info->first_bad_addr = addr; |
492 | |
493 | slab = kasan_addr_to_slab(addr); |
494 | if (slab) { |
495 | info->cache = slab->slab_cache; |
496 | info->object = nearest_obj(cache: info->cache, slab, x: addr); |
497 | |
498 | /* Try to determine allocation size based on the metadata. */ |
499 | info->alloc_size = kasan_get_alloc_size(object: info->object, cache: info->cache); |
500 | /* Fallback to the object size if failed. */ |
501 | if (!info->alloc_size) |
502 | info->alloc_size = info->cache->object_size; |
503 | } else |
504 | info->cache = info->object = NULL; |
505 | |
506 | switch (info->type) { |
507 | case KASAN_REPORT_INVALID_FREE: |
508 | info->bug_type = "invalid-free" ; |
509 | break; |
510 | case KASAN_REPORT_DOUBLE_FREE: |
511 | info->bug_type = "double-free" ; |
512 | break; |
513 | default: |
514 | /* bug_type filled in by kasan_complete_mode_report_info. */ |
515 | break; |
516 | } |
517 | |
518 | /* Fill in mode-specific report info fields. */ |
519 | kasan_complete_mode_report_info(info); |
520 | } |
521 | |
522 | void kasan_report_invalid_free(void *ptr, unsigned long ip, enum kasan_report_type type) |
523 | { |
524 | unsigned long flags; |
525 | struct kasan_report_info info; |
526 | |
527 | /* |
528 | * Do not check report_suppressed_sw(), as an invalid-free cannot be |
529 | * caused by accessing poisoned memory and thus should not be suppressed |
530 | * by kasan_disable/enable_current() critical sections. |
531 | * |
532 | * Note that for Hardware Tag-Based KASAN, kasan_report_invalid_free() |
533 | * is triggered by explicit tag checks and not by the ones performed by |
534 | * the CPU. Thus, reporting invalid-free is not suppressed as well. |
535 | */ |
536 | if (unlikely(!report_enabled())) |
537 | return; |
538 | |
539 | start_report(flags: &flags, sync: true); |
540 | |
541 | __memset(s: &info, c: 0, n: sizeof(info)); |
542 | info.type = type; |
543 | info.access_addr = ptr; |
544 | info.access_size = 0; |
545 | info.is_write = false; |
546 | info.ip = ip; |
547 | |
548 | complete_report_info(info: &info); |
549 | |
550 | print_report(info: &info); |
551 | |
552 | /* |
553 | * Invalid free is considered a "write" since the allocator's metadata |
554 | * updates involves writes. |
555 | */ |
556 | end_report(flags: &flags, addr: ptr, is_write: true); |
557 | } |
558 | |
559 | /* |
560 | * kasan_report() is the only reporting function that uses |
561 | * user_access_save/restore(): kasan_report_invalid_free() cannot be called |
562 | * from a UACCESS region, and kasan_report_async() is not used on x86. |
563 | */ |
564 | bool kasan_report(const void *addr, size_t size, bool is_write, |
565 | unsigned long ip) |
566 | { |
567 | bool ret = true; |
568 | unsigned long ua_flags = user_access_save(); |
569 | unsigned long irq_flags; |
570 | struct kasan_report_info info; |
571 | |
572 | if (unlikely(report_suppressed_sw()) || unlikely(!report_enabled())) { |
573 | ret = false; |
574 | goto out; |
575 | } |
576 | |
577 | start_report(flags: &irq_flags, sync: true); |
578 | |
579 | __memset(s: &info, c: 0, n: sizeof(info)); |
580 | info.type = KASAN_REPORT_ACCESS; |
581 | info.access_addr = addr; |
582 | info.access_size = size; |
583 | info.is_write = is_write; |
584 | info.ip = ip; |
585 | |
586 | complete_report_info(info: &info); |
587 | |
588 | print_report(info: &info); |
589 | |
590 | end_report(flags: &irq_flags, addr: (void *)addr, is_write); |
591 | |
592 | out: |
593 | user_access_restore(ua_flags); |
594 | |
595 | return ret; |
596 | } |
597 | |
598 | #ifdef CONFIG_KASAN_HW_TAGS |
599 | void kasan_report_async(void) |
600 | { |
601 | unsigned long flags; |
602 | |
603 | /* |
604 | * Do not check report_suppressed_sw(), as |
605 | * kasan_disable/enable_current() critical sections do not affect |
606 | * Hardware Tag-Based KASAN. |
607 | */ |
608 | if (unlikely(!report_enabled())) |
609 | return; |
610 | |
611 | start_report(&flags, false); |
612 | pr_err("BUG: KASAN: invalid-access\n" ); |
613 | pr_err("Asynchronous fault: no details available\n" ); |
614 | pr_err("\n" ); |
615 | dump_stack_lvl(KERN_ERR); |
616 | /* |
617 | * Conservatively set is_write=true, because no details are available. |
618 | * In this mode, kasan.fault=panic_on_write is like kasan.fault=panic. |
619 | */ |
620 | end_report(&flags, NULL, true); |
621 | } |
622 | #endif /* CONFIG_KASAN_HW_TAGS */ |
623 | |
624 | #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) |
625 | /* |
626 | * With CONFIG_KASAN_INLINE, accesses to bogus pointers (outside the high |
627 | * canonical half of the address space) cause out-of-bounds shadow memory reads |
628 | * before the actual access. For addresses in the low canonical half of the |
629 | * address space, as well as most non-canonical addresses, that out-of-bounds |
630 | * shadow memory access lands in the non-canonical part of the address space. |
631 | * Help the user figure out what the original bogus pointer was. |
632 | */ |
633 | void kasan_non_canonical_hook(unsigned long addr) |
634 | { |
635 | unsigned long orig_addr; |
636 | const char *bug_type; |
637 | |
638 | if (addr < KASAN_SHADOW_OFFSET) |
639 | return; |
640 | |
641 | orig_addr = (addr - KASAN_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT; |
642 | /* |
643 | * For faults near the shadow address for NULL, we can be fairly certain |
644 | * that this is a KASAN shadow memory access. |
645 | * For faults that correspond to shadow for low canonical addresses, we |
646 | * can still be pretty sure - that shadow region is a fairly narrow |
647 | * chunk of the non-canonical address space. |
648 | * But faults that look like shadow for non-canonical addresses are a |
649 | * really large chunk of the address space. In that case, we still |
650 | * print the decoded address, but make it clear that this is not |
651 | * necessarily what's actually going on. |
652 | */ |
653 | if (orig_addr < PAGE_SIZE) |
654 | bug_type = "null-ptr-deref" ; |
655 | else if (orig_addr < TASK_SIZE) |
656 | bug_type = "probably user-memory-access" ; |
657 | else |
658 | bug_type = "maybe wild-memory-access" ; |
659 | pr_alert("KASAN: %s in range [0x%016lx-0x%016lx]\n" , bug_type, |
660 | orig_addr, orig_addr + KASAN_GRANULE_SIZE - 1); |
661 | } |
662 | #endif |
663 | |