mm/kasan/report.c

Source file repositories/reference/linux-study-clean/mm/kasan/report.c

File Facts

System
Linux kernel
Corpus path
mm/kasan/report.c
Extension
.c
Size
18481 bytes
Lines
681
Domain
Core OS
Bucket
Memory Management
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

static inline bool kasan_kunit_test_suite_executing(void) { return false; }

#endif /* CONFIG_KASAN_KUNIT_TEST */

#if IS_ENABLED(CONFIG_KUNIT)

static void fail_non_kasan_kunit_test(void)
{
	struct kunit *test;

	if (kasan_kunit_test_suite_executing())
		return;

	test = current->kunit_test;
	if (test)
		kunit_set_failure(test);
}

#else /* CONFIG_KUNIT */

static inline void fail_non_kasan_kunit_test(void) { }

#endif /* CONFIG_KUNIT */

static DEFINE_RAW_SPINLOCK(report_lock);

static void start_report(unsigned long *flags)
{
	fail_non_kasan_kunit_test();
	/* Respect the /proc/sys/kernel/traceoff_on_warning interface. */
	disable_trace_on_warning();
	/* Do not allow LOCKDEP mangling KASAN reports. */
	lockdep_off();
	/* Make sure we don't end up in loop. */
	report_suppress_start();
	raw_spin_lock_irqsave(&report_lock, *flags);
	pr_err("==================================================================\n");
}

static void end_report(unsigned long *flags, const void *addr, bool is_write)
{
	if (addr)
		trace_error_report_end(ERROR_DETECTOR_KASAN,
				       (unsigned long)addr);
	pr_err("==================================================================\n");
	raw_spin_unlock_irqrestore(&report_lock, *flags);
	if (!test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
		check_panic_on_warn("KASAN");
	switch (kasan_arg_fault) {
	case KASAN_ARG_FAULT_DEFAULT:
	case KASAN_ARG_FAULT_REPORT:
		break;
	case KASAN_ARG_FAULT_PANIC:
		panic("kasan.fault=panic set ...\n");
		break;
	case KASAN_ARG_FAULT_PANIC_ON_WRITE:
		if (is_write)
			panic("kasan.fault=panic_on_write set ...\n");
		break;
	}
	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
	lockdep_on();
	report_suppress_stop();
}

static void print_error_description(struct kasan_report_info *info)
{
	pr_err("BUG: KASAN: %s in %pS\n", info->bug_type, (void *)info->ip);

	if (info->type != KASAN_REPORT_ACCESS) {
		pr_err("Free of addr %px by task %s/%d\n",
			info->access_addr, current->comm, task_pid_nr(current));
		return;
	}

	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));
}

static void print_track(struct kasan_track *track, const char *prefix)
{
#ifdef CONFIG_KASAN_EXTRA_INFO
	u64 ts_nsec = track->timestamp;
	unsigned long rem_usec;

Annotation

Implementation Notes