1 //===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Entry points to the runtime library for Clang's undefined behavior sanitizer. 10 // 11 //===----------------------------------------------------------------------===// 12 #ifndef UBSAN_HANDLERS_H 13 #define UBSAN_HANDLERS_H 14 15 #include "ubsan_value.h" 16 17 namespace __ubsan { 18 19 struct TypeMismatchData { 20 SourceLocation Loc; 21 const TypeDescriptor &Type; 22 unsigned char LogAlignment; 23 unsigned char TypeCheckKind; 24 }; 25 26 #define UNRECOVERABLE(checkname, ...) \ 27 extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ 28 void __ubsan_handle_ ## checkname( __VA_ARGS__ ); 29 30 #define RECOVERABLE(checkname, ...) \ 31 extern "C" SANITIZER_INTERFACE_ATTRIBUTE \ 32 void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \ 33 extern "C" SANITIZER_INTERFACE_ATTRIBUTE NORETURN \ 34 void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ ); 35 36 /// \brief Handle a runtime type check failure, caused by either a misaligned 37 /// pointer, a null pointer, or a pointer to insufficient storage for the 38 /// type. 39 RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer) 40 41 struct AlignmentAssumptionData { 42 SourceLocation Loc; 43 SourceLocation AssumptionLoc; 44 const TypeDescriptor &Type; 45 }; 46 47 /// \brief Handle a runtime alignment assumption check failure, 48 /// caused by a misaligned pointer. 49 RECOVERABLE(alignment_assumption, AlignmentAssumptionData *Data, 50 ValueHandle Pointer, ValueHandle Alignment, ValueHandle Offset) 51 52 struct OverflowData { 53 SourceLocation Loc; 54 const TypeDescriptor &Type; 55 }; 56 57 /// \brief Handle an integer addition overflow. 58 RECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 59 60 /// \brief Handle an integer subtraction overflow. 61 RECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 62 63 /// \brief Handle an integer multiplication overflow. 64 RECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS) 65 66 /// \brief Handle a signed integer overflow for a unary negate operator. 67 RECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal) 68 69 /// \brief Handle an INT_MIN/-1 overflow or division by zero. 70 RECOVERABLE(divrem_overflow, OverflowData *Data, 71 ValueHandle LHS, ValueHandle RHS) 72 73 struct ShiftOutOfBoundsData { 74 SourceLocation Loc; 75 const TypeDescriptor &LHSType; 76 const TypeDescriptor &RHSType; 77 }; 78 79 /// \brief Handle a shift where the RHS is out of bounds or a left shift where 80 /// the LHS is negative or overflows. 81 RECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data, 82 ValueHandle LHS, ValueHandle RHS) 83 84 struct OutOfBoundsData { 85 SourceLocation Loc; 86 const TypeDescriptor &ArrayType; 87 const TypeDescriptor &IndexType; 88 }; 89 90 /// \brief Handle an array index out of bounds error. 91 RECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index) 92 93 struct UnreachableData { 94 SourceLocation Loc; 95 }; 96 97 /// \brief Handle a __builtin_unreachable which is reached. 98 UNRECOVERABLE(builtin_unreachable, UnreachableData *Data) 99 /// \brief Handle reaching the end of a value-returning function. 100 UNRECOVERABLE(missing_return, UnreachableData *Data) 101 102 struct VLABoundData { 103 SourceLocation Loc; 104 const TypeDescriptor &Type; 105 }; 106 107 /// \brief Handle a VLA with a non-positive bound. 108 RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound) 109 110 // Keeping this around for binary compatibility with (sanitized) programs 111 // compiled with older compilers. 112 struct FloatCastOverflowData { 113 const TypeDescriptor &FromType; 114 const TypeDescriptor &ToType; 115 }; 116 117 struct FloatCastOverflowDataV2 { 118 SourceLocation Loc; 119 const TypeDescriptor &FromType; 120 const TypeDescriptor &ToType; 121 }; 122 123 /// Handle overflow in a conversion to or from a floating-point type. 124 /// void *Data is one of FloatCastOverflowData* or FloatCastOverflowDataV2* 125 RECOVERABLE(float_cast_overflow, void *Data, ValueHandle From) 126 127 struct InvalidValueData { 128 SourceLocation Loc; 129 const TypeDescriptor &Type; 130 }; 131 132 /// \brief Handle a load of an invalid value for the type. 133 RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val) 134 135 /// Known implicit conversion check kinds. 136 /// Keep in sync with the enum of the same name in CGExprScalar.cpp 137 enum ImplicitConversionCheckKind : unsigned char { 138 ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. 139 ICCK_UnsignedIntegerTruncation = 1, 140 ICCK_SignedIntegerTruncation = 2, 141 ICCK_IntegerSignChange = 3, 142 ICCK_SignedIntegerTruncationOrSignChange = 4, 143 }; 144 145 struct ImplicitConversionData { 146 SourceLocation Loc; 147 const TypeDescriptor &FromType; 148 const TypeDescriptor &ToType; 149 /* ImplicitConversionCheckKind */ unsigned char Kind; 150 }; 151 152 /// \brief Implict conversion that changed the value. 153 RECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src, 154 ValueHandle Dst) 155 156 /// Known builtin check kinds. 157 /// Keep in sync with the enum of the same name in CodeGenFunction.h 158 enum BuiltinCheckKind : unsigned char { 159 BCK_CTZPassedZero, 160 BCK_CLZPassedZero, 161 }; 162 163 struct InvalidBuiltinData { 164 SourceLocation Loc; 165 unsigned char Kind; 166 }; 167 168 /// Handle a builtin called in an invalid way. 169 RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data) 170 171 struct NonNullReturnData { 172 SourceLocation AttrLoc; 173 }; 174 175 /// \brief Handle returning null from function with the returns_nonnull 176 /// attribute, or a return type annotated with _Nonnull. 177 RECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 178 RECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 179 180 struct NonNullArgData { 181 SourceLocation Loc; 182 SourceLocation AttrLoc; 183 int ArgIndex; 184 }; 185 186 /// \brief Handle passing null pointer to a function parameter with the nonnull 187 /// attribute, or a _Nonnull type annotation. 188 RECOVERABLE(nonnull_arg, NonNullArgData *Data) 189 RECOVERABLE(nullability_arg, NonNullArgData *Data) 190 191 struct PointerOverflowData { 192 SourceLocation Loc; 193 }; 194 195 RECOVERABLE(pointer_overflow, PointerOverflowData *Data, ValueHandle Base, 196 ValueHandle Result) 197 198 /// \brief Known CFI check kinds. 199 /// Keep in sync with the enum of the same name in CodeGenFunction.h 200 enum CFITypeCheckKind : unsigned char { 201 CFITCK_VCall, 202 CFITCK_NVCall, 203 CFITCK_DerivedCast, 204 CFITCK_UnrelatedCast, 205 CFITCK_ICall, 206 CFITCK_NVMFCall, 207 CFITCK_VMFCall, 208 }; 209 210 struct CFICheckFailData { 211 CFITypeCheckKind CheckKind; 212 SourceLocation Loc; 213 const TypeDescriptor &Type; 214 }; 215 216 /// \brief Handle control flow integrity failures. 217 RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, 218 uptr VtableIsValid) 219 220 struct ReportOptions; 221 222 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_cfi_bad_type( 223 CFICheckFailData *Data, ValueHandle Vtable, bool ValidVtable, 224 ReportOptions Opts); 225 226 } 227 228 #endif // UBSAN_HANDLERS_H 229