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

Last change on this file since eec201d was bf05c74, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Fix kernel ubsan

  • Property mode set to 100644
File size: 6.6 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 <mem.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);
115
116static void print_loc(const char *func, struct source_location *loc)
117{
118 const char *f = func;
119 const char func_prefix[] = "__ubsan_handle";
120
121 if (!memcmp(f, func_prefix, sizeof(func_prefix) - 1))
122 f += sizeof(func_prefix);
123
124 PRINTF("Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n",
125 f, loc->file_name, loc->line, loc->column);
126}
127
128void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
129 unsigned long ptr)
130{
131 print_loc(__func__, &data->loc);
132 ubsan_panic();
133}
134
135void __ubsan_handle_add_overflow(struct overflow_data *data,
136 unsigned long lhs,
137 unsigned long rhs)
138{
139 print_loc(__func__, &data->loc);
140 ubsan_panic();
141}
142
143void __ubsan_handle_sub_overflow(struct overflow_data *data,
144 unsigned long lhs,
145 unsigned long rhs)
146{
147 print_loc(__func__, &data->loc);
148 ubsan_panic();
149}
150
151void __ubsan_handle_mul_overflow(struct overflow_data *data,
152 unsigned long lhs,
153 unsigned long rhs)
154{
155 print_loc(__func__, &data->loc);
156 ubsan_panic();
157}
158
159void __ubsan_handle_negate_overflow(struct overflow_data *data,
160 unsigned long old_val)
161{
162 print_loc(__func__, &data->loc);
163 ubsan_panic();
164}
165
166void __ubsan_handle_divrem_overflow(struct overflow_data *data,
167 unsigned long lhs,
168 unsigned long rhs)
169{
170 print_loc(__func__, &data->loc);
171 ubsan_panic();
172}
173
174void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
175 unsigned long lhs,
176 unsigned long rhs)
177{
178 print_loc(__func__, &data->loc);
179 PRINTF("LHS type: %s, value: %lu, RHS type: %s, value: %lu\n",
180 data->lhs_type->type_name, lhs, data->rhs_type->type_name, rhs);
181 ubsan_panic();
182}
183
184void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
185 unsigned long idx)
186{
187 print_loc(__func__, &data->loc);
188 ubsan_panic();
189}
190
191void __ubsan_handle_unreachable(struct unreachable_data *data)
192{
193 print_loc(__func__, &data->loc);
194 ubsan_panic();
195}
196
197void __ubsan_handle_missing_return(struct unreachable_data *data)
198{
199 print_loc(__func__, &data->loc);
200 ubsan_panic();
201}
202
203void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
204 unsigned long bound)
205{
206 print_loc(__func__, &data->loc);
207 ubsan_panic();
208}
209
210void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
211 unsigned long val)
212{
213 print_loc(__func__, &data->loc);
214 ubsan_panic();
215}
216
217#if __GCC_VERSION < 60000
218void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data, size_t arg_no)
219{
220 print_loc(__func__, &data->loc);
221 ubsan_panic();
222}
223#else
224void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
225{
226 print_loc(__func__, &data->loc);
227 ubsan_panic();
228}
229#endif
230
231void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
232{
233 print_loc(__func__, &data->loc);
234 ubsan_panic();
235}
236
237void __ubsan_handle_nonnull_return_v1(struct nonnull_return_data *data,
238 struct source_location *loc)
239{
240 print_loc(__func__, &data->loc);
241 ubsan_panic();
242}
243
244void __ubsan_handle_pointer_overflow(struct pointer_overflow_data *data,
245 unsigned long base, unsigned long result)
246{
247 print_loc(__func__, &data->loc);
248 ubsan_panic();
249}
250
251void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
252 unsigned long ptr)
253{
254 print_loc(__func__, &data->loc);
255 ubsan_panic();
256}
Note: See TracBrowser for help on using the repository browser.