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