1*344aa361SAndroid Build Coastguard Worker /* 2*344aa361SAndroid Build Coastguard Worker * Copyright (c) 2019 Google Inc. All rights reserved 3*344aa361SAndroid Build Coastguard Worker * 4*344aa361SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining 5*344aa361SAndroid Build Coastguard Worker * a copy of this software and associated documentation files 6*344aa361SAndroid Build Coastguard Worker * (the "Software"), to deal in the Software without restriction, 7*344aa361SAndroid Build Coastguard Worker * including without limitation the rights to use, copy, modify, merge, 8*344aa361SAndroid Build Coastguard Worker * publish, distribute, sublicense, and/or sell copies of the Software, 9*344aa361SAndroid Build Coastguard Worker * and to permit persons to whom the Software is furnished to do so, 10*344aa361SAndroid Build Coastguard Worker * subject to the following conditions: 11*344aa361SAndroid Build Coastguard Worker * 12*344aa361SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be 13*344aa361SAndroid Build Coastguard Worker * included in all copies or substantial portions of the Software. 14*344aa361SAndroid Build Coastguard Worker * 15*344aa361SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16*344aa361SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17*344aa361SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18*344aa361SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19*344aa361SAndroid Build Coastguard Worker * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20*344aa361SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21*344aa361SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22*344aa361SAndroid Build Coastguard Worker */ 23*344aa361SAndroid Build Coastguard Worker 24*344aa361SAndroid Build Coastguard Worker /* 25*344aa361SAndroid Build Coastguard Worker * LLVM UBSan handler signatures and data structures. 26*344aa361SAndroid Build Coastguard Worker * 27*344aa361SAndroid Build Coastguard Worker * Clang's headers for this are C++, so we cannot use them directly. 28*344aa361SAndroid Build Coastguard Worker * This ia a C-styled rewrite. 29*344aa361SAndroid Build Coastguard Worker * See LLVM's ubsan_handlers.h for reference. 30*344aa361SAndroid Build Coastguard Worker */ 31*344aa361SAndroid Build Coastguard Worker #pragma once 32*344aa361SAndroid Build Coastguard Worker 33*344aa361SAndroid Build Coastguard Worker #include <stdint.h> 34*344aa361SAndroid Build Coastguard Worker 35*344aa361SAndroid Build Coastguard Worker #include "ubsan_value.h" 36*344aa361SAndroid Build Coastguard Worker 37*344aa361SAndroid Build Coastguard Worker const char* type_check_kinds[] = {"load of", 38*344aa361SAndroid Build Coastguard Worker "store to", 39*344aa361SAndroid Build Coastguard Worker "reference binding to", 40*344aa361SAndroid Build Coastguard Worker "member access within", 41*344aa361SAndroid Build Coastguard Worker "member call on", 42*344aa361SAndroid Build Coastguard Worker "constructor call on", 43*344aa361SAndroid Build Coastguard Worker "downcast of", 44*344aa361SAndroid Build Coastguard Worker "downcast of", 45*344aa361SAndroid Build Coastguard Worker "upcast of", 46*344aa361SAndroid Build Coastguard Worker "cast to virtual base of", 47*344aa361SAndroid Build Coastguard Worker "_Nonnull binding to", 48*344aa361SAndroid Build Coastguard Worker "dynamic operation on"}; 49*344aa361SAndroid Build Coastguard Worker 50*344aa361SAndroid Build Coastguard Worker struct type_mismatch_data { 51*344aa361SAndroid Build Coastguard Worker struct source_location loc; 52*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* type; 53*344aa361SAndroid Build Coastguard Worker uint8_t log_alignment; 54*344aa361SAndroid Build Coastguard Worker uint8_t type_check_kind; 55*344aa361SAndroid Build Coastguard Worker }; 56*344aa361SAndroid Build Coastguard Worker 57*344aa361SAndroid Build Coastguard Worker struct alignment_assumption_data { 58*344aa361SAndroid Build Coastguard Worker struct source_location loc; 59*344aa361SAndroid Build Coastguard Worker struct source_location assumption_loc; 60*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* type; 61*344aa361SAndroid Build Coastguard Worker }; 62*344aa361SAndroid Build Coastguard Worker 63*344aa361SAndroid Build Coastguard Worker struct overflow_data { 64*344aa361SAndroid Build Coastguard Worker struct source_location loc; 65*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* type; 66*344aa361SAndroid Build Coastguard Worker }; 67*344aa361SAndroid Build Coastguard Worker 68*344aa361SAndroid Build Coastguard Worker struct shift_out_of_bounds_data { 69*344aa361SAndroid Build Coastguard Worker struct source_location loc; 70*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* lhs_type; 71*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* rhs_type; 72*344aa361SAndroid Build Coastguard Worker }; 73*344aa361SAndroid Build Coastguard Worker 74*344aa361SAndroid Build Coastguard Worker struct out_of_bounds_data { 75*344aa361SAndroid Build Coastguard Worker struct source_location loc; 76*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* array_type; 77*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* index_type; 78*344aa361SAndroid Build Coastguard Worker }; 79*344aa361SAndroid Build Coastguard Worker 80*344aa361SAndroid Build Coastguard Worker struct unreachable_data { 81*344aa361SAndroid Build Coastguard Worker struct source_location loc; 82*344aa361SAndroid Build Coastguard Worker }; 83*344aa361SAndroid Build Coastguard Worker 84*344aa361SAndroid Build Coastguard Worker struct vla_bound_data { 85*344aa361SAndroid Build Coastguard Worker struct source_location loc; 86*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* type; 87*344aa361SAndroid Build Coastguard Worker }; 88*344aa361SAndroid Build Coastguard Worker 89*344aa361SAndroid Build Coastguard Worker struct float_cast_overflow_data { 90*344aa361SAndroid Build Coastguard Worker struct source_location loc; 91*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* from_type; 92*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* to_type; 93*344aa361SAndroid Build Coastguard Worker }; 94*344aa361SAndroid Build Coastguard Worker 95*344aa361SAndroid Build Coastguard Worker struct invalid_value_data { 96*344aa361SAndroid Build Coastguard Worker struct source_location loc; 97*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* type; 98*344aa361SAndroid Build Coastguard Worker }; 99*344aa361SAndroid Build Coastguard Worker 100*344aa361SAndroid Build Coastguard Worker enum implicit_conversion_check_kind { 101*344aa361SAndroid Build Coastguard Worker ICK_LEGACY_TRUNC = 0, 102*344aa361SAndroid Build Coastguard Worker ICK_UNSIGNED_TRUNC = 1, 103*344aa361SAndroid Build Coastguard Worker ICK_SIGNED_TRUNC = 2, 104*344aa361SAndroid Build Coastguard Worker ICK_SIGN_CHANGE = 3, 105*344aa361SAndroid Build Coastguard Worker ICK_SIGNED_TRUNC_OR_SIGN_CHANGE = 4, 106*344aa361SAndroid Build Coastguard Worker }; 107*344aa361SAndroid Build Coastguard Worker 108*344aa361SAndroid Build Coastguard Worker static const char* implicit_conversion_check_kinds[] = { 109*344aa361SAndroid Build Coastguard Worker "legacy truncation", 110*344aa361SAndroid Build Coastguard Worker "unsigned truncation", 111*344aa361SAndroid Build Coastguard Worker "signed truncation", 112*344aa361SAndroid Build Coastguard Worker "sign change", 113*344aa361SAndroid Build Coastguard Worker "signed truncation or sign change", 114*344aa361SAndroid Build Coastguard Worker }; 115*344aa361SAndroid Build Coastguard Worker 116*344aa361SAndroid Build Coastguard Worker struct implicit_conversion_data { 117*344aa361SAndroid Build Coastguard Worker struct source_location loc; 118*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* from_type; 119*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* to_type; 120*344aa361SAndroid Build Coastguard Worker uint8_t check_kind; 121*344aa361SAndroid Build Coastguard Worker }; 122*344aa361SAndroid Build Coastguard Worker 123*344aa361SAndroid Build Coastguard Worker enum builtin_check_kind { 124*344aa361SAndroid Build Coastguard Worker BCK_CTZ_PASSED_ZERO = 0, 125*344aa361SAndroid Build Coastguard Worker BCK_CLZ_PASSED_ZERO = 1, 126*344aa361SAndroid Build Coastguard Worker }; 127*344aa361SAndroid Build Coastguard Worker 128*344aa361SAndroid Build Coastguard Worker struct invalid_builtin_data { 129*344aa361SAndroid Build Coastguard Worker struct source_location loc; 130*344aa361SAndroid Build Coastguard Worker uint8_t check_kind; 131*344aa361SAndroid Build Coastguard Worker }; 132*344aa361SAndroid Build Coastguard Worker 133*344aa361SAndroid Build Coastguard Worker struct function_type_mismatch_data { 134*344aa361SAndroid Build Coastguard Worker struct source_location loc; 135*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* type; 136*344aa361SAndroid Build Coastguard Worker }; 137*344aa361SAndroid Build Coastguard Worker 138*344aa361SAndroid Build Coastguard Worker struct non_null_return_data { 139*344aa361SAndroid Build Coastguard Worker struct source_location attr_loc; 140*344aa361SAndroid Build Coastguard Worker }; 141*344aa361SAndroid Build Coastguard Worker 142*344aa361SAndroid Build Coastguard Worker struct non_null_arg_data { 143*344aa361SAndroid Build Coastguard Worker struct source_location loc; 144*344aa361SAndroid Build Coastguard Worker struct source_location attr_loc; 145*344aa361SAndroid Build Coastguard Worker int arg_index; 146*344aa361SAndroid Build Coastguard Worker }; 147*344aa361SAndroid Build Coastguard Worker 148*344aa361SAndroid Build Coastguard Worker struct pointer_overflow_data { 149*344aa361SAndroid Build Coastguard Worker struct source_location loc; 150*344aa361SAndroid Build Coastguard Worker }; 151*344aa361SAndroid Build Coastguard Worker 152*344aa361SAndroid Build Coastguard Worker enum cfi_type_check_kind { 153*344aa361SAndroid Build Coastguard Worker CFI_TCK_VCALL, 154*344aa361SAndroid Build Coastguard Worker CFI_TCK_NVCALL, 155*344aa361SAndroid Build Coastguard Worker CFI_TCK_DERIVED_CAST, 156*344aa361SAndroid Build Coastguard Worker CFI_TCK_UNRELATED_CAST, 157*344aa361SAndroid Build Coastguard Worker CFI_TCK_ICALL, 158*344aa361SAndroid Build Coastguard Worker CFI_TCK_NVMFCALL, 159*344aa361SAndroid Build Coastguard Worker CFI_TCK_VMFCALL 160*344aa361SAndroid Build Coastguard Worker }; 161*344aa361SAndroid Build Coastguard Worker 162*344aa361SAndroid Build Coastguard Worker struct cfi_check_fail_data { 163*344aa361SAndroid Build Coastguard Worker uint8_t check_kind; 164*344aa361SAndroid Build Coastguard Worker struct source_location loc; 165*344aa361SAndroid Build Coastguard Worker const struct type_descriptor* type; 166*344aa361SAndroid Build Coastguard Worker }; 167*344aa361SAndroid Build Coastguard Worker 168*344aa361SAndroid Build Coastguard Worker #define UBSAN_HANDLER(checkname, ...) \ 169*344aa361SAndroid Build Coastguard Worker __attribute__((noinline)) void __ubsan_handle_##checkname(__VA_ARGS__) 170*344aa361SAndroid Build Coastguard Worker 171*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(type_mismatch, 172*344aa361SAndroid Build Coastguard Worker struct type_mismatch_data* data, 173*344aa361SAndroid Build Coastguard Worker value_handle_t val); 174*344aa361SAndroid Build Coastguard Worker 175*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(alignment_assumption, 176*344aa361SAndroid Build Coastguard Worker struct alignment_assumption_data* data, 177*344aa361SAndroid Build Coastguard Worker value_handle_t val, 178*344aa361SAndroid Build Coastguard Worker value_handle_t alignment, 179*344aa361SAndroid Build Coastguard Worker value_handle_t offset); 180*344aa361SAndroid Build Coastguard Worker 181*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(add_overflow, 182*344aa361SAndroid Build Coastguard Worker struct overflow_data* data, 183*344aa361SAndroid Build Coastguard Worker value_handle_t lhs, 184*344aa361SAndroid Build Coastguard Worker value_handle_t rhs); 185*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(sub_overflow, 186*344aa361SAndroid Build Coastguard Worker struct overflow_data* data, 187*344aa361SAndroid Build Coastguard Worker value_handle_t lhs, 188*344aa361SAndroid Build Coastguard Worker value_handle_t rhs); 189*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(mul_overflow, 190*344aa361SAndroid Build Coastguard Worker struct overflow_data* data, 191*344aa361SAndroid Build Coastguard Worker value_handle_t lhs, 192*344aa361SAndroid Build Coastguard Worker value_handle_t rhs); 193*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(negate_overflow, struct overflow_data* data, value_handle_t val); 194*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(divrem_overflow, 195*344aa361SAndroid Build Coastguard Worker struct overflow_data* data, 196*344aa361SAndroid Build Coastguard Worker value_handle_t lhs, 197*344aa361SAndroid Build Coastguard Worker value_handle_t rhs); 198*344aa361SAndroid Build Coastguard Worker 199*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(shift_out_of_bounds, 200*344aa361SAndroid Build Coastguard Worker struct shift_out_of_bounds_data* data, 201*344aa361SAndroid Build Coastguard Worker value_handle_t lhs, 202*344aa361SAndroid Build Coastguard Worker value_handle_t rhs); 203*344aa361SAndroid Build Coastguard Worker 204*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(out_of_bounds, 205*344aa361SAndroid Build Coastguard Worker struct out_of_bounds_data* data, 206*344aa361SAndroid Build Coastguard Worker value_handle_t index); 207*344aa361SAndroid Build Coastguard Worker 208*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(builtin_unreachable, struct unreachable_data* data); 209*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(missing_return, struct unreachable_data* data); 210*344aa361SAndroid Build Coastguard Worker 211*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(vla_bound_not_positive, 212*344aa361SAndroid Build Coastguard Worker struct vla_bound_data* data, 213*344aa361SAndroid Build Coastguard Worker value_handle_t bound); 214*344aa361SAndroid Build Coastguard Worker 215*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(float_cast_overflow, 216*344aa361SAndroid Build Coastguard Worker struct float_cast_overflow_data* data, 217*344aa361SAndroid Build Coastguard Worker value_handle_t from); 218*344aa361SAndroid Build Coastguard Worker 219*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(load_invalid_value, 220*344aa361SAndroid Build Coastguard Worker struct invalid_value_data* data, 221*344aa361SAndroid Build Coastguard Worker value_handle_t val); 222*344aa361SAndroid Build Coastguard Worker 223*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(implicit_conversion, 224*344aa361SAndroid Build Coastguard Worker struct implicit_conversion_data* data, 225*344aa361SAndroid Build Coastguard Worker value_handle_t src, 226*344aa361SAndroid Build Coastguard Worker value_handle_t dst); 227*344aa361SAndroid Build Coastguard Worker 228*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(invalid_builtin, struct invalid_builtin_data* data); 229*344aa361SAndroid Build Coastguard Worker 230*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(function_type_mismatch, 231*344aa361SAndroid Build Coastguard Worker struct function_type_mismatch_data* data, 232*344aa361SAndroid Build Coastguard Worker value_handle_t val); 233*344aa361SAndroid Build Coastguard Worker 234*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(nonnull_return_v1, 235*344aa361SAndroid Build Coastguard Worker struct non_null_return_data* data, 236*344aa361SAndroid Build Coastguard Worker struct source_location loc); 237*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(nullability_return_v1, 238*344aa361SAndroid Build Coastguard Worker struct non_null_return_data* data, 239*344aa361SAndroid Build Coastguard Worker struct source_location loc); 240*344aa361SAndroid Build Coastguard Worker 241*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(nonnull_arg, struct non_null_arg_data* data); 242*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(nullability_arg, struct non_null_arg_data* data); 243*344aa361SAndroid Build Coastguard Worker 244*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(pointer_overflow, 245*344aa361SAndroid Build Coastguard Worker struct pointer_overflow_data* data, 246*344aa361SAndroid Build Coastguard Worker value_handle_t base, 247*344aa361SAndroid Build Coastguard Worker value_handle_t result); 248*344aa361SAndroid Build Coastguard Worker 249*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(cfi_check_fail, 250*344aa361SAndroid Build Coastguard Worker struct cfi_check_fail_data* data, 251*344aa361SAndroid Build Coastguard Worker value_handle_t func, 252*344aa361SAndroid Build Coastguard Worker uintptr_t vtable_is_valid); 253*344aa361SAndroid Build Coastguard Worker 254*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(cfi_check_fail_abort, 255*344aa361SAndroid Build Coastguard Worker struct cfi_check_fail_data* data, 256*344aa361SAndroid Build Coastguard Worker value_handle_t func, 257*344aa361SAndroid Build Coastguard Worker uintptr_t vtable_is_valid); 258*344aa361SAndroid Build Coastguard Worker 259*344aa361SAndroid Build Coastguard Worker UBSAN_HANDLER(vla_bound_not_positive, 260*344aa361SAndroid Build Coastguard Worker struct vla_bound_data* data, 261*344aa361SAndroid Build Coastguard Worker value_handle_t val); 262