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