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