// 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/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;

#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_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.allow_reporting)
		return;
	if (!origin)
		return;

	current->kmsan_ctx.allow_reporting = false;
	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);
	current->kmsan_ctx.allow_reporting = true;
}
