]>
Commit | Line | Data |
---|---|---|
cb323159 A |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
7 | * | |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://www.opensolaris.org/os/licensing. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | ||
22 | #include <sys/dtrace_impl.h> | |
23 | #include <sys/fbt.h> | |
24 | #include <sys/sysctl.h> | |
25 | ||
26 | #define CLOSURE(s) #s, | |
27 | #define CRITICAL(s) #s, | |
28 | ||
29 | #if KASAN | |
30 | #define KASAN_ONLY(s) #s, | |
31 | #else | |
32 | #define KASAN_ONLY(s) | |
33 | #endif /* KASAN */ | |
34 | ||
35 | #if defined(__arm__) || defined(__arm64__) | |
36 | #define ARM_ONLY(s) #s, | |
37 | #else | |
38 | #define ARM_ONLY(s) | |
39 | #endif /* defined(__arm__) || defined(__arm64__) */ | |
40 | #if defined(__x86_64__) | |
41 | #define X86_ONLY(s) #s, | |
42 | #else | |
43 | #define X86_ONLY(s) | |
44 | #endif /* defined(__x86_64__) */ | |
45 | ||
46 | /* | |
47 | * Routine prefixes that must not be probed, either because they are used in | |
48 | * the exception path, by dtrace code in probe context, or are general | |
49 | * critical routines that must never be probed. | |
50 | * | |
51 | * All routines whose name start with one of these will be ignored. | |
52 | * | |
53 | * This must be kept in asciibetical order for purposes of bsearch(). | |
54 | */ | |
55 | const char * fbt_blacklist[] = | |
56 | { | |
57 | CRITICAL(Call_DebuggerC) | |
58 | CLOSURE(ClearIdlePop) | |
59 | CLOSURE(Debugger) | |
60 | CRITICAL(IOCPURunPlatformPanicActions) | |
61 | CLOSURE(IS_64BIT_PROCESS) | |
62 | CRITICAL(OSAdd) | |
63 | CRITICAL(OSBit) | |
64 | CLOSURE(OSCompareAndSwap) | |
65 | CRITICAL(OSDecrement) | |
66 | CRITICAL(OSIncrement) | |
67 | CRITICAL(PEARMDebugPanicHook) | |
68 | CRITICAL(PEHaltRestart) | |
69 | CRITICAL(PE_) | |
70 | CRITICAL(SavePanicInfo) | |
71 | CLOSURE(SetIdlePop) | |
72 | CRITICAL(SysChoked) | |
73 | CRITICAL(_ZN15OSMetaClassBase12safeMetaCastEPKS_PK11OSMetaClass) /* OSMetaClassBase::safeMetaCast */ | |
74 | CRITICAL(_ZN16IOPlatformExpert11haltRestartEj) /* IOPlatformExpert::haltRestart */ | |
75 | CRITICAL(_ZN18IODTPlatformExpert11haltRestartEj) /* IODTPlatformExpert::haltRestart */ | |
76 | ARM_ONLY(_ZN8ASPNVRAM4syncEv) /* ASPNVRAM::sync */ | |
77 | CRITICAL(_ZN9IODTNVRAM13savePanicInfoEPhy) /* IODTNVRAM::savePanicInfo */ | |
78 | CRITICAL(_ZN9IOService14newTemperatureElPS_) /* IOService::newTemperature */ | |
79 | CRITICAL(_ZN9IOService26temperatureCriticalForZoneEPS_) /* IOService::temperatureCriticalForZone */ | |
80 | CRITICAL(_ZNK11OSMetaClass13checkMetaCastEPK15OSMetaClassBase) /* OSMetaClass::checkMetaCast */ | |
81 | CRITICAL(_ZNK15OSMetaClassBase8metaCastEPK11OSMetaClass) /* OSMetaClassBase::metaCast */ | |
82 | CRITICAL(_ZNK6OSData14getBytesNoCopyEv) /* Data::getBytesNoCopy, IOHibernateSystemWake path */ | |
83 | KASAN_ONLY(__asan) | |
84 | ARM_ONLY(__div) | |
85 | CLOSURE(__dtrace_probe) | |
86 | KASAN_ONLY(__kasan) | |
87 | ARM_ONLY(__mod) | |
88 | CRITICAL(__strlcpy_chk) | |
89 | ARM_ONLY(__udiv) | |
90 | ARM_ONLY(__umod) | |
91 | CRITICAL(_disable_preemption) | |
92 | CRITICAL(_enable_preemption) | |
93 | CLOSURE(absolutetime_to_microtime) | |
94 | X86_ONLY(acpi_) | |
95 | X86_ONLY(act_machine) | |
96 | CLOSURE(act_set_astbsd) | |
97 | ARM_ONLY(alternate_debugger_enter) | |
98 | ARM_ONLY(arm_init_idle_cpu) | |
99 | CLOSURE(ast_dtrace_on) | |
100 | CLOSURE(ast_pending) | |
101 | CRITICAL(bcopy) | |
102 | CLOSURE(clean_dcache) | |
103 | CLOSURE(clean_mmu_dcache) | |
104 | CRITICAL(clock_) | |
105 | X86_ONLY(commpage_) | |
106 | CRITICAL(console_cpu_alloc) | |
107 | CRITICAL(console_cpu_free) | |
108 | CLOSURE(copyin) | |
109 | CLOSURE(copyout) | |
110 | CRITICAL(cpu_) | |
111 | CLOSURE(current_proc) | |
112 | CLOSURE(current_processor) | |
113 | CLOSURE(current_task) | |
114 | CLOSURE(current_thread) | |
115 | CLOSURE(debug_) | |
116 | X86_ONLY(dsmos_) | |
117 | CLOSURE(dtrace_) | |
118 | CRITICAL(enter_lohandler) | |
119 | CRITICAL(fasttrap_) | |
120 | CRITICAL(fbt_invop) | |
121 | CRITICAL(fbt_perfCallback) | |
122 | CLOSURE(find_user_regs) | |
123 | ARM_ONLY(fleh_) | |
124 | CLOSURE(flush_dcache) | |
125 | ARM_ONLY(flush_mmu_tlb_) | |
126 | CLOSURE(flush_tlb64) | |
127 | CRITICAL(fuword) | |
128 | CLOSURE(get_bsdtask_info) | |
129 | CLOSURE(get_bsdthread_info) | |
130 | CRITICAL(get_preemption_level) | |
131 | CRITICAL(get_threadtask) | |
132 | ARM_ONLY(get_vfp_enabled) | |
133 | CRITICAL(getminor) | |
134 | CRITICAL(handle_pending_TLB_flushes) | |
135 | CRITICAL(hibernate_) | |
136 | X86_ONLY(hndl_) | |
137 | CRITICAL(hw_) | |
138 | X86_ONLY(idt64) | |
139 | CRITICAL(interrupt) | |
140 | CRITICAL(invalidate_mmu_icache) | |
141 | CRITICAL(is_saved_state32) | |
142 | KASAN_ONLY(kasan) | |
143 | CLOSURE(kauth_cred_get) | |
144 | CLOSURE(kauth_getgid) | |
145 | CLOSURE(kauth_getuid) | |
146 | CRITICAL(kdb_) | |
147 | CRITICAL(kdp_) | |
148 | CRITICAL(kernel_preempt_check) | |
149 | CRITICAL(kernel_trap) | |
150 | CRITICAL(kprintf) | |
151 | CRITICAL(ks_) | |
152 | CLOSURE(kvtophys) | |
153 | X86_ONLY(lapic_) | |
154 | CRITICAL(lo_alltraps) | |
155 | CRITICAL(lock_debugger) | |
156 | CLOSURE(mach_absolute_time) | |
157 | CRITICAL(machine_) | |
158 | X86_ONLY(mapping_) | |
159 | CRITICAL(mca_cpu_alloc) | |
160 | CRITICAL(mca_cpu_init) | |
161 | CLOSURE(memcpy) | |
162 | CLOSURE(memmove) | |
163 | CRITICAL(ml_) | |
164 | CLOSURE(mt_core_snap) | |
165 | CLOSURE(mt_cur_cpu_cycles) | |
166 | CLOSURE(mt_cur_cpu_instrs) | |
167 | CLOSURE(mt_cur_thread_cycles) | |
168 | CLOSURE(mt_cur_thread_instrs) | |
169 | CLOSURE(mt_fixed_counts) | |
170 | CLOSURE(mt_fixed_counts_internal) | |
171 | CLOSURE(mt_mtc_update_count) | |
172 | CLOSURE(mt_update_thread) | |
173 | CRITICAL(nanoseconds_to_absolutetime) | |
174 | CRITICAL(nanotime_to_absolutetime) | |
f427ee49 | 175 | CRITICAL(no_asts) |
cb323159 A |
176 | CRITICAL(ovbcopy) |
177 | CRITICAL(packA) | |
178 | X86_ONLY(pal_) | |
179 | CLOSURE(panic) | |
180 | CRITICAL(phystokv) | |
181 | CRITICAL(platform_) | |
182 | X86_ONLY(pltrace) | |
183 | X86_ONLY(pmCPU) | |
184 | X86_ONLY(pmKextRegister) | |
185 | X86_ONLY(pmMarkAllCPUsOff) | |
186 | X86_ONLY(pmSafeMode) | |
187 | X86_ONLY(pmTimerRestore) | |
188 | X86_ONLY(pmTimerSave) | |
189 | X86_ONLY(pmUnRegister) | |
190 | X86_ONLY(pmap64_pdpt) | |
f427ee49 | 191 | CLOSURE(pmap_find_pa) |
cb323159 | 192 | CLOSURE(pmap_find_phys) |
f427ee49 | 193 | ARM_ONLY(pmap_get_cpu_data) |
cb323159 A |
194 | CLOSURE(pmap_get_mapwindow) |
195 | CLOSURE(pmap_pde) | |
196 | CLOSURE(pmap_pde_internal0) | |
197 | CLOSURE(pmap_pde_internal1) | |
198 | CLOSURE(pmap_pte) | |
199 | CLOSURE(pmap_pte_internal) | |
200 | CLOSURE(pmap_put_mapwindow) | |
201 | CLOSURE(pmap_valid_page) | |
f427ee49 | 202 | CLOSURE(pmap_vtophys) |
cb323159 A |
203 | X86_ONLY(pms) |
204 | CRITICAL(power_management_init) | |
205 | CRITICAL(preemption_underflow_panic) | |
206 | CLOSURE(prf) | |
f427ee49 | 207 | CLOSURE(proc_best_name) |
cb323159 | 208 | CLOSURE(proc_is64bit) |
c3c9b80d | 209 | X86_ONLY(proc_require) |
94ff46dc | 210 | CRITICAL(rbtrace_bt) |
cb323159 A |
211 | CRITICAL(register_cpu_setup_func) |
212 | CRITICAL(ret64_iret) | |
213 | CRITICAL(ret_to_user) | |
214 | CRITICAL(return_to_kernel) | |
215 | CRITICAL(return_to_user) | |
216 | CRITICAL(rtc_) | |
217 | CRITICAL(rtclock_) | |
218 | CRITICAL(saved_state64) | |
219 | CLOSURE(sdt_getargdesc) | |
220 | CRITICAL(sdt_invop) | |
221 | CLOSURE(setPop) | |
222 | ARM_ONLY(sleh_) | |
223 | CRITICAL(sprlock) | |
224 | CRITICAL(sprunlock) | |
225 | CLOSURE(strlcpy) | |
226 | CRITICAL(strlen) | |
227 | CRITICAL(strncmp) | |
228 | CRITICAL(suword) | |
229 | X86_ONLY(sync_iss_to_iks_unconditionally) | |
230 | CLOSURE(systrace_stub) | |
231 | CRITICAL(t_invop) | |
232 | CLOSURE(timer_grab) | |
233 | ARM_ONLY(timer_state_event) | |
234 | CRITICAL(tmrCvt) | |
235 | CRITICAL(trap_from_kernel) | |
94ff46dc | 236 | CRITICAL(traptrace_) |
cb323159 A |
237 | CRITICAL(tsc_) |
238 | CRITICAL(uart_putc) | |
239 | CRITICAL(unlock_debugger) | |
240 | CRITICAL(unpackA) | |
241 | CRITICAL(unregister_cpu_setup_func) | |
242 | CRITICAL(uread) | |
243 | CRITICAL(uwrite) | |
244 | CRITICAL(vstart) | |
c3c9b80d A |
245 | X86_ONLY(zone_has_index) |
246 | X86_ONLY(zone_id_require) | |
247 | X86_ONLY(zone_id_require_panic) | |
248 | X86_ONLY(zone_range_contains) | |
249 | X86_ONLY(zone_require_panic) | |
cb323159 A |
250 | }; |
251 | #define BLACKLIST_COUNT (sizeof(fbt_blacklist)/sizeof(fbt_blacklist[0])) | |
252 | ||
253 | /* | |
254 | * Modules that should not be probed. | |
255 | * | |
256 | * This must be kept in asciibetical order for purposes of bsearch(). | |
257 | */ | |
258 | static const char* fbt_module_blacklist[] = { | |
259 | X86_ONLY(com.apple.driver.AppleACPIEC) | |
260 | X86_ONLY(com.apple.driver.AppleACPIPlatform) | |
261 | ARM_ONLY(com.apple.driver.AppleARMPlatform) | |
262 | X86_ONLY(com.apple.driver.AppleEFI) | |
263 | X86_ONLY(com.apple.driver.AppleIntelCPUPowerManagement) | |
264 | ARM_ONLY(com.apple.driver.AppleInterruptController) | |
265 | X86_ONLY(com.apple.driver.AppleRTC) | |
266 | X86_ONLY(com.apple.iokit.IOACPIFamily) | |
267 | }; | |
268 | #define MODULE_BLACKLIST_COUNT (sizeof(fbt_module_blacklist)/sizeof(fbt_module_blacklist[0])) | |
269 | ||
270 | int ignore_fbt_blacklist = 0; | |
271 | extern int dtrace_kernel_symbol_mode; | |
272 | ||
273 | #pragma clang diagnostic push | |
274 | #pragma clang diagnostic ignored "-Wcast-qual" | |
275 | static int | |
276 | _cmp(const void *a, const void *b) | |
277 | { | |
278 | const char *v = *(const char **)b; | |
279 | return strncmp((const char *)a, v, strlen(v)); | |
280 | } | |
281 | ||
282 | ||
283 | #pragma clang diagnostic pop | |
284 | /* | |
285 | * Module validation | |
286 | */ | |
287 | bool | |
288 | fbt_module_excluded(struct modctl* ctl) | |
289 | { | |
290 | const char *excluded; | |
291 | ||
292 | ASSERT(!MOD_FBT_DONE(ctl)); | |
293 | ||
294 | if (ctl->mod_address == 0 || ctl->mod_size == 0 || !ctl->mod_loaded) { | |
295 | return true; | |
296 | } | |
297 | ||
298 | if (ignore_fbt_blacklist) { | |
299 | return false; | |
300 | } | |
301 | ||
302 | excluded = bsearch(ctl->mod_modname, fbt_module_blacklist, | |
303 | MODULE_BLACKLIST_COUNT, sizeof(fbt_module_blacklist[0]), _cmp); | |
304 | return excluded; | |
305 | } | |
306 | ||
307 | /* | |
308 | * FBT probe name validation | |
309 | */ | |
310 | bool | |
311 | fbt_excluded(const char* name) | |
312 | { | |
313 | const char *excluded; | |
314 | ||
315 | if (ignore_fbt_blacklist) { | |
316 | return false; | |
317 | } | |
318 | ||
319 | excluded = bsearch(name, fbt_blacklist, BLACKLIST_COUNT, sizeof(name), | |
320 | _cmp ); | |
321 | return excluded; | |
322 | } | |
323 | ||
324 | SYSCTL_DECL(_kern_dtrace); | |
325 | ||
326 | static int | |
327 | sysctl_dtrace_ignore_fbt_blacklist SYSCTL_HANDLER_ARGS | |
328 | { | |
329 | #pragma unused(oidp, arg2) | |
330 | int err; | |
331 | int value = *(int*)arg1; | |
332 | ||
333 | err = sysctl_io_number(req, value, sizeof(value), &value, NULL); | |
334 | if (err) { | |
335 | return err; | |
336 | } | |
337 | if (req->newptr) { | |
338 | if (!(value == 0 || value == 1)) { | |
339 | return ERANGE; | |
340 | } | |
341 | ||
342 | /* | |
343 | * We do not allow setting the blacklist back to on, as we have no way | |
344 | * of knowing if those unsafe probes are still used. | |
345 | * | |
346 | * If we are using kernel symbols, we also do not allow any change, | |
347 | * since the symbols are jettison'd after the first pass. | |
348 | * | |
349 | * We do not need to take any locks here because those symbol modes | |
350 | * are permanent and do not change after boot. | |
351 | */ | |
352 | if (value != 1 || dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_NEVER || | |
353 | dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_ALWAYS_FROM_KERNEL) { | |
354 | return EPERM; | |
355 | } | |
356 | ||
357 | ignore_fbt_blacklist = 1; | |
358 | } | |
359 | ||
360 | return 0; | |
361 | } | |
362 | ||
363 | SYSCTL_PROC(_kern_dtrace, OID_AUTO, ignore_fbt_blacklist, | |
364 | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, | |
365 | &ignore_fbt_blacklist, 0, | |
366 | sysctl_dtrace_ignore_fbt_blacklist, "I", "fbt provider ignore blacklist"); | |
367 | ||
368 | void | |
369 | fbt_blacklist_init(void) | |
370 | { | |
371 | PE_parse_boot_argn("IgnoreFBTBlacklist", &ignore_fbt_blacklist, sizeof(ignore_fbt_blacklist)); | |
372 | #if DEBUG || DEVELOPMENT | |
373 | for (size_t i = 1; i < BLACKLIST_COUNT; i++) { | |
374 | if (strcmp(fbt_blacklist[i - 1], fbt_blacklist[i]) > 0) { | |
375 | panic("unordered fbt blacklist %s > %s", fbt_blacklist[i - 1], fbt_blacklist[i]); | |
376 | } | |
377 | } | |
378 | #endif /* DEBUG || DEVELOPMENT */ | |
379 | } |