1 /* 2 * Copyright (c) 2018-2021 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #ifndef _UBSAN_H_ 30 #define _UBSAN_H_ 31 32 #include <stdint.h> 33 #include <stdbool.h> 34 35 struct san_type_desc { 36 uint16_t type; // 0: integer, 1: float 37 union { 38 struct { 39 uint16_t issigned : 1; 40 uint16_t width : 15; 41 }; /* int descriptor */ 42 struct { 43 uint16_t float_desc; 44 }; /* float descriptor */ 45 }; 46 const char name[]; 47 }; 48 49 struct san_src_loc { 50 const char *filename; 51 uint32_t line; 52 uint32_t col; 53 }; 54 55 struct ubsan_overflow_desc { 56 struct san_src_loc loc; 57 struct san_type_desc *ty; 58 }; 59 60 struct ubsan_unreachable_desc { 61 struct san_src_loc loc; 62 }; 63 64 struct ubsan_shift_desc { 65 struct san_src_loc loc; 66 struct san_type_desc *lhs_t; 67 struct san_type_desc *rhs_t; 68 }; 69 70 struct ubsan_align_desc { 71 struct san_src_loc loc; 72 struct san_type_desc *ty; 73 uint8_t align; 74 uint8_t kind; 75 }; 76 77 struct ubsan_ptroverflow_desc { 78 struct san_src_loc loc; 79 }; 80 81 struct ubsan_oob_desc { 82 struct san_src_loc loc; 83 struct san_type_desc *array_ty; 84 struct san_type_desc *index_ty; 85 }; 86 87 struct ubsan_load_invalid_desc { 88 struct san_src_loc loc; 89 struct san_type_desc *type; 90 }; 91 92 struct ubsan_nullability_arg_desc { 93 struct san_src_loc loc; 94 struct san_src_loc attr_loc; 95 int arg_index; 96 }; 97 98 struct ubsan_nullability_ret_desc { 99 struct san_src_loc loc; 100 }; 101 102 struct ubsan_missing_ret_desc { 103 struct san_src_loc loc; 104 }; 105 106 struct ubsan_float_desc { 107 struct san_src_loc loc; 108 struct san_type_desc *type_from; 109 struct san_type_desc *type_to; 110 }; 111 112 struct ubsan_implicit_conv_desc { 113 struct san_src_loc loc; 114 struct san_type_desc *type_from; 115 struct san_type_desc *type_to; 116 unsigned char kind; 117 }; 118 119 struct ubsan_func_type_mismatch_desc { 120 struct san_src_loc loc; 121 struct san_type_desc *type; 122 }; 123 124 struct ubsan_vla_bound_desc { 125 struct san_src_loc loc; 126 struct san_type_desc *type; 127 }; 128 129 struct ubsan_invalid_builtin { 130 struct san_src_loc loc; 131 unsigned char kind; 132 }; 133 134 OS_ENUM(ubsan_violation_type, uint8_t, 135 UBSAN_OVERFLOW_add = 1, 136 UBSAN_OVERFLOW_sub, 137 UBSAN_OVERFLOW_mul, 138 UBSAN_OVERFLOW_divrem, 139 UBSAN_OVERFLOW_negate, 140 UBSAN_UNREACHABLE, 141 UBSAN_SHIFT, 142 UBSAN_ALIGN, 143 UBSAN_POINTER_OVERFLOW, 144 UBSAN_OOB, 145 UBSAN_TYPE_MISMATCH, 146 UBSAN_LOAD_INVALID_VALUE, 147 UBSAN_NULLABILITY_ARG, 148 UBSAN_NULLABILITY_RETURN, 149 UBSAN_MISSING_RETURN, 150 UBSAN_FLOAT_CAST_OVERFLOW, 151 UBSAN_IMPLICIT_CONVERSION, 152 UBSAN_FUNCTION_TYPE_MISMATCH, 153 UBSAN_VLA_BOUND_NOT_POSITIVE, 154 UBSAN_INVALID_BUILTIN, 155 UBSAN_VIOLATION_MAX 156 ); 157 158 typedef struct ubsan_violation { 159 ubsan_violation_type_t ubsan_type; 160 uint64_t lhs; 161 uint64_t rhs; 162 union { 163 struct ubsan_overflow_desc *overflow; 164 struct ubsan_unreachable_desc *unreachable; 165 struct ubsan_shift_desc *shift; 166 struct ubsan_align_desc *align; 167 struct ubsan_ptroverflow_desc *ptroverflow; 168 struct ubsan_oob_desc *oob; 169 struct ubsan_load_invalid_desc *invalid; 170 struct ubsan_nullability_arg_desc *nonnull_arg; 171 struct ubsan_nullability_ret_desc *nonnull_ret; 172 struct ubsan_missing_ret_desc *missing_ret; 173 struct ubsan_float_desc *flt; 174 struct ubsan_implicit_conv_desc *implicit; 175 struct ubsan_func_type_mismatch_desc *func_mismatch; 176 struct ubsan_vla_bound_desc *vla_bound; 177 struct ubsan_invalid_builtin *invalid_builtin; 178 const char *func; 179 }; 180 struct san_src_loc *loc; 181 } ubsan_violation_t; 182 183 typedef struct ubsan_buf { 184 char *ub_buf; 185 size_t ub_buf_size; 186 size_t ub_written; 187 bool ub_err; 188 } ubsan_buf_t; 189 190 void ubsan_log_append(ubsan_violation_t *); 191 192 void ubsan_json_init(ubsan_buf_t *, char *, size_t); 193 void ubsan_json_begin(ubsan_buf_t *, size_t); 194 size_t ubsan_json_finish(ubsan_buf_t *); 195 bool ubsan_json_format(ubsan_violation_t *, ubsan_buf_t *); 196 197 /* 198 * UBSan ABI 199 */ 200 void __ubsan_handle_add_overflow(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 201 void __ubsan_handle_add_overflow_abort(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 202 void __ubsan_handle_builtin_unreachable(struct ubsan_unreachable_desc *); 203 void __ubsan_handle_divrem_overflow(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 204 void __ubsan_handle_divrem_overflow_abort(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 205 void __ubsan_handle_float_cast_overflow(struct ubsan_float_desc *, uint64_t); 206 void __ubsan_handle_float_cast_overflow_abort(struct ubsan_float_desc *, uint64_t); 207 void __ubsan_handle_function_type_mismatch(struct ubsan_func_type_mismatch_desc*, uint64_t); 208 void __ubsan_handle_function_type_mismatch_abort(struct ubsan_func_type_mismatch_desc *, uint64_t); 209 void __ubsan_handle_implicit_conversion(struct ubsan_implicit_conv_desc *, uint64_t, uint64_t); 210 void __ubsan_handle_implicit_conversion_abort(struct ubsan_implicit_conv_desc *, uint64_t, uint64_t); 211 void __ubsan_handle_invalid_builtin(struct ubsan_invalid_builtin *); 212 void __ubsan_handle_invalid_builtin_abort(struct ubsan_invalid_builtin *); 213 void __ubsan_handle_load_invalid_value(struct ubsan_load_invalid_desc *, uint64_t); 214 void __ubsan_handle_load_invalid_value_abort(struct ubsan_load_invalid_desc *, uint64_t); 215 void __ubsan_handle_missing_return(struct ubsan_missing_ret_desc *); 216 void __ubsan_handle_missing_return_abort(struct ubsan_missing_ret_desc *); 217 void __ubsan_handle_mul_overflow(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 218 void __ubsan_handle_mul_overflow_abort(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 219 void __ubsan_handle_negate_overflow(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 220 void __ubsan_handle_negate_overflow_abort(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 221 void __ubsan_handle_nonnull_arg(struct ubsan_nullability_arg_desc *); 222 void __ubsan_handle_nonnull_arg_abort(struct ubsan_nullability_arg_desc *); 223 void __ubsan_handle_nonnull_return_v1(struct ubsan_nullability_ret_desc *, uint64_t); 224 void __ubsan_handle_nonnull_return_v1_abort(struct ubsan_nullability_ret_desc *, uint64_t); 225 void __ubsan_handle_nullability_arg(struct ubsan_nullability_arg_desc *); 226 void __ubsan_handle_nullability_arg_abort(struct ubsan_nullability_arg_desc *); 227 void __ubsan_handle_nullability_return_v1(struct ubsan_nullability_ret_desc *, uint64_t); 228 void __ubsan_handle_nullability_return_v1_abort(struct ubsan_nullability_ret_desc *, uint64_t); 229 void __ubsan_handle_out_of_bounds(struct ubsan_oob_desc *, uint64_t idx); 230 void __ubsan_handle_out_of_bounds_abort(struct ubsan_oob_desc *, uint64_t idx); 231 void __ubsan_handle_pointer_overflow(struct ubsan_ptroverflow_desc *, uint64_t lhs, uint64_t rhs); 232 void __ubsan_handle_pointer_overflow_abort(struct ubsan_ptroverflow_desc *, uint64_t lhs, uint64_t rhs); 233 void __ubsan_handle_shift_out_of_bounds(struct ubsan_shift_desc *, uint64_t lhs, uint64_t rhs); 234 void __ubsan_handle_shift_out_of_bounds_abort(struct ubsan_shift_desc *, uint64_t lhs, uint64_t rhs); 235 void __ubsan_handle_sub_overflow(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 236 void __ubsan_handle_sub_overflow_abort(struct ubsan_overflow_desc *, uint64_t lhs, uint64_t rhs); 237 void __ubsan_handle_type_mismatch_v1(struct ubsan_align_desc *, uint64_t val); 238 void __ubsan_handle_type_mismatch_v1_abort(struct ubsan_align_desc *, uint64_t val); 239 void __ubsan_handle_vla_bound_not_positive(struct ubsan_vla_bound_desc *, uint64_t); 240 void __ubsan_handle_vla_bound_not_positive_abort(struct ubsan_vla_bound_desc *, uint64_t); 241 242 #endif /* _UBSAN_H_ */ 243