• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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