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