report.c 13.3 KB
Newer Older
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 <linux/bitops.h>
13
#include <linux/ftrace.h>
14
#include <linux/init.h>
15 16 17 18 19
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/printk.h>
#include <linux/sched.h>
#include <linux/slab.h>
20
#include <linux/stackdepot.h>
21 22 23 24
#include <linux/stacktrace.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/kasan.h>
25
#include <linux/module.h>
26
#include <linux/sched/task_stack.h>
27
#include <linux/uaccess.h>
28
#include <trace/events/error_report.h>
29

30 31
#include <asm/sections.h>

P
Patricia Alfonso 已提交
32 33
#include <kunit/test.h>

34
#include "kasan.h"
35
#include "../slab.h"
36

37
static unsigned long kasan_flags;
38

39 40
#define KASAN_BIT_REPORTED	0
#define KASAN_BIT_MULTI_SHOT	1
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
enum kasan_arg_fault {
	KASAN_ARG_FAULT_DEFAULT,
	KASAN_ARG_FAULT_REPORT,
	KASAN_ARG_FAULT_PANIC,
};

static enum kasan_arg_fault kasan_arg_fault __ro_after_init = KASAN_ARG_FAULT_DEFAULT;

/* kasan.fault=report/panic */
static int __init early_kasan_fault(char *arg)
{
	if (!arg)
		return -EINVAL;

	if (!strcmp(arg, "report"))
		kasan_arg_fault = KASAN_ARG_FAULT_REPORT;
	else if (!strcmp(arg, "panic"))
		kasan_arg_fault = KASAN_ARG_FAULT_PANIC;
	else
		return -EINVAL;

	return 0;
}
early_param("kasan.fault", early_kasan_fault);

67
bool kasan_save_enable_multi_shot(void)
68
{
69
	return test_and_set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
70
}
71
EXPORT_SYMBOL_GPL(kasan_save_enable_multi_shot);
72

73
void kasan_restore_multi_shot(bool enabled)
74
{
75 76
	if (!enabled)
		clear_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
77
}
78
EXPORT_SYMBOL_GPL(kasan_restore_multi_shot);
79

80
static int __init kasan_set_multi_shot(char *str)
A
Andrey Konovalov 已提交
81
{
82 83
	set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
	return 1;
A
Andrey Konovalov 已提交
84
}
85
__setup("kasan_multi_shot", kasan_set_multi_shot);
A
Andrey Konovalov 已提交
86

87
static void print_error_description(struct kasan_access_info *info)
88
{
A
Andrey Konovalov 已提交
89
	pr_err("BUG: KASAN: %s in %pS\n",
90
		kasan_get_bug_type(info), (void *)info->ip);
91 92 93 94 95 96 97 98
	if (info->access_size)
		pr_err("%s of size %zu at addr %px by task %s/%d\n",
			info->is_write ? "Write" : "Read", info->access_size,
			info->access_addr, current->comm, task_pid_nr(current));
	else
		pr_err("%s at addr %px by task %s/%d\n",
			info->is_write ? "Write" : "Read",
			info->access_addr, current->comm, task_pid_nr(current));
99 100
}

101 102
static DEFINE_SPINLOCK(report_lock);

103
static void start_report(unsigned long *flags)
104 105 106 107 108 109 110 111 112
{
	/*
	 * Make sure we don't end up in loop.
	 */
	kasan_disable_current();
	spin_lock_irqsave(&report_lock, *flags);
	pr_err("==================================================================\n");
}

113
static void end_report(unsigned long *flags, unsigned long addr)
114
{
115
	if (!kasan_async_fault_possible())
116
		trace_error_report_end(ERROR_DETECTOR_KASAN, addr);
117 118 119
	pr_err("==================================================================\n");
	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
	spin_unlock_irqrestore(&report_lock, *flags);
120
	if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) {
121 122 123 124 125 126 127
		/*
		 * This thread may hit another WARN() in the panic path.
		 * Resetting this prevents additional WARN() from panicking the
		 * system on this thread.  Other threads are blocked by the
		 * panic_mutex in panic().
		 */
		panic_on_warn = 0;
D
Dmitry Vyukov 已提交
128
		panic("panic_on_warn set ...\n");
129
	}
130
	if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC)
131
		panic("kasan.fault=panic set ...\n");
132 133 134
	kasan_enable_current();
}

135
static void print_track(struct kasan_track *track, const char *prefix)
A
Alexander Potapenko 已提交
136
{
137
	pr_err("%s by task %u:\n", prefix, track->pid);
138
	if (track->stack) {
139
		stack_depot_print(track->stack);
140 141 142
	} else {
		pr_err("(stack is not available)\n");
	}
A
Alexander Potapenko 已提交
143 144
}

