cpuidle, clk: Remove trace_.*_rcuidle()
[linux-block.git] / lib / ubsan.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
c6d30853
AR
2/*
3 * UBSAN error reporting functions
4 *
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
c6d30853
AR
7 */
8
9#include <linux/bitops.h>
10#include <linux/bug.h>
11#include <linux/ctype.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/sched.h>
d08965a2 16#include <linux/uaccess.h>
1195505f 17#include <kunit/test-bug.h>
c6d30853
AR
18
19#include "ubsan.h"
20
d3c22797 21static const char * const type_check_kinds[] = {
c6d30853
AR
22 "load of",
23 "store to",
24 "reference binding to",
25 "member access within",
26 "member call on",
27 "constructor call on",
28 "downcast of",
29 "downcast of"
30};
31
32#define REPORTED_BIT 31
33
34#if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
35#define COLUMN_MASK (~(1U << REPORTED_BIT))
36#define LINE_MASK (~0U)
37#else
38#define COLUMN_MASK (~0U)
39#define LINE_MASK (~(1U << REPORTED_BIT))
40#endif
41
42#define VALUE_LENGTH 40
43
44static bool was_reported(struct source_location *location)
45{
46 return test_and_set_bit(REPORTED_BIT, &location->reported);
47}
48
c6d30853
AR
49static bool suppress_report(struct source_location *loc)
50{
51 return current->in_ubsan || was_reported(loc);
52}
53
54static bool type_is_int(struct type_descriptor *type)
55{
56 return type->type_kind == type_kind_int;
57}
58
59static bool type_is_signed(struct type_descriptor *type)
60{
61 WARN_ON(!type_is_int(type));
62 return type->type_info & 1;
63}
64
65static unsigned type_bit_width(struct type_descriptor *type)
66{
67 return 1 << (type->type_info >> 1);
68}
69
70static bool is_inline_int(struct type_descriptor *type)
71{
72 unsigned inline_bits = sizeof(unsigned long)*8;
73 unsigned bits = type_bit_width(type);
74
75 WARN_ON(!type_is_int(type));
76
77 return bits <= inline_bits;
78}
79
f0996bc2 80static s_max get_signed_val(struct type_descriptor *type, void *val)
c6d30853
AR
81{
82 if (is_inline_int(type)) {
83 unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
f0996bc2
AR
84 unsigned long ulong_val = (unsigned long)val;
85
86 return ((s_max)ulong_val) << extra_bits >> extra_bits;
c6d30853
AR
87 }
88
89 if (type_bit_width(type) == 64)
90 return *(s64 *)val;
91
92 return *(s_max *)val;
93}
94
f0996bc2 95static bool val_is_negative(struct type_descriptor *type, void *val)
c6d30853
AR
96{
97 return type_is_signed(type) && get_signed_val(type, val) < 0;
98}
99
f0996bc2 100static u_max get_unsigned_val(struct type_descriptor *type, void *val)
c6d30853
AR
101{
102 if (is_inline_int(type))
f0996bc2 103 return (unsigned long)val;
c6d30853
AR
104
105 if (type_bit_width(type) == 64)
106 return *(u64 *)val;
107
108 return *(u_max *)val;
109}
110
111static void val_to_string(char *str, size_t size, struct type_descriptor *type,
f0996bc2 112 void *value)
c6d30853
AR
113{
114 if (type_is_int(type)) {
115 if (type_bit_width(type) == 128) {
c12d3362 116#if defined(CONFIG_ARCH_SUPPORTS_INT128)
c6d30853
AR
117 u_max val = get_unsigned_val(type, value);
118
119 scnprintf(str, size, "0x%08x%08x%08x%08x",
120 (u32)(val >> 96),
121 (u32)(val >> 64),
122 (u32)(val >> 32),
123 (u32)(val));
124#else
125 WARN_ON(1);
126#endif
127 } else if (type_is_signed(type)) {
128 scnprintf(str, size, "%lld",
129 (s64)get_signed_val(type, value));
130 } else {
131 scnprintf(str, size, "%llu",
132 (u64)get_unsigned_val(type, value));
133 }
134 }
135}
136
ef065653 137static void ubsan_prologue(struct source_location *loc, const char *reason)
c6d30853
AR
138{
139 current->in_ubsan++;
c6d30853
AR
140
141 pr_err("========================================"
142 "========================================\n");
ef065653
KC
143 pr_err("UBSAN: %s in %s:%d:%d\n", reason, loc->file_name,
144 loc->line & LINE_MASK, loc->column & COLUMN_MASK);
1195505f
UG
145
146 kunit_fail_current_test("%s in %s", reason, loc->file_name);
c6d30853
AR
147}
148
ce5c31db 149static void ubsan_epilogue(void)
c6d30853
AR
150{
151 dump_stack();
152 pr_err("========================================"
153 "========================================\n");
ce5c31db 154
c6d30853 155 current->in_ubsan--;
1d28c8d6 156
79cc1ba7 157 check_panic_on_warn("UBSAN");
c6d30853
AR
158}
159
469cbd01 160void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
c6d30853 161{
469cbd01 162 struct overflow_data *data = _data;
c6d30853
AR
163 char rhs_val_str[VALUE_LENGTH];
164
165 if (suppress_report(&data->location))
166 return;
167
ef065653 168 ubsan_prologue(&data->location, "division-overflow");
c6d30853
AR
169
170 val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
171
172 if (type_is_signed(data->type) && get_signed_val(data->type, rhs) == -1)
173 pr_err("division of %s by -1 cannot be represented in type %s\n",
174 rhs_val_str, data->type->type_name);
175 else
176 pr_err("division by zero\n");
177
ce5c31db 178 ubsan_epilogue();
c6d30853
AR
179}
180EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
181
42440c1f 182static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
c6d30853 183{
42440c1f 184 if (suppress_report(data->location))
c6d30853
AR
185 return;
186
ef065653 187 ubsan_prologue(data->location, "null-ptr-deref");
c6d30853
AR
188
189 pr_err("%s null pointer of type %s\n",
190 type_check_kinds[data->type_check_kind],
191 data->type->type_name);
192
ce5c31db 193 ubsan_epilogue();
c6d30853
AR
194}
195
42440c1f 196static void handle_misaligned_access(struct type_mismatch_data_common *data,
c6d30853
AR
197 unsigned long ptr)
198{
42440c1f 199 if (suppress_report(data->location))
c6d30853
AR
200 return;
201
ef065653 202 ubsan_prologue(data->location, "misaligned-access");
c6d30853
AR
203
204 pr_err("%s misaligned address %p for type %s\n",
205 type_check_kinds[data->type_check_kind],
206 (void *)ptr, data->type->type_name);
207 pr_err("which requires %ld byte alignment\n", data->alignment);
208
ce5c31db 209 ubsan_epilogue();
c6d30853
AR
210}
211
42440c1f 212static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
c6d30853
AR
213 unsigned long ptr)
214{
42440c1f 215 if (suppress_report(data->location))
c6d30853
AR
216 return;
217
ef065653 218 ubsan_prologue(data->location, "object-size-mismatch");
901d805c 219 pr_err("%s address %p with insufficient space\n",
c6d30853
AR
220 type_check_kinds[data->type_check_kind],
221 (void *) ptr);
222 pr_err("for an object of type %s\n", data->type->type_name);
ce5c31db 223 ubsan_epilogue();
c6d30853
AR
224}
225
42440c1f 226static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
c6d30853
AR
227 unsigned long ptr)
228{
d08965a2 229 unsigned long flags = user_access_save();
c6d30853
AR
230
231 if (!ptr)
232 handle_null_ptr_deref(data);
233 else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
b8fe1120 234 handle_misaligned_access(data, ptr);
c6d30853
AR
235 else
236 handle_object_size_mismatch(data, ptr);
d08965a2
PZ
237
238 user_access_restore(flags);
c6d30853 239}
42440c1f
AR
240
241void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
f0996bc2 242 void *ptr)
42440c1f
AR
243{
244 struct type_mismatch_data_common common_data = {
245 .location = &data->location,
246 .type = data->type,
247 .alignment = data->alignment,
248 .type_check_kind = data->type_check_kind
249 };
250
f0996bc2 251 ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
42440c1f 252}
c6d30853
AR
253EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
254
469cbd01 255void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr)
42440c1f 256{
469cbd01 257 struct type_mismatch_data_v1 *data = _data;
42440c1f
AR
258 struct type_mismatch_data_common common_data = {
259 .location = &data->location,
260 .type = data->type,
261 .alignment = 1UL << data->log_alignment,
262 .type_check_kind = data->type_check_kind
263 };
264
f0996bc2 265 ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
42440c1f
AR
266}
267EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
268
469cbd01 269void __ubsan_handle_out_of_bounds(void *_data, void *index)
c6d30853 270{
469cbd01 271 struct out_of_bounds_data *data = _data;
c6d30853
AR
272 char index_str[VALUE_LENGTH];
273
274 if (suppress_report(&data->location))
275 return;
276
ef065653 277 ubsan_prologue(&data->location, "array-index-out-of-bounds");
c6d30853
AR
278
279 val_to_string(index_str, sizeof(index_str), data->index_type, index);
280 pr_err("index %s is out of range for type %s\n", index_str,
281 data->array_type->type_name);
ce5c31db 282 ubsan_epilogue();
c6d30853
AR
283}
284EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
285
469cbd01 286void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs)
c6d30853 287{
469cbd01 288 struct shift_out_of_bounds_data *data = _data;
c6d30853
AR
289 struct type_descriptor *rhs_type = data->rhs_type;
290 struct type_descriptor *lhs_type = data->lhs_type;
291 char rhs_str[VALUE_LENGTH];
292 char lhs_str[VALUE_LENGTH];
9a50dcaf 293 unsigned long ua_flags = user_access_save();
c6d30853
AR
294
295 if (suppress_report(&data->location))
9a50dcaf 296 goto out;
c6d30853 297
ef065653 298 ubsan_prologue(&data->location, "shift-out-of-bounds");
c6d30853
AR
299
300 val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
301 val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
302
303 if (val_is_negative(rhs_type, rhs))
304 pr_err("shift exponent %s is negative\n", rhs_str);
305
306 else if (get_unsigned_val(rhs_type, rhs) >=
307 type_bit_width(lhs_type))
308 pr_err("shift exponent %s is too large for %u-bit type %s\n",
309 rhs_str,
310 type_bit_width(lhs_type),
311 lhs_type->type_name);
312 else if (val_is_negative(lhs_type, lhs))
313 pr_err("left shift of negative value %s\n",
314 lhs_str);
315 else
316 pr_err("left shift of %s by %s places cannot be"
317 " represented in type %s\n",
318 lhs_str, rhs_str,
319 lhs_type->type_name);
320
ce5c31db 321 ubsan_epilogue();
9a50dcaf
PZ
322out:
323 user_access_restore(ua_flags);
c6d30853
AR
324}
325EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
326
327
469cbd01 328void __ubsan_handle_builtin_unreachable(void *_data)
c6d30853 329{
469cbd01 330 struct unreachable_data *data = _data;
ef065653 331 ubsan_prologue(&data->location, "unreachable");
c6d30853 332 pr_err("calling __builtin_unreachable()\n");
ce5c31db 333 ubsan_epilogue();
c6d30853
AR
334 panic("can't return from __builtin_unreachable()");
335}
336EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
337
469cbd01 338void __ubsan_handle_load_invalid_value(void *_data, void *val)
c6d30853 339{
469cbd01 340 struct invalid_value_data *data = _data;
c6d30853
AR
341 char val_str[VALUE_LENGTH];
342
343 if (suppress_report(&data->location))
344 return;
345
ef065653 346 ubsan_prologue(&data->location, "invalid-load");
c6d30853
AR
347
348 val_to_string(val_str, sizeof(val_str), data->type, val);
349
350 pr_err("load of value %s is not a valid value for type %s\n",
351 val_str, data->type->type_name);
352
ce5c31db 353 ubsan_epilogue();
c6d30853
AR
354}
355EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
28abcc96
NC
356
357void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
358 unsigned long align,
359 unsigned long offset);
360void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
361 unsigned long align,
362 unsigned long offset)
363{
364 struct alignment_assumption_data *data = _data;
365 unsigned long real_ptr;
366
367 if (suppress_report(&data->location))
368 return;
369
370 ubsan_prologue(&data->location, "alignment-assumption");
371
372 if (offset)
373 pr_err("assumption of %lu byte alignment (with offset of %lu byte) for pointer of type %s failed",
374 align, offset, data->type->type_name);
375 else
376 pr_err("assumption of %lu byte alignment for pointer of type %s failed",
377 align, data->type->type_name);
378
379 real_ptr = ptr - offset;
380 pr_err("%saddress is %lu aligned, misalignment offset is %lu bytes",
381 offset ? "offset " : "", BIT(real_ptr ? __ffs(real_ptr) : 0),
382 real_ptr & (align - 1));
383
384 ubsan_epilogue();
385}
386EXPORT_SYMBOL(__ubsan_handle_alignment_assumption);