253 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// Entry points to the runtime library for Clang's undefined behavior sanitizer.10//11//===----------------------------------------------------------------------===//12#ifndef UBSAN_HANDLERS_H13#define UBSAN_HANDLERS_H14 15#include "ubsan_value.h"16 17namespace __ubsan {18 19struct 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 misaligned37/// pointer, a null pointer, or a pointer to insufficient storage for the38/// type.39RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer)40 41struct 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.49RECOVERABLE(alignment_assumption, AlignmentAssumptionData *Data,50 ValueHandle Pointer, ValueHandle Alignment, ValueHandle Offset)51 52struct OverflowData {53 SourceLocation Loc;54 const TypeDescriptor &Type;55};56 57/// \brief Handle an integer addition overflow.58RECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)59 60/// \brief Handle an integer subtraction overflow.61RECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)62 63/// \brief Handle an integer multiplication overflow.64RECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)65 66/// \brief Handle a signed integer overflow for a unary negate operator.67RECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal)68 69/// \brief Handle an INT_MIN/-1 overflow or division by zero.70RECOVERABLE(divrem_overflow, OverflowData *Data,71 ValueHandle LHS, ValueHandle RHS)72 73struct 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 where80/// the LHS is negative or overflows.81RECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data,82 ValueHandle LHS, ValueHandle RHS)83 84struct OutOfBoundsData {85 SourceLocation Loc;86 const TypeDescriptor &ArrayType;87 const TypeDescriptor &IndexType;88};89 90/// \brief Handle an array index out of bounds error.91RECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index)92 93/// \brief Handle an local object access out of bounds error.94RECOVERABLE(local_out_of_bounds)95 96struct UnreachableData {97 SourceLocation Loc;98};99 100/// \brief Handle a __builtin_unreachable which is reached.101UNRECOVERABLE(builtin_unreachable, UnreachableData *Data)102/// \brief Handle reaching the end of a value-returning function.103UNRECOVERABLE(missing_return, UnreachableData *Data)104 105struct VLABoundData {106 SourceLocation Loc;107 const TypeDescriptor &Type;108};109 110/// \brief Handle a VLA with a non-positive bound.111RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound)112 113// Keeping this around for binary compatibility with (sanitized) programs114// compiled with older compilers.115struct FloatCastOverflowData {116 const TypeDescriptor &FromType;117 const TypeDescriptor &ToType;118};119 120struct 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*128RECOVERABLE(float_cast_overflow, void *Data, ValueHandle From)129 130struct InvalidValueData {131 SourceLocation Loc;132 const TypeDescriptor &Type;133};134 135/// \brief Handle a load of an invalid value for the type.136RECOVERABLE(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.cpp140enum 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 148struct 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.157RECOVERABLE(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.h162enum BuiltinCheckKind : unsigned char {163 BCK_CTZPassedZero,164 BCK_CLZPassedZero,165 BCK_AssumePassedFalse,166};167 168struct InvalidBuiltinData {169 SourceLocation Loc;170 unsigned char Kind;171};172 173/// Handle a builtin called in an invalid way.174RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data)175 176struct InvalidObjCCast {177 SourceLocation Loc;178 const TypeDescriptor &ExpectedType;179};180 181/// Handle an invalid ObjC cast.182RECOVERABLE(invalid_objc_cast, InvalidObjCCast *Data, ValueHandle Pointer)183 184struct NonNullReturnData {185 SourceLocation AttrLoc;186};187 188/// \brief Handle returning null from function with the returns_nonnull189/// attribute, or a return type annotated with _Nonnull.190RECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc)191RECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc)192 193struct NonNullArgData {194 SourceLocation Loc;195 SourceLocation AttrLoc;196 int ArgIndex;197};198 199/// \brief Handle passing null pointer to a function parameter with the nonnull200/// attribute, or a _Nonnull type annotation.201RECOVERABLE(nonnull_arg, NonNullArgData *Data)202RECOVERABLE(nullability_arg, NonNullArgData *Data)203 204struct PointerOverflowData {205 SourceLocation Loc;206};207 208RECOVERABLE(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.h213enum 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 223struct CFICheckFailData {224 CFITypeCheckKind CheckKind;225 SourceLocation Loc;226 const TypeDescriptor &Type;227};228 229/// \brief Handle control flow integrity failures.230RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function,231 uptr VtableIsValid)232 233struct ReportOptions;234 235extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_cfi_bad_type(236 CFICheckFailData *Data, ValueHandle Vtable, bool ValidVtable,237 ReportOptions Opts);238 239struct FunctionTypeMismatchData {240 SourceLocation Loc;241 const TypeDescriptor &Type;242};243 244extern "C" SANITIZER_INTERFACE_ATTRIBUTE void245__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,246 ValueHandle Val);247extern "C" SANITIZER_INTERFACE_ATTRIBUTE void248__ubsan_handle_function_type_mismatch_abort(FunctionTypeMismatchData *Data,249 ValueHandle Val);250}251 252#endif // UBSAN_HANDLERS_H253