xref: /xnu-10063.141.1/san/memory/kasan.h (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
1*d8b80295SApple OSS Distributions /*
2*d8b80295SApple OSS Distributions  * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
3*d8b80295SApple OSS Distributions  *
4*d8b80295SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*d8b80295SApple OSS Distributions  *
6*d8b80295SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*d8b80295SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*d8b80295SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*d8b80295SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*d8b80295SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*d8b80295SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*d8b80295SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*d8b80295SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*d8b80295SApple OSS Distributions  *
15*d8b80295SApple OSS Distributions  * Please obtain a copy of the License at
16*d8b80295SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*d8b80295SApple OSS Distributions  *
18*d8b80295SApple OSS Distributions  * The Original Code and all software distributed under the License are
19*d8b80295SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*d8b80295SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*d8b80295SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*d8b80295SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*d8b80295SApple OSS Distributions  * Please see the License for the specific language governing rights and
24*d8b80295SApple OSS Distributions  * limitations under the License.
25*d8b80295SApple OSS Distributions  *
26*d8b80295SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*d8b80295SApple OSS Distributions  */
28*d8b80295SApple OSS Distributions 
29*d8b80295SApple OSS Distributions #ifndef _KASAN_H_
30*d8b80295SApple OSS Distributions #define _KASAN_H_
31*d8b80295SApple OSS Distributions 
32*d8b80295SApple OSS Distributions #if KERNEL_PRIVATE
33*d8b80295SApple OSS Distributions 
34*d8b80295SApple OSS Distributions #include <mach/mach_types.h>
35*d8b80295SApple OSS Distributions #include <sys/queue.h>
36*d8b80295SApple OSS Distributions 
37*d8b80295SApple OSS Distributions typedef uintptr_t uptr;
38*d8b80295SApple OSS Distributions 
39*d8b80295SApple OSS Distributions #if KASAN
40*d8b80295SApple OSS Distributions 
41*d8b80295SApple OSS Distributions #if KASAN_CLASSIC
42*d8b80295SApple OSS Distributions #include "kasan-classic.h"
43*d8b80295SApple OSS Distributions #elif KASAN_TBI
44*d8b80295SApple OSS Distributions #include "kasan-tbi.h"
45*d8b80295SApple OSS Distributions #else
46*d8b80295SApple OSS Distributions #error "No kasan model specified"
47*d8b80295SApple OSS Distributions #endif
48*d8b80295SApple OSS Distributions 
49*d8b80295SApple OSS Distributions /*
50*d8b80295SApple OSS Distributions  * When mapping shadow memory, decide whether the created mapping can be later
51*d8b80295SApple OSS Distributions  * updated/poisoned or whether it should just stay marked accessible for its
52*d8b80295SApple OSS Distributions  * lifetime (and catch incorrect attempts at poisoning it).
53*d8b80295SApple OSS Distributions  *
54*d8b80295SApple OSS Distributions  * Consumed by: kasan_map_shadow()
55*d8b80295SApple OSS Distributions  */
56*d8b80295SApple OSS Distributions #define KASAN_CANNOT_POISON             true
57*d8b80295SApple OSS Distributions #define KASAN_MAY_POISON                false
58*d8b80295SApple OSS Distributions 
59*d8b80295SApple OSS Distributions __BEGIN_DECLS
60*d8b80295SApple OSS Distributions 
61*d8b80295SApple OSS Distributions void kasan_map_shadow(vm_offset_t, vm_size_t, bool);
62*d8b80295SApple OSS Distributions 
63*d8b80295SApple OSS Distributions /* KASAN enable/disable and general initialization. */
64*d8b80295SApple OSS Distributions void kasan_init(void);
65*d8b80295SApple OSS Distributions void kasan_late_init(void);
66*d8b80295SApple OSS Distributions void kasan_reserve_memory(void *);
67*d8b80295SApple OSS Distributions void kasan_notify_stolen(vm_offset_t);
68*d8b80295SApple OSS Distributions 
69*d8b80295SApple OSS Distributions /*
70*d8b80295SApple OSS Distributions  * Helper functions to run the necessary initialization and cleanup
71*d8b80295SApple OSS Distributions  * at every KEXT load/unload.
72*d8b80295SApple OSS Distributions  */
73*d8b80295SApple OSS Distributions void kasan_load_kext(vm_offset_t, vm_size_t, const void *);
74*d8b80295SApple OSS Distributions void kasan_unload_kext(vm_offset_t, vm_size_t);
75*d8b80295SApple OSS Distributions 
76*d8b80295SApple OSS Distributions /*
77*d8b80295SApple OSS Distributions  * API for the kernel to communicate to KASAN that a new range needs to be
78*d8b80295SApple OSS Distributions  * accounted for in the shadow table.
79*d8b80295SApple OSS Distributions  */
80*d8b80295SApple OSS Distributions void kasan_notify_address(vm_offset_t, vm_size_t);
81*d8b80295SApple OSS Distributions void kasan_notify_address_nopoison(vm_offset_t, vm_size_t);
82*d8b80295SApple OSS Distributions 
83*d8b80295SApple OSS Distributions /*
84*d8b80295SApple OSS Distributions  * Control the shadow table state for a given range.
85*d8b80295SApple OSS Distributions  */
86*d8b80295SApple OSS Distributions void kasan_poison(vm_offset_t, vm_size_t, vm_size_t, vm_size_t, uint8_t);
87*d8b80295SApple OSS Distributions void kasan_unpoison(void *, vm_size_t);
88*d8b80295SApple OSS Distributions void kasan_poison_range(vm_offset_t, vm_size_t, uint8_t);
89*d8b80295SApple OSS Distributions void kasan_unpoison_stack(vm_offset_t, vm_size_t);
90*d8b80295SApple OSS Distributions void kasan_unpoison_curstack(bool);
91*d8b80295SApple OSS Distributions bool kasan_check_shadow(vm_address_t, vm_size_t, uint8_t);
92*d8b80295SApple OSS Distributions void kasan_unpoison_cxx_array_cookie(void *);
93*d8b80295SApple OSS Distributions 
94*d8b80295SApple OSS Distributions /* Fakestack */
95*d8b80295SApple OSS Distributions void kasan_fakestack_drop(thread_t); /* mark all fakestack entries for thread as unused */
96*d8b80295SApple OSS Distributions void kasan_fakestack_gc(thread_t);   /* free and poison all unused fakestack objects for thread */
97*d8b80295SApple OSS Distributions void kasan_fakestack_suspend(void);
98*d8b80295SApple OSS Distributions void kasan_fakestack_resume(void);
99*d8b80295SApple OSS Distributions void kasan_unpoison_fakestack(thread_t);
100*d8b80295SApple OSS Distributions 
101*d8b80295SApple OSS Distributions /* KDP support */
102*d8b80295SApple OSS Distributions typedef int (*pmap_traverse_callback)(vm_map_offset_t, vm_map_offset_t, void *);
103*d8b80295SApple OSS Distributions int kasan_traverse_mappings(pmap_traverse_callback, void *);
104*d8b80295SApple OSS Distributions void kasan_kdp_disable(void);
105*d8b80295SApple OSS Distributions 
106*d8b80295SApple OSS Distributions /* Tests API */
107*d8b80295SApple OSS Distributions struct kasan_test {
108*d8b80295SApple OSS Distributions 	int (* func)(struct kasan_test *);
109*d8b80295SApple OSS Distributions 	void (* cleanup)(struct kasan_test *);
110*d8b80295SApple OSS Distributions 	const char *name;
111*d8b80295SApple OSS Distributions 	int result;
112*d8b80295SApple OSS Distributions 	void *data;
113*d8b80295SApple OSS Distributions 	size_t datasz;
114*d8b80295SApple OSS Distributions };
115*d8b80295SApple OSS Distributions void __kasan_runtests(struct kasan_test *, int numtests);
116*d8b80295SApple OSS Distributions 
117*d8b80295SApple OSS Distributions #if XNU_KERNEL_PRIVATE
118*d8b80295SApple OSS Distributions extern unsigned shadow_pages_total;
119*d8b80295SApple OSS Distributions 
120*d8b80295SApple OSS Distributions #if __arm64__
121*d8b80295SApple OSS Distributions void kasan_notify_address_zero(vm_offset_t, vm_size_t);
122*d8b80295SApple OSS Distributions #elif __x86_64__
123*d8b80295SApple OSS Distributions extern void kasan_map_low_fixed_regions(void);
124*d8b80295SApple OSS Distributions extern unsigned shadow_stolen_idx;
125*d8b80295SApple OSS Distributions #endif /* __arm64__ */
126*d8b80295SApple OSS Distributions 
127*d8b80295SApple OSS Distributions #endif /* XNU_KERNEL_PRIVATE */
128*d8b80295SApple OSS Distributions 
129*d8b80295SApple OSS Distributions #if HIBERNATION
130*d8b80295SApple OSS Distributions /*
131*d8b80295SApple OSS Distributions  * hibernate_write_image() needs to know the current extent of the shadow table
132*d8b80295SApple OSS Distributions  */
133*d8b80295SApple OSS Distributions extern vm_offset_t shadow_pnext, shadow_ptop;
134*d8b80295SApple OSS Distributions #endif /* HIBERNATION */
135*d8b80295SApple OSS Distributions 
136*d8b80295SApple OSS Distributions /* thread interface */
137*d8b80295SApple OSS Distributions struct kasan_thread_data {
138*d8b80295SApple OSS Distributions 	LIST_HEAD(fakestack_header_list, fakestack_header) fakestack_head;
139*d8b80295SApple OSS Distributions };
140*d8b80295SApple OSS Distributions struct kasan_thread_data *kasan_get_thread_data(thread_t);
141*d8b80295SApple OSS Distributions void kasan_init_thread(struct kasan_thread_data *);
142*d8b80295SApple OSS Distributions 
143*d8b80295SApple OSS Distributions /*
144*d8b80295SApple OSS Distributions  * ASAN callbacks - inserted by the compiler
145*d8b80295SApple OSS Distributions  */
146*d8b80295SApple OSS Distributions 
147*d8b80295SApple OSS Distributions extern int __asan_option_detect_stack_use_after_return;
148*d8b80295SApple OSS Distributions extern const uintptr_t __asan_shadow_memory_dynamic_address;
149*d8b80295SApple OSS Distributions 
150*d8b80295SApple OSS Distributions #define KASAN_DECLARE_FOREACH_WIDTH(ret, func, ...) \
151*d8b80295SApple OSS Distributions 	ret func ## 1(__VA_ARGS__); \
152*d8b80295SApple OSS Distributions 	ret func ## 2(__VA_ARGS__); \
153*d8b80295SApple OSS Distributions 	ret func ## 4(__VA_ARGS__); \
154*d8b80295SApple OSS Distributions 	ret func ## 8(__VA_ARGS__); \
155*d8b80295SApple OSS Distributions 	ret func ## 16(__VA_ARGS__)
156*d8b80295SApple OSS Distributions 
157*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_load, uptr);
158*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_store, uptr);
159*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_store, uptr);
160*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_exp_load, uptr, int32_t);
161*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_report_exp_store, uptr, int32_t);
162*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_exp_load, uptr, int32_t);
163*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_exp_store, uptr, int32_t);
164*d8b80295SApple OSS Distributions KASAN_DECLARE_FOREACH_WIDTH(void, __asan_load, uptr);
165*d8b80295SApple OSS Distributions 
166*d8b80295SApple OSS Distributions void __asan_report_load_n(uptr, unsigned long);
167*d8b80295SApple OSS Distributions void __asan_report_store_n(uptr, unsigned long);
168*d8b80295SApple OSS Distributions void __asan_handle_no_return(void);
169*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_0(size_t);
170*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_1(size_t);
171*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_2(size_t);
172*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_3(size_t);
173*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_4(size_t);
174*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_5(size_t);
175*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_6(size_t);
176*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_7(size_t);
177*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_8(size_t);
178*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_9(size_t);
179*d8b80295SApple OSS Distributions uptr __asan_stack_malloc_10(size_t);
180*d8b80295SApple OSS Distributions void __asan_stack_free_0(uptr, size_t);
181*d8b80295SApple OSS Distributions void __asan_stack_free_1(uptr, size_t);
182*d8b80295SApple OSS Distributions void __asan_stack_free_2(uptr, size_t);
183*d8b80295SApple OSS Distributions void __asan_stack_free_3(uptr, size_t);
184*d8b80295SApple OSS Distributions void __asan_stack_free_4(uptr, size_t);
185*d8b80295SApple OSS Distributions void __asan_stack_free_5(uptr, size_t);
186*d8b80295SApple OSS Distributions void __asan_stack_free_6(uptr, size_t);
187*d8b80295SApple OSS Distributions void __asan_stack_free_7(uptr, size_t);
188*d8b80295SApple OSS Distributions void __asan_stack_free_8(uptr, size_t);
189*d8b80295SApple OSS Distributions void __asan_stack_free_9(uptr, size_t);
190*d8b80295SApple OSS Distributions void __asan_stack_free_10(uptr, size_t);
191*d8b80295SApple OSS Distributions void __asan_poison_cxx_array_cookie(uptr);
192*d8b80295SApple OSS Distributions uptr __asan_load_cxx_array_cookie(uptr *);
193*d8b80295SApple OSS Distributions void __asan_poison_stack_memory(uptr, size_t);
194*d8b80295SApple OSS Distributions void __asan_unpoison_stack_memory(uptr, size_t);
195*d8b80295SApple OSS Distributions void __asan_alloca_poison(uptr, uptr);
196*d8b80295SApple OSS Distributions void __asan_allocas_unpoison(uptr, uptr);
197*d8b80295SApple OSS Distributions void __asan_loadN(uptr, size_t);
198*d8b80295SApple OSS Distributions void __asan_storeN(uptr, size_t);
199*d8b80295SApple OSS Distributions void __sanitizer_ptr_sub(uptr, uptr);
200*d8b80295SApple OSS Distributions void __sanitizer_ptr_cmp(uptr, uptr);
201*d8b80295SApple OSS Distributions void __sanitizer_annotate_contiguous_container(const void *, const void *,
202*d8b80295SApple OSS Distributions     const void *, const void *n);
203*d8b80295SApple OSS Distributions 
204*d8b80295SApple OSS Distributions void __asan_exp_loadN(uptr, size_t, int32_t);
205*d8b80295SApple OSS Distributions void __asan_exp_storeN(uptr, size_t, int32_t);
206*d8b80295SApple OSS Distributions void __asan_report_exp_load_n(uptr, unsigned long, int32_t);
207*d8b80295SApple OSS Distributions void __asan_report_exp_store_n(uptr, unsigned long, int32_t);
208*d8b80295SApple OSS Distributions 
209*d8b80295SApple OSS Distributions void __asan_set_shadow_00(uptr, size_t);
210*d8b80295SApple OSS Distributions void __asan_set_shadow_f1(uptr, size_t);
211*d8b80295SApple OSS Distributions void __asan_set_shadow_f2(uptr, size_t);
212*d8b80295SApple OSS Distributions void __asan_set_shadow_f3(uptr, size_t);
213*d8b80295SApple OSS Distributions void __asan_set_shadow_f5(uptr, size_t);
214*d8b80295SApple OSS Distributions void __asan_set_shadow_f8(uptr, size_t);
215*d8b80295SApple OSS Distributions 
216*d8b80295SApple OSS Distributions void __asan_init_v5(void);
217*d8b80295SApple OSS Distributions void __asan_register_globals(uptr, uptr);
218*d8b80295SApple OSS Distributions void __asan_unregister_globals(uptr, uptr);
219*d8b80295SApple OSS Distributions void __asan_register_elf_globals(uptr, uptr, uptr);
220*d8b80295SApple OSS Distributions void __asan_unregister_elf_globals(uptr, uptr, uptr);
221*d8b80295SApple OSS Distributions 
222*d8b80295SApple OSS Distributions void __asan_before_dynamic_init(uptr);
223*d8b80295SApple OSS Distributions void __asan_after_dynamic_init(void);
224*d8b80295SApple OSS Distributions void __asan_init(void);
225*d8b80295SApple OSS Distributions void __asan_unregister_image_globals(uptr);
226*d8b80295SApple OSS Distributions void __asan_register_image_globals(uptr);
227*d8b80295SApple OSS Distributions 
228*d8b80295SApple OSS Distributions void __hwasan_tag_memory(uintptr_t, unsigned char, uintptr_t);
229*d8b80295SApple OSS Distributions unsigned char __hwasan_generate_tag(void);
230*d8b80295SApple OSS Distributions 
231*d8b80295SApple OSS Distributions __END_DECLS
232*d8b80295SApple OSS Distributions 
233*d8b80295SApple OSS Distributions #endif /* KASAN */
234*d8b80295SApple OSS Distributions 
235*d8b80295SApple OSS Distributions #if __has_feature(address_sanitizer)
236*d8b80295SApple OSS Distributions #define NOKASAN __attribute__ ((no_sanitize_address))
237*d8b80295SApple OSS Distributions #elif __has_feature(hwaddress_sanitizer)
238*d8b80295SApple OSS Distributions #define NOKASAN __attribute__((no_sanitize("kernel-hwaddress")))
239*d8b80295SApple OSS Distributions #else /* address_sanitizer || hwaddress_sanitizer */
240*d8b80295SApple OSS Distributions #define NOKASAN
241*d8b80295SApple OSS Distributions #endif
242*d8b80295SApple OSS Distributions 
243*d8b80295SApple OSS Distributions /*
244*d8b80295SApple OSS Distributions  * KASAN provides a description of each global variable in the
245*d8b80295SApple OSS Distributions  * __DATA.__asan_globals section. This description is walked for xnu at boot
246*d8b80295SApple OSS Distributions  * and at each KEXT load/unload operation, to allow the KASAN implementation
247*d8b80295SApple OSS Distributions  * to perform the necessary redzoning around each variable.
248*d8b80295SApple OSS Distributions  *
249*d8b80295SApple OSS Distributions  * Consumed in OSKext.cpp, so must stay outside KASAN-specific defines.
250*d8b80295SApple OSS Distributions  */
251*d8b80295SApple OSS Distributions #define KASAN_GLOBAL_SEGNAME  "__DATA"
252*d8b80295SApple OSS Distributions #define KASAN_GLOBAL_SECTNAME "__asan_globals"
253*d8b80295SApple OSS Distributions 
254*d8b80295SApple OSS Distributions #endif /* KERNEL_PRIVATE */
255*d8b80295SApple OSS Distributions #endif /* _KASAN_H_ */
256