1*1031c584SApple OSS Distributions /*
2*1031c584SApple OSS Distributions * Copyright (c) 2018-2021 Apple Inc. All rights reserved.
3*1031c584SApple OSS Distributions *
4*1031c584SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*1031c584SApple OSS Distributions *
6*1031c584SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*1031c584SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*1031c584SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*1031c584SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*1031c584SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*1031c584SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*1031c584SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*1031c584SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*1031c584SApple OSS Distributions *
15*1031c584SApple OSS Distributions * Please obtain a copy of the License at
16*1031c584SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*1031c584SApple OSS Distributions *
18*1031c584SApple OSS Distributions * The Original Code and all software distributed under the License are
19*1031c584SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*1031c584SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*1031c584SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*1031c584SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*1031c584SApple OSS Distributions * Please see the License for the specific language governing rights and
24*1031c584SApple OSS Distributions * limitations under the License.
25*1031c584SApple OSS Distributions *
26*1031c584SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*1031c584SApple OSS Distributions */
28*1031c584SApple OSS Distributions
29*1031c584SApple OSS Distributions #include <stdatomic.h>
30*1031c584SApple OSS Distributions #include <kern/debug.h>
31*1031c584SApple OSS Distributions #include <kern/assert.h>
32*1031c584SApple OSS Distributions #include <libkern/libkern.h>
33*1031c584SApple OSS Distributions #include "ubsan.h"
34*1031c584SApple OSS Distributions
35*1031c584SApple OSS Distributions static const uint32_t line_acquired = 0x80000000UL;
36*1031c584SApple OSS Distributions static const char *get_mismatch_kind(uint8_t kind);
37*1031c584SApple OSS Distributions
38*1031c584SApple OSS Distributions /*
39*1031c584SApple OSS Distributions * A simple JSON serializer. Character quoting is not supported.
40*1031c584SApple OSS Distributions */
41*1031c584SApple OSS Distributions
42*1031c584SApple OSS Distributions static size_t
ubsan_buf_available(const ubsan_buf_t * ub)43*1031c584SApple OSS Distributions ubsan_buf_available(const ubsan_buf_t *ub)
44*1031c584SApple OSS Distributions {
45*1031c584SApple OSS Distributions assert(ub->ub_buf_size >= ub->ub_written);
46*1031c584SApple OSS Distributions return ub->ub_buf_size - ub->ub_written;
47*1031c584SApple OSS Distributions }
48*1031c584SApple OSS Distributions
49*1031c584SApple OSS Distributions static void
ubsan_buf_rewind(ubsan_buf_t * ub,size_t mark)50*1031c584SApple OSS Distributions ubsan_buf_rewind(ubsan_buf_t *ub, size_t mark)
51*1031c584SApple OSS Distributions {
52*1031c584SApple OSS Distributions assert(mark < ub->ub_buf_size);
53*1031c584SApple OSS Distributions ub->ub_written = mark;
54*1031c584SApple OSS Distributions ub->ub_buf[ub->ub_written] = '\0';
55*1031c584SApple OSS Distributions }
56*1031c584SApple OSS Distributions
57*1031c584SApple OSS Distributions __printflike(2, 0)
58*1031c584SApple OSS Distributions static void
ubsan_json_log_ap(ubsan_buf_t * ub,const char * fmt,va_list ap)59*1031c584SApple OSS Distributions ubsan_json_log_ap(ubsan_buf_t *ub, const char *fmt, va_list ap)
60*1031c584SApple OSS Distributions {
61*1031c584SApple OSS Distributions const size_t available = ubsan_buf_available(ub);
62*1031c584SApple OSS Distributions
63*1031c584SApple OSS Distributions if (available == 0) {
64*1031c584SApple OSS Distributions return;
65*1031c584SApple OSS Distributions }
66*1031c584SApple OSS Distributions
67*1031c584SApple OSS Distributions int n = vsnprintf(&ub->ub_buf[ub->ub_written], available, fmt, ap);
68*1031c584SApple OSS Distributions assert(n >= 0);
69*1031c584SApple OSS Distributions
70*1031c584SApple OSS Distributions if (n <= available) {
71*1031c584SApple OSS Distributions ub->ub_written += n;
72*1031c584SApple OSS Distributions } else {
73*1031c584SApple OSS Distributions ub->ub_err = true;
74*1031c584SApple OSS Distributions ub->ub_written = ub->ub_buf_size;
75*1031c584SApple OSS Distributions }
76*1031c584SApple OSS Distributions }
77*1031c584SApple OSS Distributions
78*1031c584SApple OSS Distributions __printflike(2, 3)
79*1031c584SApple OSS Distributions static void
ubsan_json_log(ubsan_buf_t * ub,const char * fmt,...)80*1031c584SApple OSS Distributions ubsan_json_log(ubsan_buf_t *ub, const char *fmt, ...)
81*1031c584SApple OSS Distributions {
82*1031c584SApple OSS Distributions va_list ap;
83*1031c584SApple OSS Distributions
84*1031c584SApple OSS Distributions va_start(ap, fmt);
85*1031c584SApple OSS Distributions ubsan_json_log_ap(ub, fmt, ap);
86*1031c584SApple OSS Distributions va_end(ap);
87*1031c584SApple OSS Distributions }
88*1031c584SApple OSS Distributions
89*1031c584SApple OSS Distributions static bool
ubsan_json_struct_is_empty(const ubsan_buf_t * ub)90*1031c584SApple OSS Distributions ubsan_json_struct_is_empty(const ubsan_buf_t *ub)
91*1031c584SApple OSS Distributions {
92*1031c584SApple OSS Distributions if (ub->ub_written == 0) {
93*1031c584SApple OSS Distributions return true;
94*1031c584SApple OSS Distributions }
95*1031c584SApple OSS Distributions char prev_c = ub->ub_buf[ub->ub_written - 1];
96*1031c584SApple OSS Distributions return prev_c == '{' || prev_c == '[';
97*1031c584SApple OSS Distributions }
98*1031c584SApple OSS Distributions
99*1031c584SApple OSS Distributions static int64_t
signed_num(size_t bit_width,uint64_t value)100*1031c584SApple OSS Distributions signed_num(size_t bit_width, uint64_t value)
101*1031c584SApple OSS Distributions {
102*1031c584SApple OSS Distributions switch (bit_width / 8) {
103*1031c584SApple OSS Distributions case sizeof(int8_t):
104*1031c584SApple OSS Distributions return (int8_t)value;
105*1031c584SApple OSS Distributions case sizeof(int16_t):
106*1031c584SApple OSS Distributions return (int16_t)value;
107*1031c584SApple OSS Distributions case sizeof(int32_t):
108*1031c584SApple OSS Distributions return (int32_t)value;
109*1031c584SApple OSS Distributions case sizeof(int64_t):
110*1031c584SApple OSS Distributions return (int64_t)value;
111*1031c584SApple OSS Distributions default:
112*1031c584SApple OSS Distributions panic("Invalid bit width %lu", bit_width);
113*1031c584SApple OSS Distributions }
114*1031c584SApple OSS Distributions }
115*1031c584SApple OSS Distributions
116*1031c584SApple OSS Distributions static void
ubsan_json_struct_begin(ubsan_buf_t * ub,const char * section_name,bool is_array)117*1031c584SApple OSS Distributions ubsan_json_struct_begin(ubsan_buf_t *ub, const char *section_name, bool is_array)
118*1031c584SApple OSS Distributions {
119*1031c584SApple OSS Distributions if (!ubsan_json_struct_is_empty(ub)) {
120*1031c584SApple OSS Distributions ubsan_json_log(ub, ",");
121*1031c584SApple OSS Distributions }
122*1031c584SApple OSS Distributions
123*1031c584SApple OSS Distributions if (section_name) {
124*1031c584SApple OSS Distributions assert(section_name[0] != '\0');
125*1031c584SApple OSS Distributions ubsan_json_log(ub, "\"%s\":", section_name);
126*1031c584SApple OSS Distributions }
127*1031c584SApple OSS Distributions
128*1031c584SApple OSS Distributions ubsan_json_log(ub, is_array ? "[" : "{");
129*1031c584SApple OSS Distributions
130*1031c584SApple OSS Distributions if (ubsan_buf_available(ub) == 0 || ub->ub_err) {
131*1031c584SApple OSS Distributions ub->ub_err = true;
132*1031c584SApple OSS Distributions return;
133*1031c584SApple OSS Distributions }
134*1031c584SApple OSS Distributions ub->ub_buf_size--; // Reserve for ] or }
135*1031c584SApple OSS Distributions }
136*1031c584SApple OSS Distributions
137*1031c584SApple OSS Distributions static void
ubsan_json_struct_end(ubsan_buf_t * ub,bool is_array)138*1031c584SApple OSS Distributions ubsan_json_struct_end(ubsan_buf_t *ub, bool is_array)
139*1031c584SApple OSS Distributions {
140*1031c584SApple OSS Distributions ub->ub_buf_size++; // Reserved for ] or }
141*1031c584SApple OSS Distributions assert(ub->ub_buf[ub->ub_written - 1] != ',');
142*1031c584SApple OSS Distributions ubsan_json_log(ub, is_array ? "]" : "}");
143*1031c584SApple OSS Distributions }
144*1031c584SApple OSS Distributions
145*1031c584SApple OSS Distributions static void
ubsan_json_obj_begin(ubsan_buf_t * ub,const char * section_name)146*1031c584SApple OSS Distributions ubsan_json_obj_begin(ubsan_buf_t *ub, const char *section_name)
147*1031c584SApple OSS Distributions {
148*1031c584SApple OSS Distributions ubsan_json_struct_begin(ub, section_name, false);
149*1031c584SApple OSS Distributions }
150*1031c584SApple OSS Distributions
151*1031c584SApple OSS Distributions static void
ubsan_json_obj_end(ubsan_buf_t * ub)152*1031c584SApple OSS Distributions ubsan_json_obj_end(ubsan_buf_t *ub)
153*1031c584SApple OSS Distributions {
154*1031c584SApple OSS Distributions ubsan_json_struct_end(ub, false);
155*1031c584SApple OSS Distributions }
156*1031c584SApple OSS Distributions
157*1031c584SApple OSS Distributions static void
ubsan_json_array_begin(ubsan_buf_t * ub,const char * section_name)158*1031c584SApple OSS Distributions ubsan_json_array_begin(ubsan_buf_t *ub, const char *section_name)
159*1031c584SApple OSS Distributions {
160*1031c584SApple OSS Distributions ubsan_json_struct_begin(ub, section_name, true);
161*1031c584SApple OSS Distributions }
162*1031c584SApple OSS Distributions
163*1031c584SApple OSS Distributions static void
ubsan_json_array_end(ubsan_buf_t * ub)164*1031c584SApple OSS Distributions ubsan_json_array_end(ubsan_buf_t *ub)
165*1031c584SApple OSS Distributions {
166*1031c584SApple OSS Distributions ubsan_json_struct_end(ub, true);
167*1031c584SApple OSS Distributions }
168*1031c584SApple OSS Distributions
169*1031c584SApple OSS Distributions __printflike(4, 0)
170*1031c584SApple OSS Distributions static void
ubsan_json_kv_ap(ubsan_buf_t * ub,bool quote,const char * key,const char * fmt,va_list ap)171*1031c584SApple OSS Distributions ubsan_json_kv_ap(ubsan_buf_t *ub, bool quote, const char *key, const char *fmt, va_list ap)
172*1031c584SApple OSS Distributions {
173*1031c584SApple OSS Distributions assert(key && key[0] != '\0');
174*1031c584SApple OSS Distributions assert(fmt && fmt[0] != '\0');
175*1031c584SApple OSS Distributions
176*1031c584SApple OSS Distributions if (!ubsan_json_struct_is_empty(ub)) {
177*1031c584SApple OSS Distributions ubsan_json_log(ub, ",");
178*1031c584SApple OSS Distributions }
179*1031c584SApple OSS Distributions
180*1031c584SApple OSS Distributions ubsan_json_log(ub, "\"%s\":", key);
181*1031c584SApple OSS Distributions
182*1031c584SApple OSS Distributions if (quote) {
183*1031c584SApple OSS Distributions ubsan_json_log(ub, "\"");
184*1031c584SApple OSS Distributions ubsan_json_log_ap(ub, fmt, ap);
185*1031c584SApple OSS Distributions ubsan_json_log(ub, "\"");
186*1031c584SApple OSS Distributions } else {
187*1031c584SApple OSS Distributions ubsan_json_log_ap(ub, fmt, ap);
188*1031c584SApple OSS Distributions }
189*1031c584SApple OSS Distributions }
190*1031c584SApple OSS Distributions
191*1031c584SApple OSS Distributions __printflike(4, 5)
192*1031c584SApple OSS Distributions static void
ubsan_json_kv(ubsan_buf_t * ub,int quote,const char * key,const char * fmt,...)193*1031c584SApple OSS Distributions ubsan_json_kv(ubsan_buf_t *ub, int quote, const char *key, const char *fmt, ...)
194*1031c584SApple OSS Distributions {
195*1031c584SApple OSS Distributions va_list ap;
196*1031c584SApple OSS Distributions
197*1031c584SApple OSS Distributions va_start(ap, fmt);
198*1031c584SApple OSS Distributions ubsan_json_kv_ap(ub, quote, key, fmt, ap);
199*1031c584SApple OSS Distributions va_end(ap);
200*1031c584SApple OSS Distributions }
201*1031c584SApple OSS Distributions
202*1031c584SApple OSS Distributions __printflike(3, 4)
203*1031c584SApple OSS Distributions static void
ubsan_json_fmt(ubsan_buf_t * ub,const char * key,const char * fmt,...)204*1031c584SApple OSS Distributions ubsan_json_fmt(ubsan_buf_t *ub, const char *key, const char *fmt, ...)
205*1031c584SApple OSS Distributions {
206*1031c584SApple OSS Distributions va_list ap;
207*1031c584SApple OSS Distributions
208*1031c584SApple OSS Distributions va_start(ap, fmt);
209*1031c584SApple OSS Distributions ubsan_json_kv_ap(ub, true, key, fmt, ap);
210*1031c584SApple OSS Distributions va_end(ap);
211*1031c584SApple OSS Distributions }
212*1031c584SApple OSS Distributions
213*1031c584SApple OSS Distributions static void
ubsan_json_unum(ubsan_buf_t * ub,const char * key,uint64_t number)214*1031c584SApple OSS Distributions ubsan_json_unum(ubsan_buf_t *ub, const char *key, uint64_t number)
215*1031c584SApple OSS Distributions {
216*1031c584SApple OSS Distributions ubsan_json_kv(ub, false, key, "%llu", number);
217*1031c584SApple OSS Distributions }
218*1031c584SApple OSS Distributions
219*1031c584SApple OSS Distributions static void
ubsan_json_snum(ubsan_buf_t * ub,const char * key,int64_t number)220*1031c584SApple OSS Distributions ubsan_json_snum(ubsan_buf_t *ub, const char *key, int64_t number)
221*1031c584SApple OSS Distributions {
222*1031c584SApple OSS Distributions ubsan_json_kv(ub, false, key, "%lld", number);
223*1031c584SApple OSS Distributions }
224*1031c584SApple OSS Distributions
225*1031c584SApple OSS Distributions static void
ubsan_json_num(ubsan_buf_t * ub,const char * key,struct san_type_desc * std,uint64_t value)226*1031c584SApple OSS Distributions ubsan_json_num(ubsan_buf_t *ub, const char *key, struct san_type_desc *std, uint64_t value)
227*1031c584SApple OSS Distributions {
228*1031c584SApple OSS Distributions if (std->issigned) {
229*1031c584SApple OSS Distributions ubsan_json_snum(ub, key, signed_num(1 << std->width, value));
230*1031c584SApple OSS Distributions } else {
231*1031c584SApple OSS Distributions ubsan_json_unum(ub, key, value);
232*1031c584SApple OSS Distributions }
233*1031c584SApple OSS Distributions }
234*1031c584SApple OSS Distributions
235*1031c584SApple OSS Distributions static void
ubsan_json_bool(ubsan_buf_t * ub,const char * key,bool value)236*1031c584SApple OSS Distributions ubsan_json_bool(ubsan_buf_t *ub, const char *key, bool value)
237*1031c584SApple OSS Distributions {
238*1031c584SApple OSS Distributions ubsan_json_kv(ub, false, key, "%s", value ? "true" : "false");
239*1031c584SApple OSS Distributions }
240*1031c584SApple OSS Distributions
241*1031c584SApple OSS Distributions static void
ubsan_json_str(ubsan_buf_t * ub,const char * key,const char * string)242*1031c584SApple OSS Distributions ubsan_json_str(ubsan_buf_t *ub, const char *key, const char *string)
243*1031c584SApple OSS Distributions {
244*1031c584SApple OSS Distributions const char *str_value = string;
245*1031c584SApple OSS Distributions bool quote = true;
246*1031c584SApple OSS Distributions
247*1031c584SApple OSS Distributions if (!str_value) {
248*1031c584SApple OSS Distributions str_value = "null";
249*1031c584SApple OSS Distributions quote = false;
250*1031c584SApple OSS Distributions }
251*1031c584SApple OSS Distributions
252*1031c584SApple OSS Distributions ubsan_json_kv(ub, quote, key, "%s", str_value);
253*1031c584SApple OSS Distributions }
254*1031c584SApple OSS Distributions
255*1031c584SApple OSS Distributions static void
ubsan_json_loc(ubsan_buf_t * ub,const char * desc,struct san_src_loc * loc)256*1031c584SApple OSS Distributions ubsan_json_loc(ubsan_buf_t *ub, const char *desc, struct san_src_loc *loc)
257*1031c584SApple OSS Distributions {
258*1031c584SApple OSS Distributions ubsan_json_obj_begin(ub, desc);
259*1031c584SApple OSS Distributions
260*1031c584SApple OSS Distributions ubsan_json_str(ub, "file", loc->filename);
261*1031c584SApple OSS Distributions ubsan_json_unum(ub, "line", loc->line & ~line_acquired);
262*1031c584SApple OSS Distributions ubsan_json_unum(ub, "column", loc->col);
263*1031c584SApple OSS Distributions
264*1031c584SApple OSS Distributions ubsan_json_obj_end(ub);
265*1031c584SApple OSS Distributions }
266*1031c584SApple OSS Distributions
267*1031c584SApple OSS Distributions static void
ubsan_json_type(ubsan_buf_t * ub,const char * section,uint64_t * value,struct san_type_desc * std)268*1031c584SApple OSS Distributions ubsan_json_type(ubsan_buf_t *ub, const char *section, uint64_t *value, struct san_type_desc *std)
269*1031c584SApple OSS Distributions {
270*1031c584SApple OSS Distributions if (section) {
271*1031c584SApple OSS Distributions ubsan_json_obj_begin(ub, section);
272*1031c584SApple OSS Distributions }
273*1031c584SApple OSS Distributions
274*1031c584SApple OSS Distributions if (value) {
275*1031c584SApple OSS Distributions ubsan_json_num(ub, "value", std, *value);
276*1031c584SApple OSS Distributions }
277*1031c584SApple OSS Distributions ubsan_json_str(ub, "type", std->name);
278*1031c584SApple OSS Distributions ubsan_json_bool(ub, "signed", std->issigned);
279*1031c584SApple OSS Distributions ubsan_json_unum(ub, "width", 1 << std->width);
280*1031c584SApple OSS Distributions
281*1031c584SApple OSS Distributions if (section) {
282*1031c584SApple OSS Distributions ubsan_json_obj_end(ub);
283*1031c584SApple OSS Distributions }
284*1031c584SApple OSS Distributions }
285*1031c584SApple OSS Distributions
286*1031c584SApple OSS Distributions /*
287*1031c584SApple OSS Distributions * return true for the first visit to this loc, false every subsequent time
288*1031c584SApple OSS Distributions */
289*1031c584SApple OSS Distributions static bool
ubsan_loc_acquire(struct san_src_loc * loc)290*1031c584SApple OSS Distributions ubsan_loc_acquire(struct san_src_loc *loc)
291*1031c584SApple OSS Distributions {
292*1031c584SApple OSS Distributions uint32_t line = loc->line;
293*1031c584SApple OSS Distributions if (line & line_acquired) {
294*1031c584SApple OSS Distributions return false;
295*1031c584SApple OSS Distributions }
296*1031c584SApple OSS Distributions uint32_t acq = line | line_acquired;
297*1031c584SApple OSS Distributions return atomic_compare_exchange_strong((_Atomic uint32_t *)&loc->line, &line, acq);
298*1031c584SApple OSS Distributions }
299*1031c584SApple OSS Distributions
300*1031c584SApple OSS Distributions static void
format_overflow(ubsan_violation_t * v,ubsan_buf_t * ub)301*1031c584SApple OSS Distributions format_overflow(ubsan_violation_t *v, ubsan_buf_t *ub)
302*1031c584SApple OSS Distributions {
303*1031c584SApple OSS Distributions static const char *const overflow_str[] = {
304*1031c584SApple OSS Distributions NULL,
305*1031c584SApple OSS Distributions "add",
306*1031c584SApple OSS Distributions "sub",
307*1031c584SApple OSS Distributions "mul",
308*1031c584SApple OSS Distributions "divrem",
309*1031c584SApple OSS Distributions "negate",
310*1031c584SApple OSS Distributions NULL
311*1031c584SApple OSS Distributions };
312*1031c584SApple OSS Distributions struct san_type_desc *ty = v->overflow->ty;
313*1031c584SApple OSS Distributions
314*1031c584SApple OSS Distributions ubsan_json_fmt(ub, "problem", "type overflow");
315*1031c584SApple OSS Distributions ubsan_json_str(ub, "op", overflow_str[v->ubsan_type]);
316*1031c584SApple OSS Distributions ubsan_json_type(ub, "lhs", &v->lhs, ty);
317*1031c584SApple OSS Distributions ubsan_json_unum(ub, "rhs", v->rhs);
318*1031c584SApple OSS Distributions }
319*1031c584SApple OSS Distributions
320*1031c584SApple OSS Distributions static void
format_shift(ubsan_violation_t * v,ubsan_buf_t * ub)321*1031c584SApple OSS Distributions format_shift(ubsan_violation_t *v, ubsan_buf_t *ub)
322*1031c584SApple OSS Distributions {
323*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "bad shift");
324*1031c584SApple OSS Distributions ubsan_json_type(ub, "lhs", &v->lhs, v->shift->lhs_t);
325*1031c584SApple OSS Distributions ubsan_json_type(ub, "rhs", &v->rhs, v->shift->rhs_t);
326*1031c584SApple OSS Distributions }
327*1031c584SApple OSS Distributions
328*1031c584SApple OSS Distributions static const char *
get_mismatch_kind(uint8_t kind)329*1031c584SApple OSS Distributions get_mismatch_kind(uint8_t kind)
330*1031c584SApple OSS Distributions {
331*1031c584SApple OSS Distributions static const char *const mismatch_kinds[] = {
332*1031c584SApple OSS Distributions "load of",
333*1031c584SApple OSS Distributions "store to",
334*1031c584SApple OSS Distributions "reference binding to",
335*1031c584SApple OSS Distributions "member access within",
336*1031c584SApple OSS Distributions "member call on",
337*1031c584SApple OSS Distributions "constructor call on",
338*1031c584SApple OSS Distributions "downcast of",
339*1031c584SApple OSS Distributions "downcast of",
340*1031c584SApple OSS Distributions "upcast of",
341*1031c584SApple OSS Distributions "cast to virtual base of",
342*1031c584SApple OSS Distributions "_Nonnull binding to"
343*1031c584SApple OSS Distributions };
344*1031c584SApple OSS Distributions
345*1031c584SApple OSS Distributions return (kind < (sizeof(mismatch_kinds) / sizeof(mismatch_kinds[0])))
346*1031c584SApple OSS Distributions ? mismatch_kinds[kind]
347*1031c584SApple OSS Distributions : "some";
348*1031c584SApple OSS Distributions }
349*1031c584SApple OSS Distributions
350*1031c584SApple OSS Distributions static void
format_type_mismatch(ubsan_violation_t * v,ubsan_buf_t * ub)351*1031c584SApple OSS Distributions format_type_mismatch(ubsan_violation_t *v, ubsan_buf_t *ub)
352*1031c584SApple OSS Distributions {
353*1031c584SApple OSS Distributions const char *kind = get_mismatch_kind(v->align->kind);
354*1031c584SApple OSS Distributions const size_t alignment = 1 << v->align->align;
355*1031c584SApple OSS Distributions uintptr_t addr = (uintptr_t)v->lhs;
356*1031c584SApple OSS Distributions
357*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "type mismatch");
358*1031c584SApple OSS Distributions
359*1031c584SApple OSS Distributions if (!addr) {
360*1031c584SApple OSS Distributions ubsan_json_fmt(ub, "kind", "%s NULL pointer", kind);
361*1031c584SApple OSS Distributions ubsan_json_str(ub, "type", v->align->ty->name);
362*1031c584SApple OSS Distributions return;
363*1031c584SApple OSS Distributions }
364*1031c584SApple OSS Distributions
365*1031c584SApple OSS Distributions if (alignment && (addr & (alignment - 1))) {
366*1031c584SApple OSS Distributions ubsan_json_fmt(ub, "kind", "%s misaligned", kind);
367*1031c584SApple OSS Distributions ubsan_json_unum(ub, "required", alignment);
368*1031c584SApple OSS Distributions } else {
369*1031c584SApple OSS Distributions ubsan_json_fmt(ub, "kind", "%s insufficient size", kind);
370*1031c584SApple OSS Distributions }
371*1031c584SApple OSS Distributions ubsan_json_type(ub, NULL, (uint64_t *)&addr, v->align->ty);
372*1031c584SApple OSS Distributions }
373*1031c584SApple OSS Distributions
374*1031c584SApple OSS Distributions static void
format_oob(ubsan_violation_t * v,ubsan_buf_t * ub)375*1031c584SApple OSS Distributions format_oob(ubsan_violation_t *v, ubsan_buf_t *ub)
376*1031c584SApple OSS Distributions {
377*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "OOB array indexing");
378*1031c584SApple OSS Distributions ubsan_json_type(ub, "array", NULL, v->oob->array_ty);
379*1031c584SApple OSS Distributions ubsan_json_type(ub, "idx", &v->lhs, v->oob->index_ty);
380*1031c584SApple OSS Distributions }
381*1031c584SApple OSS Distributions
382*1031c584SApple OSS Distributions static void
format_nullability_arg(ubsan_violation_t * v,ubsan_buf_t * ub)383*1031c584SApple OSS Distributions format_nullability_arg(ubsan_violation_t *v, ubsan_buf_t *ub)
384*1031c584SApple OSS Distributions {
385*1031c584SApple OSS Distributions struct ubsan_nullability_arg_desc *data = v->nonnull_arg;
386*1031c584SApple OSS Distributions
387*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "nullability");
388*1031c584SApple OSS Distributions ubsan_json_snum(ub, "arg", data->arg_index);
389*1031c584SApple OSS Distributions ubsan_json_str(ub, "attr", v->lhs ? "nonnull" : "_Nonnull");
390*1031c584SApple OSS Distributions ubsan_json_loc(ub, "declared", &data->attr_loc);
391*1031c584SApple OSS Distributions }
392*1031c584SApple OSS Distributions
393*1031c584SApple OSS Distributions static void
format_nonnull_return(ubsan_violation_t * v,ubsan_buf_t * ub)394*1031c584SApple OSS Distributions format_nonnull_return(ubsan_violation_t *v, ubsan_buf_t *ub)
395*1031c584SApple OSS Distributions {
396*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "nonnull return");
397*1031c584SApple OSS Distributions ubsan_json_str(ub, "attr", v->lhs ? "returns_nonnull" : "_Nonnull");
398*1031c584SApple OSS Distributions ubsan_json_loc(ub, "declared", (struct san_src_loc *)v->rhs);
399*1031c584SApple OSS Distributions }
400*1031c584SApple OSS Distributions
401*1031c584SApple OSS Distributions static void
format_load_invalid_value(ubsan_violation_t * v,ubsan_buf_t * ub)402*1031c584SApple OSS Distributions format_load_invalid_value(ubsan_violation_t *v, ubsan_buf_t *ub)
403*1031c584SApple OSS Distributions {
404*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "invalid load");
405*1031c584SApple OSS Distributions ubsan_json_type(ub, NULL, &v->lhs, v->invalid->type);
406*1031c584SApple OSS Distributions }
407*1031c584SApple OSS Distributions
408*1031c584SApple OSS Distributions static void
format_missing_return(ubsan_violation_t * v __unused,ubsan_buf_t * ub)409*1031c584SApple OSS Distributions format_missing_return(ubsan_violation_t *v __unused, ubsan_buf_t *ub)
410*1031c584SApple OSS Distributions {
411*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "missing return");
412*1031c584SApple OSS Distributions }
413*1031c584SApple OSS Distributions
414*1031c584SApple OSS Distributions static void
format_float_cast_overflow(ubsan_violation_t * v,ubsan_buf_t * ub)415*1031c584SApple OSS Distributions format_float_cast_overflow(ubsan_violation_t *v, ubsan_buf_t *ub)
416*1031c584SApple OSS Distributions {
417*1031c584SApple OSS Distributions struct ubsan_float_desc *data = v->flt;
418*1031c584SApple OSS Distributions /*
419*1031c584SApple OSS Distributions * Cannot print out offending value (e.g. using %A, %f and so on) as kernel logging
420*1031c584SApple OSS Distributions * does not support float types (yet).
421*1031c584SApple OSS Distributions */
422*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "cast overflow");
423*1031c584SApple OSS Distributions ubsan_json_str(ub, "src", data->type_from->name);
424*1031c584SApple OSS Distributions ubsan_json_str(ub, "to", data->type_to->name);
425*1031c584SApple OSS Distributions }
426*1031c584SApple OSS Distributions
427*1031c584SApple OSS Distributions static const char *
get_implicit_conv_type(unsigned char kind)428*1031c584SApple OSS Distributions get_implicit_conv_type(unsigned char kind)
429*1031c584SApple OSS Distributions {
430*1031c584SApple OSS Distributions static const char * const conv_types[] = {
431*1031c584SApple OSS Distributions "integer truncation",
432*1031c584SApple OSS Distributions "unsigned integer truncation",
433*1031c584SApple OSS Distributions "signed integer truncation",
434*1031c584SApple OSS Distributions "integer sign change",
435*1031c584SApple OSS Distributions "signed integer truncation or sign change"
436*1031c584SApple OSS Distributions };
437*1031c584SApple OSS Distributions static const size_t conv_types_cnt = sizeof(conv_types) / sizeof(conv_types[0]);
438*1031c584SApple OSS Distributions
439*1031c584SApple OSS Distributions return kind < conv_types_cnt ? conv_types[kind] : "unknown implicit integer conversion";
440*1031c584SApple OSS Distributions }
441*1031c584SApple OSS Distributions
442*1031c584SApple OSS Distributions static void
format_implicit_conversion(ubsan_violation_t * v,ubsan_buf_t * ub)443*1031c584SApple OSS Distributions format_implicit_conversion(ubsan_violation_t *v, ubsan_buf_t *ub)
444*1031c584SApple OSS Distributions {
445*1031c584SApple OSS Distributions struct ubsan_implicit_conv_desc *data = v->implicit;
446*1031c584SApple OSS Distributions
447*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", get_implicit_conv_type(data->kind));
448*1031c584SApple OSS Distributions ubsan_json_type(ub, "lhs", &v->lhs, data->type_to);
449*1031c584SApple OSS Distributions ubsan_json_type(ub, "rhs", &v->rhs, data->type_from);
450*1031c584SApple OSS Distributions }
451*1031c584SApple OSS Distributions
452*1031c584SApple OSS Distributions static void
format_function_type_mismatch(ubsan_violation_t * v,ubsan_buf_t * ub)453*1031c584SApple OSS Distributions format_function_type_mismatch(ubsan_violation_t *v, ubsan_buf_t *ub)
454*1031c584SApple OSS Distributions {
455*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "bad indirect call");
456*1031c584SApple OSS Distributions ubsan_json_type(ub, NULL, &v->lhs, v->func_mismatch->type);
457*1031c584SApple OSS Distributions }
458*1031c584SApple OSS Distributions
459*1031c584SApple OSS Distributions static void
format_vla_bound_not_positive(ubsan_violation_t * v,ubsan_buf_t * ub)460*1031c584SApple OSS Distributions format_vla_bound_not_positive(ubsan_violation_t *v, ubsan_buf_t *ub)
461*1031c584SApple OSS Distributions {
462*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "non-positive VLA bound");
463*1031c584SApple OSS Distributions ubsan_json_type(ub, NULL, &v->lhs, v->vla_bound->type);
464*1031c584SApple OSS Distributions }
465*1031c584SApple OSS Distributions
466*1031c584SApple OSS Distributions static void
format_invalid_builtin(ubsan_violation_t * v,ubsan_buf_t * ub)467*1031c584SApple OSS Distributions format_invalid_builtin(ubsan_violation_t *v, ubsan_buf_t *ub)
468*1031c584SApple OSS Distributions {
469*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "invalid builtin");
470*1031c584SApple OSS Distributions ubsan_json_str(ub, "op", v->invalid_builtin->kind == 0 ? "ctz()" : "clz()");
471*1031c584SApple OSS Distributions }
472*1031c584SApple OSS Distributions
473*1031c584SApple OSS Distributions static void
format_ptr_overflow(ubsan_violation_t * v,ubsan_buf_t * ub)474*1031c584SApple OSS Distributions format_ptr_overflow(ubsan_violation_t *v, ubsan_buf_t *ub)
475*1031c584SApple OSS Distributions {
476*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "pointer overflow");
477*1031c584SApple OSS Distributions ubsan_json_unum(ub, "lhs", v->lhs);
478*1031c584SApple OSS Distributions ubsan_json_unum(ub, "rhs", v->rhs);
479*1031c584SApple OSS Distributions }
480*1031c584SApple OSS Distributions
481*1031c584SApple OSS Distributions static void
format_unreachable(ubsan_buf_t * ub)482*1031c584SApple OSS Distributions format_unreachable(ubsan_buf_t *ub)
483*1031c584SApple OSS Distributions {
484*1031c584SApple OSS Distributions ubsan_json_str(ub, "problem", "unreachable");
485*1031c584SApple OSS Distributions }
486*1031c584SApple OSS Distributions
487*1031c584SApple OSS Distributions void
ubsan_json_init(ubsan_buf_t * ub,char * buf,size_t bufsize)488*1031c584SApple OSS Distributions ubsan_json_init(ubsan_buf_t *ub, char *buf, size_t bufsize)
489*1031c584SApple OSS Distributions {
490*1031c584SApple OSS Distributions assert(bufsize > sizeof("{\"count\":9999,\"violations\":[]}"));
491*1031c584SApple OSS Distributions assert(buf);
492*1031c584SApple OSS Distributions
493*1031c584SApple OSS Distributions ub->ub_buf = buf;
494*1031c584SApple OSS Distributions ub->ub_buf_size = bufsize;
495*1031c584SApple OSS Distributions ub->ub_written = 0;
496*1031c584SApple OSS Distributions ub->ub_err = false;
497*1031c584SApple OSS Distributions }
498*1031c584SApple OSS Distributions
499*1031c584SApple OSS Distributions void
ubsan_json_begin(ubsan_buf_t * ub,size_t nentries)500*1031c584SApple OSS Distributions ubsan_json_begin(ubsan_buf_t *ub, size_t nentries)
501*1031c584SApple OSS Distributions {
502*1031c584SApple OSS Distributions ub->ub_buf_size--; // for '\0'
503*1031c584SApple OSS Distributions
504*1031c584SApple OSS Distributions ubsan_json_obj_begin(ub, NULL);
505*1031c584SApple OSS Distributions ubsan_json_unum(ub, "count", nentries);
506*1031c584SApple OSS Distributions ubsan_json_array_begin(ub, "violations");
507*1031c584SApple OSS Distributions
508*1031c584SApple OSS Distributions assert(!ub->ub_err);
509*1031c584SApple OSS Distributions }
510*1031c584SApple OSS Distributions
511*1031c584SApple OSS Distributions size_t
ubsan_json_finish(ubsan_buf_t * ub)512*1031c584SApple OSS Distributions ubsan_json_finish(ubsan_buf_t *ub)
513*1031c584SApple OSS Distributions {
514*1031c584SApple OSS Distributions ub->ub_buf_size++; // for '\0'
515*1031c584SApple OSS Distributions ub->ub_err = false;
516*1031c584SApple OSS Distributions
517*1031c584SApple OSS Distributions ubsan_json_array_end(ub);
518*1031c584SApple OSS Distributions ubsan_json_obj_end(ub);
519*1031c584SApple OSS Distributions
520*1031c584SApple OSS Distributions assert(!ub->ub_err);
521*1031c584SApple OSS Distributions return ub->ub_written;
522*1031c584SApple OSS Distributions }
523*1031c584SApple OSS Distributions
524*1031c584SApple OSS Distributions bool
ubsan_json_format(ubsan_violation_t * v,ubsan_buf_t * ub)525*1031c584SApple OSS Distributions ubsan_json_format(ubsan_violation_t *v, ubsan_buf_t *ub)
526*1031c584SApple OSS Distributions {
527*1031c584SApple OSS Distributions const size_t mark = ub->ub_written;
528*1031c584SApple OSS Distributions
529*1031c584SApple OSS Distributions ubsan_json_obj_begin(ub, NULL);
530*1031c584SApple OSS Distributions
531*1031c584SApple OSS Distributions switch (v->ubsan_type) {
532*1031c584SApple OSS Distributions case UBSAN_OVERFLOW_add ... UBSAN_OVERFLOW_negate:
533*1031c584SApple OSS Distributions format_overflow(v, ub);
534*1031c584SApple OSS Distributions break;
535*1031c584SApple OSS Distributions case UBSAN_UNREACHABLE:
536*1031c584SApple OSS Distributions format_unreachable(ub);
537*1031c584SApple OSS Distributions break;
538*1031c584SApple OSS Distributions case UBSAN_SHIFT:
539*1031c584SApple OSS Distributions format_shift(v, ub);
540*1031c584SApple OSS Distributions break;
541*1031c584SApple OSS Distributions case UBSAN_TYPE_MISMATCH:
542*1031c584SApple OSS Distributions format_type_mismatch(v, ub);
543*1031c584SApple OSS Distributions break;
544*1031c584SApple OSS Distributions case UBSAN_POINTER_OVERFLOW:
545*1031c584SApple OSS Distributions format_ptr_overflow(v, ub);
546*1031c584SApple OSS Distributions break;
547*1031c584SApple OSS Distributions case UBSAN_OOB:
548*1031c584SApple OSS Distributions format_oob(v, ub);
549*1031c584SApple OSS Distributions break;
550*1031c584SApple OSS Distributions case UBSAN_NULLABILITY_ARG:
551*1031c584SApple OSS Distributions format_nullability_arg(v, ub);
552*1031c584SApple OSS Distributions break;
553*1031c584SApple OSS Distributions case UBSAN_NULLABILITY_RETURN:
554*1031c584SApple OSS Distributions format_nonnull_return(v, ub);
555*1031c584SApple OSS Distributions break;
556*1031c584SApple OSS Distributions case UBSAN_MISSING_RETURN:
557*1031c584SApple OSS Distributions format_missing_return(v, ub);
558*1031c584SApple OSS Distributions break;
559*1031c584SApple OSS Distributions case UBSAN_FLOAT_CAST_OVERFLOW:
560*1031c584SApple OSS Distributions format_float_cast_overflow(v, ub);
561*1031c584SApple OSS Distributions break;
562*1031c584SApple OSS Distributions case UBSAN_IMPLICIT_CONVERSION:
563*1031c584SApple OSS Distributions format_implicit_conversion(v, ub);
564*1031c584SApple OSS Distributions break;
565*1031c584SApple OSS Distributions case UBSAN_FUNCTION_TYPE_MISMATCH:
566*1031c584SApple OSS Distributions format_function_type_mismatch(v, ub);
567*1031c584SApple OSS Distributions break;
568*1031c584SApple OSS Distributions case UBSAN_VLA_BOUND_NOT_POSITIVE:
569*1031c584SApple OSS Distributions format_vla_bound_not_positive(v, ub);
570*1031c584SApple OSS Distributions break;
571*1031c584SApple OSS Distributions case UBSAN_INVALID_BUILTIN:
572*1031c584SApple OSS Distributions format_invalid_builtin(v, ub);
573*1031c584SApple OSS Distributions break;
574*1031c584SApple OSS Distributions case UBSAN_LOAD_INVALID_VALUE:
575*1031c584SApple OSS Distributions format_load_invalid_value(v, ub);
576*1031c584SApple OSS Distributions break;
577*1031c584SApple OSS Distributions default:
578*1031c584SApple OSS Distributions panic("unknown violation");
579*1031c584SApple OSS Distributions }
580*1031c584SApple OSS Distributions
581*1031c584SApple OSS Distributions ubsan_json_loc(ub, "source", v->loc);
582*1031c584SApple OSS Distributions ubsan_json_obj_end(ub);
583*1031c584SApple OSS Distributions
584*1031c584SApple OSS Distributions if (ub->ub_err) {
585*1031c584SApple OSS Distributions ubsan_buf_rewind(ub, mark);
586*1031c584SApple OSS Distributions }
587*1031c584SApple OSS Distributions assert(ub->ub_buf[ub->ub_written] == '\0');
588*1031c584SApple OSS Distributions
589*1031c584SApple OSS Distributions return !ub->ub_err;
590*1031c584SApple OSS Distributions }
591*1031c584SApple OSS Distributions
592*1031c584SApple OSS Distributions enum UBFatality { Fatal, FleshWound };
593*1031c584SApple OSS Distributions
594*1031c584SApple OSS Distributions static void
ubsan_handle(ubsan_violation_t * v,enum UBFatality fatality)595*1031c584SApple OSS Distributions ubsan_handle(ubsan_violation_t *v, enum UBFatality fatality)
596*1031c584SApple OSS Distributions {
597*1031c584SApple OSS Distributions if (!ubsan_loc_acquire(v->loc)) {
598*1031c584SApple OSS Distributions /* violation site already reported */
599*1031c584SApple OSS Distributions return;
600*1031c584SApple OSS Distributions }
601*1031c584SApple OSS Distributions ubsan_log_append(v);
602*1031c584SApple OSS Distributions
603*1031c584SApple OSS Distributions if (fatality != Fatal) {
604*1031c584SApple OSS Distributions return;
605*1031c584SApple OSS Distributions }
606*1031c584SApple OSS Distributions
607*1031c584SApple OSS Distributions static char buf[512] = { 0 };
608*1031c584SApple OSS Distributions ubsan_buf_t ubsan_buf;
609*1031c584SApple OSS Distributions
610*1031c584SApple OSS Distributions ubsan_json_init(&ubsan_buf, buf, sizeof(buf));
611*1031c584SApple OSS Distributions
612*1031c584SApple OSS Distributions if (ubsan_json_format(v, &ubsan_buf)) {
613*1031c584SApple OSS Distributions printf("UBSan: %s", buf);
614*1031c584SApple OSS Distributions }
615*1031c584SApple OSS Distributions }
616*1031c584SApple OSS Distributions
617*1031c584SApple OSS Distributions void
__ubsan_handle_builtin_unreachable(struct ubsan_unreachable_desc * desc)618*1031c584SApple OSS Distributions __ubsan_handle_builtin_unreachable(struct ubsan_unreachable_desc *desc)
619*1031c584SApple OSS Distributions {
620*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_UNREACHABLE, 0, 0, .unreachable = desc, &desc->loc };
621*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
622*1031c584SApple OSS Distributions }
623*1031c584SApple OSS Distributions
624*1031c584SApple OSS Distributions void
__ubsan_handle_shift_out_of_bounds(struct ubsan_shift_desc * desc,uint64_t lhs,uint64_t rhs)625*1031c584SApple OSS Distributions __ubsan_handle_shift_out_of_bounds(struct ubsan_shift_desc *desc, uint64_t lhs, uint64_t rhs)
626*1031c584SApple OSS Distributions {
627*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_SHIFT, lhs, rhs, .shift = desc, &desc->loc };
628*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
629*1031c584SApple OSS Distributions }
630*1031c584SApple OSS Distributions
631*1031c584SApple OSS Distributions void
__ubsan_handle_shift_out_of_bounds_abort(struct ubsan_shift_desc * desc,uint64_t lhs,uint64_t rhs)632*1031c584SApple OSS Distributions __ubsan_handle_shift_out_of_bounds_abort(struct ubsan_shift_desc *desc, uint64_t lhs, uint64_t rhs)
633*1031c584SApple OSS Distributions {
634*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_SHIFT, lhs, rhs, .shift = desc, &desc->loc };
635*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
636*1031c584SApple OSS Distributions }
637*1031c584SApple OSS Distributions
638*1031c584SApple OSS Distributions #define DEFINE_OVERFLOW(op) \
639*1031c584SApple OSS Distributions void __ubsan_handle_##op##_overflow(struct ubsan_overflow_desc *desc, uint64_t lhs, uint64_t rhs) { \
640*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_OVERFLOW_##op, lhs, rhs, .overflow = desc, &desc->loc }; \
641*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound); \
642*1031c584SApple OSS Distributions } \
643*1031c584SApple OSS Distributions void __ubsan_handle_##op##_overflow_abort(struct ubsan_overflow_desc *desc, uint64_t lhs, uint64_t rhs) { \
644*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_OVERFLOW_##op, lhs, rhs, .overflow = desc, &desc->loc }; \
645*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal); \
646*1031c584SApple OSS Distributions }
647*1031c584SApple OSS Distributions
648*1031c584SApple OSS Distributions DEFINE_OVERFLOW(add)
DEFINE_OVERFLOW(sub)649*1031c584SApple OSS Distributions DEFINE_OVERFLOW(sub)
650*1031c584SApple OSS Distributions DEFINE_OVERFLOW(mul)
651*1031c584SApple OSS Distributions DEFINE_OVERFLOW(divrem)
652*1031c584SApple OSS Distributions DEFINE_OVERFLOW(negate)
653*1031c584SApple OSS Distributions
654*1031c584SApple OSS Distributions void
655*1031c584SApple OSS Distributions __ubsan_handle_type_mismatch_v1(struct ubsan_align_desc *desc, uint64_t val)
656*1031c584SApple OSS Distributions {
657*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_TYPE_MISMATCH, val, 0, .align = desc, &desc->loc };
658*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
659*1031c584SApple OSS Distributions }
660*1031c584SApple OSS Distributions
661*1031c584SApple OSS Distributions void
__ubsan_handle_type_mismatch_v1_abort(struct ubsan_align_desc * desc,uint64_t val)662*1031c584SApple OSS Distributions __ubsan_handle_type_mismatch_v1_abort(struct ubsan_align_desc *desc, uint64_t val)
663*1031c584SApple OSS Distributions {
664*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_TYPE_MISMATCH, val, 0, .align = desc, &desc->loc };
665*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
666*1031c584SApple OSS Distributions }
667*1031c584SApple OSS Distributions
668*1031c584SApple OSS Distributions void
__ubsan_handle_pointer_overflow(struct ubsan_ptroverflow_desc * desc,uint64_t before,uint64_t after)669*1031c584SApple OSS Distributions __ubsan_handle_pointer_overflow(struct ubsan_ptroverflow_desc *desc, uint64_t before, uint64_t after)
670*1031c584SApple OSS Distributions {
671*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_POINTER_OVERFLOW, before, after, .ptroverflow = desc, &desc->loc };
672*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
673*1031c584SApple OSS Distributions }
674*1031c584SApple OSS Distributions
675*1031c584SApple OSS Distributions void
__ubsan_handle_pointer_overflow_abort(struct ubsan_ptroverflow_desc * desc,uint64_t before,uint64_t after)676*1031c584SApple OSS Distributions __ubsan_handle_pointer_overflow_abort(struct ubsan_ptroverflow_desc *desc, uint64_t before, uint64_t after)
677*1031c584SApple OSS Distributions {
678*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_POINTER_OVERFLOW, before, after, .ptroverflow = desc, &desc->loc };
679*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
680*1031c584SApple OSS Distributions }
681*1031c584SApple OSS Distributions
682*1031c584SApple OSS Distributions void
__ubsan_handle_out_of_bounds(struct ubsan_oob_desc * desc,uint64_t idx)683*1031c584SApple OSS Distributions __ubsan_handle_out_of_bounds(struct ubsan_oob_desc *desc, uint64_t idx)
684*1031c584SApple OSS Distributions {
685*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_OOB, idx, 0, .oob = desc, &desc->loc };
686*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
687*1031c584SApple OSS Distributions }
688*1031c584SApple OSS Distributions
689*1031c584SApple OSS Distributions void
__ubsan_handle_out_of_bounds_abort(struct ubsan_oob_desc * desc,uint64_t idx)690*1031c584SApple OSS Distributions __ubsan_handle_out_of_bounds_abort(struct ubsan_oob_desc *desc, uint64_t idx)
691*1031c584SApple OSS Distributions {
692*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_OOB, idx, 0, .oob = desc, &desc->loc };
693*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
694*1031c584SApple OSS Distributions }
695*1031c584SApple OSS Distributions
696*1031c584SApple OSS Distributions void
__ubsan_handle_nullability_arg(struct ubsan_nullability_arg_desc * desc)697*1031c584SApple OSS Distributions __ubsan_handle_nullability_arg(struct ubsan_nullability_arg_desc *desc)
698*1031c584SApple OSS Distributions {
699*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_ARG, 0, 0, .nonnull_arg = desc, &desc->loc };
700*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
701*1031c584SApple OSS Distributions }
702*1031c584SApple OSS Distributions
703*1031c584SApple OSS Distributions void
__ubsan_handle_nullability_arg_abort(struct ubsan_nullability_arg_desc * desc)704*1031c584SApple OSS Distributions __ubsan_handle_nullability_arg_abort(struct ubsan_nullability_arg_desc *desc)
705*1031c584SApple OSS Distributions {
706*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_ARG, 0, 0, .nonnull_arg = desc, &desc->loc };
707*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
708*1031c584SApple OSS Distributions }
709*1031c584SApple OSS Distributions
710*1031c584SApple OSS Distributions void
__ubsan_handle_nonnull_arg(struct ubsan_nullability_arg_desc * desc)711*1031c584SApple OSS Distributions __ubsan_handle_nonnull_arg(struct ubsan_nullability_arg_desc *desc)
712*1031c584SApple OSS Distributions {
713*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_ARG, 1, 0, .nonnull_arg = desc, &desc->loc };
714*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
715*1031c584SApple OSS Distributions }
716*1031c584SApple OSS Distributions
717*1031c584SApple OSS Distributions void
__ubsan_handle_nonnull_arg_abort(struct ubsan_nullability_arg_desc * desc)718*1031c584SApple OSS Distributions __ubsan_handle_nonnull_arg_abort(struct ubsan_nullability_arg_desc *desc)
719*1031c584SApple OSS Distributions {
720*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_ARG, 1, 0, .nonnull_arg = desc, &desc->loc };
721*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
722*1031c584SApple OSS Distributions }
723*1031c584SApple OSS Distributions
724*1031c584SApple OSS Distributions void
__ubsan_handle_nullability_return_v1(struct ubsan_nullability_ret_desc * desc,uint64_t declaration)725*1031c584SApple OSS Distributions __ubsan_handle_nullability_return_v1(struct ubsan_nullability_ret_desc *desc, uint64_t declaration)
726*1031c584SApple OSS Distributions {
727*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_RETURN, 0, (uint64_t)&desc->loc, .nonnull_ret = desc, (struct san_src_loc *)declaration };
728*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
729*1031c584SApple OSS Distributions }
730*1031c584SApple OSS Distributions
731*1031c584SApple OSS Distributions void
__ubsan_handle_nullability_return_v1_abort(struct ubsan_nullability_ret_desc * desc,uint64_t declaration)732*1031c584SApple OSS Distributions __ubsan_handle_nullability_return_v1_abort(struct ubsan_nullability_ret_desc *desc, uint64_t declaration)
733*1031c584SApple OSS Distributions {
734*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_RETURN, 0, (uint64_t)&desc->loc, .nonnull_ret = desc, (struct san_src_loc *)declaration };
735*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
736*1031c584SApple OSS Distributions }
737*1031c584SApple OSS Distributions
738*1031c584SApple OSS Distributions void
__ubsan_handle_nonnull_return_v1(struct ubsan_nullability_ret_desc * desc,uint64_t declaration)739*1031c584SApple OSS Distributions __ubsan_handle_nonnull_return_v1(struct ubsan_nullability_ret_desc *desc, uint64_t declaration)
740*1031c584SApple OSS Distributions {
741*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_RETURN, 1, (uint64_t)&desc->loc, .nonnull_ret = desc, (struct san_src_loc *)declaration };
742*1031c584SApple OSS Distributions ubsan_handle(&v, FleshWound);
743*1031c584SApple OSS Distributions }
744*1031c584SApple OSS Distributions
745*1031c584SApple OSS Distributions void
__ubsan_handle_nonnull_return_v1_abort(struct ubsan_nullability_ret_desc * desc,uint64_t declaration)746*1031c584SApple OSS Distributions __ubsan_handle_nonnull_return_v1_abort(struct ubsan_nullability_ret_desc *desc, uint64_t declaration)
747*1031c584SApple OSS Distributions {
748*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_NULLABILITY_RETURN, 1, (uint64_t)&desc->loc, .nonnull_ret = desc, (struct san_src_loc *)declaration };
749*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
750*1031c584SApple OSS Distributions }
751*1031c584SApple OSS Distributions
752*1031c584SApple OSS Distributions void
__ubsan_handle_missing_return(struct ubsan_missing_ret_desc * desc)753*1031c584SApple OSS Distributions __ubsan_handle_missing_return(struct ubsan_missing_ret_desc *desc)
754*1031c584SApple OSS Distributions {
755*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_MISSING_RETURN, 0, 0, .missing_ret = desc, &desc->loc };
756*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
757*1031c584SApple OSS Distributions }
758*1031c584SApple OSS Distributions
759*1031c584SApple OSS Distributions void
__ubsan_handle_missing_return_abort(struct ubsan_missing_ret_desc * desc)760*1031c584SApple OSS Distributions __ubsan_handle_missing_return_abort(struct ubsan_missing_ret_desc *desc)
761*1031c584SApple OSS Distributions {
762*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_MISSING_RETURN, 0, 0, .missing_ret = desc, &desc->loc };
763*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
764*1031c584SApple OSS Distributions }
765*1031c584SApple OSS Distributions
766*1031c584SApple OSS Distributions void
__ubsan_handle_float_cast_overflow(struct ubsan_float_desc * desc,uint64_t value)767*1031c584SApple OSS Distributions __ubsan_handle_float_cast_overflow(struct ubsan_float_desc *desc, uint64_t value)
768*1031c584SApple OSS Distributions {
769*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_FLOAT_CAST_OVERFLOW, value, 0, .flt = desc, &desc->loc };
770*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
771*1031c584SApple OSS Distributions }
772*1031c584SApple OSS Distributions
773*1031c584SApple OSS Distributions void
__ubsan_handle_float_cast_overflow_abort(struct ubsan_float_desc * desc,uint64_t value)774*1031c584SApple OSS Distributions __ubsan_handle_float_cast_overflow_abort(struct ubsan_float_desc *desc, uint64_t value)
775*1031c584SApple OSS Distributions {
776*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_FLOAT_CAST_OVERFLOW, value, 0, .flt = desc, &desc->loc };
777*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
778*1031c584SApple OSS Distributions }
779*1031c584SApple OSS Distributions
780*1031c584SApple OSS Distributions void
__ubsan_handle_implicit_conversion(struct ubsan_implicit_conv_desc * desc,uint64_t from,uint64_t to)781*1031c584SApple OSS Distributions __ubsan_handle_implicit_conversion(struct ubsan_implicit_conv_desc *desc, uint64_t from, uint64_t to)
782*1031c584SApple OSS Distributions {
783*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_IMPLICIT_CONVERSION, from, to, .implicit = desc, &desc->loc };
784*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
785*1031c584SApple OSS Distributions }
786*1031c584SApple OSS Distributions
787*1031c584SApple OSS Distributions void
__ubsan_handle_implicit_conversion_abort(struct ubsan_implicit_conv_desc * desc,uint64_t from,uint64_t to)788*1031c584SApple OSS Distributions __ubsan_handle_implicit_conversion_abort(struct ubsan_implicit_conv_desc *desc, uint64_t from, uint64_t to)
789*1031c584SApple OSS Distributions {
790*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_IMPLICIT_CONVERSION, from, to, .implicit = desc, &desc->loc };
791*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
792*1031c584SApple OSS Distributions }
793*1031c584SApple OSS Distributions
794*1031c584SApple OSS Distributions void
__ubsan_handle_function_type_mismatch(struct ubsan_func_type_mismatch_desc * desc,uint64_t func)795*1031c584SApple OSS Distributions __ubsan_handle_function_type_mismatch(struct ubsan_func_type_mismatch_desc *desc, uint64_t func)
796*1031c584SApple OSS Distributions {
797*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_FUNCTION_TYPE_MISMATCH, func, 0, .func_mismatch = desc, &desc->loc };
798*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
799*1031c584SApple OSS Distributions }
800*1031c584SApple OSS Distributions
801*1031c584SApple OSS Distributions void
__ubsan_handle_function_type_mismatch_abort(struct ubsan_func_type_mismatch_desc * desc,uint64_t func)802*1031c584SApple OSS Distributions __ubsan_handle_function_type_mismatch_abort(struct ubsan_func_type_mismatch_desc *desc, uint64_t func)
803*1031c584SApple OSS Distributions {
804*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_FUNCTION_TYPE_MISMATCH, func, 0, .func_mismatch = desc, &desc->loc };
805*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
806*1031c584SApple OSS Distributions }
807*1031c584SApple OSS Distributions
808*1031c584SApple OSS Distributions void
__ubsan_handle_vla_bound_not_positive(struct ubsan_vla_bound_desc * desc,uint64_t length)809*1031c584SApple OSS Distributions __ubsan_handle_vla_bound_not_positive(struct ubsan_vla_bound_desc *desc, uint64_t length)
810*1031c584SApple OSS Distributions {
811*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_VLA_BOUND_NOT_POSITIVE, length, 0, .vla_bound = desc, &desc->loc };
812*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
813*1031c584SApple OSS Distributions }
814*1031c584SApple OSS Distributions
815*1031c584SApple OSS Distributions void
__ubsan_handle_vla_bound_not_positive_abort(struct ubsan_vla_bound_desc * desc,uint64_t length)816*1031c584SApple OSS Distributions __ubsan_handle_vla_bound_not_positive_abort(struct ubsan_vla_bound_desc *desc, uint64_t length)
817*1031c584SApple OSS Distributions {
818*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_VLA_BOUND_NOT_POSITIVE, length, 0, .vla_bound = desc, &desc->loc };
819*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
820*1031c584SApple OSS Distributions }
821*1031c584SApple OSS Distributions
822*1031c584SApple OSS Distributions void
__ubsan_handle_invalid_builtin(struct ubsan_invalid_builtin * desc)823*1031c584SApple OSS Distributions __ubsan_handle_invalid_builtin(struct ubsan_invalid_builtin *desc)
824*1031c584SApple OSS Distributions {
825*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_INVALID_BUILTIN, 0, 0, .invalid_builtin = desc, &desc->loc };
826*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
827*1031c584SApple OSS Distributions }
828*1031c584SApple OSS Distributions
829*1031c584SApple OSS Distributions void
__ubsan_handle_invalid_builtin_abort(struct ubsan_invalid_builtin * desc)830*1031c584SApple OSS Distributions __ubsan_handle_invalid_builtin_abort(struct ubsan_invalid_builtin *desc)
831*1031c584SApple OSS Distributions {
832*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_INVALID_BUILTIN, 0, 0, .invalid_builtin = desc, &desc->loc };
833*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
834*1031c584SApple OSS Distributions }
835*1031c584SApple OSS Distributions
836*1031c584SApple OSS Distributions void
__ubsan_handle_load_invalid_value(struct ubsan_load_invalid_desc * desc,uint64_t invalid_value)837*1031c584SApple OSS Distributions __ubsan_handle_load_invalid_value(struct ubsan_load_invalid_desc *desc, uint64_t invalid_value)
838*1031c584SApple OSS Distributions {
839*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_LOAD_INVALID_VALUE, invalid_value, 0, .invalid = desc, &desc->loc };
840*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
841*1031c584SApple OSS Distributions }
842*1031c584SApple OSS Distributions
843*1031c584SApple OSS Distributions void
__ubsan_handle_load_invalid_value_abort(struct ubsan_load_invalid_desc * desc,uint64_t invalid_value)844*1031c584SApple OSS Distributions __ubsan_handle_load_invalid_value_abort(struct ubsan_load_invalid_desc *desc, uint64_t invalid_value)
845*1031c584SApple OSS Distributions {
846*1031c584SApple OSS Distributions ubsan_violation_t v = { UBSAN_LOAD_INVALID_VALUE, invalid_value, 0, .invalid = desc, &desc->loc };
847*1031c584SApple OSS Distributions ubsan_handle(&v, Fatal);
848*1031c584SApple OSS Distributions }
849