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 /// \brief Handle an local object access out of bounds error. 94 RECOVERABLE(local_out_of_bounds) 95 96 struct UnreachableData { 97 SourceLocation Loc; 98 }; 99 100 /// \brief Handle a __builtin_unreachable which is reached. 101 UNRECOVERABLE(builtin_unreachable, UnreachableData *Data) 102 /// \brief Handle reaching the end of a value-returning function. 103 UNRECOVERABLE(missing_return, UnreachableData *Data) 104 105 struct VLABoundData { 106 SourceLocation Loc; 107 const TypeDescriptor &Type; 108 }; 109 110 /// \brief Handle a VLA with a non-positive bound. 111 RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound) 112 113 // Keeping this around for binary compatibility with (sanitized) programs 114 // compiled with older compilers. 115 struct FloatCastOverflowData { 116 const TypeDescriptor &FromType; 117 const TypeDescriptor &ToType; 118 }; 119 120 struct FloatCastOverflowDataV2 { 121 SourceLocation Loc; 122 const TypeDescriptor &FromType; 123 const TypeDescriptor &ToType; 124 }; 125 126 /// Handle overflow in a conversion to or from a floating-point type. 127 /// void *Data is one of FloatCastOverflowData* or FloatCastOverflowDataV2* 128 RECOVERABLE(float_cast_overflow, void *Data, ValueHandle From) 129 130 struct InvalidValueData { 131 SourceLocation Loc; 132 const TypeDescriptor &Type; 133 }; 134 135 /// \brief Handle a load of an invalid value for the type. 136 RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val) 137 138 /// Known implicit conversion check kinds. 139 /// Keep in sync with the enum of the same name in CGExprScalar.cpp 140 enum ImplicitConversionCheckKind : unsigned char { 141 ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. 142 ICCK_UnsignedIntegerTruncation = 1, 143 ICCK_SignedIntegerTruncation = 2, 144 ICCK_IntegerSignChange = 3, 145 ICCK_SignedIntegerTruncationOrSignChange = 4, 146 }; 147 148 struct ImplicitConversionData { 149 SourceLocation Loc; 150 const TypeDescriptor &FromType; 151 const TypeDescriptor &ToType; 152 /* ImplicitConversionCheckKind */ unsigned char Kind; 153 unsigned int BitfieldBits; 154 }; 155 156 /// \brief Implict conversion that changed the value. 157 RECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src, 158 ValueHandle Dst) 159 160 /// Known builtin check kinds. 161 /// Keep in sync with the enum of the same name in CodeGenFunction.h 162 enum BuiltinCheckKind : unsigned char { 163 BCK_CTZPassedZero, 164 BCK_CLZPassedZero, 165 BCK_AssumePassedFalse, 166 }; 167 168 struct InvalidBuiltinData { 169 SourceLocation Loc; 170 unsigned char Kind; 171 }; 172 173 /// Handle a builtin called in an invalid way. 174 RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data) 175 176 struct InvalidObjCCast { 177 SourceLocation Loc; 178 const TypeDescriptor &ExpectedType; 179 }; 180 181 /// Handle an invalid ObjC cast. 182 RECOVERABLE(invalid_objc_cast, InvalidObjCCast *Data, ValueHandle Pointer) 183 184 struct NonNullReturnData { 185 SourceLocation AttrLoc; 186 }; 187 188 /// \brief Handle returning null from function with the returns_nonnull 189 /// attribute, or a return type annotated with _Nonnull. 190 RECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 191 RECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc) 192 193 struct NonNullArgData { 194 SourceLocation Loc; 195 SourceLocation AttrLoc; 196 int ArgIndex; 197 }; 198 199 /// \brief Handle passing null pointer to a function parameter with the nonnull 200 /// attribute, or a _Nonnull type annotation. 201 RECOVERABLE(nonnull_arg, NonNullArgData *Data) 202 RECOVERABLE(nullability_arg, NonNullArgData *Data) 203 204 struct PointerOverflowData { 205 SourceLocation Loc; 206 }; 207 208 RECOVERABLE(pointer_overflow, PointerOverflowData *Data, ValueHandle Base, 209 ValueHandle Result) 210 211 /// \brief Known CFI check kinds. 212 /// Keep in sync with the enum of the same name in CodeGenFunction.h 213 enum CFITypeCheckKind : unsigned char { 214 CFITCK_VCall, 215 CFITCK_NVCall, 216 CFITCK_DerivedCast, 217 CFITCK_UnrelatedCast, 218 CFITCK_ICall, 219 CFITCK_NVMFCall, 220 CFITCK_VMFCall, 221 }; 222 223 struct CFICheckFailData { 224 CFITypeCheckKind CheckKind; 225 SourceLocation Loc; 226 const TypeDescriptor &Type; 227 }; 228 229 /// \brief Handle control flow integrity failures. 230 RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, 231 uptr VtableIsValid) 232 233 struct ReportOptions; 234 235 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_cfi_bad_type( 236 CFICheckFailData *Data, ValueHandle Vtable, bool ValidVtable, 237 ReportOptions Opts); 238 239 struct FunctionTypeMismatchData { 240 SourceLocation Loc; 241 const TypeDescriptor &Type; 242 }; 243 244 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void 245 __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data, 246 ValueHandle Val); 247 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void 248 __ubsan_handle_function_type_mismatch_abort(FunctionTypeMismatchData *Data, 249 ValueHandle Val); 250 } 251 252 #endif // UBSAN_HANDLERS_H 253