145
struct page *kasan_addr_to_page(const void *addr)
146 147 148 149 150 151 152
{
	if ((addr >= (void *)PAGE_OFFSET) &&
			(addr < high_memory))
		return virt_to_head_page(addr);
	return NULL;
}

153 154 155 156 157 158 159 160
struct slab *kasan_addr_to_slab(const void *addr)
{
	if ((addr >= (void *)PAGE_OFFSET) &&
			(addr < high_memory))
		return virt_to_slab(addr);
	return NULL;
}

161 162
static void describe_object_addr(struct kmem_cache *cache, void *object,
				const void *addr)
A
Alexander Potapenko 已提交
163
{
164 165 166 167
	unsigned long access_addr = (unsigned long)addr;
	unsigned long object_addr = (unsigned long)object;
	const char *rel_type;
	int rel_bytes;
A
Alexander Potapenko 已提交
168

169
	pr_err("The buggy address belongs to the object at %px\n"
170 171
	       " which belongs to the cache %s of size %d\n",
		object, cache->name, cache->object_size);
172

173
	if (!addr)
A
Alexander Potapenko 已提交
174
		return;
175

176 177 178 179 180 181 182 183 184 185 186 187
	if (access_addr < object_addr) {
		rel_type = "to the left";
		rel_bytes = object_addr - access_addr;
	} else if (access_addr >= object_addr + cache->object_size) {
		rel_type = "to the right";
		rel_bytes = access_addr - (object_addr + cache->object_size);
	} else {
		rel_type = "inside";
		rel_bytes = access_addr - object_addr;
	}

	pr_err("The buggy address is located %d bytes %s of\n"
188
	       " %d-byte region [%px, %px)\n",
189 190 191 192
		rel_bytes, rel_type, cache->object_size, (void *)object_addr,
		(void *)(object_addr + cache->object_size));
}

193 194
static void describe_object_stacks(struct kmem_cache *cache, void *object,
					const void *addr, u8 tag)
195
{
196 197
	struct kasan_alloc_meta *alloc_meta;
	struct kasan_track *free_track;
198

199 200
	alloc_meta = kasan_get_alloc_meta(cache, object);
	if (alloc_meta) {
201
		print_track(&alloc_meta->alloc_track, "Allocated");
202
		pr_err("\n");
203 204 205 206 207 208 209
	}

	free_track = kasan_get_free_track(cache, object, tag);
	if (free_track) {
		print_track(free_track, "Freed");
		pr_err("\n");
	}
210 211

#ifdef CONFIG_KASAN_GENERIC
212 213 214 215
	if (!alloc_meta)
		return;
	if (alloc_meta->aux_stack[0]) {
		pr_err("Last potentially related work creation:\n");
216
		stack_depot_print(alloc_meta->aux_stack[0]);
217
		pr_err("\n");
218
	}
219 220
	if (alloc_meta->aux_stack[1]) {
		pr_err("Second to last potentially related work creation:\n");
221
		stack_depot_print(alloc_meta->aux_stack[1]);
222 223 224
		pr_err("\n");
	}
#endif
225
}
226

227 228 229 230 231
static void describe_object(struct kmem_cache *cache, void *object,
				const void *addr, u8 tag)
{
	if (kasan_stack_collection_enabled())
		describe_object_stacks(cache, object, addr, tag);
232
	describe_object_addr(cache, object, addr);
A
Alexander Potapenko 已提交
233 234
}

235 236
static inline bool kernel_or_module_addr(const void *addr)
{
K
Kefeng Wang 已提交
237
	if (is_kernel((unsigned long)addr))
238 239 240 241 242 243 244 245 246 247 248 249 250
		return true;
	if (is_module_address((unsigned long)addr))
		return true;
	return false;
}

static inline bool init_task_stack_addr(const void *addr)
{
	return addr >= (void *)&init_thread_union.stack &&
		(addr <= (void *)&init_thread_union.stack +
			sizeof(init_thread_union.stack));
}

251
static void print_address_description(void *addr, u8 tag)
252
{
253
	struct page *page = kasan_addr_to_page(addr);
254

255
	dump_stack_lvl(KERN_ERR);
256
	pr_err("\n");
257 258

	if (page && PageSlab(page)) {
259 260 261
		struct slab *slab = page_slab(page);
		struct kmem_cache *cache = slab->slab_cache;
		void *object = nearest_obj(cache, slab,	addr);
262

263
		describe_object(cache, object, addr, tag);
264 265
	}

266 267 268 269 270 271 272 273
	if (kernel_or_module_addr(addr) && !init_task_stack_addr(addr)) {
		pr_err("The buggy address belongs to the variable:\n");
		pr_err(" %pS\n", addr);
	}

	if (page) {
		pr_err("The buggy address belongs to the page:\n");
		dump_page(page, "kasan: bad access detected");
274
	}
275

276
	kasan_print_address_stack_frame(addr);
277 278
}

