xref: /aosp_15_r20/trusty/kernel/lib/ubsan/ubsan.h (revision 344aa361028b423587d4ef3fa52a23d194628137)
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