]>
Commit | Line | Data |
---|---|---|
5ba3f43e A |
1 | /* |
2 | * Copyright (c) 2000-2014 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_INTERNAL_H_ | |
30 | #define _KASAN_INTERNAL_H_ | |
31 | ||
32 | #include <stdbool.h> | |
33 | #include <mach/mach_vm.h> | |
34 | #include <kern/zalloc.h> | |
35 | ||
36 | typedef uintptr_t uptr; | |
37 | ||
5c9f4661 A |
38 | #define MiB(x) ((x) * 1024UL * 1024) |
39 | ||
5ba3f43e A |
40 | /* |
41 | * KASAN features and config | |
42 | */ | |
a39ff7e2 | 43 | #define KASAN_DEBUG 0 |
5ba3f43e | 44 | #define FAKESTACK 1 |
5ba3f43e A |
45 | /* KASAN_KALLOC defined in kasan.h */ |
46 | /* KASAN_ZALLOC defined in kasan.h */ | |
47 | #define FAKESTACK_QUARANTINE (1 && FAKESTACK) | |
48 | ||
49 | #define QUARANTINE_ENTRIES 5000 | |
5c9f4661 A |
50 | #define QUARANTINE_MAXSIZE MiB(10) |
51 | ||
52 | /* | |
53 | * The amount of physical memory stolen by KASan at boot to back the shadow memory | |
54 | * and page tables. Larger memory systems need to steal proportionally less. | |
55 | */ | |
56 | #ifdef __arm64__ | |
57 | /* Works out at about 25% of 512 MiB and 15% of 3GiB system */ | |
58 | # define STOLEN_MEM_PERCENT 13UL | |
59 | # define STOLEN_MEM_BYTES MiB(62) | |
60 | #else | |
61 | # define STOLEN_MEM_PERCENT 25UL | |
62 | # define STOLEN_MEM_BYTES 0 | |
63 | #endif | |
5ba3f43e | 64 | |
a39ff7e2 A |
65 | /* boot-args */ |
66 | #define KASAN_ARGS_FAKESTACK 0x0010U | |
67 | #define KASAN_ARGS_REPORTIGNORED 0x0020U | |
68 | #define KASAN_ARGS_NODYCHECKS 0x0100U | |
69 | #define KASAN_ARGS_NOPOISON_HEAP 0x0200U | |
70 | #define KASAN_ARGS_NOPOISON_GLOBAL 0x0400U | |
71 | ||
5ba3f43e A |
72 | #ifndef KASAN |
73 | # error KASAN undefined | |
74 | #endif | |
75 | ||
76 | #ifndef KASAN_SHIFT | |
77 | # error KASAN_SHIFT undefined | |
78 | #endif | |
79 | ||
80 | #define ADDRESS_FOR_SHADOW(x) (((x) - KASAN_SHIFT) << 3) | |
81 | #define SHADOW_FOR_ADDRESS(x) (uint8_t *)(((x) >> 3) + KASAN_SHIFT) | |
82 | ||
a39ff7e2 A |
83 | #if KASAN_DEBUG |
84 | # define NOINLINE __attribute__ ((noinline)) | |
85 | #else | |
86 | # define NOINLINE | |
87 | #endif | |
5ba3f43e A |
88 | #define ALWAYS_INLINE inline __attribute__((always_inline)) |
89 | ||
90 | #define CLANG_MIN_VERSION(x) (defined(__apple_build_version__) && (__apple_build_version__ >= (x))) | |
91 | ||
92 | #define BIT(x) (1U << (x)) | |
93 | ||
a39ff7e2 A |
94 | enum __attribute__((flag_enum)) kasan_access_types { |
95 | TYPE_LOAD = BIT(0), /* regular memory load */ | |
96 | TYPE_STORE = BIT(1), /* regular store */ | |
97 | TYPE_MEMR = BIT(2), /* memory intrinsic (read) */ | |
98 | TYPE_MEMW = BIT(3), /* memory intrinsic (write) */ | |
99 | TYPE_STRR = BIT(4), /* string intrinsic (read) */ | |
100 | TYPE_STRW = BIT(5), /* string intrinsic (write) */ | |
101 | TYPE_KFREE = BIT(6), /* kfree() */ | |
102 | TYPE_ZFREE = BIT(7), /* zfree() */ | |
103 | TYPE_FSFREE = BIT(8), /* fakestack free */ | |
104 | ||
105 | TYPE_UAF = BIT(12), | |
106 | TYPE_POISON_GLOBAL = BIT(13), | |
107 | TYPE_POISON_HEAP = BIT(14), | |
108 | /* no TYPE_POISON_STACK, because the runtime does not control stack poisoning */ | |
109 | TYPE_TEST = BIT(15), | |
5ba3f43e A |
110 | |
111 | /* masks */ | |
a39ff7e2 A |
112 | TYPE_MEM = TYPE_MEMR|TYPE_MEMW, /* memory intrinsics */ |
113 | TYPE_STR = TYPE_STRR|TYPE_STRW, /* string intrinsics */ | |
114 | TYPE_READ = TYPE_LOAD|TYPE_MEMR|TYPE_STRR, /* all reads */ | |
115 | TYPE_WRITE = TYPE_STORE|TYPE_MEMW|TYPE_STRW, /* all writes */ | |
116 | TYPE_RW = TYPE_READ|TYPE_WRITE, /* reads and writes */ | |
117 | TYPE_FREE = TYPE_KFREE|TYPE_ZFREE|TYPE_FSFREE, | |
118 | TYPE_NORMAL = TYPE_RW|TYPE_FREE, | |
119 | TYPE_DYNAMIC = TYPE_NORMAL|TYPE_UAF, | |
120 | TYPE_POISON = TYPE_POISON_GLOBAL|TYPE_POISON_HEAP, | |
121 | TYPE_ALL = ~0U, | |
5ba3f43e A |
122 | }; |
123 | ||
a39ff7e2 A |
124 | enum kasan_violation_types { |
125 | REASON_POISONED = 0, /* read or write of poisoned data */ | |
126 | REASON_BAD_METADATA = 1, /* incorrect kasan metadata */ | |
127 | REASON_INVALID_SIZE = 2, /* free size did not match alloc size */ | |
128 | REASON_MOD_AFTER_FREE = 3, /* object modified after free */ | |
129 | REASON_MOD_OOB = 4, /* out of bounds modification of object */ | |
130 | }; | |
131 | ||
132 | typedef enum kasan_access_types access_t; | |
133 | typedef enum kasan_violation_types violation_t; | |
134 | ||
5ba3f43e | 135 | bool kasan_range_poisoned(vm_offset_t base, vm_size_t size, vm_offset_t *first_invalid); |
a39ff7e2 | 136 | void kasan_check_range(const void *x, size_t sz, access_t); |
5ba3f43e A |
137 | void kasan_test(int testno, int fail); |
138 | void kasan_handle_test(void); | |
5ba3f43e A |
139 | void kasan_free_internal(void **addrp, vm_size_t *sizep, int type, zone_t *, vm_size_t user_size, int locked, bool doquarantine); |
140 | void kasan_poison(vm_offset_t base, vm_size_t size, vm_size_t leftrz, vm_size_t rightrz, uint8_t flags); | |
5ba3f43e A |
141 | void kasan_lock(boolean_t *b); |
142 | void kasan_unlock(boolean_t b); | |
a39ff7e2 | 143 | bool kasan_lock_held(thread_t thread); |
5ba3f43e A |
144 | void kasan_init_fakestack(void); |
145 | ||
146 | /* dynamic blacklist */ | |
147 | void kasan_init_dybl(void); | |
a39ff7e2 | 148 | bool kasan_is_blacklisted(access_t); |
5ba3f43e A |
149 | void kasan_dybl_load_kext(uintptr_t addr, const char *kextname); |
150 | void kasan_dybl_unload_kext(uintptr_t addr); | |
151 | ||
152 | /* arch-specific interface */ | |
153 | void kasan_arch_init(void); | |
a39ff7e2 | 154 | bool kasan_is_shadow_mapped(uintptr_t shadowp); |
5ba3f43e A |
155 | |
156 | extern vm_address_t kernel_vbase; | |
157 | extern vm_address_t kernel_vtop; | |
158 | ||
a39ff7e2 A |
159 | extern unsigned shadow_pages_used; |
160 | ||
161 | /* boot-arg configurable */ | |
162 | extern int fakestack_enabled; | |
5ba3f43e A |
163 | |
164 | /* Describes the source location where a global is defined. */ | |
165 | struct asan_global_source_location { | |
166 | const char *filename; | |
167 | int line_no; | |
168 | int column_no; | |
169 | }; | |
170 | ||
171 | /* Describes an instrumented global variable. */ | |
172 | struct asan_global { | |
173 | uptr addr; | |
174 | uptr size; | |
175 | uptr size_with_redzone; | |
176 | const char *name; | |
177 | const char *module; | |
178 | uptr has_dynamic_init; | |
179 | struct asan_global_source_location *location; | |
180 | #if CLANG_MIN_VERSION(8020000) | |
181 | uptr odr_indicator; | |
182 | #endif | |
183 | }; | |
184 | ||
185 | #if defined(__x86_64__) | |
186 | # define _JBLEN ((9 * 2) + 3 + 16) | |
5c9f4661 A |
187 | #elif defined(__arm64__) |
188 | # define _JBLEN ((14 + 8 + 2) * 2) | |
189 | #else | |
190 | # error "Unknown arch" | |
5ba3f43e A |
191 | #endif |
192 | ||
5ba3f43e A |
193 | typedef int jmp_buf[_JBLEN]; |
194 | void _longjmp(jmp_buf env, int val); | |
195 | int _setjmp(jmp_buf env); | |
196 | ||
197 | #endif /* _KASAN_INTERNAL_H_ */ |