FreeBSD kernel kern code
kern_ubsan.c
Go to the documentation of this file.
1/* $NetBSD: ubsan.c,v 1.3 2018/08/03 16:31:04 kamil Exp $ */
2
3/*-
4 * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * The micro UBSan implementation for the userland (uUBSan) and kernel (kUBSan).
31 * The uBSSan versions is suitable for inclusion into libc or used standalone
32 * with ATF tests.
33 *
34 * This file due to long symbol names generated by a compiler during the
35 * instrumentation process does not follow the KNF style with 80-column limit.
36 */
37
38#include <sys/cdefs.h>
39#ifdef __FreeBSD__
40__FBSDID("$FreeBSD$");
41#else
42#if defined(_KERNEL)
43__KERNEL_RCSID(0, "$NetBSD: ubsan.c,v 1.3 2018/08/03 16:31:04 kamil Exp $");
44#else
45__RCSID("$NetBSD: ubsan.c,v 1.3 2018/08/03 16:31:04 kamil Exp $");
46#endif
47#endif
48
49#if defined(_KERNEL)
50#include <sys/param.h>
51#include <sys/types.h>
52#include <sys/limits.h>
53#include <sys/systm.h>
54#include <machine/_inttypes.h>
55#include <machine/stdarg.h>
56#define ASSERT(x) KASSERT(x, ("%s: " __STRING(x) " failed", __func__))
57#define __arraycount(x) nitems(x)
58#define ISSET(x, y) ((x) & (y))
59#define __BIT(x) ((uintmax_t)1 << (uintmax_t)(x))
60#define __LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask))
61#define __SHIFTOUT(__x, __mask) (((__x) & (__mask)) / __LOWEST_SET_BIT(__mask))
62#else
63#if defined(_LIBC)
64#include "namespace.h"
65#endif
66#include <sys/param.h>
67#include <assert.h>
68#include <inttypes.h>
69#include <math.h>
70#include <signal.h>
71#include <stdarg.h>
72#include <stdbool.h>
73#include <stdint.h>
74#include <stdio.h>
75#include <stdlib.h>
76#include <string.h>
77#include <syslog.h>
78#include <unistd.h>
79#if defined(_LIBC)
80#include "extern.h"
81#define ubsan_vsyslog vsyslog_ss
82#define ASSERT(x) _DIAGASSERT(x)
83#else
84#define ubsan_vsyslog vsyslog_r
85#define ASSERT(x) assert(x)
86#endif
87/* These macros are available in _KERNEL only */
88#define SET(t, f) ((t) |= (f))
89#define ISSET(t, f) ((t) & (f))
90#define CLR(t, f) ((t) &= ~(f))
91#endif
92
93#define REINTERPRET_CAST(__dt, __st) ((__dt)(__st))
94#define STATIC_CAST(__dt, __st) ((__dt)(__st))
95
96#define ACK_REPORTED __BIT(31)
97
98#define MUL_STRING "*"
99#define PLUS_STRING "+"
100#define MINUS_STRING "-"
101#define DIVREM_STRING "divrem"
102
103#define CFI_VCALL 0
104#define CFI_NVCALL 1
105#define CFI_DERIVEDCAST 2
106#define CFI_UNRELATEDCAST 3
107#define CFI_ICALL 4
108#define CFI_NVMFCALL 5
109#define CFI_VMFCALL 6
110
111#define NUMBER_MAXLEN 128
112#define LOCATION_MAXLEN (PATH_MAX + 32 /* ':LINE:COLUMN' */)
113
114#define WIDTH_8 8
115#define WIDTH_16 16
116#define WIDTH_32 32
117#define WIDTH_64 64
118#define WIDTH_80 80
119#define WIDTH_96 96
120#define WIDTH_128 128
121
122#define NUMBER_SIGNED_BIT 1U
123
124#if __SIZEOF_INT128__
125typedef __int128 longest;
126typedef unsigned __int128 ulongest;
127#else
128typedef int64_t longest;
129typedef uint64_t ulongest;
130#endif
131
132#ifndef _KERNEL
133static int ubsan_flags = -1;
134#define UBSAN_ABORT __BIT(0)
135#define UBSAN_STDOUT __BIT(1)
136#define UBSAN_STDERR __BIT(2)
137#define UBSAN_SYSLOG __BIT(3)
138#endif
139
140/* Undefined Behavior specific defines and structures */
141
142#define KIND_INTEGER 0
143#define KIND_FLOAT 1
144#define KIND_UNKNOWN UINT16_MAX
145
148 uint32_t mLine;
149 uint32_t mColumn;
150};
151
153 uint16_t mTypeKind;
154 uint16_t mTypeInfo;
155 uint8_t mTypeName[1];
156};
157
161};
162
165};
166
168 uint8_t mCheckKind;
171};
172
178};
179
183};
184
187 uint8_t mKind;
188};
189
193};
194
199};
200
203};
204
209};
210
213};
214
219};
220
224 unsigned long mLogAlignment;
226};
227
233};
234
238};
239
241 struct CSourceLocation mLocation; /* This field exists in this struct since 2015 August 11th */
244};
245
250};
251
252/* Local utility functions */
253static void Report(bool isFatal, const char *pFormat, ...) __printflike(2, 3);
254static bool isAlreadyReported(struct CSourceLocation *pLocation);
255static size_t zDeserializeTypeWidth(struct CTypeDescriptor *pType);
256static void DeserializeLocation(char *pBuffer, size_t zBUfferLength, struct CSourceLocation *pLocation);
257#ifdef __SIZEOF_INT128__
258static void DeserializeUINT128(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, __uint128_t U128);
259#endif
260static void DeserializeNumberSigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, longest L);
261static void DeserializeNumberUnsigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, ulongest L);
262#ifndef _KERNEL
263static void DeserializeFloatOverPointer(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long *pNumber);
264static void DeserializeFloatInlined(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber);
265#endif
266static longest llliGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber);
267static ulongest llluGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber);
268#ifndef _KERNEL
269static void DeserializeNumberFloat(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber);
270#endif
271static void DeserializeNumber(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber);
272static const char *DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind);
273static const char *DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind);
274static const char *DeserializeCFICheckKind(uint8_t hhuCFICheckKind);
275static bool isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber);
276static bool isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth);
277
278/* Unused in this implementation, emitted by the C++ check dynamic type cast. */
280
281/* Public symbols used in the instrumentation of the code generation part */
282void __ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
283void __ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
284void __ubsan_handle_alignment_assumption(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset);
285void __ubsan_handle_alignment_assumption_abort(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset);
287void __ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer);
288void __ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable);
289void __ubsan_handle_cfi_check_fail_abort(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable);
290void __ubsan_handle_divrem_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
291void __ubsan_handle_divrem_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
292void __ubsan_handle_dynamic_type_cache_miss(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash);
293void __ubsan_handle_dynamic_type_cache_miss_abort(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash);
294void __ubsan_handle_float_cast_overflow(struct CFloatCastOverflowData *pData, unsigned long ulFrom);
295void __ubsan_handle_float_cast_overflow_abort(struct CFloatCastOverflowData *pData, unsigned long ulFrom);
296void __ubsan_handle_function_type_mismatch(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction);
297void __ubsan_handle_function_type_mismatch_abort(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction);
300void __ubsan_handle_load_invalid_value(struct CInvalidValueData *pData, unsigned long ulVal);
301void __ubsan_handle_load_invalid_value_abort(struct CInvalidValueData *pData, unsigned long ulVal);
303void __ubsan_handle_mul_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
304void __ubsan_handle_mul_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
305void __ubsan_handle_negate_overflow(struct COverflowData *pData, unsigned long ulOldVal);
306void __ubsan_handle_negate_overflow_abort(struct COverflowData *pData, unsigned long ulOldVal);
309void __ubsan_handle_nonnull_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
310void __ubsan_handle_nonnull_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
313void __ubsan_handle_nullability_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
314void __ubsan_handle_nullability_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
315void __ubsan_handle_out_of_bounds(struct COutOfBoundsData *pData, unsigned long ulIndex);
316void __ubsan_handle_out_of_bounds_abort(struct COutOfBoundsData *pData, unsigned long ulIndex);
317void __ubsan_handle_pointer_overflow(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult);
318void __ubsan_handle_pointer_overflow_abort(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult);
319void __ubsan_handle_shift_out_of_bounds(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS);
320void __ubsan_handle_shift_out_of_bounds_abort(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS);
321void __ubsan_handle_sub_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
322void __ubsan_handle_sub_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
323void __ubsan_handle_type_mismatch(struct CTypeMismatchData *pData, unsigned long ulPointer);
324void __ubsan_handle_type_mismatch_abort(struct CTypeMismatchData *pData, unsigned long ulPointer);
325void __ubsan_handle_type_mismatch_v1(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer);
326void __ubsan_handle_type_mismatch_v1_abort(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer);
327void __ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound);
328void __ubsan_handle_vla_bound_not_positive_abort(struct CVLABoundData *pData, unsigned long ulBound);
329void __ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr);
330
331static void HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation);
332static void HandleNegateOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulOldValue);
333static void HandleBuiltinUnreachable(bool isFatal, struct CUnreachableData *pData);
334static void HandleTypeMismatch(bool isFatal, struct CSourceLocation *mLocation, struct CTypeDescriptor *mType, unsigned long mLogAlignment, uint8_t mTypeCheckKind, unsigned long ulPointer);
335static void HandleVlaBoundNotPositive(bool isFatal, struct CVLABoundData *pData, unsigned long ulBound);
336static void HandleOutOfBounds(bool isFatal, struct COutOfBoundsData *pData, unsigned long ulIndex);
337static void HandleShiftOutOfBounds(bool isFatal, struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS);
338static void HandleLoadInvalidValue(bool isFatal, struct CInvalidValueData *pData, unsigned long ulValue);
339static void HandleInvalidBuiltin(bool isFatal, struct CInvalidBuiltinData *pData);
340static void HandleFunctionTypeMismatch(bool isFatal, struct CFunctionTypeMismatchData *pData, unsigned long ulFunction);
341static void HandleCFIBadType(bool isFatal, struct CCFICheckFailData *pData, unsigned long ulVtable, bool *bValidVtable, bool *FromUnrecoverableHandler, unsigned long *ProgramCounter, unsigned long *FramePointer);
342static void HandleDynamicTypeCacheMiss(bool isFatal, struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash);
343static void HandleFloatCastOverflow(bool isFatal, struct CFloatCastOverflowData *pData, unsigned long ulFrom);
344static void HandleMissingReturn(bool isFatal, struct CUnreachableData *pData);
345static void HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData);
346static void HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
347static void HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult);
348static void HandleAlignmentAssumption(bool isFatal, struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset);
349
350static void
351HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation)
352{
353 char szLocation[LOCATION_MAXLEN];
354 char szLHS[NUMBER_MAXLEN];
355 char szRHS[NUMBER_MAXLEN];
356
357 ASSERT(pData);
358
359 if (isAlreadyReported(&pData->mLocation))
360 return;
361
362 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
363 DeserializeNumber(szLocation, szLHS, NUMBER_MAXLEN, pData->mType, ulLHS);
364 DeserializeNumber(szLocation, szRHS, NUMBER_MAXLEN, pData->mType, ulRHS);
365
366 Report(isFatal, "UBSan: Undefined Behavior in %s, %s integer overflow: %s %s %s cannot be represented in type %s\n",
367 szLocation, ISSET(pData->mType->mTypeInfo, NUMBER_SIGNED_BIT) ? "signed" : "unsigned", szLHS, szOperation, szRHS, pData->mType->mTypeName);
368}
369
370static void
371HandleNegateOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulOldValue)
372{
373 char szLocation[LOCATION_MAXLEN];
374 char szOldValue[NUMBER_MAXLEN];
375
376 ASSERT(pData);
377
378 if (isAlreadyReported(&pData->mLocation))
379 return;
380
381 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
382 DeserializeNumber(szLocation, szOldValue, NUMBER_MAXLEN, pData->mType, ulOldValue);
383
384 Report(isFatal, "UBSan: Undefined Behavior in %s, negation of %s cannot be represented in type %s\n",
385 szLocation, szOldValue, pData->mType->mTypeName);
386}
387
388static void
389HandleBuiltinUnreachable(bool isFatal, struct CUnreachableData *pData)
390{
391 char szLocation[LOCATION_MAXLEN];
392
393 ASSERT(pData);
394
395 if (isAlreadyReported(&pData->mLocation))
396 return;
397
398 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
399
400 Report(isFatal, "UBSan: Undefined Behavior in %s, calling __builtin_unreachable()\n",
401 szLocation);
402}
403
404static void
405HandleTypeMismatch(bool isFatal, struct CSourceLocation *mLocation, struct CTypeDescriptor *mType, unsigned long mLogAlignment, uint8_t mTypeCheckKind, unsigned long ulPointer)
406{
407 char szLocation[LOCATION_MAXLEN];
408
409 ASSERT(mLocation);
410 ASSERT(mType);
411
412 if (isAlreadyReported(mLocation))
413 return;
414
415 DeserializeLocation(szLocation, LOCATION_MAXLEN, mLocation);
416
417 if (ulPointer == 0) {
418 Report(isFatal, "UBSan: Undefined Behavior in %s, %s null pointer of type %s\n",
419 szLocation, DeserializeTypeCheckKind(mTypeCheckKind), mType->mTypeName);
420 } else if ((mLogAlignment - 1) & ulPointer) {
421 Report(isFatal, "UBSan: Undefined Behavior in %s, %s misaligned address %p for type %s which requires %ld byte alignment\n",
422 szLocation, DeserializeTypeCheckKind(mTypeCheckKind), REINTERPRET_CAST(void *, ulPointer), mType->mTypeName, mLogAlignment);
423 } else {
424 Report(isFatal, "UBSan: Undefined Behavior in %s, %s address %p with insufficient space for an object of type %s\n",
425 szLocation, DeserializeTypeCheckKind(mTypeCheckKind), REINTERPRET_CAST(void *, ulPointer), mType->mTypeName);
426 }
427}
428
429static void
430HandleVlaBoundNotPositive(bool isFatal, struct CVLABoundData *pData, unsigned long ulBound)
431{
432 char szLocation[LOCATION_MAXLEN];
433 char szBound[NUMBER_MAXLEN];
434
435 ASSERT(pData);
436
437 if (isAlreadyReported(&pData->mLocation))
438 return;
439
440 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
441 DeserializeNumber(szLocation, szBound, NUMBER_MAXLEN, pData->mType, ulBound);
442
443 Report(isFatal, "UBSan: Undefined Behavior in %s, variable length array bound value %s <= 0\n",
444 szLocation, szBound);
445}
446
447static void
448HandleOutOfBounds(bool isFatal, struct COutOfBoundsData *pData, unsigned long ulIndex)
449{
450 char szLocation[LOCATION_MAXLEN];
451 char szIndex[NUMBER_MAXLEN];
452
453 ASSERT(pData);
454
455 if (isAlreadyReported(&pData->mLocation))
456 return;
457
458 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
459 DeserializeNumber(szLocation, szIndex, NUMBER_MAXLEN, pData->mIndexType, ulIndex);
460
461 Report(isFatal, "UBSan: Undefined Behavior in %s, index %s is out of range for type %s\n",
462 szLocation, szIndex, pData->mArrayType->mTypeName);
463}
464
465static void
466HandleShiftOutOfBounds(bool isFatal, struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
467{
468 char szLocation[LOCATION_MAXLEN];
469 char szLHS[NUMBER_MAXLEN];
470 char szRHS[NUMBER_MAXLEN];
471
472 ASSERT(pData);
473
474 if (isAlreadyReported(&pData->mLocation))
475 return;
476
477 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
478 DeserializeNumber(szLocation, szLHS, NUMBER_MAXLEN, pData->mLHSType, ulLHS);
479 DeserializeNumber(szLocation, szRHS, NUMBER_MAXLEN, pData->mRHSType, ulRHS);
480
481 if (isNegativeNumber(szLocation, pData->mRHSType, ulRHS))
482 Report(isFatal, "UBSan: Undefined Behavior in %s, shift exponent %s is negative\n",
483 szLocation, szRHS);
484 else if (isShiftExponentTooLarge(szLocation, pData->mRHSType, ulRHS, zDeserializeTypeWidth(pData->mLHSType)))
485 Report(isFatal, "UBSan: Undefined Behavior in %s, shift exponent %s is too large for %zu-bit type %s\n",
486 szLocation, szRHS, zDeserializeTypeWidth(pData->mLHSType), pData->mLHSType->mTypeName);
487 else if (isNegativeNumber(szLocation, pData->mLHSType, ulLHS))
488 Report(isFatal, "UBSan: Undefined Behavior in %s, left shift of negative value %s\n",
489 szLocation, szLHS);
490 else
491 Report(isFatal, "UBSan: Undefined Behavior in %s, left shift of %s by %s places cannot be represented in type %s\n",
492 szLocation, szLHS, szRHS, pData->mLHSType->mTypeName);
493}
494
495static void
496HandleLoadInvalidValue(bool isFatal, struct CInvalidValueData *pData, unsigned long ulValue)
497{
498 char szLocation[LOCATION_MAXLEN];
499 char szValue[NUMBER_MAXLEN];
500
501 ASSERT(pData);
502
503 if (isAlreadyReported(&pData->mLocation))
504 return;
505
506 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
507 DeserializeNumber(szLocation, szValue, NUMBER_MAXLEN, pData->mType, ulValue);
508
509 Report(isFatal, "UBSan: Undefined Behavior in %s, load of value %s is not a valid value for type %s\n",
510 szLocation, szValue, pData->mType->mTypeName);
511}
512
513static void
514HandleInvalidBuiltin(bool isFatal, struct CInvalidBuiltinData *pData)
515{
516 char szLocation[LOCATION_MAXLEN];
517
518 ASSERT(pData);
519
520 if (isAlreadyReported(&pData->mLocation))
521 return;
522
523 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
524
525 Report(isFatal, "UBSan: Undefined Behavior in %s, passing zero to %s, which is not a valid argument\n",
526 szLocation, DeserializeBuiltinCheckKind(pData->mKind));
527}
528
529static void
530HandleFunctionTypeMismatch(bool isFatal, struct CFunctionTypeMismatchData *pData, unsigned long ulFunction)
531{
532 char szLocation[LOCATION_MAXLEN];
533
534 /*
535 * There is no a portable C solution to translate an address of a
536 * function to its name. On the cost of getting this routine simple
537 * and portable without ifdefs between the userland and the kernel
538 * just print the address of the function as-is.
539 *
540 * For better diagnostic messages in the userland, users shall use
541 * the full upstream version shipped along with the compiler toolchain.
542 */
543
544 ASSERT(pData);
545
546 if (isAlreadyReported(&pData->mLocation))
547 return;
548
549 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
550
551 Report(isFatal, "UBSan: Undefined Behavior in %s, call to function %#lx through pointer to incorrect function type %s\n",
552 szLocation, ulFunction, pData->mType->mTypeName);
553}
554
555static void
556HandleCFIBadType(bool isFatal, struct CCFICheckFailData *pData, unsigned long ulVtable, bool *bValidVtable, bool *FromUnrecoverableHandler, unsigned long *ProgramCounter, unsigned long *FramePointer)
557{
558 char szLocation[LOCATION_MAXLEN];
559
560 /*
561 * This is a minimal implementation without diving into C++
562 * specifics and (Itanium) ABI deserialization.
563 */
564
565 ASSERT(pData);
566
567 if (isAlreadyReported(&pData->mLocation))
568 return;
569
570 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
571
572 if (pData->mCheckKind == CFI_ICALL || pData->mCheckKind == CFI_VMFCALL) {
573 Report(isFatal, "UBSan: Undefined Behavior in %s, control flow integrity check for type %s failed during %s (vtable address %#lx)\n",
574 szLocation, pData->mType->mTypeName, DeserializeCFICheckKind(pData->mCheckKind), ulVtable);
575 } else {
576 Report(isFatal || FromUnrecoverableHandler, "UBSan: Undefined Behavior in %s, control flow integrity check for type %s failed during %s (vtable address %#lx; %s vtable; from %s handler; Program Counter %#lx; Frame Pointer %#lx)\n",
577 szLocation, pData->mType->mTypeName, DeserializeCFICheckKind(pData->mCheckKind), ulVtable, *bValidVtable ? "valid" : "invalid", *FromUnrecoverableHandler ? "unrecoverable" : "recoverable", *ProgramCounter, *FramePointer);
578 }
579}
580
581static void
582HandleDynamicTypeCacheMiss(bool isFatal, struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
583{
584#if 0
585 char szLocation[LOCATION_MAXLEN];
586
587 /*
588 * Unimplemented.
589 *
590 * This UBSan handler is special as the check has to be impelemented
591 * in an implementation. In order to handle it there is need to
592 * introspect into C++ ABI internals (RTTI) and use low-level
593 * C++ runtime interfaces.
594 */
595
596 ASSERT(pData);
597
598 if (isAlreadyReported(&pData->mLocation))
599 return;
600
601 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
602
603 Report(isFatal, "UBSan: Undefined Behavior in %s, %s address %#lx which might not point to an object of type %s\n"
604 szLocation, DeserializeTypeCheckKind(pData->mTypeCheckKind), ulPointer, pData->mType);
605#endif
606}
607
608static void
609HandleFloatCastOverflow(bool isFatal, struct CFloatCastOverflowData *pData, unsigned long ulFrom)
610{
611 char szLocation[LOCATION_MAXLEN];
612 char szFrom[NUMBER_MAXLEN];
613
614 ASSERT(pData);
615
616 if (isAlreadyReported(&pData->mLocation))
617 return;
618
619 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
620 DeserializeNumber(szLocation, szFrom, NUMBER_MAXLEN, pData->mFromType, ulFrom);
621
622 Report(isFatal, "UBSan: Undefined Behavior in %s, %s (of type %s) is outside the range of representable values of type %s\n",
623 szLocation, szFrom, pData->mFromType->mTypeName, pData->mToType->mTypeName);
624}
625
626static void
627HandleMissingReturn(bool isFatal, struct CUnreachableData *pData)
628{
629 char szLocation[LOCATION_MAXLEN];
630
631 ASSERT(pData);
632
633 if (isAlreadyReported(&pData->mLocation))
634 return;
635
636 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
637
638 Report(isFatal, "UBSan: Undefined Behavior in %s, execution reached the end of a value-returning function without returning a value\n",
639 szLocation);
640}
641
642static void
643HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData)
644{
645 char szLocation[LOCATION_MAXLEN];
646 char szAttributeLocation[LOCATION_MAXLEN];
647
648 ASSERT(pData);
649
650 if (isAlreadyReported(&pData->mLocation))
651 return;
652
653 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
654 if (pData->mAttributeLocation.mFilename)
655 DeserializeLocation(szAttributeLocation, LOCATION_MAXLEN, &pData->mAttributeLocation);
656 else
657 szAttributeLocation[0] = '\0';
658
659 Report(isFatal, "UBSan: Undefined Behavior in %s, null pointer passed as argument %d, which is declared to never be null%s%s\n",
660 szLocation, pData->mArgIndex, pData->mAttributeLocation.mFilename ? ", nonnull/_Nonnull specified in " : "", szAttributeLocation);
661}
662
663static void
664HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
665{
666 char szLocation[LOCATION_MAXLEN];
667 char szAttributeLocation[LOCATION_MAXLEN];
668
669 ASSERT(pData);
670 ASSERT(pLocationPointer);
671
672 if (isAlreadyReported(pLocationPointer))
673 return;
674
675 DeserializeLocation(szLocation, LOCATION_MAXLEN, pLocationPointer);
676 if (pData->mAttributeLocation.mFilename)
677 DeserializeLocation(szAttributeLocation, LOCATION_MAXLEN, &pData->mAttributeLocation);
678 else
679 szAttributeLocation[0] = '\0';
680
681 Report(isFatal, "UBSan: Undefined Behavior in %s, null pointer returned from function declared to never return null%s%s\n",
682 szLocation, pData->mAttributeLocation.mFilename ? ", nonnull/_Nonnull specified in " : "", szAttributeLocation);
683}
684
685static void
686HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
687{
688 char szLocation[LOCATION_MAXLEN];
689
690 ASSERT(pData);
691
692 if (isAlreadyReported(&pData->mLocation))
693 return;
694
695 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
696
697 Report(isFatal, "UBSan: Undefined Behavior in %s, pointer expression with base %#lx overflowed to %#lx\n",
698 szLocation, ulBase, ulResult);
699}
700
701static void
702HandleAlignmentAssumption(bool isFatal, struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
703{
704 char szLocation[LOCATION_MAXLEN];
705 char szAssumptionLocation[LOCATION_MAXLEN];
706 unsigned long ulRealPointer;
707
708 ASSERT(pData);
709
710 if (isAlreadyReported(&pData->mLocation))
711 return;
712
713 DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
714
715 ulRealPointer = ulPointer - ulOffset;
716
717 if (pData->mAssumptionLocation.mFilename != NULL) {
718 DeserializeLocation(szAssumptionLocation, LOCATION_MAXLEN,
719 &pData->mAssumptionLocation);
720 Report(isFatal, "UBSan: Undefined Behavior in %s, alignment assumption of %#lx for pointer %#lx (offset %#lx), assumption made in %s\n",
721 szLocation, ulAlignment, ulRealPointer, ulOffset,
722 szAssumptionLocation);
723 } else {
724 Report(isFatal, "UBSan: Undefined Behavior in %s, alignment assumption of %#lx for pointer %#lx (offset %#lx)\n",
725 szLocation, ulAlignment, ulRealPointer, ulOffset);
726 }
727}
728
729/* Definions of public symbols emitted by the instrumentation code */
730void
731__ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
732{
733
734 ASSERT(pData);
735
736 HandleOverflow(false, pData, ulLHS, ulRHS, PLUS_STRING);
737}
738
739void
740__ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
741{
742
743 ASSERT(pData);
744
745 HandleOverflow(true, pData, ulLHS, ulRHS, PLUS_STRING);
746}
747
748void
749__ubsan_handle_alignment_assumption(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
750{
751
752 ASSERT(pData);
753
754 HandleAlignmentAssumption(false, pData, ulPointer, ulAlignment, ulOffset);
755}
756
757void
758__ubsan_handle_alignment_assumption_abort(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
759{
760
761 ASSERT(pData);
762
763 HandleAlignmentAssumption(true, pData, ulPointer, ulAlignment, ulOffset);
764}
765
766void
768{
769
770 ASSERT(pData);
771
772 HandleBuiltinUnreachable(true, pData);
773}
774
775void
776__ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer)
777{
778
779 ASSERT(pData);
780
781 HandleCFIBadType(false, pData, ulVtable, &bValidVtable, &FromUnrecoverableHandler, &ProgramCounter, &FramePointer);
782}
783
784void
785__ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable)
786{
787
788 ASSERT(pData);
789
790 HandleCFIBadType(false, pData, ulValue, 0, 0, 0, 0);
791}
792
793void
794__ubsan_handle_cfi_check_fail_abort(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable)
795{
796
797 ASSERT(pData);
798
799 HandleCFIBadType(true, pData, ulValue, 0, 0, 0, 0);
800}
801
802void
803__ubsan_handle_divrem_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
804{
805
806 ASSERT(pData);
807
808 HandleOverflow(false, pData, ulLHS, ulRHS, DIVREM_STRING);
809}
810
811void
812__ubsan_handle_divrem_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
813{
814
815 ASSERT(pData);
816
817 HandleOverflow(true, pData, ulLHS, ulRHS, DIVREM_STRING);
818}
819
820void
821__ubsan_handle_dynamic_type_cache_miss(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
822{
823
824 ASSERT(pData);
825
826 HandleDynamicTypeCacheMiss(false, pData, ulPointer, ulHash);
827}
828
829void
830__ubsan_handle_dynamic_type_cache_miss_abort(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
831{
832
833 ASSERT(pData);
834
835 HandleDynamicTypeCacheMiss(false, pData, ulPointer, ulHash);
836}
837
838void
840{
841
842 ASSERT(pData);
843
844 HandleFloatCastOverflow(false, pData, ulFrom);
845}
846
847void
849{
850
851 ASSERT(pData);
852
853 HandleFloatCastOverflow(true, pData, ulFrom);
854}
855
856void
858{
859
860 ASSERT(pData);
861
862 HandleFunctionTypeMismatch(false, pData, ulFunction);
863}
864
865void
867{
868
869 ASSERT(pData);
870
871 HandleFunctionTypeMismatch(false, pData, ulFunction);
872}
873
874void
876{
877
878 ASSERT(pData);
879
880 HandleInvalidBuiltin(true, pData);
881}
882
883void
885{
886
887 ASSERT(pData);
888
889 HandleInvalidBuiltin(true, pData);
890}
891
892void
893__ubsan_handle_load_invalid_value(struct CInvalidValueData *pData, unsigned long ulValue)
894{
895
896 ASSERT(pData);
897
898 HandleLoadInvalidValue(false, pData, ulValue);
899}
900
901void
903{
904
905 ASSERT(pData);
906
907 HandleLoadInvalidValue(true, pData, ulValue);
908}
909
910void
912{
913
914 ASSERT(pData);
915
916 HandleMissingReturn(true, pData);
917}
918
919void
920__ubsan_handle_mul_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
921{
922
923 ASSERT(pData);
924
925 HandleOverflow(false, pData, ulLHS, ulRHS, MUL_STRING);
926}
927
928void
929__ubsan_handle_mul_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
930{
931
932 ASSERT(pData);
933
934 HandleOverflow(true, pData, ulLHS, ulRHS, MUL_STRING);
935}
936
937void
938__ubsan_handle_negate_overflow(struct COverflowData *pData, unsigned long ulOldValue)
939{
940
941 ASSERT(pData);
942
943 HandleNegateOverflow(false, pData, ulOldValue);
944}
945
946void
947__ubsan_handle_negate_overflow_abort(struct COverflowData *pData, unsigned long ulOldValue)
948{
949
950 ASSERT(pData);
951
952 HandleNegateOverflow(true, pData, ulOldValue);
953}
954
955void
957{
958
959 ASSERT(pData);
960
961 HandleNonnullArg(false, pData);
962}
963
964void
966{
967
968 ASSERT(pData);
969
970 HandleNonnullArg(true, pData);
971}
972
973void
975{
976
977 ASSERT(pData);
978 ASSERT(pLocationPointer);
979
980 HandleNonnullReturn(false, pData, pLocationPointer);
981}
982
983void
985{
986
987 ASSERT(pData);
988 ASSERT(pLocationPointer);
989
990 HandleNonnullReturn(true, pData, pLocationPointer);
991}
992
993void
995{
996
997 ASSERT(pData);
998
999 HandleNonnullArg(false, pData);
1000}
1001
1002void
1004{
1005
1006 ASSERT(pData);
1007
1008 HandleNonnullArg(true, pData);
1009}
1010
1011void
1013{
1014
1015 ASSERT(pData);
1016 ASSERT(pLocationPointer);
1017
1018 HandleNonnullReturn(false, pData, pLocationPointer);
1019}
1020
1021void
1023{
1024
1025 ASSERT(pData);
1026 ASSERT(pLocationPointer);
1027
1028 HandleNonnullReturn(true, pData, pLocationPointer);
1029}
1030
1031void
1032__ubsan_handle_out_of_bounds(struct COutOfBoundsData *pData, unsigned long ulIndex)
1033{
1034
1035 ASSERT(pData);
1036
1037 HandleOutOfBounds(false, pData, ulIndex);
1038}
1039
1040void
1041__ubsan_handle_out_of_bounds_abort(struct COutOfBoundsData *pData, unsigned long ulIndex)
1042{
1043
1044 ASSERT(pData);
1045
1046 HandleOutOfBounds(true, pData, ulIndex);
1047}
1048
1049void
1050__ubsan_handle_pointer_overflow(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
1051{
1052
1053 ASSERT(pData);
1054
1055 HandlePointerOverflow(false, pData, ulBase, ulResult);
1056}
1057
1058void
1059__ubsan_handle_pointer_overflow_abort(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
1060{
1061
1062 ASSERT(pData);
1063
1064 HandlePointerOverflow(true, pData, ulBase, ulResult);
1065}
1066
1067void
1068__ubsan_handle_shift_out_of_bounds(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
1069{
1070
1071 ASSERT(pData);
1072
1073 HandleShiftOutOfBounds(false, pData, ulLHS, ulRHS);
1074}
1075
1076void
1077__ubsan_handle_shift_out_of_bounds_abort(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
1078{
1079
1080 ASSERT(pData);
1081
1082 HandleShiftOutOfBounds(true, pData, ulLHS, ulRHS);
1083}
1084
1085void
1086__ubsan_handle_sub_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
1087{
1088
1089 ASSERT(pData);
1090
1091 HandleOverflow(false, pData, ulLHS, ulRHS, MINUS_STRING);
1092}
1093
1094void
1095__ubsan_handle_sub_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
1096{
1097
1098 ASSERT(pData);
1099
1100 HandleOverflow(true, pData, ulLHS, ulRHS, MINUS_STRING);
1101}
1102
1103void
1104__ubsan_handle_type_mismatch(struct CTypeMismatchData *pData, unsigned long ulPointer)
1105{
1106
1107 ASSERT(pData);
1108
1109 HandleTypeMismatch(false, &pData->mLocation, pData->mType, pData->mLogAlignment, pData->mTypeCheckKind, ulPointer);
1110}
1111
1112void
1113__ubsan_handle_type_mismatch_abort(struct CTypeMismatchData *pData, unsigned long ulPointer)
1114{
1115
1116 ASSERT(pData);
1117
1118 HandleTypeMismatch(true, &pData->mLocation, pData->mType, pData->mLogAlignment, pData->mTypeCheckKind, ulPointer);
1119}
1120
1121void
1122__ubsan_handle_type_mismatch_v1(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer)
1123{
1124
1125 ASSERT(pData);
1126
1127 HandleTypeMismatch(false, &pData->mLocation, pData->mType, __BIT(pData->mLogAlignment), pData->mTypeCheckKind, ulPointer);
1128}
1129
1130void
1132{
1133
1134 ASSERT(pData);
1135
1136 HandleTypeMismatch(true, &pData->mLocation, pData->mType, __BIT(pData->mLogAlignment), pData->mTypeCheckKind, ulPointer);
1137}
1138
1139void
1140__ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound)
1141{
1142
1143 ASSERT(pData);
1144
1145 HandleVlaBoundNotPositive(false, pData, ulBound);
1146}
1147
1148void
1150{
1151
1152 ASSERT(pData);
1153
1154 HandleVlaBoundNotPositive(true, pData, ulBound);
1155}
1156
1157void
1158__ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr)
1159{
1160 /*
1161 * Unimplemented.
1162 *
1163 * The __ubsan_on_report() feature is non trivial to implement in a
1164 * shared code between the kernel and userland. It's also opening
1165 * new sets of potential problems as we are not expected to slow down
1166 * execution of certain kernel subsystems (synchronization issues,
1167 * interrupt handling etc).
1168 *
1169 * A proper solution would need probably a lock-free bounded queue built
1170 * with atomic operations with the property of miltiple consumers and
1171 * multiple producers. Maintaining and validating such code is not
1172 * worth the effort.
1173 *
1174 * A legitimate user - besides testing framework - is a debugger plugin
1175 * intercepting reports from the UBSan instrumentation. For such
1176 * scenarios it is better to run the Clang/GCC version.
1177 */
1178}
1179
1180/* Local utility functions */
1181
1182static void
1183Report(bool isFatal, const char *pFormat, ...)
1184{
1185 va_list ap;
1186
1187 ASSERT(pFormat);
1188
1189 va_start(ap, pFormat);
1190#if defined(_KERNEL)
1191 if (isFatal)
1192 vpanic(pFormat, ap);
1193 else
1194 vprintf(pFormat, ap);
1195#else
1196 if (ubsan_flags == -1) {
1197 char buf[1024];
1198 char *p;
1199
1200 ubsan_flags = UBSAN_STDERR;
1201
1202 if (getenv_r("LIBC_UBSAN", buf, sizeof(buf)) != -1) {
1203 for (p = buf; *p; p++) {
1204 switch (*p) {
1205 case 'a':
1206 SET(ubsan_flags, UBSAN_ABORT);
1207 break;
1208 case 'A':
1209 CLR(ubsan_flags, UBSAN_ABORT);
1210 break;
1211 case 'e':
1212 SET(ubsan_flags, UBSAN_STDERR);
1213 break;
1214 case 'E':
1215 CLR(ubsan_flags, UBSAN_STDERR);
1216 break;
1217 case 'l':
1218 SET(ubsan_flags, UBSAN_SYSLOG);
1219 break;
1220 case 'L':
1221 CLR(ubsan_flags, UBSAN_SYSLOG);
1222 break;
1223 case 'o':
1224 SET(ubsan_flags, UBSAN_STDOUT);
1225 break;
1226 case 'O':
1227 CLR(ubsan_flags, UBSAN_STDOUT);
1228 break;
1229 default:
1230 break;
1231 }
1232 }
1233 }
1234 }
1235
1236 // The *v*print* functions can flush the va_list argument.
1237 // Create a local copy for each call to prevent invalid read.
1238 if (ISSET(ubsan_flags, UBSAN_STDOUT)) {
1239 va_list tmp;
1240 va_copy(tmp, ap);
1241 vprintf(pFormat, tmp);
1242 va_end(tmp);
1243 fflush(stdout);
1244 }
1245 if (ISSET(ubsan_flags, UBSAN_STDERR)) {
1246 va_list tmp;
1247 va_copy(tmp, ap);
1248 vfprintf(stderr, pFormat, tmp);
1249 va_end(tmp);
1250 fflush(stderr);
1251 }
1252 if (ISSET(ubsan_flags, UBSAN_SYSLOG)) {
1253 va_list tmp;
1254 va_copy(tmp, ap);
1255 struct syslog_data SyslogData = SYSLOG_DATA_INIT;
1256 ubsan_vsyslog(LOG_DEBUG | LOG_USER, &SyslogData, pFormat, tmp);
1257 va_end(tmp);
1258 }
1259 if (isFatal || ISSET(ubsan_flags, UBSAN_ABORT)) {
1260 abort();
1261 /* NOTREACHED */
1262 }
1263#endif
1264 va_end(ap);
1265}
1266
1267static bool
1269{
1270 /*
1271 * This code is shared between libc, kernel and standalone usage.
1272 * It shall work in early bootstrap phase of both of them.
1273 */
1274
1275 uint32_t siOldValue;
1276 volatile uint32_t *pLine;
1277
1278 ASSERT(pLocation);
1279
1280 pLine = &pLocation->mLine;
1281
1282 do {
1283 siOldValue = *pLine;
1284 } while (__sync_val_compare_and_swap(pLine, siOldValue, siOldValue | ACK_REPORTED) != siOldValue);
1285
1286 return ISSET(siOldValue, ACK_REPORTED);
1287}
1288
1289static size_t
1291{
1292 size_t zWidth = 0;
1293
1294 ASSERT(pType);
1295
1296 switch (pType->mTypeKind) {
1297 case KIND_INTEGER:
1298 zWidth = __BIT(__SHIFTOUT(pType->mTypeInfo, ~NUMBER_SIGNED_BIT));
1299 break;
1300 case KIND_FLOAT:
1301 zWidth = pType->mTypeInfo;
1302 break;
1303 default:
1304 Report(true, "UBSan: Unknown variable type %#04" PRIx16 "\n", pType->mTypeKind);
1305 /* NOTREACHED */
1306 }
1307
1308 /* Invalid width will be transformed to 0 */
1309 ASSERT(zWidth > 0);
1310
1311 return zWidth;
1312}
1313
1314static void
1315DeserializeLocation(char *pBuffer, size_t zBUfferLength, struct CSourceLocation *pLocation)
1316{
1317
1318 ASSERT(pLocation);
1319 ASSERT(pLocation->mFilename);
1320
1321 snprintf(pBuffer, zBUfferLength, "%s:%" PRIu32 ":%" PRIu32, pLocation->mFilename, pLocation->mLine & (uint32_t)~ACK_REPORTED, pLocation->mColumn);
1322}
1323
1324#ifdef __SIZEOF_INT128__
1325static void
1326DeserializeUINT128(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, __uint128_t U128)
1327{
1328 char szBuf[3]; /* 'XX\0' */
1329 char rgNumber[sizeof(ulongest)];
1330 ssize_t zI;
1331
1332 memcpy(rgNumber, &U128, sizeof(U128));
1333
1334 strlcpy(pBuffer, "Undecoded-128-bit-Integer-Type (0x", zBUfferLength);
1335#if BYTE_ORDER == LITTLE_ENDIAN
1336 for (zI = sizeof(ulongest) - 1; zI >= 0; zI--) {
1337#else
1338 for (zI = 0; zI < (ssize_t)sizeof(ulongest); zI++) {
1339#endif
1340 snprintf(szBuf, sizeof(szBuf), "%02" PRIx8, rgNumber[zI]);
1341 strlcat(pBuffer, szBuf, zBUfferLength);
1342 }
1343 strlcat(pBuffer, ")", zBUfferLength);
1344}
1345#endif
1346
1347static void
1348DeserializeNumberSigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, longest L)
1349{
1350
1351 ASSERT(pBuffer);
1352 ASSERT(zBUfferLength > 0);
1353 ASSERT(pType);
1355
1356 switch (zDeserializeTypeWidth(pType)) {
1357 default:
1358 ASSERT(0 && "Invalid codepath");
1359 /* NOTREACHED */
1360#ifdef __SIZEOF_INT128__
1361 case WIDTH_128:
1362 DeserializeUINT128(pBuffer, zBUfferLength, pType, STATIC_CAST(__uint128_t, L));
1363 break;
1364#endif
1365 case WIDTH_64:
1366 case WIDTH_32:
1367 case WIDTH_16:
1368 case WIDTH_8:
1369 snprintf(pBuffer, zBUfferLength, "%" PRId64, STATIC_CAST(int64_t, L));
1370 break;
1371 }
1372}
1373
1374static void
1375DeserializeNumberUnsigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, ulongest L)
1376{
1377
1378 ASSERT(pBuffer);
1379 ASSERT(zBUfferLength > 0);
1380 ASSERT(pType);
1382
1383 switch (zDeserializeTypeWidth(pType)) {
1384 default:
1385 ASSERT(0 && "Invalid codepath");
1386 /* NOTREACHED */
1387#ifdef __SIZEOF_INT128__
1388 case WIDTH_128:
1389 DeserializeUINT128(pBuffer, zBUfferLength, pType, STATIC_CAST(__uint128_t, L));
1390 break;
1391#endif
1392 case WIDTH_64:
1393 case WIDTH_32:
1394 case WIDTH_16:
1395 case WIDTH_8:
1396 snprintf(pBuffer, zBUfferLength, "%" PRIu64, STATIC_CAST(uint64_t, L));
1397 break;
1398 }
1399}
1400
1401#ifndef _KERNEL
1402static void
1403DeserializeFloatOverPointer(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long *pNumber)
1404{
1405 double D;
1406#ifdef __HAVE_LONG_DOUBLE
1407 long double LD;
1408#endif
1409
1410 ASSERT(pBuffer);
1411 ASSERT(zBUfferLength > 0);
1412 ASSERT(pType);
1413 ASSERT(pNumber);
1414 /*
1415 * This function handles 64-bit number over a pointer on 32-bit CPUs.
1416 */
1417 ASSERT((sizeof(*pNumber) * CHAR_BIT < WIDTH_64) || (zDeserializeTypeWidth(pType) >= WIDTH_64));
1418 ASSERT(sizeof(D) == sizeof(uint64_t));
1419#ifdef __HAVE_LONG_DOUBLE
1420 ASSERT(sizeof(LD) > sizeof(uint64_t));
1421#endif
1422
1423 switch (zDeserializeTypeWidth(pType)) {
1424#ifdef __HAVE_LONG_DOUBLE
1425 case WIDTH_128:
1426 case WIDTH_96:
1427 case WIDTH_80:
1428 memcpy(&LD, pNumber, sizeof(long double));
1429 snprintf(pBuffer, zBUfferLength, "%Lg", LD);
1430 break;
1431#endif
1432 case WIDTH_64:
1433 memcpy(&D, pNumber, sizeof(double));
1434 snprintf(pBuffer, zBUfferLength, "%g", D);
1435 break;
1436 }
1437}
1438
1439static void
1440DeserializeFloatInlined(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber)
1441{
1442 float F;
1443 double D;
1444 uint32_t U32;
1445
1446 ASSERT(pBuffer);
1447 ASSERT(zBUfferLength > 0);
1448 ASSERT(pType);
1449 ASSERT(sizeof(F) == sizeof(uint32_t));
1450 ASSERT(sizeof(D) == sizeof(uint64_t));
1451
1452 switch (zDeserializeTypeWidth(pType)) {
1453 case WIDTH_64:
1454 memcpy(&D, &ulNumber, sizeof(double));
1455 snprintf(pBuffer, zBUfferLength, "%g", D);
1456 break;
1457 case WIDTH_32:
1458 /*
1459 * On supported platforms sizeof(float)==sizeof(uint32_t)
1460 * unsigned long is either 32 or 64-bit, cast it to 32-bit
1461 * value in order to call memcpy(3) in an Endian-aware way.
1462 */
1463 U32 = STATIC_CAST(uint32_t, ulNumber);
1464 memcpy(&F, &U32, sizeof(float));
1465 snprintf(pBuffer, zBUfferLength, "%g", F);
1466 break;
1467 case WIDTH_16:
1468 snprintf(pBuffer, zBUfferLength, "Undecoded-16-bit-Floating-Type (%#04" PRIx16 ")", STATIC_CAST(uint16_t, ulNumber));
1469 break;
1470 }
1471}
1472#endif
1473
1474static longest
1475llliGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
1476{
1477 size_t zNumberWidth;
1478 longest L = 0;
1479
1480 ASSERT(szLocation);
1481 ASSERT(pType);
1482
1483 zNumberWidth = zDeserializeTypeWidth(pType);
1484 switch (zNumberWidth) {
1485 default:
1486 Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation);
1487 /* NOTREACHED */
1488 case WIDTH_128:
1489#ifdef __SIZEOF_INT128__
1490 memcpy(&L, REINTERPRET_CAST(longest *, ulNumber), sizeof(longest));
1491#else
1492 Report(true, "UBSan: Unexpected 128-Bit Type in %s\n", szLocation);
1493 /* NOTREACHED */
1494#endif
1495 break;
1496 case WIDTH_64:
1497 if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) {
1498 L = *REINTERPRET_CAST(int64_t *, ulNumber);
1499 } else {
1500 L = STATIC_CAST(int64_t, STATIC_CAST(uint64_t, ulNumber));
1501 }
1502 break;
1503 case WIDTH_32:
1504 L = STATIC_CAST(int32_t, STATIC_CAST(uint32_t, ulNumber));
1505 break;
1506 case WIDTH_16:
1507 L = STATIC_CAST(int16_t, STATIC_CAST(uint16_t, ulNumber));
1508 break;
1509 case WIDTH_8:
1510 L = STATIC_CAST(int8_t, STATIC_CAST(uint8_t, ulNumber));
1511 break;
1512 }
1513
1514 return L;
1515}
1516
1517static ulongest
1518llluGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
1519{
1520 size_t zNumberWidth;
1521 ulongest UL = 0;
1522
1523 ASSERT(pType);
1524
1525 zNumberWidth = zDeserializeTypeWidth(pType);
1526 switch (zNumberWidth) {
1527 default:
1528 Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation);
1529 /* NOTREACHED */
1530 case WIDTH_128:
1531#ifdef __SIZEOF_INT128__
1532 memcpy(&UL, REINTERPRET_CAST(ulongest *, ulNumber), sizeof(ulongest));
1533 break;
1534#else
1535 Report(true, "UBSan: Unexpected 128-Bit Type in %s\n", szLocation);
1536 /* NOTREACHED */
1537#endif
1538 case WIDTH_64:
1539 if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) {
1540 UL = *REINTERPRET_CAST(uint64_t *, ulNumber);
1541 break;
1542 }
1543 /* FALLTHROUGH */
1544 case WIDTH_32:
1545 /* FALLTHROUGH */
1546 case WIDTH_16:
1547 /* FALLTHROUGH */
1548 case WIDTH_8:
1549 UL = ulNumber;
1550 break;
1551 }
1552
1553 return UL;
1554}
1555
1556#ifndef _KERNEL
1557static void
1558DeserializeNumberFloat(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber)
1559{
1560 size_t zNumberWidth;
1561
1562 ASSERT(szLocation);
1563 ASSERT(pBuffer);
1564 ASSERT(zBUfferLength > 0);
1565 ASSERT(pType);
1566 ASSERT(pType->mTypeKind == KIND_FLOAT);
1567
1568 zNumberWidth = zDeserializeTypeWidth(pType);
1569 switch (zNumberWidth) {
1570 default:
1571 Report(true, "UBSan: Unexpected %zu-Bit Type in %s\n", zNumberWidth, szLocation);
1572 /* NOTREACHED */
1573#ifdef __HAVE_LONG_DOUBLE
1574 case WIDTH_128:
1575 case WIDTH_96:
1576 case WIDTH_80:
1577 DeserializeFloatOverPointer(pBuffer, zBUfferLength, pType, REINTERPRET_CAST(unsigned long *, ulNumber));
1578 break;
1579#endif
1580 case WIDTH_64:
1581 if (sizeof(ulNumber) * CHAR_BIT < WIDTH_64) {
1582 DeserializeFloatOverPointer(pBuffer, zBUfferLength, pType, REINTERPRET_CAST(unsigned long *, ulNumber));
1583 break;
1584 }
1585 case WIDTH_32:
1586 case WIDTH_16:
1587 DeserializeFloatInlined(pBuffer, zBUfferLength, pType, ulNumber);
1588 break;
1589 }
1590}
1591#endif
1592
1593static void
1594DeserializeNumber(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber)
1595{
1596
1597 ASSERT(szLocation);
1598 ASSERT(pBuffer);
1599 ASSERT(zBUfferLength > 0);
1600 ASSERT(pType);
1601
1602 switch(pType->mTypeKind) {
1603 case KIND_INTEGER:
1604 if (ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT)) {
1605 longest L = llliGetNumber(szLocation, pType, ulNumber);
1606 DeserializeNumberSigned(pBuffer, zBUfferLength, pType, L);
1607 } else {
1608 ulongest UL = llluGetNumber(szLocation, pType, ulNumber);
1609 DeserializeNumberUnsigned(pBuffer, zBUfferLength, pType, UL);
1610 }
1611 break;
1612 case KIND_FLOAT:
1613#ifdef _KERNEL
1614 Report(true, "UBSan: Unexpected Float Type in %s\n", szLocation);
1615 /* NOTREACHED */
1616#else
1617 DeserializeNumberFloat(szLocation, pBuffer, zBUfferLength, pType, ulNumber);
1618#endif
1619 break;
1620 case KIND_UNKNOWN:
1621 Report(true, "UBSan: Unknown Type in %s\n", szLocation);
1622 /* NOTREACHED */
1623 break;
1624 }
1625}
1626
1627static const char *
1628DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind)
1629{
1630 const char *rgczTypeCheckKinds[] = {
1631 "load of",
1632 "store to",
1633 "reference binding to",
1634 "member access within",
1635 "member call on",
1636 "constructor call on",
1637 "downcast of",
1638 "downcast of",
1639 "upcast of",
1640 "cast to virtual base of",
1641 "_Nonnull binding to",
1642 "dynamic operation on"
1643 };
1644
1645 ASSERT(__arraycount(rgczTypeCheckKinds) > hhuTypeCheckKind);
1646
1647 return rgczTypeCheckKinds[hhuTypeCheckKind];
1648}
1649
1650static const char *
1651DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind)
1652{
1653 const char *rgczBuiltinCheckKinds[] = {
1654 "ctz()",
1655 "clz()"
1656 };
1657
1658 ASSERT(__arraycount(rgczBuiltinCheckKinds) > hhuBuiltinCheckKind);
1659
1660 return rgczBuiltinCheckKinds[hhuBuiltinCheckKind];
1661}
1662
1663static const char *
1664DeserializeCFICheckKind(uint8_t hhuCFICheckKind)
1665{
1666 const char *rgczCFICheckKinds[] = {
1667 "virtual call", // CFI_VCALL
1668 "non-virtual call", // CFI_NVCALL
1669 "base-to-derived cast", // CFI_DERIVEDCAST
1670 "cast to unrelated type", // CFI_UNRELATEDCAST
1671 "indirect function call", // CFI_ICALL
1672 "non-virtual pointer to member function call", // CFI_NVMFCALL
1673 "virtual pointer to member function call", // CFI_VMFCALL
1674 };
1675
1676 ASSERT(__arraycount(rgczCFICheckKinds) > hhuCFICheckKind);
1677
1678 return rgczCFICheckKinds[hhuCFICheckKind];
1679}
1680
1681static bool
1682isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
1683{
1684
1685 ASSERT(szLocation);
1686 ASSERT(pType);
1687 ASSERT(pType->mTypeKind == KIND_INTEGER);
1688
1689 if (!ISSET(pType->mTypeInfo, NUMBER_SIGNED_BIT))
1690 return false;
1691
1692 return llliGetNumber(szLocation, pType, ulNumber) < 0;
1693}
1694
1695static bool
1696isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth)
1697{
1698
1699 ASSERT(szLocation);
1700 ASSERT(pType);
1701 ASSERT(pType->mTypeKind == KIND_INTEGER);
1702
1703 return llluGetNumber(szLocation, pType, ulNumber) >= zWidth;
1704}
void vpanic(const char *fmt, va_list ap)
void __ubsan_handle_float_cast_overflow(struct CFloatCastOverflowData *pData, unsigned long ulFrom)
Definition: kern_ubsan.c:839
void __ubsan_handle_type_mismatch(struct CTypeMismatchData *pData, unsigned long ulPointer)
Definition: kern_ubsan.c:1104
static void HandleCFIBadType(bool isFatal, struct CCFICheckFailData *pData, unsigned long ulVtable, bool *bValidVtable, bool *FromUnrecoverableHandler, unsigned long *ProgramCounter, unsigned long *FramePointer)
Definition: kern_ubsan.c:556
static void HandleMissingReturn(bool isFatal, struct CUnreachableData *pData)
Definition: kern_ubsan.c:627
void __ubsan_handle_mul_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:920
static bool isNegativeNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
Definition: kern_ubsan.c:1682
void __ubsan_handle_type_mismatch_v1(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer)
Definition: kern_ubsan.c:1122
#define LOCATION_MAXLEN
Definition: kern_ubsan.c:112
#define CFI_ICALL
Definition: kern_ubsan.c:107
#define __arraycount(x)
Definition: kern_ubsan.c:57
void __ubsan_handle_sub_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:1095
void __ubsan_handle_mul_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:929
static void Report(bool isFatal, const char *pFormat,...) __printflike(2
Definition: kern_ubsan.c:1183
#define ISSET(x, y)
Definition: kern_ubsan.c:58
static void HandleAlignmentAssumption(bool isFatal, struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
Definition: kern_ubsan.c:702
void __ubsan_handle_out_of_bounds_abort(struct COutOfBoundsData *pData, unsigned long ulIndex)
Definition: kern_ubsan.c:1041
#define WIDTH_16
Definition: kern_ubsan.c:115
#define WIDTH_64
Definition: kern_ubsan.c:117
void __ubsan_handle_nonnull_arg(struct CNonNullArgData *pData)
Definition: kern_ubsan.c:956
static void DeserializeNumberSigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, longest L)
Definition: kern_ubsan.c:1348
void __ubsan_handle_pointer_overflow_abort(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
Definition: kern_ubsan.c:1059
void __ubsan_handle_missing_return(struct CUnreachableData *pData)
Definition: kern_ubsan.c:911
static void HandleFloatCastOverflow(bool isFatal, struct CFloatCastOverflowData *pData, unsigned long ulFrom)
Definition: kern_ubsan.c:609
void __ubsan_handle_function_type_mismatch_abort(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction)
Definition: kern_ubsan.c:866
void __ubsan_handle_function_type_mismatch(struct CFunctionTypeMismatchData *pData, unsigned long ulFunction)
Definition: kern_ubsan.c:857
void __ubsan_handle_load_invalid_value_abort(struct CInvalidValueData *pData, unsigned long ulVal)
Definition: kern_ubsan.c:902
void __ubsan_handle_dynamic_type_cache_miss(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
Definition: kern_ubsan.c:821
void __ubsan_handle_alignment_assumption(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
Definition: kern_ubsan.c:749
void __ubsan_handle_negate_overflow_abort(struct COverflowData *pData, unsigned long ulOldVal)
Definition: kern_ubsan.c:947
static const char * DeserializeCFICheckKind(uint8_t hhuCFICheckKind)
Definition: kern_ubsan.c:1664
#define STATIC_CAST(__dt, __st)
Definition: kern_ubsan.c:94
void __ubsan_handle_vla_bound_not_positive_abort(struct CVLABoundData *pData, unsigned long ulBound)
Definition: kern_ubsan.c:1149
void __ubsan_handle_cfi_check_fail_abort(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable)
Definition: kern_ubsan.c:794
void __ubsan_handle_vla_bound_not_positive(struct CVLABoundData *pData, unsigned long ulBound)
Definition: kern_ubsan.c:1140
void __ubsan_handle_shift_out_of_bounds(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:1068
void __ubsan_handle_nonnull_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
Definition: kern_ubsan.c:974
void __ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:740
intptr_t __ubsan_vptr_type_cache[128]
Definition: kern_ubsan.c:279
void __ubsan_handle_float_cast_overflow_abort(struct CFloatCastOverflowData *pData, unsigned long ulFrom)
Definition: kern_ubsan.c:848
#define WIDTH_96
Definition: kern_ubsan.c:119
static void DeserializeNumber(char *szLocation, char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, unsigned long ulNumber)
Definition: kern_ubsan.c:1594
void __ubsan_handle_divrem_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:812
static void HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData)
Definition: kern_ubsan.c:643
void __ubsan_handle_sub_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:1086
uint64_t ulongest
Definition: kern_ubsan.c:129
void __ubsan_handle_pointer_overflow(struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
Definition: kern_ubsan.c:1050
static void HandleDynamicTypeCacheMiss(bool isFatal, struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
Definition: kern_ubsan.c:582
static void HandleNegateOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulOldValue)
Definition: kern_ubsan.c:371
static void HandleLoadInvalidValue(bool isFatal, struct CInvalidValueData *pData, unsigned long ulValue)
Definition: kern_ubsan.c:496
#define WIDTH_8
Definition: kern_ubsan.c:114
#define WIDTH_32
Definition: kern_ubsan.c:116
void __ubsan_handle_dynamic_type_cache_miss_abort(struct CDynamicTypeCacheMissData *pData, unsigned long ulPointer, unsigned long ulHash)
Definition: kern_ubsan.c:830
void __ubsan_handle_nullability_arg_abort(struct CNonNullArgData *pData)
Definition: kern_ubsan.c:1003
#define DIVREM_STRING
Definition: kern_ubsan.c:101
static void HandleInvalidBuiltin(bool isFatal, struct CInvalidBuiltinData *pData)
Definition: kern_ubsan.c:514
void __ubsan_handle_invalid_builtin_abort(struct CInvalidBuiltinData *pData)
Definition: kern_ubsan.c:884
static void HandleTypeMismatch(bool isFatal, struct CSourceLocation *mLocation, struct CTypeDescriptor *mType, unsigned long mLogAlignment, uint8_t mTypeCheckKind, unsigned long ulPointer)
Definition: kern_ubsan.c:405
static void DeserializeLocation(char *pBuffer, size_t zBUfferLength, struct CSourceLocation *pLocation)
Definition: kern_ubsan.c:1315
void __ubsan_handle_builtin_unreachable(struct CUnreachableData *pData)
Definition: kern_ubsan.c:767
static longest llliGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
Definition: kern_ubsan.c:1475
static void HandleBuiltinUnreachable(bool isFatal, struct CUnreachableData *pData)
Definition: kern_ubsan.c:389
void __ubsan_handle_alignment_assumption_abort(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
Definition: kern_ubsan.c:758
__FBSDID("$FreeBSD$")
#define ACK_REPORTED
Definition: kern_ubsan.c:96
static void HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult)
Definition: kern_ubsan.c:686
static void HandleOutOfBounds(bool isFatal, struct COutOfBoundsData *pData, unsigned long ulIndex)
Definition: kern_ubsan.c:448
static void DeserializeNumberUnsigned(char *pBuffer, size_t zBUfferLength, struct CTypeDescriptor *pType, ulongest L)
Definition: kern_ubsan.c:1375
#define KIND_INTEGER
Definition: kern_ubsan.c:142
#define NUMBER_MAXLEN
Definition: kern_ubsan.c:111
static void HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
Definition: kern_ubsan.c:664
void __ubsan_handle_load_invalid_value(struct CInvalidValueData *pData, unsigned long ulVal)
Definition: kern_ubsan.c:893
static void HandleShiftOutOfBounds(bool isFatal, struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:466
void __ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:731
#define __BIT(x)
Definition: kern_ubsan.c:59
#define WIDTH_128
Definition: kern_ubsan.c:120
static void HandleFunctionTypeMismatch(bool isFatal, struct CFunctionTypeMismatchData *pData, unsigned long ulFunction)
Definition: kern_ubsan.c:530
void __ubsan_handle_nonnull_arg_abort(struct CNonNullArgData *pData)
Definition: kern_ubsan.c:965
#define KIND_UNKNOWN
Definition: kern_ubsan.c:144
void __ubsan_handle_nullability_return_v1(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
Definition: kern_ubsan.c:1012
void __ubsan_handle_invalid_builtin(struct CInvalidBuiltinData *pData)
Definition: kern_ubsan.c:875
void __ubsan_handle_type_mismatch_v1_abort(struct CTypeMismatchData_v1 *pData, unsigned long ulPointer)
Definition: kern_ubsan.c:1131
void __ubsan_handle_nullability_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
Definition: kern_ubsan.c:1022
void __ubsan_handle_negate_overflow(struct COverflowData *pData, unsigned long ulOldVal)
Definition: kern_ubsan.c:938
void __ubsan_handle_nonnull_return_v1_abort(struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer)
Definition: kern_ubsan.c:984
#define CFI_VMFCALL
Definition: kern_ubsan.c:109
static size_t zDeserializeTypeWidth(struct CTypeDescriptor *pType)
Definition: kern_ubsan.c:1290
static const char * DeserializeBuiltinCheckKind(uint8_t hhuBuiltinCheckKind)
Definition: kern_ubsan.c:1651
#define ASSERT(x)
Definition: kern_ubsan.c:56
static void static bool isAlreadyReported(struct CSourceLocation *pLocation)
Definition: kern_ubsan.c:1268
void __ubsan_handle_type_mismatch_abort(struct CTypeMismatchData *pData, unsigned long ulPointer)
Definition: kern_ubsan.c:1113
void __ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer)
Definition: kern_ubsan.c:776
static bool isShiftExponentTooLarge(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber, size_t zWidth)
Definition: kern_ubsan.c:1696
int64_t longest
Definition: kern_ubsan.c:128
#define NUMBER_SIGNED_BIT
Definition: kern_ubsan.c:122
void __ubsan_get_current_report_data(const char **ppOutIssueKind, const char **ppOutMessage, const char **ppOutFilename, uint32_t *pOutLine, uint32_t *pOutCol, char **ppOutMemoryAddr)
Definition: kern_ubsan.c:1158
void __ubsan_handle_divrem_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:803
#define REINTERPRET_CAST(__dt, __st)
Definition: kern_ubsan.c:93
#define KIND_FLOAT
Definition: kern_ubsan.c:143
static ulongest llluGetNumber(char *szLocation, struct CTypeDescriptor *pType, unsigned long ulNumber)
Definition: kern_ubsan.c:1518
static void HandleVlaBoundNotPositive(bool isFatal, struct CVLABoundData *pData, unsigned long ulBound)
Definition: kern_ubsan.c:430
void __ubsan_handle_nullability_arg(struct CNonNullArgData *pData)
Definition: kern_ubsan.c:994
static void HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation)
Definition: kern_ubsan.c:351
#define WIDTH_80
Definition: kern_ubsan.c:118
static const char * DeserializeTypeCheckKind(uint8_t hhuTypeCheckKind)
Definition: kern_ubsan.c:1628
#define PLUS_STRING
Definition: kern_ubsan.c:99
void __ubsan_handle_out_of_bounds(struct COutOfBoundsData *pData, unsigned long ulIndex)
Definition: kern_ubsan.c:1032
void __ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable)
Definition: kern_ubsan.c:785
#define __SHIFTOUT(__x, __mask)
Definition: kern_ubsan.c:61
#define MINUS_STRING
Definition: kern_ubsan.c:100
void __ubsan_handle_shift_out_of_bounds_abort(struct CShiftOutOfBoundsData *pData, unsigned long ulLHS, unsigned long ulRHS)
Definition: kern_ubsan.c:1077
#define MUL_STRING
Definition: kern_ubsan.c:98
#define F(x, y, z)
Definition: md4c.c:70
struct CSourceLocation mLocation
Definition: kern_ubsan.c:247
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:249
struct CSourceLocation mAssumptionLocation
Definition: kern_ubsan.c:248
uint8_t mCheckKind
Definition: kern_ubsan.c:168
struct CSourceLocation mLocation
Definition: kern_ubsan.c:169
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:170
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:175
struct CSourceLocation mLocation
Definition: kern_ubsan.c:174
struct CSourceLocation mLocation
Definition: kern_ubsan.c:241
struct CTypeDescriptor * mToType
Definition: kern_ubsan.c:243
struct CTypeDescriptor * mFromType
Definition: kern_ubsan.c:242
struct CSourceLocation mLocation
Definition: kern_ubsan.c:181
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:182
struct CSourceLocation mLocation
Definition: kern_ubsan.c:186
struct CSourceLocation mLocation
Definition: kern_ubsan.c:191
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:192
struct CSourceLocation mLocation
Definition: kern_ubsan.c:196
struct CSourceLocation mAttributeLocation
Definition: kern_ubsan.c:197
struct CSourceLocation mAttributeLocation
Definition: kern_ubsan.c:202
struct CSourceLocation mLocation
Definition: kern_ubsan.c:206
struct CTypeDescriptor * mArrayType
Definition: kern_ubsan.c:207
struct CTypeDescriptor * mIndexType
Definition: kern_ubsan.c:208
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:160
struct CSourceLocation mLocation
Definition: kern_ubsan.c:159
struct CSourceLocation mLocation
Definition: kern_ubsan.c:212
struct CTypeDescriptor * mRHSType
Definition: kern_ubsan.c:218
struct CTypeDescriptor * mLHSType
Definition: kern_ubsan.c:217
struct CSourceLocation mLocation
Definition: kern_ubsan.c:216
char * mFilename
Definition: kern_ubsan.c:147
uint32_t mColumn
Definition: kern_ubsan.c:149
uint32_t mLine
Definition: kern_ubsan.c:148
uint16_t mTypeKind
Definition: kern_ubsan.c:153
uint16_t mTypeInfo
Definition: kern_ubsan.c:154
uint8_t mTypeName[1]
Definition: kern_ubsan.c:155
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:230
struct CSourceLocation mLocation
Definition: kern_ubsan.c:229
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:223
unsigned long mLogAlignment
Definition: kern_ubsan.c:224
uint8_t mTypeCheckKind
Definition: kern_ubsan.c:225
struct CSourceLocation mLocation
Definition: kern_ubsan.c:222
struct CSourceLocation mLocation
Definition: kern_ubsan.c:164
struct CTypeDescriptor * mType
Definition: kern_ubsan.c:237
struct CSourceLocation mLocation
Definition: kern_ubsan.c:236
int vprintf(const char *fmt, va_list ap)
Definition: subr_prf.c:410
int snprintf(char *str, size_t size, const char *format,...)
Definition: subr_prf.c:550
struct stat * buf