Merge tag 'pci-v6.16-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
[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>
25b84002 17#include <linux/ubsan.h>
1195505f 18#include <kunit/test-bug.h>
c6d30853
AR
19
20#include "ubsan.h"
21
61b38f75 22#if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2)
25b84002
KC
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 */
d683a856 28const char *report_ubsan_failure(u32 check_type)
25b84002
KC
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
ed2b548f 47#if defined(CONFIG_UBSAN_DIV_ZERO) || defined(CONFIG_UBSAN_INTEGER_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 81#endif
ed2b548f 82#ifdef CONFIG_UBSAN_INTEGER_WRAP
f4626c12
KC
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
61b38f75
MS
100#endif
101
102#ifndef CONFIG_UBSAN_TRAP
d3c22797 103static const char * const type_check_kinds[] = {
c6d30853
AR
104 "load of",
105 "store to",
106 "reference binding to",
107 "member access within",
108 "member call on",
109 "constructor call on",
110 "downcast of",
111 "downcast of"
112};
113
114#define REPORTED_BIT 31
115
116#if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
117#define COLUMN_MASK (~(1U << REPORTED_BIT))
118#define LINE_MASK (~0U)
119#else
120#define COLUMN_MASK (~0U)
121#define LINE_MASK (~(1U << REPORTED_BIT))
122#endif
123
124#define VALUE_LENGTH 40
125
126static bool was_reported(struct source_location *location)
127{
128 return test_and_set_bit(REPORTED_BIT, &location->reported);
129}
130
c6d30853
AR
131static bool suppress_report(struct source_location *loc)
132{
133 return current->in_ubsan || was_reported(loc);
134}
135
136static bool type_is_int(struct type_descriptor *type)
137{
138 return type->type_kind == type_kind_int;
139}
140
141static bool type_is_signed(struct type_descriptor *type)
142{
143 WARN_ON(!type_is_int(type));
144 return type->type_info & 1;
145}
146
147static unsigned type_bit_width(struct type_descriptor *type)
148{
149 return 1 << (type->type_info >> 1);
150}
151
152static bool is_inline_int(struct type_descriptor *type)
153{
154 unsigned inline_bits = sizeof(unsigned long)*8;
155 unsigned bits = type_bit_width(type);
156
157 WARN_ON(!type_is_int(type));
158
159 return bits <= inline_bits;
160}
161
f0996bc2 162static s_max get_signed_val(struct type_descriptor *type, void *val)
c6d30853
AR
163{
164 if (is_inline_int(type)) {
165 unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
f0996bc2
AR
166 unsigned long ulong_val = (unsigned long)val;
167
168 return ((s_max)ulong_val) << extra_bits >> extra_bits;
c6d30853
AR
169 }
170
171 if (type_bit_width(type) == 64)
172 return *(s64 *)val;
173
174 return *(s_max *)val;
175}
176
f0996bc2 177static bool val_is_negative(struct type_descriptor *type, void *val)
c6d30853
AR
178{
179 return type_is_signed(type) && get_signed_val(type, val) < 0;
180}
181
f0996bc2 182static u_max get_unsigned_val(struct type_descriptor *type, void *val)
c6d30853
AR
183{
184 if (is_inline_int(type))
f0996bc2 185 return (unsigned long)val;
c6d30853
AR
186
187 if (type_bit_width(type) == 64)
188 return *(u64 *)val;
189
190 return *(u_max *)val;
191}
192
193static void val_to_string(char *str, size_t size, struct type_descriptor *type,
f0996bc2 194 void *value)
c6d30853
AR
195{
196 if (type_is_int(type)) {
197 if (type_bit_width(type) == 128) {
c12d3362 198#if defined(CONFIG_ARCH_SUPPORTS_INT128)
c6d30853
AR
199 u_max val = get_unsigned_val(type, value);
200
201 scnprintf(str, size, "0x%08x%08x%08x%08x",
202 (u32)(val >> 96),
203 (u32)(val >> 64),
204 (u32)(val >> 32),
205 (u32)(val));
206#else
207 WARN_ON(1);
208#endif
209 } else if (type_is_signed(type)) {
210 scnprintf(str, size, "%lld",
211 (s64)get_signed_val(type, value));
212 } else {
213 scnprintf(str, size, "%llu",
214 (u64)get_unsigned_val(type, value));
215 }
216 }
217}
218
ef065653 219static void ubsan_prologue(struct source_location *loc, const char *reason)
c6d30853
AR
220{
221 current->in_ubsan++;
c6d30853 222
ffda6556
BPA
223 pr_warn(CUT_HERE);
224
ef065653
KC
225 pr_err("UBSAN: %s in %s:%d:%d\n", reason, loc->file_name,
226 loc->line & LINE_MASK, loc->column & COLUMN_MASK);
1195505f
UG
227
228 kunit_fail_current_test("%s in %s", reason, loc->file_name);
c6d30853
AR
229}
230
ce5c31db 231static void ubsan_epilogue(void)
c6d30853
AR
232{
233 dump_stack();
ffda6556 234 pr_warn("---[ end trace ]---\n");
ce5c31db 235
c6d30853 236 current->in_ubsan--;
1d28c8d6 237
79cc1ba7 238 check_panic_on_warn("UBSAN");
c6d30853
AR
239}
240
557f8c58
KC
241static void handle_overflow(struct overflow_data *data, void *lhs,
242 void *rhs, char op)
243{
244
245 struct type_descriptor *type = data->type;
246 char lhs_val_str[VALUE_LENGTH];
247 char rhs_val_str[VALUE_LENGTH];
248
249 if (suppress_report(&data->location))
250 return;
251
252 ubsan_prologue(&data->location, type_is_signed(type) ?
253 "signed-integer-overflow" :
254 "unsigned-integer-overflow");
255
256 val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
257 val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
258 pr_err("%s %c %s cannot be represented in type %s\n",
259 lhs_val_str,
260 op,
261 rhs_val_str,
262 type->type_name);
263
264 ubsan_epilogue();
265}
266
267void __ubsan_handle_add_overflow(void *data,
268 void *lhs, void *rhs)
269{
270
271 handle_overflow(data, lhs, rhs, '+');
272}
273EXPORT_SYMBOL(__ubsan_handle_add_overflow);
274
275void __ubsan_handle_sub_overflow(void *data,
276 void *lhs, void *rhs)
277{
278 handle_overflow(data, lhs, rhs, '-');
279}
280EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
281
282void __ubsan_handle_mul_overflow(void *data,
283 void *lhs, void *rhs)
284{
285 handle_overflow(data, lhs, rhs, '*');
286}
287EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
288
289void __ubsan_handle_negate_overflow(void *_data, void *old_val)
290{
291 struct overflow_data *data = _data;
292 char old_val_str[VALUE_LENGTH];
293
294 if (suppress_report(&data->location))
295 return;
296
297 ubsan_prologue(&data->location, "negation-overflow");
298
299 val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
300
301 pr_err("negation of %s cannot be represented in type %s:\n",
302 old_val_str, data->type->type_name);
303
304 ubsan_epilogue();
305}
306EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
307
ed2b548f
KC
308void __ubsan_handle_implicit_conversion(void *_data, void *from_val, void *to_val)
309{
310 struct implicit_conversion_data *data = _data;
311 char from_val_str[VALUE_LENGTH];
312 char to_val_str[VALUE_LENGTH];
313
314 if (suppress_report(&data->location))
315 return;
316
317 val_to_string(from_val_str, sizeof(from_val_str), data->from_type, from_val);
318 val_to_string(to_val_str, sizeof(to_val_str), data->to_type, to_val);
319
320 ubsan_prologue(&data->location, "implicit-conversion");
321
322 pr_err("cannot represent %s value %s during %s %s, truncated to %s\n",
323 data->from_type->type_name,
324 from_val_str,
325 type_check_kinds[data->type_check_kind],
326 data->to_type->type_name,
327 to_val_str);
328
329 ubsan_epilogue();
330}
331EXPORT_SYMBOL(__ubsan_handle_implicit_conversion);
557f8c58 332
469cbd01 333void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
c6d30853 334{
469cbd01 335 struct overflow_data *data = _data;
c6d30853
AR
336 char rhs_val_str[VALUE_LENGTH];
337
338 if (suppress_report(&data->location))
339 return;
340
ef065653 341 ubsan_prologue(&data->location, "division-overflow");
c6d30853
AR
342
343 val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
344
345 if (type_is_signed(data->type) && get_signed_val(data->type, rhs) == -1)
346 pr_err("division of %s by -1 cannot be represented in type %s\n",
347 rhs_val_str, data->type->type_name);
348 else
349 pr_err("division by zero\n");
350
ce5c31db 351 ubsan_epilogue();
c6d30853
AR
352}
353EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
354
42440c1f 355static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
c6d30853 356{
42440c1f 357 if (suppress_report(data->location))
c6d30853
AR
358 return;
359
ef065653 360 ubsan_prologue(data->location, "null-ptr-deref");
c6d30853
AR
361
362 pr_err("%s null pointer of type %s\n",
363 type_check_kinds[data->type_check_kind],
364 data->type->type_name);
365
ce5c31db 366 ubsan_epilogue();
c6d30853
AR
367}
368
42440c1f 369static void handle_misaligned_access(struct type_mismatch_data_common *data,
c6d30853
AR
370 unsigned long ptr)
371{
42440c1f 372 if (suppress_report(data->location))
c6d30853
AR
373 return;
374
ef065653 375 ubsan_prologue(data->location, "misaligned-access");
c6d30853
AR
376
377 pr_err("%s misaligned address %p for type %s\n",
378 type_check_kinds[data->type_check_kind],
379 (void *)ptr, data->type->type_name);
380 pr_err("which requires %ld byte alignment\n", data->alignment);
381
ce5c31db 382 ubsan_epilogue();
c6d30853
AR
383}
384
42440c1f 385static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
c6d30853
AR
386 unsigned long ptr)
387{
42440c1f 388 if (suppress_report(data->location))
c6d30853
AR
389 return;
390
ef065653 391 ubsan_prologue(data->location, "object-size-mismatch");
901d805c 392 pr_err("%s address %p with insufficient space\n",
c6d30853
AR
393 type_check_kinds[data->type_check_kind],
394 (void *) ptr);
395 pr_err("for an object of type %s\n", data->type->type_name);
ce5c31db 396 ubsan_epilogue();
c6d30853
AR
397}
398
42440c1f 399static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
c6d30853
AR
400 unsigned long ptr)
401{
d08965a2 402 unsigned long flags = user_access_save();
c6d30853
AR
403
404 if (!ptr)
405 handle_null_ptr_deref(data);
406 else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
b8fe1120 407 handle_misaligned_access(data, ptr);
c6d30853
AR
408 else
409 handle_object_size_mismatch(data, ptr);
d08965a2
PZ
410
411 user_access_restore(flags);
c6d30853 412}
42440c1f
AR
413
414void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
f0996bc2 415 void *ptr)
42440c1f
AR
416{
417 struct type_mismatch_data_common common_data = {
418 .location = &data->location,
419 .type = data->type,
420 .alignment = data->alignment,
421 .type_check_kind = data->type_check_kind
422 };
423
f0996bc2 424 ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
42440c1f 425}
c6d30853
AR
426EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
427
469cbd01 428void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr)
42440c1f 429{
469cbd01 430 struct type_mismatch_data_v1 *data = _data;
42440c1f
AR
431 struct type_mismatch_data_common common_data = {
432 .location = &data->location,
433 .type = data->type,
434 .alignment = 1UL << data->log_alignment,
435 .type_check_kind = data->type_check_kind
436 };
437
f0996bc2 438 ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
42440c1f
AR
439}
440EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
441
469cbd01 442void __ubsan_handle_out_of_bounds(void *_data, void *index)
c6d30853 443{
469cbd01 444 struct out_of_bounds_data *data = _data;
c6d30853
AR
445 char index_str[VALUE_LENGTH];
446
447 if (suppress_report(&data->location))
448 return;
449
ef065653 450 ubsan_prologue(&data->location, "array-index-out-of-bounds");
c6d30853
AR
451
452 val_to_string(index_str, sizeof(index_str), data->index_type, index);
453 pr_err("index %s is out of range for type %s\n", index_str,
454 data->array_type->type_name);
ce5c31db 455 ubsan_epilogue();
c6d30853
AR
456}
457EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
458
469cbd01 459void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs)
c6d30853 460{
469cbd01 461 struct shift_out_of_bounds_data *data = _data;
c6d30853
AR
462 struct type_descriptor *rhs_type = data->rhs_type;
463 struct type_descriptor *lhs_type = data->lhs_type;
464 char rhs_str[VALUE_LENGTH];
465 char lhs_str[VALUE_LENGTH];
9a50dcaf 466 unsigned long ua_flags = user_access_save();
c6d30853
AR
467
468 if (suppress_report(&data->location))
9a50dcaf 469 goto out;
c6d30853 470
ef065653 471 ubsan_prologue(&data->location, "shift-out-of-bounds");
c6d30853
AR
472
473 val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
474 val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
475
476 if (val_is_negative(rhs_type, rhs))
477 pr_err("shift exponent %s is negative\n", rhs_str);
478
479 else if (get_unsigned_val(rhs_type, rhs) >=
480 type_bit_width(lhs_type))
481 pr_err("shift exponent %s is too large for %u-bit type %s\n",
482 rhs_str,
483 type_bit_width(lhs_type),
484 lhs_type->type_name);
485 else if (val_is_negative(lhs_type, lhs))
486 pr_err("left shift of negative value %s\n",
487 lhs_str);
488 else
489 pr_err("left shift of %s by %s places cannot be"
490 " represented in type %s\n",
491 lhs_str, rhs_str,
492 lhs_type->type_name);
493
ce5c31db 494 ubsan_epilogue();
9a50dcaf
PZ
495out:
496 user_access_restore(ua_flags);
c6d30853
AR
497}
498EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
499
500
469cbd01 501void __ubsan_handle_builtin_unreachable(void *_data)
c6d30853 502{
469cbd01 503 struct unreachable_data *data = _data;
ef065653 504 ubsan_prologue(&data->location, "unreachable");
c6d30853 505 pr_err("calling __builtin_unreachable()\n");
ce5c31db 506 ubsan_epilogue();
c6d30853
AR
507 panic("can't return from __builtin_unreachable()");
508}
509EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
510
469cbd01 511void __ubsan_handle_load_invalid_value(void *_data, void *val)
c6d30853 512{
469cbd01 513 struct invalid_value_data *data = _data;
c6d30853 514 char val_str[VALUE_LENGTH];
f18b0d7e 515 unsigned long ua_flags = user_access_save();
c6d30853
AR
516
517 if (suppress_report(&data->location))
f18b0d7e 518 goto out;
c6d30853 519
ef065653 520 ubsan_prologue(&data->location, "invalid-load");
c6d30853
AR
521
522 val_to_string(val_str, sizeof(val_str), data->type, val);
523
524 pr_err("load of value %s is not a valid value for type %s\n",
525 val_str, data->type->type_name);
526
ce5c31db 527 ubsan_epilogue();
f18b0d7e
PZ
528out:
529 user_access_restore(ua_flags);
c6d30853
AR
530}
531EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
28abcc96 532
28abcc96
NC
533void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
534 unsigned long align,
535 unsigned long offset)
536{
537 struct alignment_assumption_data *data = _data;
538 unsigned long real_ptr;
539
540 if (suppress_report(&data->location))
541 return;
542
543 ubsan_prologue(&data->location, "alignment-assumption");
544
545 if (offset)
546 pr_err("assumption of %lu byte alignment (with offset of %lu byte) for pointer of type %s failed",
547 align, offset, data->type->type_name);
548 else
549 pr_err("assumption of %lu byte alignment for pointer of type %s failed",
550 align, data->type->type_name);
551
552 real_ptr = ptr - offset;
553 pr_err("%saddress is %lu aligned, misalignment offset is %lu bytes",
554 offset ? "offset " : "", BIT(real_ptr ? __ffs(real_ptr) : 0),
555 real_ptr & (align - 1));
556
557 ubsan_epilogue();
558}
559EXPORT_SYMBOL(__ubsan_handle_alignment_assumption);
25b84002
KC
560
561#endif /* !CONFIG_UBSAN_TRAP */