279
static bool meta_row_is_guilty(const void *row, const void *addr)
280
{
281
	return (row <= addr) && (addr < row + META_MEM_BYTES_PER_ROW);
282 283
}

284
static int meta_pointer_offset(const void *row, const void *addr)
285
{
286 287 288 289 290 291 292 293 294
	/*
	 * Memory state around the buggy address:
	 *  ff00ff00ff00ff00: 00 00 00 05 fe fe fe fe fe fe fe fe fe fe fe fe
	 *  ...
	 *
	 * The length of ">ff00ff00ff00ff00: " is
	 *    3 + (BITS_PER_LONG / 8) * 2 chars.
	 * The length of each granule metadata is 2 bytes
	 *    plus 1 byte for space.
295
	 */
296 297
	return 3 + (BITS_PER_LONG / 8) * 2 +
		(addr - row) / KASAN_GRANULE_SIZE * 3 + 1;
298 299
}

300
static void print_memory_metadata(const void *addr)
301 302
{
	int i;
303
	void *row;
304

305 306
	row = (void *)round_down((unsigned long)addr, META_MEM_BYTES_PER_ROW)
			- META_ROWS_AROUND_ADDR * META_MEM_BYTES_PER_ROW;
307 308 309

	pr_err("Memory state around the buggy address:\n");

310
	for (i = -META_ROWS_AROUND_ADDR; i <= META_ROWS_AROUND_ADDR; i++) {
311 312
		char buffer[4 + (BITS_PER_LONG / 8) * 2];
		char metadata[META_BYTES_PER_ROW];
313 314

		snprintf(buffer, sizeof(buffer),
315 316
				(i == 0) ? ">%px: " : " %px: ", row);

317 318 319 320 321
		/*
		 * We should not pass a shadow pointer to generic
		 * function, because generic functions may try to
		 * access kasan mapping for the passed address.
		 */
322
		kasan_metadata_fetch_row(&metadata[0], row);
323

324
		print_hex_dump(KERN_ERR, buffer,
325
			DUMP_PREFIX_NONE, META_BYTES_PER_ROW, 1,
326
			metadata, META_BYTES_PER_ROW, 0);
327

328 329
		if (meta_row_is_guilty(row, addr))
			pr_err("%*c\n", meta_pointer_offset(row, addr), '^');
330

331
		row += META_MEM_BYTES_PER_ROW;
332 333 334
	}
}

