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