xref: /openbsd-src/sys/kern/subr_kubsan.c (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*	$OpenBSD: subr_kubsan.c,v 1.12 2019/11/06 19:16:48 anton Exp $	*/
2 
3 /*
4  * Copyright (c) 2019 Anton Lindqvist <anton@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/param.h>
21 #include <sys/atomic.h>
22 #include <sys/syslimits.h>
23 #include <sys/systm.h>
24 #include <sys/timeout.h>
25 
26 #include <uvm/uvm_extern.h>
27 
28 #define KUBSAN_INTERVAL	100	/* report interval in msec */
29 #define KUBSAN_NSLOTS	32
30 
31 #define NUMBER_BUFSIZ		32
32 #define LOCATION_BUFSIZ		(PATH_MAX + 32)	/* filename:line:column */
33 #define LOCATION_REPORTED	(1U << 31)
34 
35 #define NBITS(typ)	(1 << ((typ)->t_info >> 1))
36 #define SIGNED(typ)	((typ)->t_info & 1)
37 
38 struct kubsan_report {
39 	enum {
40 		KUBSAN_FLOAT_CAST_OVERFLOW,
41 		KUBSAN_INVALID_VALUE,
42 		KUBSAN_NEGATE_OVERFLOW,
43 		KUBSAN_NONNULL_ARG,
44 		KUBSAN_OUT_OF_BOUNDS,
45 		KUBSAN_OVERFLOW,
46 		KUBSAN_POINTER_OVERFLOW,
47 		KUBSAN_SHIFT_OUT_OF_BOUNDS,
48 		KUBSAN_TYPE_MISMATCH,
49 		KUBSAN_UNREACHABLE,
50 	} kr_type;
51 
52 	struct source_location *kr_src;
53 
54 	union {
55 		struct {
56 			const struct float_cast_overflow_data *v_data;
57 			unsigned long v_val;
58 		} v_float_cast_overflow;
59 
60 		struct {
61 			const struct invalid_value_data *v_data;
62 			unsigned long v_val;
63 		} v_invalid_value;
64 
65 		struct {
66 			const struct overflow_data *v_data;
67 			unsigned int v_val;
68 		} v_negate_overflow;
69 
70 		struct {
71 			const struct nonnull_arg_data *v_data;
72 		} v_nonnull_arg;
73 
74 		struct {
75 			const struct out_of_bounds_data *v_data;
76 			unsigned int v_idx;
77 		} v_out_of_bounds;
78 
79 		struct {
80 			const struct overflow_data *v_data;
81 			unsigned long v_lhs;
82 			unsigned long v_rhs;
83 			char v_op;
84 		} v_overflow;
85 
86 		struct {
87 			const struct pointer_overflow_data *v_data;
88 			unsigned long v_base;
89 			unsigned long v_res;
90 		} v_pointer_overflow;
91 
92 		struct {
93 			const struct shift_out_of_bounds_data *v_data;
94 			unsigned long v_lhs;
95 			unsigned long v_rhs;
96 		} v_shift_out_of_bounds;
97 
98 		struct {
99 			const struct type_mismatch_data *v_data;
100 			unsigned long v_ptr;
101 		} v_type_mismatch;
102 	} kr_u;
103 };
104 #define kr_float_cast_overflow		kr_u.v_float_cast_overflow
105 #define kr_invalid_value		kr_u.v_invalid_value
106 #define kr_negate_overflow		kr_u.v_negate_overflow
107 #define kr_nonnull_arg			kr_u.v_nonnull_arg
108 #define kr_out_of_bounds		kr_u.v_out_of_bounds
109 #define kr_overflow			kr_u.v_overflow
110 #define kr_pointer_overflow		kr_u.v_pointer_overflow
111 #define kr_shift_out_of_bounds		kr_u.v_shift_out_of_bounds
112 #define kr_type_mismatch		kr_u.v_type_mismatch
113 
114 struct type_descriptor {
115 	uint16_t t_kind;
116 	uint16_t t_info;
117 	char t_name[1];	/* type name as variable length array */
118 };
119 
120 struct source_location {
121 	const char *sl_filename;
122 	uint32_t sl_line;
123 	uint32_t sl_column;
124 };
125 
126 struct float_cast_overflow_data {
127 	struct source_location d_src;
128 	struct type_descriptor *d_ftype;	/* from type */
129 	struct type_descriptor *d_ttype;	/* to type */
130 };
131 
132 struct invalid_value_data {
133 	struct source_location d_src;
134 	struct type_descriptor *d_type;
135 };
136 
137 struct nonnull_arg_data {
138 	struct source_location d_src;
139 	struct source_location d_attr_src;	/* __attribute__ location */
140 	int d_idx;
141 };
142 
143 struct out_of_bounds_data {
144 	struct source_location d_src;
145 	struct type_descriptor *d_atype;	/* array type */
146 	struct type_descriptor *d_itype;	/* index type */
147 };
148 
149 struct overflow_data {
150 	struct source_location d_src;
151 	struct type_descriptor *d_type;
152 };
153 
154 struct pointer_overflow_data {
155 	struct source_location d_src;
156 };
157 
158 struct shift_out_of_bounds_data {
159 	struct source_location d_src;
160 	struct type_descriptor *d_ltype;
161 	struct type_descriptor *d_rtype;
162 };
163 
164 struct type_mismatch_data {
165 	struct source_location d_src;
166 	struct type_descriptor *d_type;
167 	uint8_t d_align;	/* log2 alignment */
168 	uint8_t d_kind;
169 };
170 
171 struct unreachable_data {
172 	struct source_location d_src;
173 };
174 
175 int64_t		 kubsan_deserialize_int(struct type_descriptor *,
176 		    unsigned long);
177 uint64_t	 kubsan_deserialize_uint(struct type_descriptor *,
178 		    unsigned long);
179 void		 kubsan_defer_report(struct kubsan_report *);
180 void		 kubsan_format_int(struct type_descriptor *, unsigned long,
181 		    char *, size_t);
182 int		 kubsan_format_location(const struct source_location *, char *,
183 		    size_t);
184 int		 kubsan_is_reported(struct source_location *);
185 const char	*kubsan_kind(uint8_t);
186 void		 kubsan_report(void *);
187 void		 kubsan_unreport(struct source_location *);
188 
189 static int	is_negative(struct type_descriptor *, unsigned long);
190 static int	is_shift_exponent_too_large(struct type_descriptor *,
191 		    unsigned long);
192 
193 static const char	*pathstrip(const char *);
194 
195 #ifdef KUBSAN_WATCH
196 int kubsan_watch = 2;
197 #else
198 int kubsan_watch = 1;
199 #endif
200 
201 struct kubsan_report	*kubsan_reports = NULL;
202 struct timeout		 kubsan_timo = TIMEOUT_INITIALIZER(kubsan_report, NULL);
203 unsigned int		 kubsan_slot = 0;
204 int			 kubsan_cold = 1;
205 
206 /*
207  * Compiling the kernel with `-fsanitize=undefined' will cause the following
208  * functions to be called when a sanitizer detects undefined behavior.
209  * Some sanitizers are omitted since they are only applicable to C++.
210  *
211  * Every __ubsan_*() sanitizer function also has a corresponding
212  * __ubsan_*_abort() function as part of the ABI provided by Clang.
213  * But, since the kernel never is compiled with `fno-sanitize-recover' for
214  * obvious reasons, they are also omitted.
215  */
216 
217 void
218 __ubsan_handle_add_overflow(struct overflow_data *data,
219     unsigned long lhs, unsigned long rhs)
220 {
221 	struct kubsan_report kr = {
222 		.kr_type		= KUBSAN_OVERFLOW,
223 		.kr_src			= &data->d_src,
224 		.kr_overflow		= { data, lhs, rhs, '+' },
225 	};
226 
227 	kubsan_defer_report(&kr);
228 }
229 
230 void
231 __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
232 {
233 	struct kubsan_report kr = {
234 		.kr_type		= KUBSAN_UNREACHABLE,
235 		.kr_src			= &data->d_src,
236 	};
237 
238 	kubsan_defer_report(&kr);
239 }
240 
241 void
242 __ubsan_handle_divrem_overflow(struct overflow_data *data,
243     unsigned long lhs, unsigned long rhs)
244 {
245 	struct kubsan_report kr = {
246 		.kr_type		= KUBSAN_OVERFLOW,
247 		.kr_src			= &data->d_src,
248 		.kr_overflow		= { data, lhs, rhs, '/' },
249 	};
250 
251 	kubsan_defer_report(&kr);
252 }
253 
254 void
255 __ubsan_handle_float_cast_overflow(struct float_cast_overflow_data *data,
256     unsigned long val)
257 {
258 	struct kubsan_report kr = {
259 		.kr_type		= KUBSAN_FLOAT_CAST_OVERFLOW,
260 		.kr_src			= &data->d_src,
261 		.kr_float_cast_overflow	= { data, val },
262 	};
263 
264 	kubsan_defer_report(&kr);
265 }
266 
267 void
268 __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
269     unsigned long val)
270 {
271 	struct kubsan_report kr = {
272 		.kr_type		= KUBSAN_INVALID_VALUE,
273 		.kr_src			= &data->d_src,
274 		.kr_invalid_value	= { data, val },
275 	};
276 
277 	kubsan_defer_report(&kr);
278 }
279 
280 void
281 __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
282 {
283 	struct kubsan_report kr = {
284 		.kr_type		= KUBSAN_NONNULL_ARG,
285 		.kr_src			= &data->d_src,
286 		.kr_nonnull_arg		= { data },
287 	};
288 
289 	kubsan_defer_report(&kr);
290 }
291 
292 void
293 __ubsan_handle_mul_overflow(struct overflow_data *data,
294     unsigned long lhs, unsigned long rhs)
295 {
296 	struct kubsan_report kr = {
297 		.kr_type		= KUBSAN_OVERFLOW,
298 		.kr_src			= &data->d_src,
299 		.kr_overflow		= { data, lhs, rhs, '*' },
300 	};
301 
302 	kubsan_defer_report(&kr);
303 }
304 
305 void
306 __ubsan_handle_negate_overflow(struct overflow_data *data, unsigned long val)
307 {
308 	struct kubsan_report kr = {
309 		.kr_type		= KUBSAN_NEGATE_OVERFLOW,
310 		.kr_src			= &data->d_src,
311 		.kr_negate_overflow	= { data, val },
312 	};
313 
314 	kubsan_defer_report(&kr);
315 }
316 
317 void
318 __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
319     unsigned long idx)
320 {
321 	struct kubsan_report kr = {
322 		.kr_type		= KUBSAN_OUT_OF_BOUNDS,
323 		.kr_src			= &data->d_src,
324 		.kr_out_of_bounds	= { data, idx },
325 	};
326 
327 	kubsan_defer_report(&kr);
328 }
329 
330 void
331 __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
332     unsigned long base, unsigned long res)
333 {
334 	struct kubsan_report kr = {
335 		.kr_type		= KUBSAN_POINTER_OVERFLOW,
336 		.kr_src			= &data->d_src,
337 		.kr_pointer_overflow	= { data, base, res },
338 	};
339 
340 	kubsan_defer_report(&kr);
341 }
342 
343 void
344 __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
345     unsigned long lhs, unsigned long rhs)
346 {
347 	struct kubsan_report kr = {
348 		.kr_type		= KUBSAN_SHIFT_OUT_OF_BOUNDS,
349 		.kr_src			= &data->d_src,
350 		.kr_shift_out_of_bounds	= { data, lhs, rhs },
351 	};
352 
353 	kubsan_defer_report(&kr);
354 }
355 
356 void
357 __ubsan_handle_sub_overflow(struct overflow_data *data,
358     unsigned long lhs, unsigned long rhs)
359 {
360 	struct kubsan_report kr = {
361 		.kr_type		= KUBSAN_OVERFLOW,
362 		.kr_src			= &data->d_src,
363 		.kr_overflow		= { data, lhs, rhs, '-' },
364 	};
365 
366 	kubsan_defer_report(&kr);
367 }
368 
369 void
370 __ubsan_handle_type_mismatch_v1(struct type_mismatch_data *data,
371     unsigned long ptr)
372 {
373 	struct kubsan_report kr = {
374 		.kr_type		= KUBSAN_TYPE_MISMATCH,
375 		.kr_src			= &data->d_src,
376 		.kr_type_mismatch	= { data, ptr },
377 	};
378 
379 	kubsan_defer_report(&kr);
380 }
381 
382 /*
383  * Allocate storage for reports and schedule the reporter.
384  * Must be called as early on as possible in order to catch undefined behavior
385  * during boot.
386  */
387 void
388 kubsan_init(void)
389 {
390 	kubsan_reports = (void *)uvm_pageboot_alloc(
391 	    sizeof(struct kubsan_report) * KUBSAN_NSLOTS);
392 	kubsan_cold = 0;
393 
394 	timeout_add_msec(&kubsan_timo, KUBSAN_INTERVAL);
395 }
396 
397 int64_t
398 kubsan_deserialize_int(struct type_descriptor *typ, unsigned long val)
399 {
400 	switch (NBITS(typ)) {
401 	case 8:
402 		return ((int8_t)val);
403 	case 16:
404 		return ((int16_t)val);
405 	case 32:
406 		return ((int32_t)val);
407 	case 64:
408 	default:
409 		return ((int64_t)val);
410 	}
411 }
412 
413 uint64_t
414 kubsan_deserialize_uint(struct type_descriptor *typ, unsigned long val)
415 {
416 	switch (NBITS(typ)) {
417 	case 8:
418 		return ((uint8_t)val);
419 	case 16:
420 		return ((uint16_t)val);
421 	case 32:
422 		return ((uint32_t)val);
423 	case 64:
424 	default:
425 		return ((uint64_t)val);
426 	}
427 }
428 
429 void
430 kubsan_defer_report(struct kubsan_report *kr)
431 {
432 	unsigned int slot;
433 
434 	if (__predict_false(kubsan_cold == 1) ||
435 	    kubsan_is_reported(kr->kr_src))
436 		return;
437 
438 	slot = atomic_inc_int_nv(&kubsan_slot) - 1;
439 	if (slot >= KUBSAN_NSLOTS) {
440 		/*
441 		 * No slots left, flag source location as not reported and
442 		 * hope a slot will be available next time.
443 		 */
444 		kubsan_unreport(kr->kr_src);
445 		return;
446 	}
447 
448 	memcpy(&kubsan_reports[slot], kr, sizeof(*kr));
449 }
450 
451 void
452 kubsan_format_int(struct type_descriptor *typ, unsigned long val,
453     char *buf, size_t bufsiz)
454 {
455 	switch (typ->t_kind) {
456 	case 0:	/* integer */
457 		if (SIGNED(typ)) {
458 			int64_t i = kubsan_deserialize_int(typ, val);
459 			snprintf(buf, bufsiz, "%lld", i);
460 		} else {
461 			uint64_t u = kubsan_deserialize_uint(typ, val);
462 			snprintf(buf, bufsiz, "%llu", u);
463 		}
464 		break;
465 	default:
466 		snprintf(buf, bufsiz, "%#x<NaN>", typ->t_kind);
467 	}
468 }
469 
470 int
471 kubsan_format_location(const struct source_location *src, char *buf,
472     size_t bufsiz)
473 {
474 	const char *path;
475 
476 	path = pathstrip(src->sl_filename);
477 
478 	return snprintf(buf, bufsiz, "%s:%u:%u",
479 	    path, src->sl_line & ~LOCATION_REPORTED, src->sl_column);
480 }
481 
482 int
483 kubsan_is_reported(struct source_location *src)
484 {
485 	uint32_t *line = &src->sl_line;
486 	uint32_t prev;
487 
488 	/*
489 	 * Treat everything as reported when disabled.
490 	 * Otherwise, new violations would go by unnoticed.
491 	 */
492 	if (__predict_false(kubsan_watch == 0))
493 		return (1);
494 
495 	do {
496 		prev = *line;
497 		/* If already reported, avoid redundant atomic operation. */
498 		if (prev & LOCATION_REPORTED)
499 			break;
500 	} while (atomic_cas_uint(line, prev, prev | LOCATION_REPORTED) != prev);
501 
502 	return (prev & LOCATION_REPORTED);
503 }
504 
505 const char *
506 kubsan_kind(uint8_t kind)
507 {
508 	static const char *kinds[] = {
509 		"load of",
510 		"store to",
511 		"reference binding to",
512 		"member access within",
513 		"member call on",
514 		"constructor call on",
515 		"downcast of",
516 		"downcast of",
517 		"upcast of",
518 		"cast to virtual base of",
519 		"_Nonnull binding to",
520 		"dynamic operation on"
521 	};
522 
523 	if (kind >= nitems(kinds))
524 		return ("?");
525 
526 	return (kinds[kind]);
527 }
528 
529 void
530 kubsan_report(void *arg)
531 {
532 	char bloc[LOCATION_BUFSIZ];
533 	char blhs[NUMBER_BUFSIZ];
534 	char brhs[NUMBER_BUFSIZ];
535 	struct kubsan_report *kr;
536 	unsigned int nslots;
537 	unsigned int i = 0;
538 
539 again:
540 	nslots = kubsan_slot;
541 	if (nslots == 0)
542 		goto done;
543 	if (nslots > KUBSAN_NSLOTS)
544 		nslots = KUBSAN_NSLOTS;
545 
546 	for (; i < nslots; i++) {
547 		kr = &kubsan_reports[i];
548 
549 		kubsan_format_location(kr->kr_src, bloc, sizeof(bloc));
550 		switch (kr->kr_type) {
551 		case KUBSAN_FLOAT_CAST_OVERFLOW: {
552 			const struct float_cast_overflow_data *data =
553 			    kr->kr_float_cast_overflow.v_data;
554 
555 			kubsan_format_int(data->d_ftype,
556 			    kr->kr_float_cast_overflow.v_val,
557 			    blhs, sizeof(blhs));
558 			printf("kubsan: %s: %s of type %s is outside the range "
559 			    "of representable values of type %s\n",
560 			    bloc, blhs, data->d_ftype->t_name,
561 			    data->d_ttype->t_name);
562 			break;
563 		}
564 
565 		case KUBSAN_INVALID_VALUE: {
566 			const struct invalid_value_data *data =
567 			    kr->kr_invalid_value.v_data;
568 
569 			kubsan_format_int(data->d_type,
570 			    kr->kr_invalid_value.v_val, blhs, sizeof(blhs));
571 			printf("kubsan: %s: load invalid value: load of value "
572 			    "%s is not a valid value for type %s\n",
573 			    bloc, blhs, data->d_type->t_name);
574 			break;
575 		}
576 
577 		case KUBSAN_NEGATE_OVERFLOW: {
578 			const struct overflow_data *data =
579 			    kr->kr_negate_overflow.v_data;
580 
581 			kubsan_format_int(data->d_type,
582 			    kr->kr_negate_overflow.v_val, blhs, sizeof(blhs));
583 			printf("kubsan: %s: negate overflow: negation of %s "
584 			    "cannot be represented in type %s\n",
585 			    bloc, blhs, data->d_type->t_name);
586 			break;
587 		}
588 
589 		case KUBSAN_NONNULL_ARG: {
590 			const struct nonnull_arg_data *data =
591 			    kr->kr_nonnull_arg.v_data;
592 
593 			if (data->d_attr_src.sl_filename)
594 				kubsan_format_location(&data->d_attr_src,
595 				    blhs, sizeof(blhs));
596 			else
597 				blhs[0] = '\0';
598 
599 			printf("kubsan: %s: null pointer passed as argument "
600 			    "%d, which is declared to never be null%s%s\n",
601 			    bloc, data->d_idx,
602 			    blhs[0] ? "nonnull specified in " : "", blhs);
603 			break;
604 		}
605 
606 		case KUBSAN_OUT_OF_BOUNDS: {
607 			const struct out_of_bounds_data *data =
608 			    kr->kr_out_of_bounds.v_data;
609 
610 			kubsan_format_int(data->d_itype,
611 			    kr->kr_out_of_bounds.v_idx, blhs, sizeof(blhs));
612 			printf("kubsan: %s: out of bounds: index %s is out of "
613 			    "range for type %s\n",
614 			    bloc, blhs, data->d_atype->t_name);
615 			break;
616 		}
617 
618 		case KUBSAN_OVERFLOW: {
619 			const struct overflow_data *data =
620 			    kr->kr_overflow.v_data;
621 
622 			kubsan_format_int(data->d_type,
623 			    kr->kr_overflow.v_lhs, blhs, sizeof(blhs));
624 			kubsan_format_int(data->d_type,
625 			    kr->kr_overflow.v_rhs, brhs, sizeof(brhs));
626                         printf("kubsan: %s: %s integer overflow: %s %c %s "
627                             "cannot be represented in type %s\n",
628 			    bloc, SIGNED(data->d_type) ? "signed" : "unsigned",
629 			    blhs, kr->kr_overflow.v_op, brhs,
630 			    data->d_type->t_name);
631 			break;
632 		}
633 
634 		case KUBSAN_POINTER_OVERFLOW:
635 			printf("kubsan: %s: pointer overflow: pointer "
636 			    "expression with base %#lx overflowed to %#lx\n",
637 			    bloc, kr->kr_pointer_overflow.v_base,
638 			    kr->kr_pointer_overflow.v_res);
639 			break;
640 
641 		case KUBSAN_SHIFT_OUT_OF_BOUNDS: {
642 			const struct shift_out_of_bounds_data *data =
643 				kr->kr_shift_out_of_bounds.v_data;
644 			unsigned long lhs = kr->kr_shift_out_of_bounds.v_lhs;
645 			unsigned long rhs = kr->kr_shift_out_of_bounds.v_rhs;
646 
647 			kubsan_format_int(data->d_ltype, lhs, blhs,
648 			    sizeof(blhs));
649 			kubsan_format_int(data->d_rtype, rhs, brhs,
650 			    sizeof(brhs));
651 			if (is_negative(data->d_rtype, rhs))
652 				printf("kubsan: %s: shift: shift exponent %s "
653 				    "is negative\n",
654 				    bloc, brhs);
655 			else if (is_shift_exponent_too_large(data->d_rtype, rhs))
656 				printf("kubsan: %s: shift: shift exponent %s "
657 				    "is too large for %u-bit type\n",
658 				    bloc, brhs, NBITS(data->d_rtype));
659 			else if (is_negative(data->d_ltype, lhs))
660 				printf("kubsan: %s: shift: left shift of "
661 				    "negative value %s\n",
662 				    bloc, blhs);
663 			else
664 				printf("kubsan: %s: shift: left shift of %s by "
665 				    "%s places cannot be represented in type "
666 				    "%s\n",
667 				    bloc, blhs, brhs, data->d_ltype->t_name);
668 			break;
669 		}
670 
671 		case KUBSAN_TYPE_MISMATCH: {
672 			const struct type_mismatch_data *data =
673 				kr->kr_type_mismatch.v_data;
674 			unsigned long ptr = kr->kr_type_mismatch.v_ptr;
675 			unsigned long align = 1UL << data->d_align;
676 
677 			if (ptr == 0UL)
678 				printf("kubsan: %s: type mismatch: %s null "
679 				    "pointer of type %s\n",
680 				    bloc, kubsan_kind(data->d_kind),
681 				    data->d_type->t_name);
682 			else if (ptr & (align - 1))
683 				printf("kubsan: %s: type mismatch: %s "
684 				    "misaligned address %p for type %s which "
685 				    "requires %lu byte alignment\n",
686 				    bloc, kubsan_kind(data->d_kind),
687 				    (void *)ptr, data->d_type->t_name, align);
688 			else
689 				printf("kubsan: %s: type mismatch: %s address "
690 				    "%p with insufficient space for an object "
691 				    "of type %s\n",
692 				    bloc, kubsan_kind(data->d_kind),
693 				    (void *)ptr, data->d_type->t_name);
694 			break;
695 		}
696 
697 		case KUBSAN_UNREACHABLE:
698 			printf("kubsan: %s: unreachable: calling "
699 			    "__builtin_unreachable()\n",
700 			    bloc);
701 			break;
702 		}
703 
704 #ifdef DDB
705 		if (kubsan_watch == 2)
706 			db_enter();
707 #endif
708 	}
709 
710 	/* New reports can arrive at any time. */
711 	if (atomic_cas_uint(&kubsan_slot, nslots, 0) != nslots) {
712 		if (nslots < KUBSAN_NSLOTS)
713 			goto again;
714 		atomic_swap_uint(&kubsan_slot, 0);
715 	}
716 
717 done:
718 	timeout_add_msec(&kubsan_timo, KUBSAN_INTERVAL);
719 }
720 
721 void
722 kubsan_unreport(struct source_location *src)
723 {
724 	uint32_t *line = &src->sl_line;
725 
726 	atomic_clearbits_int(line, LOCATION_REPORTED);
727 }
728 
729 static int
730 is_negative(struct type_descriptor *typ, unsigned long val)
731 {
732 	return (SIGNED(typ) && kubsan_deserialize_int(typ, val) < 0);
733 }
734 
735 static int
736 is_shift_exponent_too_large(struct type_descriptor *typ, unsigned long val)
737 {
738 	return (kubsan_deserialize_int(typ, val) >= NBITS(typ));
739 }
740 
741 /*
742  * A source location is an absolute path making reports quite long.
743  * Instead, use everything after the first /sys/ segment as the path.
744  */
745 static const char *
746 pathstrip(const char *path)
747 {
748 	const char *needle = "/sys/";
749 	size_t i, j;
750 
751 	for (i = j = 0; path[i] != '\0'; i++) {
752 		if (path[i] != needle[j]) {
753 			j = 0;
754 			continue;
755 		}
756 
757 		if (needle[++j] == '\0')
758 			return path + i + 1;
759 	}
760 
761 	return path;
762 }
763