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 */
61const 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 */
293static 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
305int ignore_fbt_blacklist = 0;
306extern int dtrace_kernel_symbol_mode;
307
308#pragma clang diagnostic push
309#pragma clang diagnostic ignored "-Wcast-qual"
310static 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 */
322bool
323fbt_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 */
345bool
346fbt_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
359SYSCTL_DECL(_kern_dtrace);
360
361static int
362sysctl_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
398SYSCTL_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
403void
404fbt_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