335
static bool report_enabled(void)
336
{
337
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
338 339
	if (current->kasan_depth)
		return false;
340
#endif
341 342 343 344 345
	if (test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
		return true;
	return !test_and_set_bit(KASAN_BIT_REPORTED, &kasan_flags);
}

P
Patricia Alfonso 已提交
346 347 348 349 350 351 352 353 354 355 356 357 358 359
#if IS_ENABLED(CONFIG_KUNIT)
static void kasan_update_kunit_status(struct kunit *cur_test)
{
	struct kunit_resource *resource;
	struct kunit_kasan_expectation *kasan_data;

	resource = kunit_find_named_resource(cur_test, "kasan_data");

	if (!resource) {
		kunit_set_failure(cur_test);
		return;
	}

	kasan_data = (struct kunit_kasan_expectation *)resource->data;
360
	WRITE_ONCE(kasan_data->report_found, true);
P
Patricia Alfonso 已提交
361 362 363 364
	kunit_put_resource(resource);
}
#endif /* IS_ENABLED(CONFIG_KUNIT) */

365
void kasan_report_invalid_free(void *object, unsigned long ip)
366 367
{
	unsigned long flags;
368
	u8 tag = get_tag(object);
369

370
	object = kasan_reset_tag(object);
P
Patricia Alfonso 已提交
371 372 373 374 375 376

#if IS_ENABLED(CONFIG_KUNIT)
	if (current->kunit_test)
		kasan_update_kunit_status(current->kunit_test);
#endif /* IS_ENABLED(CONFIG_KUNIT) */

377
	start_report(&flags);
378
	pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", (void *)ip);
379
	kasan_print_tags(tag, object);
380
	pr_err("\n");
381
	print_address_description(object, tag);
382
	pr_err("\n");
383
	print_memory_metadata(object);
384
	end_report(&flags, (unsigned long)object);
385 386
}

387 388 389 390 391
#ifdef CONFIG_KASAN_HW_TAGS
void kasan_report_async(void)
{
	unsigned long flags;

392 393 394 395 396
#if IS_ENABLED(CONFIG_KUNIT)
	if (current->kunit_test)
		kasan_update_kunit_status(current->kunit_test);
#endif /* IS_ENABLED(CONFIG_KUNIT) */

397 398 399 400
	start_report(&flags);
	pr_err("BUG: KASAN: invalid-access\n");
	pr_err("Asynchronous mode enabled: no access details available\n");
	pr_err("\n");
401
	dump_stack_lvl(KERN_ERR);
402 403 404 405
	end_report(&flags, 0);
}
#endif /* CONFIG_KASAN_HW_TAGS */

406 407
static void __kasan_report(unsigned long addr, size_t size, bool is_write,
				unsigned long ip)
408 409
{
	struct kasan_access_info info;
410 411 412
	void *tagged_addr;
	void *untagged_addr;
	unsigned long flags;
413

P
Patricia Alfonso 已提交
414 415 416 417 418
#if IS_ENABLED(CONFIG_KUNIT)
	if (current->kunit_test)
		kasan_update_kunit_status(current->kunit_test);
#endif /* IS_ENABLED(CONFIG_KUNIT) */

419 420
	disable_trace_on_warning();

421
	tagged_addr = (void *)addr;
422
	untagged_addr = kasan_reset_tag(tagged_addr);
423 424

	info.access_addr = tagged_addr;
425
	if (addr_has_metadata(untagged_addr))
426 427
		info.first_bad_addr =
			kasan_find_first_bad_addr(tagged_addr, size);
428 429
	else
		info.first_bad_addr = untagged_addr;
430 431 432
	info.access_size = size;
	info.is_write = is_write;
	info.ip = ip;
433

434 435 436
	start_report(&flags);

	print_error_description(&info);
437
	if (addr_has_metadata(untagged_addr))
438
		kasan_print_tags(get_tag(tagged_addr), info.first_bad_addr);
439 440
	pr_err("\n");

441
	if (addr_has_metadata(untagged_addr)) {
442
		print_address_description(untagged_addr, get_tag(tagged_addr));
443
		pr_err("\n");
444
		print_memory_metadata(info.first_bad_addr);
445
	} else {
446
		dump_stack_lvl(KERN_ERR);
447 448
	}

449
	end_report(&flags, addr);
450
}
451

452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
bool kasan_report(unsigned long addr, size_t size, bool is_write,
			unsigned long ip)
{
	unsigned long flags = user_access_save();
	bool ret = false;

	if (likely(report_enabled())) {
		__kasan_report(addr, size, is_write, ip);
		ret = true;
	}

	user_access_restore(flags);

	return ret;
}

468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
#ifdef CONFIG_KASAN_INLINE
/*
 * With CONFIG_KASAN_INLINE, accesses to bogus pointers (outside the high
 * canonical half of the address space) cause out-of-bounds shadow memory reads
 * before the actual access. For addresses in the low canonical half of the
 * address space, as well as most non-canonical addresses, that out-of-bounds
 * shadow memory access lands in the non-canonical part of the address space.
 * Help the user figure out what the original bogus pointer was.
 */
void kasan_non_canonical_hook(unsigned long addr)
{
	unsigned long orig_addr;
	const char *bug_type;

	if (addr < KASAN_SHADOW_OFFSET)
		return;

	orig_addr = (addr - KASAN_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT;
	/*
	 * For faults near the shadow address for NULL, we can be fairly certain
	 * that this is a KASAN shadow memory access.
	 * For faults that correspond to shadow for low canonical addresses, we
	 * can still be pretty sure - that shadow region is a fairly narrow
	 * chunk of the non-canonical address space.
	 * But faults that look like shadow for non-canonical addresses are a
	 * really large chunk of the address space. In that case, we still
	 * print the decoded address, but make it clear that this is not
	 * necessarily what's actually going on.
	 */
	if (orig_addr < PAGE_SIZE)
		bug_type = "null-ptr-deref";
	else if (orig_addr < TASK_SIZE)
		bug_type = "probably user-memory-access";
	else
		bug_type = "maybe wild-memory-access";
	pr_alert("KASAN: %s in range [0x%016lx-0x%016lx]\n", bug_type,
504
		 orig_addr, orig_addr + KASAN_GRANULE_SIZE - 1);
505 506
}
#endif