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 unsigned int BitfieldBits; 151 }; 152 153 /// \brief Implict conversion that changed the value. 154 RECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src, 155 ValueHandle Dst) 156 157 /// Known builtin check kinds. 158 /// Keep in sync with the enum of the same name in CodeGenFunction.h 159 enum BuiltinCheckKind : unsigned char { 160 BCK_CTZPassedZero, 161 BCK_CLZPassedZero, 162 }; 163 164 struct InvalidBuiltinData { 165 SourceLocation Loc; 166 unsigned char Kind; 167 }; 168 169 /// Handle a builtin called in an invalid way. 170 RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data) 171 172 struct InvalidObjCCast { 173 SourceLocation Loc; 174 const TypeDescriptor &ExpectedType; 175 }; 176 177 /// Handle an invalid ObjC cast. 178 RECOVERABLE(invalid_objc_cast, InvalidObjCCast *Data, ValueHandle Pointer) 179 180 struct NonNullReturnData { 181 SourceLocation AttrLoc; 182 }; 183 184 /// \brief Handle returning null from function with the returns_nonnull 185 /// attribute, or a return type annotated with _Nonnull. 186 RECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 187 RECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 188 189 struct NonNullArgData { 190 SourceLocation Loc; 191 SourceLocation AttrLoc; 192 int ArgIndex; 193 }; 194 195 /// \brief Handle passing null pointer to a function parameter with the nonnull 196 /// attribute, or a _Nonnull type annotation. 197 RECOVERABLE(nonnull_arg, NonNullArgData *Data) 198 RECOVERABLE(nullability_arg, NonNullArgData *Data) 199 200 struct PointerOverflowData { 201 SourceLocation Loc; 202 }; 203 204 RECOVERABLE(pointer_overflow, PointerOverflowData *Data, ValueHandle Base, 205 ValueHandle Result) 206 207 /// \brief Known CFI check kinds. 208 /// Keep in sync with the enum of the same name in CodeGenFunction.h 209 enum CFITypeCheckKind : unsigned char { 210 CFITCK_VCall, 211 CFITCK_NVCall, 212 CFITCK_DerivedCast, 213 CFITCK_UnrelatedCast, 214 CFITCK_ICall, 215 CFITCK_NVMFCall, 216 CFITCK_VMFCall, 217 }; 218 219 struct CFICheckFailData { 220 CFITypeCheckKind CheckKind; 221 SourceLocation Loc; 222 const TypeDescriptor &Type; 223 }; 224 225 /// \brief Handle control flow integrity failures. 226 RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, 227 uptr VtableIsValid) 228 229 struct ReportOptions; 230 231 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_cfi_bad_type( 232 CFICheckFailData *Data, ValueHandle Vtable, bool ValidVtable, 233 ReportOptions Opts); 234 235 struct FunctionTypeMismatchData { 236 SourceLocation Loc; 237 const TypeDescriptor &Type; 238 }; 239 240 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void 241 __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data, 242 ValueHandle Val); 243 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void 244 __ubsan_handle_function_type_mismatch_abort(FunctionTypeMismatchData *Data, 245 ValueHandle Val); 246 } 247 248 #endif // UBSAN_HANDLERS_H 249