source: mainline/kernel/generic/src/lib/ubsan.c@ b169619

topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b169619 was b169619, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 20 months ago

Deduplicate mem functions

There are a number of functions which are copied between
kernel, libc, and potentially boot too. mem*() functions
are first such offenders. All this duplicate code will
be moved to directory 'common'.

  • Property mode set to 100644
File size: 6.7 KB
Line 
1// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (c) 2016, Linaro Limited
4 */
5
6/* Modified for HelenOS use by Jiří Zárevúcky. */
7
8#include <stdbool.h>
9#include <stdint.h>
10#include <stddef.h>
11#include <panic.h>
12#include <memw.h>
13
14#define PRINTF(...) printf(__VA_ARGS__)
15#define ubsan_panic() panic("... aborting ...")
16
17struct source_location {
18 const char *file_name;
19 uint32_t line;
20 uint32_t column;
21};
22
23struct type_descriptor {
24 uint16_t type_kind;
25 uint16_t type_info;
26 char type_name[];
27};
28
29struct type_mismatch_data {
30 struct source_location loc;
31 struct type_descriptor *type;
32 unsigned long alignment;
33 unsigned char type_check_kind;
34};
35
36struct type_mismatch_data_v1 {
37 struct source_location loc;
38 struct type_descriptor *type;
39 unsigned char log_alignment;
40 unsigned char type_check_kind;
41};
42
43struct overflow_data {
44 struct source_location loc;
45 struct type_descriptor *type;
46};
47
48struct shift_out_of_bounds_data {
49 struct source_location loc;
50 struct type_descriptor *lhs_type;
51 struct type_descriptor *rhs_type;
52};
53
54struct out_of_bounds_data {
55 struct source_location loc;
56 struct type_descriptor *array_type;
57 struct type_descriptor *index_type;
58};
59
60struct unreachable_data {
61 struct source_location loc;
62};
63
64struct vla_bound_data {
65 struct source_location loc;
66 struct type_descriptor *type;
67};
68
69struct invalid_value_data {
70 struct source_location loc;
71 struct type_descriptor *type;
72};
73
74struct nonnull_arg_data {
75 struct source_location loc;
76};
77
78struct nonnull_return_data {
79 struct source_location loc;
80 struct source_location attr_loc;
81};
82
83struct pointer_overflow_data {
84 struct source_location loc;
85};
86
87/*
88 * When compiling with -fsanitize=undefined the compiler expects functions
89 * with the following signatures. The functions are never called directly,
90 * only when undefined behavior is detected in instrumented code.
91 */
92void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, unsigned long ptr);
93void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data, unsigned long ptr);
94void __ubsan_handle_add_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
95void __ubsan_handle_sub_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
96void __ubsan_handle_mul_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
97void __ubsan_handle_negate_overflow(struct overflow_data *data, unsigned long old_val);
98void __ubsan_handle_divrem_overflow(struct overflow_data *data, unsigned long lhs, unsigned long rhs);
99void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data, unsigned long lhs, unsigned long rhs);
100void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data, unsigned long idx);
101void __ubsan_handle_unreachable(struct unreachable_data *data);
102void __ubsan_handle_missing_return(struct unreachable_data *data);
103void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data, unsigned long bound);
104void __ubsan_handle_load_invalid_value(struct invalid_value_data *data, unsigned long val);
105#if __GCC_VERSION < 60000
106void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data, size_t arg_no);
107#else
108void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data);
109#endif
110void __ubsan_handle_nonnull_return(struct nonnull_return_data *data);
111void __ubsan_handle_nonnull_return_v1(struct nonnull_return_data *data,
112 struct source_location *loc);
113void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
114 unsigned long base, unsigned long result);
115void __ubsan_handle_builtin_unreachable(struct unreachable_data *data);
116
117static void print_loc(const char *func, struct source_location *loc)
118{
119 const char *f = func;
120 const char func_prefix[] = "__ubsan_handle";
121
122 if (!memcmp(f, func_prefix, sizeof(func_prefix) - 1))
123 f += sizeof(func_prefix);
124
125 PRINTF("Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n",
126 f, loc->file_name, loc->line, loc->column);
127}
128
129void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
130 unsigned long ptr)
131{
132 print_loc(__func__, &data->loc);
133 ubsan_panic();
134}
135
136void __ubsan_handle_add_overflow(struct overflow_data *data,
137 unsigned long lhs,
138 unsigned long rhs)
139{
140 print_loc(__func__, &data->loc);
141 ubsan_panic();
142}
143
144void __ubsan_handle_sub_overflow(struct overflow_data *data,
145 unsigned long lhs,
146 unsigned long rhs)
147{
148 print_loc(__func__, &data->loc);
149 ubsan_panic();
150}
151
152void __ubsan_handle_mul_overflow(struct overflow_data *data,
153 unsigned long lhs,
154 unsigned long rhs)
155{
156 print_loc(__func__, &data->loc);
157 ubsan_panic();
158}
159
160void __ubsan_handle_negate_overflow(struct overflow_data *data,
161 unsigned long old_val)
162{
163 print_loc(__func__, &data->loc);
164 ubsan_panic();
165}
166
167void __ubsan_handle_divrem_overflow(struct overflow_data *data,
168 unsigned long lhs,
169 unsigned long rhs)
170{
171 print_loc(__func__, &data->loc);
172 ubsan_panic();
173}
174
175void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
176 unsigned long lhs,
177 unsigned long rhs)
178{
179 print_loc(__func__, &data->loc);
180 PRINTF("LHS type: %s, value: %lu, RHS type: %s, value: %lu\n",
181 data->lhs_type->type_name, lhs, data->rhs_type->type_name, rhs);
182 ubsan_panic();
183}
184
185void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
186 unsigned long idx)
187{
188 print_loc(__func__, &data->loc);
189 ubsan_panic();
190}
191
192void __ubsan_handle_unreachable(struct unreachable_data *data)
193{
194 print_loc(__func__, &data->loc);
195 ubsan_panic();
196}
197
198void __ubsan_handle_missing_return(struct unreachable_data *data)
199{
200 print_loc(__func__, &data->loc);
201 ubsan_panic();
202}
203
204void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
205 unsigned long bound)
206{
207 print_loc(__func__, &data->loc);
208 ubsan_panic();
209}
210
211void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
212 unsigned long val)
213{
214 print_loc(__func__, &data->loc);
215 ubsan_panic();
216}
217
218#if __GCC_VERSION < 60000
219void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data, size_t arg_no)
220{
221 print_loc(__func__, &data->loc);
222 ubsan_panic();
223}
224#else
225void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
226{
227 print_loc(__func__, &data->loc);
228 ubsan_panic();
229}
230#endif
231
232void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
233{
234 print_loc(__func__, &data->loc);
235 ubsan_panic();
236}
237
238void __ubsan_handle_nonnull_return_v1(struct nonnull_return_data *data,
239 struct source_location *loc)
240{
241 print_loc(__func__, &data->loc);
242 ubsan_panic();
243}
244
245void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
246 unsigned long base, unsigned long result)
247{
248 print_loc(__func__, &data->loc);
249 ubsan_panic();
250}
251
252void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
253 unsigned long ptr)
254{
255 print_loc(__func__, &data->loc);
256 ubsan_panic();
257}
258
259void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
260{
261 print_loc(__func__, &data->loc);
262 ubsan_panic();
263}
Note: See TracBrowser for help on using the repository browser.