]> git.ipfire.org Git - thirdparty/linux.git/blame - lib/ubsan.c
Merge tag 'cocci-for-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall...
[thirdparty/linux.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>
25b84002 17#include <linux/ubsan.h>
1195505f 18#include <kunit/test-bug.h>
c6d30853
AR
19
20#include "ubsan.h"
21
25b84002
KC
22#ifdef CONFIG_UBSAN_TRAP
23/*
24 * Only include matches for UBSAN checks that are actually compiled in.
25 * The mappings of struct SanitizerKind (the -fsanitize=xxx args) to
26 * enum SanitizerHandler (the traps) in Clang is in clang/lib/CodeGen/.
27 */
28const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)
29{
30 switch (check_type) {
31#ifdef CONFIG_UBSAN_BOUNDS
32 /*
33 * SanitizerKind::ArrayBounds and SanitizerKind::LocalBounds
34 * emit SanitizerHandler::OutOfBounds.
35 */
36 case ubsan_out_of_bounds:
37 return "UBSAN: array index out of bounds";
38#endif
39#ifdef CONFIG_UBSAN_SHIFT
40 /*
41 * SanitizerKind::ShiftBase and SanitizerKind::ShiftExponent
42 * emit SanitizerHandler::ShiftOutOfBounds.
43 */
44 case ubsan_shift_out_of_bounds:
45 return "UBSAN: shift out of bounds";
46#endif
f4626c12 47#if defined(CONFIG_UBSAN_DIV_ZERO) || defined(CONFIG_UBSAN_SIGNED_WRAP)
25b84002 48 /*
f4626c12
KC
49 * SanitizerKind::IntegerDivideByZero and
50 * SanitizerKind::SignedIntegerOverflow emit
25b84002
KC
51 * SanitizerHandler::DivremOverflow.
52 */
53 case ubsan_divrem_overflow:
54 return "UBSAN: divide/remainder overflow";
55#endif
56#ifdef CONFIG_UBSAN_UNREACHABLE
57 /*
58 * SanitizerKind::Unreachable emits
59 * SanitizerHandler::BuiltinUnreachable.
60 */
61 case ubsan_builtin_unreachable:
62 return "UBSAN: unreachable code";
63#endif
64#if defined(CONFIG_UBSAN_BOOL) || defined(CONFIG_UBSAN_ENUM)
65 /*
66 * SanitizerKind::Bool and SanitizerKind::Enum emit
67 * SanitizerHandler::LoadInvalidValue.
68 */
69 case ubsan_load_invalid_value:
70 return "UBSAN: loading invalid value";
71#endif
72#ifdef CONFIG_UBSAN_ALIGNMENT
73 /*
74 * SanitizerKind::Alignment emits SanitizerHandler::TypeMismatch
75 * or SanitizerHandler::AlignmentAssumption.
76 */
77 case ubsan_alignment_assumption:
78 return "UBSAN: alignment assumption";
79 case ubsan_type_mismatch:
80 return "UBSAN: type mismatch";
f4626c12
KC
81#endif
82#ifdef CONFIG_UBSAN_SIGNED_WRAP
83 /*
84 * SanitizerKind::SignedIntegerOverflow emits
85 * SanitizerHandler::AddOverflow, SanitizerHandler::SubOverflow,
86 * or SanitizerHandler::MulOverflow.
87 */
88 case ubsan_add_overflow:
89 return "UBSAN: integer addition overflow";
90 case ubsan_sub_overflow:
91 return "UBSAN: integer subtraction overflow";
92 case ubsan_mul_overflow:
93 return "UBSAN: integer multiplication overflow";
25b84002
KC
94#endif
95 default:
96 return "UBSAN: unrecognized failure code";
97 }
98}
99
100#else
d3c22797 101static const char * const type_check_kinds[] = {
c6d30853
AR
102 "load of",
103 "store to",
104 "reference binding to",
105 "member access within",
106 "member call on",
107 "constructor call on",
108 "downcast of",
109 "downcast of"
110};
111
112#define REPORTED_BIT 31
113
114#if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
115#define COLUMN_MASK (~(1U << REPORTED_BIT))
116#define LINE_MASK (~0U)
117#else
118#define COLUMN_MASK (~0U)
119#define LINE_MASK (~(1U << REPORTED_BIT))
120#endif
121
122#define VALUE_LENGTH 40
123
124static bool was_reported(struct source_location *location)
125{
126 return test_and_set_bit(REPORTED_BIT, &location->reported);
127}
128
c6d30853
AR
129static bool suppress_report(struct source_location *loc)
130{
131 return current->in_ubsan || was_reported(loc);
132}
133
134static bool type_is_int(struct type_descriptor *type)
135{
136 return type->type_kind == type_kind_int;
137}
138
139static bool type_is_signed(struct type_descriptor *type)
140{
141 WARN_ON(!type_is_int(type));
142 return type->type_info & 1;
143}
144
145static unsigned type_bit_width(struct type_descriptor *type)
146{
147 return 1 << (type->type_info >> 1);
148}
149
150static bool is_inline_int(struct type_descriptor *type)
151{
152 unsigned inline_bits = sizeof(unsigned long)*8;
153 unsigned bits = type_bit_width(type);
154
155 WARN_ON(!type_is_int(type));
156
157 return bits <= inline_bits;
158}
159
f0996bc2 160static s_max get_signed_val(struct type_descriptor *type, void *val)
c6d30853
AR
161{
162 if (is_inline_int(type)) {
163 unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
f0996bc2
AR
164 unsigned long ulong_val = (unsigned long)val;
165
166 return ((s_max)ulong_val) << extra_bits >> extra_bits;
c6d30853
AR
167 }
168
169 if (type_bit_width(type) == 64)
170 return *(s64 *)val;
171
172 return *(s_max *)val;
173}
174
f0996bc2 175static bool val_is_negative(struct type_descriptor *type, void *val)
c6d30853
AR
176{
177 return type_is_signed(type) && get_signed_val(type, val) < 0;
178}
179
f0996bc2 180static u_max get_unsigned_val(struct type_descriptor *type, void *val)
c6d30853
AR
181{
182 if (is_inline_int(type))
f0996bc2 183 return (unsigned long)val;
c6d30853
AR
184
185 if (type_bit_width(type) == 64)
186 return *(u64 *)val;
187
188 return *(u_max *)val;
189}
190
191static void val_to_string(char *str, size_t size, struct type_descriptor *type,
f0996bc2 192 void *value)
c6d30853
AR
193{
194 if (type_is_int(type)) {
195 if (type_bit_width(type) == 128) {
c12d3362 196#if defined(CONFIG_ARCH_SUPPORTS_INT128)
c6d30853
AR
197 u_max val = get_unsigned_val(type, value);
198
199 scnprintf(str, size, "0x%08x%08x%08x%08x",
200 (u32)(val >> 96),
201 (u32)(val >> 64),
202 (u32)(val >> 32),
203 (u32)(val));
204#else
205 WARN_ON(1);
206#endif
207 } else if (type_is_signed(type)) {
208 scnprintf(str, size, "%lld",
209 (s64)get_signed_val(type, value));
210 } else {
211 scnprintf(str, size, "%llu",
212 (u64)get_unsigned_val(type, value));
213 }
214 }
215}
216
ef065653 217static void ubsan_prologue(struct source_location *loc, const char *reason)
c6d30853
AR
218{
219 current->in_ubsan++;
c6d30853 220
ffda6556
BPA
221 pr_warn(CUT_HERE);
222
ef065653
KC
223 pr_err("UBSAN: %s in %s:%d:%d\n", reason, loc->file_name,
224 loc->line & LINE_MASK, loc->column & COLUMN_MASK);
1195505f
UG
225
226 kunit_fail_current_test("%s in %s", reason, loc->file_name);
c6d30853
AR
227}
228
ce5c31db 229static void ubsan_epilogue(void)
c6d30853
AR
230{
231 dump_stack();
ffda6556 232 pr_warn("---[ end trace ]---\n");
ce5c31db 233
c6d30853 234 current->in_ubsan--;
1d28c8d6 235
79cc1ba7 236 check_panic_on_warn("UBSAN");
c6d30853
AR
237}
238
557f8c58
KC
239static void handle_overflow(struct overflow_data *data, void *lhs,
240 void *rhs, char op)
241{
242
243 struct type_descriptor *type = data->type;
244 char lhs_val_str[VALUE_LENGTH];
245 char rhs_val_str[VALUE_LENGTH];
246
247 if (suppress_report(&data->location))
248 return;
249
250 ubsan_prologue(&data->location, type_is_signed(type) ?
251 "signed-integer-overflow" :
252 "unsigned-integer-overflow");
253
254 val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
255 val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
256 pr_err("%s %c %s cannot be represented in type %s\n",
257 lhs_val_str,
258 op,
259 rhs_val_str,
260 type->type_name);
261
262 ubsan_epilogue();
263}
264
265void __ubsan_handle_add_overflow(void *data,
266 void *lhs, void *rhs)
267{
268
269 handle_overflow(data, lhs, rhs, '+');
270}
271EXPORT_SYMBOL(__ubsan_handle_add_overflow);
272
273void __ubsan_handle_sub_overflow(void *data,
274 void *lhs, void *rhs)
275{
276 handle_overflow(data, lhs, rhs, '-');
277}
278EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
279
280void __ubsan_handle_mul_overflow(void *data,
281 void *lhs, void *rhs)
282{
283 handle_overflow(data, lhs, rhs, '*');
284}
285EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
286
287void __ubsan_handle_negate_overflow(void *_data, void *old_val)
288{
289 struct overflow_data *data = _data;
290 char old_val_str[VALUE_LENGTH];
291
292 if (suppress_report(&data->location))
293 return;
294
295 ubsan_prologue(&data->location, "negation-overflow");
296
297 val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
298
299 pr_err("negation of %s cannot be represented in type %s:\n",
300 old_val_str, data->type->type_name);
301
302 ubsan_epilogue();
303}
304EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
305
306
469cbd01 307void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
c6d30853 308{
469cbd01 309 struct overflow_data *data = _data;
c6d30853
AR
310 char rhs_val_str[VALUE_LENGTH];
311
312 if (suppress_report(&data->location))
313 return;
314
ef065653 315 ubsan_prologue(&data->location, "division-overflow");
c6d30853
AR
316
317 val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
318
319 if (type_is_signed(data->type) && get_signed_val(data->type, rhs) == -1)
320 pr_err("division of %s by -1 cannot be represented in type %s\n",
321 rhs_val_str, data->type->type_name);
322 else
323 pr_err("division by zero\n");
324
ce5c31db 325 ubsan_epilogue();
c6d30853
AR
326}
327EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
328
42440c1f 329static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
c6d30853 330{
42440c1f 331 if (suppress_report(data->location))
c6d30853
AR
332 return;
333
ef065653 334 ubsan_prologue(data->location, "null-ptr-deref");
c6d30853
AR
335
336 pr_err("%s null pointer of type %s\n",
337 type_check_kinds[data->type_check_kind],
338 data->type->type_name);
339
ce5c31db 340 ubsan_epilogue();
c6d30853
AR
341}
342
42440c1f 343static void handle_misaligned_access(struct type_mismatch_data_common *data,
c6d30853
AR
344 unsigned long ptr)
345{
42440c1f 346 if (suppress_report(data->location))
c6d30853
AR
347 return;
348
ef065653 349 ubsan_prologue(data->location, "misaligned-access");
c6d30853
AR
350
351 pr_err("%s misaligned address %p for type %s\n",
352 type_check_kinds[data->type_check_kind],
353 (void *)ptr, data->type->type_name);
354 pr_err("which requires %ld byte alignment\n", data->alignment);
355
ce5c31db 356 ubsan_epilogue();
c6d30853
AR
357}
358
42440c1f 359static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
c6d30853
AR
360 unsigned long ptr)
361{
42440c1f 362 if (suppress_report(data->location))
c6d30853
AR
363 return;
364
ef065653 365 ubsan_prologue(data->location, "object-size-mismatch");
901d805c 366 pr_err("%s address %p with insufficient space\n",
c6d30853
AR
367 type_check_kinds[data->type_check_kind],
368 (void *) ptr);
369 pr_err("for an object of type %s\n", data->type->type_name);
ce5c31db 370 ubsan_epilogue();
c6d30853
AR
371}
372
42440c1f 373static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
c6d30853
AR
374 unsigned long ptr)
375{
d08965a2 376 unsigned long flags = user_access_save();
c6d30853
AR
377
378 if (!ptr)
379 handle_null_ptr_deref(data);
380 else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
b8fe1120 381 handle_misaligned_access(data, ptr);
c6d30853
AR
382 else
383 handle_object_size_mismatch(data, ptr);
d08965a2
PZ
384
385 user_access_restore(flags);
c6d30853 386}
42440c1f
AR
387
388void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
f0996bc2 389 void *ptr)
42440c1f
AR
390{
391 struct type_mismatch_data_common common_data = {
392 .location = &data->location,
393 .type = data->type,
394 .alignment = data->alignment,
395 .type_check_kind = data->type_check_kind
396 };
397
f0996bc2 398 ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
42440c1f 399}
c6d30853
AR
400EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
401
469cbd01 402void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr)
42440c1f 403{
469cbd01 404 struct type_mismatch_data_v1 *data = _data;
42440c1f
AR
405 struct type_mismatch_data_common common_data = {
406 .location = &data->location,
407 .type = data->type,
408 .alignment = 1UL << data->log_alignment,
409 .type_check_kind = data->type_check_kind
410 };
411
f0996bc2 412 ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
42440c1f
AR
413}
414EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
415
469cbd01 416void __ubsan_handle_out_of_bounds(void *_data, void *index)
c6d30853 417{
469cbd01 418 struct out_of_bounds_data *data = _data;
c6d30853
AR
419 char index_str[VALUE_LENGTH];
420
421 if (suppress_report(&data->location))
422 return;
423
ef065653 424 ubsan_prologue(&data->location, "array-index-out-of-bounds");
c6d30853
AR
425
426 val_to_string(index_str, sizeof(index_str), data->index_type, index);
427 pr_err("index %s is out of range for type %s\n", index_str,
428 data->array_type->type_name);
ce5c31db 429 ubsan_epilogue();
c6d30853
AR
430}
431EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
432
469cbd01 433void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs)
c6d30853 434{
469cbd01 435 struct shift_out_of_bounds_data *data = _data;
c6d30853
AR
436 struct type_descriptor *rhs_type = data->rhs_type;
437 struct type_descriptor *lhs_type = data->lhs_type;
438 char rhs_str[VALUE_LENGTH];
439 char lhs_str[VALUE_LENGTH];
9a50dcaf 440 unsigned long ua_flags = user_access_save();
c6d30853
AR
441
442 if (suppress_report(&data->location))
9a50dcaf 443 goto out;
c6d30853 444
ef065653 445 ubsan_prologue(&data->location, "shift-out-of-bounds");
c6d30853
AR
446
447 val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
448 val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
449
450 if (val_is_negative(rhs_type, rhs))
451 pr_err("shift exponent %s is negative\n", rhs_str);
452
453 else if (get_unsigned_val(rhs_type, rhs) >=
454 type_bit_width(lhs_type))
455 pr_err("shift exponent %s is too large for %u-bit type %s\n",
456 rhs_str,
457 type_bit_width(lhs_type),
458 lhs_type->type_name);
459 else if (val_is_negative(lhs_type, lhs))
460 pr_err("left shift of negative value %s\n",
461 lhs_str);
462 else
463 pr_err("left shift of %s by %s places cannot be"
464 " represented in type %s\n",
465 lhs_str, rhs_str,
466 lhs_type->type_name);
467
ce5c31db 468 ubsan_epilogue();
9a50dcaf
PZ
469out:
470 user_access_restore(ua_flags);
c6d30853
AR
471}
472EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
473
474
469cbd01 475void __ubsan_handle_builtin_unreachable(void *_data)
c6d30853 476{
469cbd01 477 struct unreachable_data *data = _data;
ef065653 478 ubsan_prologue(&data->location, "unreachable");
c6d30853 479 pr_err("calling __builtin_unreachable()\n");
ce5c31db 480 ubsan_epilogue();
c6d30853
AR
481 panic("can't return from __builtin_unreachable()");
482}
483EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
484
469cbd01 485void __ubsan_handle_load_invalid_value(void *_data, void *val)
c6d30853 486{
469cbd01 487 struct invalid_value_data *data = _data;
c6d30853 488 char val_str[VALUE_LENGTH];
f18b0d7e 489 unsigned long ua_flags = user_access_save();
c6d30853
AR
490
491 if (suppress_report(&data->location))
f18b0d7e 492 goto out;
c6d30853 493
ef065653 494 ubsan_prologue(&data->location, "invalid-load");
c6d30853
AR
495
496 val_to_string(val_str, sizeof(val_str), data->type, val);
497
498 pr_err("load of value %s is not a valid value for type %s\n",
499 val_str, data->type->type_name);
500
ce5c31db 501 ubsan_epilogue();
f18b0d7e
PZ
502out:
503 user_access_restore(ua_flags);
c6d30853
AR
504}
505EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
28abcc96 506
28abcc96
NC
507void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
508 unsigned long align,
509 unsigned long offset)
510{
511 struct alignment_assumption_data *data = _data;
512 unsigned long real_ptr;
513
514 if (suppress_report(&data->location))
515 return;
516
517 ubsan_prologue(&data->location, "alignment-assumption");
518
519 if (offset)
520 pr_err("assumption of %lu byte alignment (with offset of %lu byte) for pointer of type %s failed",
521 align, offset, data->type->type_name);
522 else
523 pr_err("assumption of %lu byte alignment for pointer of type %s failed",
524 align, data->type->type_name);
525
526 real_ptr = ptr - offset;
527 pr_err("%saddress is %lu aligned, misalignment offset is %lu bytes",
528 offset ? "offset " : "", BIT(real_ptr ? __ffs(real_ptr) : 0),
529 real_ptr & (align - 1));
530
531 ubsan_epilogue();
532}
533EXPORT_SYMBOL(__ubsan_handle_alignment_assumption);
25b84002
KC
534
535#endif /* !CONFIG_UBSAN_TRAP */