Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Mar 24-27, 2025, special US time zones
Register
Loading...
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * KMSAN error reporting routines.
  4 *
  5 * Copyright (C) 2019-2022 Google LLC
  6 * Author: Alexander Potapenko <glider@google.com>
  7 *
  8 */
  9
 10#include <linux/console.h>
 11#include <linux/moduleparam.h>
 12#include <linux/stackdepot.h>
 13#include <linux/stacktrace.h>
 14#include <linux/uaccess.h>
 15
 16#include "kmsan.h"
 17
 18static DEFINE_RAW_SPINLOCK(kmsan_report_lock);
 19#define DESCR_SIZE 128
 20/* Protected by kmsan_report_lock */
 21static char report_local_descr[DESCR_SIZE];
 22int panic_on_kmsan __read_mostly;
 23
 24#ifdef MODULE_PARAM_PREFIX
 25#undef MODULE_PARAM_PREFIX
 26#endif
 27#define MODULE_PARAM_PREFIX "kmsan."
 28module_param_named(panic, panic_on_kmsan, int, 0);
 29
 30/*
 31 * Skip internal KMSAN frames.
 32 */
 33static int get_stack_skipnr(const unsigned long stack_entries[],
 34			    int num_entries)
 35{
 36	int len, skip;
 37	char buf[64];
 38
 39	for (skip = 0; skip < num_entries; ++skip) {
 40		len = scnprintf(buf, sizeof(buf), "%ps",
 41				(void *)stack_entries[skip]);
 42
 43		/* Never show __msan_* or kmsan_* functions. */
 44		if ((strnstr(buf, "__msan_", len) == buf) ||
 45		    (strnstr(buf, "kmsan_", len) == buf))
 46			continue;
 47
 48		/*
 49		 * No match for runtime functions -- @skip entries to skip to
 50		 * get to first frame of interest.
 51		 */
 52		break;
 53	}
 54
 55	return skip;
 56}
 57
 58/*
 59 * Currently the descriptions of locals generated by Clang look as follows:
 60 *   ----local_name@function_name
 61 * We want to print only the name of the local, as other information in that
 62 * description can be confusing.
 63 * The meaningful part of the description is copied to a global buffer to avoid
 64 * allocating memory.
 65 */
 66static char *pretty_descr(char *descr)
 67{
 68	int pos = 0, len = strlen(descr);
 69
 70	for (int i = 0; i < len; i++) {
 71		if (descr[i] == '@')
 72			break;
 73		if (descr[i] == '-')
 74			continue;
 75		report_local_descr[pos] = descr[i];
 76		if (pos + 1 == DESCR_SIZE)
 77			break;
 78		pos++;
 79	}
 80	report_local_descr[pos] = 0;
 81	return report_local_descr;
 82}
 83
 84void kmsan_print_origin(depot_stack_handle_t origin)
 85{
 86	unsigned long *entries = NULL, *chained_entries = NULL;
 87	unsigned int nr_entries, chained_nr_entries, skipnr;
 88	void *pc1 = NULL, *pc2 = NULL;
 89	depot_stack_handle_t head;
 90	unsigned long magic;
 91	char *descr = NULL;
 92	unsigned int depth;
 93
 94	if (!origin)
 95		return;
 96
 97	while (true) {
 98		nr_entries = stack_depot_fetch(origin, &entries);
 99		depth = kmsan_depth_from_eb(stack_depot_get_extra_bits(origin));
100		magic = nr_entries ? entries[0] : 0;
101		if ((nr_entries == 4) && (magic == KMSAN_ALLOCA_MAGIC_ORIGIN)) {
102			descr = (char *)entries[1];
103			pc1 = (void *)entries[2];
104			pc2 = (void *)entries[3];
105			pr_err("Local variable %s created at:\n",
106			       pretty_descr(descr));
107			if (pc1)
108				pr_err(" %pSb\n", pc1);
109			if (pc2)
110				pr_err(" %pSb\n", pc2);
111			break;
112		}
113		if ((nr_entries == 3) && (magic == KMSAN_CHAIN_MAGIC_ORIGIN)) {
114			/*
115			 * Origin chains deeper than KMSAN_MAX_ORIGIN_DEPTH are
116			 * not stored, so the output may be incomplete.
117			 */
118			if (depth == KMSAN_MAX_ORIGIN_DEPTH)
119				pr_err("<Zero or more stacks not recorded to save memory>\n\n");
120			head = entries[1];
121			origin = entries[2];
122			pr_err("Uninit was stored to memory at:\n");
123			chained_nr_entries =
124				stack_depot_fetch(head, &chained_entries);
125			kmsan_internal_unpoison_memory(
126				chained_entries,
127				chained_nr_entries * sizeof(*chained_entries),
128				/*checked*/ false);
129			skipnr = get_stack_skipnr(chained_entries,
130						  chained_nr_entries);
131			stack_trace_print(chained_entries + skipnr,
132					  chained_nr_entries - skipnr, 0);
133			pr_err("\n");
134			continue;
135		}
136		pr_err("Uninit was created at:\n");
137		if (nr_entries) {
138			skipnr = get_stack_skipnr(entries, nr_entries);
139			stack_trace_print(entries + skipnr, nr_entries - skipnr,
140					  0);
141		} else {
142			pr_err("(stack is not available)\n");
143		}
144		break;
145	}
146}
147
148void kmsan_report(depot_stack_handle_t origin, void *address, int size,
149		  int off_first, int off_last, const void *user_addr,
150		  enum kmsan_bug_reason reason)
151{
152	unsigned long stack_entries[KMSAN_STACK_DEPTH];
153	int num_stack_entries, skipnr;
154	char *bug_type = NULL;
155	unsigned long ua_flags;
156	bool is_uaf;
157
158	if (!kmsan_enabled)
159		return;
160	if (!current->kmsan_ctx.allow_reporting)
161		return;
162	if (!origin)
163		return;
164
165	current->kmsan_ctx.allow_reporting = false;
166	ua_flags = user_access_save();
167	raw_spin_lock(&kmsan_report_lock);
168	pr_err("=====================================================\n");
169	is_uaf = kmsan_uaf_from_eb(stack_depot_get_extra_bits(origin));
170	switch (reason) {
171	case REASON_ANY:
172		bug_type = is_uaf ? "use-after-free" : "uninit-value";
173		break;
174	case REASON_COPY_TO_USER:
175		bug_type = is_uaf ? "kernel-infoleak-after-free" :
176				    "kernel-infoleak";
177		break;
178	case REASON_SUBMIT_URB:
179		bug_type = is_uaf ? "kernel-usb-infoleak-after-free" :
180				    "kernel-usb-infoleak";
181		break;
182	}
183
184	num_stack_entries =
185		stack_trace_save(stack_entries, KMSAN_STACK_DEPTH, 1);
186	skipnr = get_stack_skipnr(stack_entries, num_stack_entries);
187
188	pr_err("BUG: KMSAN: %s in %pSb\n", bug_type,
189	       (void *)stack_entries[skipnr]);
190	stack_trace_print(stack_entries + skipnr, num_stack_entries - skipnr,
191			  0);
192	pr_err("\n");
193
194	kmsan_print_origin(origin);
195
196	if (size) {
197		pr_err("\n");
198		if (off_first == off_last)
199			pr_err("Byte %d of %d is uninitialized\n", off_first,
200			       size);
201		else
202			pr_err("Bytes %d-%d of %d are uninitialized\n",
203			       off_first, off_last, size);
204	}
205	if (address)
206		pr_err("Memory access of size %d starts at %px\n", size,
207		       address);
208	if (user_addr && reason == REASON_COPY_TO_USER)
209		pr_err("Data copied to user address %px\n", user_addr);
210	pr_err("\n");
211	dump_stack_print_info(KERN_ERR);
212	pr_err("=====================================================\n");
213	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
214	raw_spin_unlock(&kmsan_report_lock);
215	if (panic_on_kmsan)
216		panic("kmsan.panic set ...\n");
217	user_access_restore(ua_flags);
218	current->kmsan_ctx.allow_reporting = true;
219}
1