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