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