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