// SPDX-License-Identifier: GPL-2.0
/*
 * KMSAN error reporting routines.
 *
 * Copyright (C) 2019-2022 Google LLC
 * Author: Alexander Potapenko <glider@google.com>
 *
 */

#include <linux/console.h>
#include <linux/kmsan.h>
#include <linux/moduleparam.h>
#include <linux/stackdepot.h>
#include <linux/stacktrace.h>
#include <linux/uaccess.h>

#include "kmsan.h"

static DEFINE_RAW_SPINLOCK(kmsan_report_lock);
#define DESCR_SIZE 128
/* Protected by kmsan_report_lock */
static char report_local_descr[DESCR_SIZE];
int panic_on_kmsan __read_mostly;
EXPORT_SYMBOL_GPL(panic_on_kmsan);

#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
#define MODULE_PARAM_PREFIX "kmsan."
module_param_named(panic, panic_on_kmsan, int, 0);

/*
 * Skip internal KMSAN frames.
 */
static int get_stack_skipnr(const unsigned long stack_entries[],
			    int num_entries)
{
	int len, skip;
	char buf[64];

	for (skip = 0; skip < num_entries; ++skip) {
		len = scnprintf(buf, sizeof(buf), "%ps",
				(void *)stack_entries[skip]);

		/* Never show __msan_* or kmsan_* functions. */
		if ((strnstr(buf, "__msan_", len) == buf) ||
		    (strnstr(buf, "kmsan_", len) == buf))
			continue;

		/*
		 * No match for runtime functions -- @skip entries to skip to
		 * get to first frame of interest.
		 */
		break;
	}

	return skip;
}

/*
 * Currently the descriptions of locals generated by Clang look as follows:
 *   ----local_name@function_name
 * We want to print only the name of the local, as other information in that
 * description can be confusing.
 * The meaningful part of the description is copied to a global buffer to avoid
 * allocating memory.
 */
static char *pretty_descr(char *descr)
{
	int pos = 0, len = strlen(descr);

	for (int i = 0; i < len; i++) {
		if (descr[i] == '@')
			break;
		if (descr[i] == '-')
			continue;
		report_local_descr[pos] = descr[i];
		if (pos + 1 == DESCR_SIZE)
			break;
		pos++;
	}
	report_local_descr[pos] = 0;
	return report_local_descr;
}

void kmsan_print_origin(depot_stack_handle_t origin)
{
	unsigned long *entries = NULL, *chained_entries = NULL;
	unsigned int nr_entries, chained_nr_entries, skipnr;
	void *pc1 = NULL, *pc2 = NULL;
	depot_stack_handle_t head;
	unsigned long magic;
	char *descr = NULL;
	unsigned int depth;

	if (!origin)
		return;

	while (true) {
		nr_entries = stack_depot_fetch(origin, &entries);
		depth = kmsan_depth_from_eb(stack_depot_get_extra_bits(origin));
		magic = nr_entries ? entries[0] : 0;
		if ((nr_entries == 4) && (magic == KMSAN_ALLOCA_MAGIC_ORIGIN)) {
			descr = (char *)entries[1];
			pc1 = (void *)entries[2];
			pc2 = (void *)entries[3];
			pr_err("Local variable %s created at:\n",
			       pretty_descr(descr));
			if (pc1)
				pr_err(" %pSb\n", pc1);
			if (pc2)
				pr_err(" %pSb\n", pc2);
			break;
		}
		if ((nr_entries == 3) && (magic == KMSAN_CHAIN_MAGIC_ORIGIN)) {
			/*
			 * Origin chains deeper than KMSAN_MAX_ORIGIN_DEPTH are
			 * not stored, so the output may be incomplete.
			 */
			if (depth == KMSAN_MAX_ORIGIN_DEPTH)
				pr_err("<Zero or more stacks not recorded to save memory>\n\n");
			head = entries[1];
			origin = entries[2];
			pr_err("Uninit was stored to memory at:\n");
			chained_nr_entries =
				stack_depot_fetch(head, &chained_entries);
			kmsan_internal_unpoison_memory(
				chained_entries,
				chained_nr_entries * sizeof(*chained_entries),
				/*checked*/ false);
			skipnr = get_stack_skipnr(chained_entries,
						  chained_nr_entries);
			stack_trace_print(chained_entries + skipnr,
					  chained_nr_entries - skipnr, 0);
			pr_err("\n");
			continue;
		}
		pr_err("Uninit was created at:\n");
		if (nr_entries) {
			skipnr = get_stack_skipnr(entries, nr_entries);
			stack_trace_print(entries + skipnr, nr_entries - skipnr,
					  0);
		} else {
			pr_err("(stack is not available)\n");
		}
		break;
	}
}

void kmsan_report(depot_stack_handle_t origin, void *address, int size,
		  int off_first, int off_last, const void __user *user_addr,
		  enum kmsan_bug_reason reason)
{
	unsigned long stack_entries[KMSAN_STACK_DEPTH];
	int num_stack_entries, skipnr;
	char *bug_type = NULL;
	unsigned long ua_flags;
	bool is_uaf;

	if (!kmsan_enabled)
		return;
	if (current->kmsan_ctx.depth)
		return;
	if (!origin)
		return;

	kmsan_disable_current();
	ua_flags = user_access_save();
	raw_spin_lock(&kmsan_report_lock);
	pr_err("=====================================================\n");
	is_uaf = kmsan_uaf_from_eb(stack_depot_get_extra_bits(origin));
	switch (reason) {
	case REASON_ANY:
		bug_type = is_uaf ? "use-after-free" : "uninit-value";
		break;
	case REASON_COPY_TO_USER:
		bug_type = is_uaf ? "kernel-infoleak-after-free" :
				    "kernel-infoleak";
		break;
	case REASON_SUBMIT_URB:
		bug_type = is_uaf ? "kernel-usb-infoleak-after-free" :
				    "kernel-usb-infoleak";
		break;
	}

	num_stack_entries =
		stack_trace_save(stack_entries, KMSAN_STACK_DEPTH, 1);
	skipnr = get_stack_skipnr(stack_entries, num_stack_entries);

	pr_err("BUG: KMSAN: %s in %pSb\n", bug_type,
	       (void *)stack_entries[skipnr]);
	stack_trace_print(stack_entries + skipnr, num_stack_entries - skipnr,
			  0);
	pr_err("\n");

	kmsan_print_origin(origin);

	if (size) {
		pr_err("\n");
		if (off_first == off_last)
			pr_err("Byte %d of %d is uninitialized\n", off_first,
			       size);
		else
			pr_err("Bytes %d-%d of %d are uninitialized\n",
			       off_first, off_last, size);
	}
	if (address)
		pr_err("Memory access of size %d starts at %px\n", size,
		       address);
	if (user_addr && reason == REASON_COPY_TO_USER)
		pr_err("Data copied to user address %px\n", user_addr);
	pr_err("\n");
	dump_stack_print_info(KERN_ERR);
	pr_err("=====================================================\n");
	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
	raw_spin_unlock(&kmsan_report_lock);
	if (panic_on_kmsan)
		panic("kmsan.panic set ...\n");
	user_access_restore(ua_flags);
	kmsan_enable_current();
}
