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 CONFIG_UBSAN_MINIMAL |
36 | #define UBSAN_MINIMAL_ONLY(s) #s, |
37 | #else |
38 | #define UBSAN_MINIMAL_ONLY(s) |
39 | #endif |
40 | |
41 | #if defined(__arm64__) |
42 | #define ARM_ONLY(s) #s, |
43 | #else |
44 | #define ARM_ONLY(s) |
45 | #endif /* defined(__arm64__) */ |
46 | #if defined(__x86_64__) |
47 | #define X86_ONLY(s) #s, |
48 | #else |
49 | #define X86_ONLY(s) |
50 | #endif /* defined(__x86_64__) */ |
51 | |
52 | /* |
53 | * Routine prefixes that must not be probed, either because they are used in |
54 | * the exception path, by dtrace code in probe context, or are general |
55 | * critical routines that must never be probed. |
56 | * |
57 | * All routines whose name start with one of these will be ignored. |
58 | * |
59 | * This must be kept in asciibetical order for purposes of bsearch(). |
60 | */ |
61 | const char * fbt_blacklist[] = |
62 | { |
63 | CRITICAL(Call_DebuggerC) |
64 | CLOSURE(ClearIdlePop) |
65 | CLOSURE(Debugger) |
66 | CRITICAL(IOCPURunPlatformPanicActions) |
67 | CLOSURE(IS_64BIT_PROCESS) |
68 | CRITICAL(OSAdd) |
69 | CRITICAL(OSBit) |
70 | CLOSURE(OSCompareAndSwap) |
71 | CRITICAL(OSDecrement) |
72 | CRITICAL(OSIncrement) |
73 | CRITICAL(PEARMDebugPanicHook) |
74 | CRITICAL(PEHaltRestart) |
75 | CRITICAL(PE_) |
76 | CRITICAL(SavePanicInfo) |
77 | CLOSURE(SetIdlePop) |
78 | CRITICAL(SysChoked) |
79 | CRITICAL(_ZN15OSMetaClassBase12safeMetaCastEPKS_PK11OSMetaClass) /* OSMetaClassBase::safeMetaCast */ |
80 | CRITICAL(_ZN16IOPlatformExpert11haltRestartEj) /* IOPlatformExpert::haltRestart */ |
81 | CRITICAL(_ZN18IODTPlatformExpert11haltRestartEj) /* IODTPlatformExpert::haltRestart */ |
82 | ARM_ONLY(_ZN8ASPNVRAM4syncEv) /* ASPNVRAM::sync */ |
83 | CRITICAL(_ZN9IODTNVRAM13savePanicInfoEPhy) /* IODTNVRAM::savePanicInfo */ |
84 | CRITICAL(_ZN9IOService14newTemperatureElPS_) /* IOService::newTemperature */ |
85 | CRITICAL(_ZN9IOService26temperatureCriticalForZoneEPS_) /* IOService::temperatureCriticalForZone */ |
86 | CRITICAL(_ZNK11OSMetaClass13checkMetaCastEPK15OSMetaClassBase) /* OSMetaClass::checkMetaCast */ |
87 | CRITICAL(_ZNK15OSMetaClassBase8metaCastEPK11OSMetaClass) /* OSMetaClassBase::metaCast */ |
88 | CRITICAL(_ZNK6OSData14getBytesNoCopyEv) /* Data::getBytesNoCopy, IOHibernateSystemWake path */ |
89 | KASAN_ONLY(__asan) |
90 | ARM_ONLY(__div) |
91 | CLOSURE(__dtrace_probe) |
92 | KASAN_ONLY(__kasan) |
93 | ARM_ONLY(__ml) |
94 | ARM_ONLY(__mod) |
95 | CRITICAL(__strlcpy_chk) |
96 | CLOSURE(__thread_ro_circularity_panic) |
97 | UBSAN_MINIMAL_ONLY(__ubsan) |
98 | ARM_ONLY(__udiv) |
99 | ARM_ONLY(__umod) |
100 | CLOSURE(_copyin) |
101 | CLOSURE(_copyout) |
102 | CRITICAL(_disable_preemption) |
103 | CRITICAL(_enable_preemption) |
104 | #if SCHED_HYGIENE_DEBUG |
105 | CLOSURE(abandon_preemption_disable_measurement) |
106 | #endif |
107 | CLOSURE(absolutetime_to_microtime) |
108 | X86_ONLY(acpi_) |
109 | X86_ONLY(act_machine) |
110 | CLOSURE(act_set_astbsd) |
111 | ARM_ONLY(add_saved_state_pc) |
112 | ARM_ONLY(alternate_debugger_enter) |
113 | ARM_ONLY(arm_init_idle_cpu) |
114 | CLOSURE(ast_dtrace_on) |
115 | CLOSURE(ast_pending) |
116 | CRITICAL(backtrace_) |
117 | CRITICAL(bcopy) |
118 | CLOSURE(clean_dcache) |
119 | CLOSURE(clean_mmu_dcache) |
120 | CRITICAL(clock_) |
121 | X86_ONLY(commpage_) |
122 | CLOSURE(copyin) |
123 | CLOSURE(copyout) |
124 | CRITICAL(cpu_) |
125 | CLOSURE(current_act) |
126 | CLOSURE(current_percpu_base) |
127 | CLOSURE(current_proc) |
128 | CLOSURE(current_processor) |
129 | CLOSURE(current_task) |
130 | CLOSURE(current_task_early) |
131 | CLOSURE(current_thread) |
132 | CLOSURE(current_thread_ro) |
133 | CLOSURE(current_thread_ro_unchecked) |
134 | CLOSURE(current_uthread) |
135 | CLOSURE(debug_) |
136 | X86_ONLY(dsmos_) |
137 | CLOSURE(dtrace_) |
138 | CRITICAL(enter_lohandler) |
139 | CRITICAL(fasttrap_) |
140 | CRITICAL(fbt_invop) |
141 | CRITICAL(fbt_perfCallback) |
142 | CLOSURE(find_user_regs) |
143 | ARM_ONLY(fleh_) |
144 | CLOSURE(flush_dcache) |
145 | ARM_ONLY(flush_mmu_tlb_) |
146 | CLOSURE(flush_tlb64) |
147 | CRITICAL(fuword) |
148 | X86_ONLY(get_active_thread) |
149 | CLOSURE(get_bsdtask_info) |
150 | CLOSURE(get_bsdthread_info) |
151 | CLOSURE(get_machthread) |
152 | CRITICAL(get_preemption_level) |
153 | ARM_ONLY(get_saved_state_lr) |
154 | ARM_ONLY(get_saved_state_reg) |
155 | ARM_ONLY(get_saved_state_sp) |
156 | CRITICAL(get_thread_ro) |
157 | CRITICAL(get_thread_ro_unchecked) |
158 | CRITICAL(get_threadtask) |
159 | CRITICAL(get_threadtask_early) |
160 | ARM_ONLY(get_vfp_enabled) |
161 | CRITICAL(getminor) |
162 | CRITICAL(handle_pending_TLB_flushes) |
163 | CRITICAL(hibernate_) |
164 | X86_ONLY(hndl_) |
165 | CRITICAL(hw_) |
166 | X86_ONLY(idt64) |
167 | CRITICAL(interrupt) |
168 | CRITICAL(invalidate_mmu_icache) |
169 | CRITICAL(is_saved_state32) |
170 | KASAN_ONLY(kasan) |
171 | CLOSURE(kauth_cred_get) |
172 | CLOSURE(kauth_getgid) |
173 | CLOSURE(kauth_getuid) |
174 | CRITICAL(kdb_) |
175 | CRITICAL(kdp_) |
176 | CRITICAL(kernel_preempt_check) |
177 | CRITICAL(kernel_trap) |
178 | CRITICAL(kprintf) |
179 | CRITICAL(ks_) |
180 | CLOSURE(kvtophys) |
181 | X86_ONLY(lapic_) |
182 | CRITICAL(lo_alltraps) |
183 | CRITICAL(lock_debugger) |
184 | CLOSURE(mach_absolute_time) |
185 | CRITICAL(machine_) |
186 | X86_ONLY(mapping_) |
187 | CRITICAL(mca_cpu_alloc) |
188 | CRITICAL(mca_cpu_init) |
189 | CLOSURE(memcpy) |
190 | CLOSURE(memmove) |
191 | CRITICAL(ml_) |
192 | CLOSURE(mt_core_snap) |
193 | CLOSURE(mt_cur_cpu) |
194 | CLOSURE(mt_fixed_counts) |
195 | CLOSURE(mt_fixed_counts_internal) |
196 | CLOSURE(mt_mtc_update_count) |
197 | CLOSURE(mt_mtc_update_fixed_counts) |
198 | CRITICAL(nanoseconds_to_absolutetime) |
199 | CRITICAL(nanotime_to_absolutetime) |
200 | CRITICAL(no_asts) |
201 | CLOSURE(other_percpu_base) |
202 | CRITICAL(ovbcopy) |
203 | CRITICAL(packA) |
204 | X86_ONLY(pal_) |
205 | CLOSURE(panic) |
206 | CRITICAL(phystokv) |
207 | CRITICAL(platform_) |
208 | X86_ONLY(pltrace) |
209 | X86_ONLY(pmCPU) |
210 | X86_ONLY(pmKextRegister) |
211 | X86_ONLY(pmMarkAllCPUsOff) |
212 | X86_ONLY(pmSafeMode) |
213 | X86_ONLY(pmTimerRestore) |
214 | X86_ONLY(pmTimerSave) |
215 | X86_ONLY(pmUnRegister) |
216 | X86_ONLY(pmap64_pdpt) |
217 | CLOSURE(pmap_find_pa) |
218 | CLOSURE(pmap_find_phys) |
219 | ARM_ONLY(pmap_get_cpu_data) |
220 | CLOSURE(pmap_get_mapwindow) |
221 | CLOSURE(pmap_pde) |
222 | CLOSURE(pmap_pde_internal0) |
223 | CLOSURE(pmap_pde_internal1) |
224 | CLOSURE(pmap_pte) |
225 | CLOSURE(pmap_pte_internal) |
226 | CLOSURE(pmap_put_mapwindow) |
227 | CLOSURE(pmap_valid_page) |
228 | CLOSURE(pmap_vtophys) |
229 | X86_ONLY(pms) |
230 | CRITICAL(power_management_init) |
231 | CRITICAL(preemption_underflow_panic) |
232 | CLOSURE(prf) |
233 | CLOSURE(proc_best_name) |
234 | CLOSURE(proc_get_task_raw) |
235 | CLOSURE(proc_is64bit) |
236 | CLOSURE(proc_require) |
237 | CLOSURE(proc_task) |
238 | CRITICAL(rbtrace_bt) |
239 | CLOSURE(recount_) |
240 | CRITICAL(register_cpu_setup_func) |
241 | CRITICAL(ret64_iret) |
242 | CRITICAL(ret_to_user) |
243 | CRITICAL(return_to_kernel) |
244 | CRITICAL(return_to_user) |
245 | CRITICAL(rtc_) |
246 | CRITICAL(rtclock_) |
247 | CRITICAL(saved_state64) |
248 | CLOSURE(sdt_getargdesc) |
249 | CRITICAL(sdt_invop) |
250 | CLOSURE(setPop) |
251 | ARM_ONLY(set_saved_state_pc) |
252 | ARM_ONLY(sleh_) |
253 | CRITICAL(sprlock) |
254 | CRITICAL(sprunlock) |
255 | CLOSURE(strlcpy) |
256 | CRITICAL(strlen) |
257 | CRITICAL(strncmp) |
258 | CRITICAL(suword) |
259 | X86_ONLY(sync_iss_to_iks_unconditionally) |
260 | CLOSURE(systrace_stub) |
261 | CRITICAL(t_invop) |
262 | CLOSURE(task_get_proc_raw) |
263 | CLOSURE(thread_tid) |
264 | CLOSURE(timer_grab) |
265 | ARM_ONLY(timer_state_event) |
266 | CRITICAL(tmrCvt) |
267 | CRITICAL(trap_from_kernel) |
268 | CRITICAL(traptrace_) |
269 | CRITICAL(tsc_) |
270 | CRITICAL(uart_putc) |
271 | CRITICAL(unlock_debugger) |
272 | CRITICAL(unpackA) |
273 | CRITICAL(unregister_cpu_setup_func) |
274 | CRITICAL(uread) |
275 | CLOSURE(uthread_is64bit) |
276 | CRITICAL(uwrite) |
277 | CRITICAL(vstart) |
278 | CLOSURE(zone_has_index) |
279 | CLOSURE(zone_id_require) |
280 | CLOSURE(zone_id_require_panic) |
281 | CLOSURE(zone_range_contains) |
282 | CLOSURE(zone_require_panic) |
283 | CLOSURE(zone_require_ro) |
284 | CLOSURE(zpercpu_count) |
285 | }; |
286 | #define BLACKLIST_COUNT (sizeof(fbt_blacklist)/sizeof(fbt_blacklist[0])) |
287 | |
288 | /* |
289 | * Modules that should not be probed. |
290 | * |
291 | * This must be kept in asciibetical order for purposes of bsearch(). |
292 | */ |
293 | static const char* fbt_module_blacklist[] = { |
294 | X86_ONLY(com.apple.driver.AppleACPIEC) |
295 | X86_ONLY(com.apple.driver.AppleACPIPlatform) |
296 | ARM_ONLY(com.apple.driver.AppleARMPlatform) |
297 | X86_ONLY(com.apple.driver.AppleEFI) |
298 | X86_ONLY(com.apple.driver.AppleIntelCPUPowerManagement) |
299 | ARM_ONLY(com.apple.driver.AppleInterruptController) |
300 | X86_ONLY(com.apple.driver.AppleRTC) |
301 | X86_ONLY(com.apple.iokit.IOACPIFamily) |
302 | }; |
303 | #define MODULE_BLACKLIST_COUNT (sizeof(fbt_module_blacklist)/sizeof(fbt_module_blacklist[0])) |
304 | |
305 | int ignore_fbt_blacklist = 0; |
306 | extern int dtrace_kernel_symbol_mode; |
307 | |
308 | #pragma clang diagnostic push |
309 | #pragma clang diagnostic ignored "-Wcast-qual" |
310 | static int |
311 | _cmp(const void *a, const void *b) |
312 | { |
313 | const char *v = *(const char **)b; |
314 | return strncmp(s1: (const char *)a, s2: v, n: strlen(s: v)); |
315 | } |
316 | |
317 | |
318 | #pragma clang diagnostic pop |
319 | /* |
320 | * Module validation |
321 | */ |
322 | bool |
323 | fbt_module_excluded(struct modctl* ctl) |
324 | { |
325 | const char *excluded; |
326 | |
327 | ASSERT(!MOD_FBT_DONE(ctl)); |
328 | |
329 | if (ctl->mod_address == 0 || ctl->mod_size == 0 || !ctl->mod_loaded) { |
330 | return true; |
331 | } |
332 | |
333 | if (ignore_fbt_blacklist) { |
334 | return false; |
335 | } |
336 | |
337 | excluded = bsearch(ctl->mod_modname, fbt_module_blacklist, |
338 | MODULE_BLACKLIST_COUNT, sizeof(fbt_module_blacklist[0]), compar: _cmp); |
339 | return excluded; |
340 | } |
341 | |
342 | /* |
343 | * FBT probe name validation |
344 | */ |
345 | bool |
346 | fbt_excluded(const char* name) |
347 | { |
348 | const char *excluded; |
349 | |
350 | if (ignore_fbt_blacklist) { |
351 | return false; |
352 | } |
353 | |
354 | excluded = bsearch(name, fbt_blacklist, BLACKLIST_COUNT, sizeof(name), |
355 | compar: _cmp ); |
356 | return excluded; |
357 | } |
358 | |
359 | SYSCTL_DECL(_kern_dtrace); |
360 | |
361 | static int |
362 | sysctl_dtrace_ignore_fbt_blacklist SYSCTL_HANDLER_ARGS |
363 | { |
364 | #pragma unused(oidp, arg2) |
365 | int err; |
366 | int value = *(int*)arg1; |
367 | |
368 | err = sysctl_io_number(req, bigValue: value, valueSize: sizeof(value), pValue: &value, NULL); |
369 | if (err) { |
370 | return err; |
371 | } |
372 | if (req->newptr) { |
373 | if (!(value == 0 || value == 1)) { |
374 | return ERANGE; |
375 | } |
376 | |
377 | /* |
378 | * We do not allow setting the blacklist back to on, as we have no way |
379 | * of knowing if those unsafe probes are still used. |
380 | * |
381 | * If we are using kernel symbols, we also do not allow any change, |
382 | * since the symbols are jettison'd after the first pass. |
383 | * |
384 | * We do not need to take any locks here because those symbol modes |
385 | * are permanent and do not change after boot. |
386 | */ |
387 | if (value != 1 || dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_NEVER || |
388 | dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_ALWAYS_FROM_KERNEL) { |
389 | return EPERM; |
390 | } |
391 | |
392 | ignore_fbt_blacklist = 1; |
393 | } |
394 | |
395 | return 0; |
396 | } |
397 | |
398 | SYSCTL_PROC(_kern_dtrace, OID_AUTO, ignore_fbt_blacklist, |
399 | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, |
400 | &ignore_fbt_blacklist, 0, |
401 | sysctl_dtrace_ignore_fbt_blacklist, "I" , "fbt provider ignore blacklist" ); |
402 | |
403 | void |
404 | fbt_blacklist_init(void) |
405 | { |
406 | PE_parse_boot_argn(arg_string: "IgnoreFBTBlacklist" , arg_ptr: &ignore_fbt_blacklist, max_arg: sizeof(ignore_fbt_blacklist)); |
407 | #if DEBUG || DEVELOPMENT |
408 | for (size_t i = 1; i < BLACKLIST_COUNT; i++) { |
409 | if (strcmp(fbt_blacklist[i - 1], fbt_blacklist[i]) > 0) { |
410 | panic("unordered fbt blacklist %s > %s" , fbt_blacklist[i - 1], fbt_blacklist[i]); |
411 | } |
412 | } |
413 | #endif /* DEBUG || DEVELOPMENT */ |
414 | } |
415 | |