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 InvalidObjCCast { 172 SourceLocation Loc; 173 const TypeDescriptor &ExpectedType; 174 }; 175 176 /// Handle an invalid ObjC cast. 177 RECOVERABLE(invalid_objc_cast, InvalidObjCCast *Data, ValueHandle Pointer) 178 179 struct NonNullReturnData { 180 SourceLocation AttrLoc; 181 }; 182 183 /// \brief Handle returning null from function with the returns_nonnull 184 /// attribute, or a return type annotated with _Nonnull. 185 RECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 186 RECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 187 188 struct NonNullArgData { 189 SourceLocation Loc; 190 SourceLocation AttrLoc; 191 int ArgIndex; 192 }; 193 194 /// \brief Handle passing null pointer to a function parameter with the nonnull 195 /// attribute, or a _Nonnull type annotation. 196 RECOVERABLE(nonnull_arg, NonNullArgData *Data) 197 RECOVERABLE(nullability_arg, NonNullArgData *Data) 198 199 struct PointerOverflowData { 200 SourceLocation Loc; 201 }; 202 203 RECOVERABLE(pointer_overflow, PointerOverflowData *Data, ValueHandle Base, 204 ValueHandle Result) 205 206 /// \brief Known CFI check kinds. 207 /// Keep in sync with the enum of the same name in CodeGenFunction.h 208 enum CFITypeCheckKind : unsigned char { 209 CFITCK_VCall, 210 CFITCK_NVCall, 211 CFITCK_DerivedCast, 212 CFITCK_UnrelatedCast, 213 CFITCK_ICall, 214 CFITCK_NVMFCall, 215 CFITCK_VMFCall, 216 }; 217 218 struct CFICheckFailData { 219 CFITypeCheckKind CheckKind; 220 SourceLocation Loc; 221 const TypeDescriptor &Type; 222 }; 223 224 /// \brief Handle control flow integrity failures. 225 RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, 226 uptr VtableIsValid) 227 228 struct ReportOptions; 229 230 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_cfi_bad_type( 231 CFICheckFailData *Data, ValueHandle Vtable, bool ValidVtable, 232 ReportOptions Opts); 233 234 } 235 236 #endif // UBSAN_HANDLERS_H 237