1 // Copyright (c) 2016-2021 Apple Inc. All rights reserved.
2 //
3 // @APPLE_OSREFERENCE_LICENSE_HEADER_START@
4 //
5 // This file contains Original Code and/or Modifications of Original Code
6 // as defined in and that are subject to the Apple Public Source License
7 // Version 2.0 (the 'License'). You may not use this file except in
8 // compliance with the License. The rights granted to you under the License
9 // may not be used to create, or enable the creation or redistribution of,
10 // unlawful or unlicensed copies of an Apple operating system, or to
11 // circumvent, violate, or enable the circumvention or violation of, any
12 // terms of an Apple operating system software license agreement.
13 //
14 // Please obtain a copy of the License at
15 // http://www.opensource.apple.com/apsl/ and read it before using this file.
16 //
17 // The Original Code and all software distributed under the License are
18 // distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19 // EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
20 // INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
22 // Please see the License for the specific language governing rights and
23 // limitations under the License.
24 //
25 // @APPLE_OSREFERENCE_LICENSE_HEADER_END@
26
27 #include <stddef.h>
28 #include <stdint.h>
29
30 #include <kern/assert.h>
31 #include <kern/backtrace.h>
32 #include <kern/cambria_layout.h>
33 #include <kern/thread.h>
34 #include <machine/machine_routines.h>
35 #include <sys/errno.h>
36 #include <vm/vm_map_xnu.h>
37
38 #if defined(__arm64__)
39 #include <arm/cpu_data.h>
40 #include <arm/cpu_data_internal.h>
41 #endif // defined(__arm64__)
42
43 #if defined(HAS_APPLE_PAC)
44 #include <ptrauth.h>
45 #endif // defined(HAS_APPLE_PAC)
46
47 #if HAS_MTE
48 #include <arm64/mte.h>
49 #endif // HAS_MTE
50
51 #if __x86_64__
52 static void
_backtrace_packed_out_of_reach(void)53 _backtrace_packed_out_of_reach(void)
54 {
55 // This symbol is used to replace frames that have been "JIT-ed"
56 // or dynamically inserted in the kernel by some kext in a regular
57 // VM mapping that might be outside of the filesets.
58 //
59 // This is an Intel only issue.
60 }
61 #endif // __x86_64__
62
63 // Pack an address according to a particular packing format.
64 static size_t
_backtrace_pack_addr(backtrace_pack_t packing,uint8_t * dst,size_t dst_size,uintptr_t addr)65 _backtrace_pack_addr(backtrace_pack_t packing, uint8_t *dst, size_t dst_size,
66 uintptr_t addr)
67 {
68 switch (packing) {
69 case BTP_NONE:
70 if (dst_size >= sizeof(addr)) {
71 memcpy(dst, &addr, sizeof(addr));
72 }
73 return sizeof(addr);
74 case BTP_KERN_OFFSET_32:;
75 uintptr_t addr_delta = addr - vm_kernel_stext;
76 int32_t addr_packed = (int32_t)addr_delta;
77 #if __x86_64__
78 if ((uintptr_t)(int32_t)addr_delta != addr_delta) {
79 addr = (vm_offset_t)&_backtrace_packed_out_of_reach;
80 addr_delta = addr - vm_kernel_stext;
81 addr_packed = (int32_t)addr_delta;
82 }
83 #else // __x86_64__
84 assert((uintptr_t)(int32_t)addr_delta == addr_delta);
85 #endif // !__x86_64__
86 if (dst_size >= sizeof(addr_packed)) {
87 memcpy(dst, &addr_packed, sizeof(addr_packed));
88 }
89 return sizeof(addr_packed);
90 default:
91 panic("backtrace: unknown packing format %d", packing);
92 }
93 }
94
95 // Since it's only called from threads that we're going to keep executing,
96 // if there's bad data the system is going to die eventually. If this function
97 // is inlined, it doesn't record the frame of the function it's inside (because
98 // there's no stack frame), so prevent that.
99 static size_t __attribute__((noinline, not_tail_called))
backtrace_internal(backtrace_pack_t packing,uint8_t * bt,size_t btsize,void * start_frame,int64_t addr_offset,backtrace_info_t * info_out)100 backtrace_internal(backtrace_pack_t packing, uint8_t *bt,
101 size_t btsize, void *start_frame, int64_t addr_offset,
102 backtrace_info_t *info_out)
103 {
104 thread_t thread = current_thread();
105 uintptr_t *fp;
106 size_t size_used = 0;
107 uintptr_t top, bottom;
108 bool in_valid_stack;
109 assert(bt != NULL);
110 assert(btsize > 0);
111
112 fp = start_frame;
113 #if defined(HAS_APPLE_PAC)
114 fp = ptrauth_strip(fp, ptrauth_key_frame_pointer);
115 #endif
116 bottom = thread->kernel_stack;
117 top = bottom + kernel_stack_size;
118
119 #define IN_STK_BOUNDS(__addr) \
120 (((uintptr_t)(__addr) >= (uintptr_t)bottom) && \
121 ((uintptr_t)(__addr) < (uintptr_t)top))
122
123 in_valid_stack = IN_STK_BOUNDS(fp) || ml_addr_in_non_xnu_stack((uintptr_t)fp);
124
125 if (!in_valid_stack) {
126 fp = NULL;
127 }
128
129 while (fp != NULL && size_used < btsize) {
130 uintptr_t *next_fp = (uintptr_t *)*fp;
131 #if defined(HAS_APPLE_PAC)
132 next_fp = ptrauth_strip(next_fp, ptrauth_key_frame_pointer);
133 #endif
134 // Return address is one word higher than frame pointer.
135 uintptr_t ret_addr = *(fp + 1);
136
137 // If the frame pointer is 0, backtracing has reached the top of
138 // the stack and there is no return address. Some stacks might not
139 // have set this up, so bounds check, as well.
140 in_valid_stack = IN_STK_BOUNDS(next_fp) || ml_addr_in_non_xnu_stack((uintptr_t)next_fp);
141
142 if (next_fp == NULL || !in_valid_stack) {
143 break;
144 }
145
146 #if defined(HAS_APPLE_PAC)
147 // Return addresses are signed by arm64e ABI, so strip it.
148 uintptr_t pc = (uintptr_t)ptrauth_strip((void *)ret_addr,
149 ptrauth_key_return_address);
150 #else // defined(HAS_APPLE_PAC)
151 uintptr_t pc = ret_addr;
152 #endif // !defined(HAS_APPLE_PAC)
153 if (pc == 0) {
154 // Once a NULL PC is encountered, ignore the rest of the call stack.
155 break;
156 }
157 pc += addr_offset;
158 size_used += _backtrace_pack_addr(packing, bt + size_used,
159 btsize - size_used, pc);
160
161 // Stacks grow down; backtracing should always be moving to higher
162 // addresses except when a frame is stitching between two different
163 // stacks.
164 if (next_fp <= fp) {
165 // This check is verbose; it is basically checking whether this
166 // thread is switching between the kernel stack and a non-XNU stack
167 // (or between one non-XNU stack and another, as there can be more
168 // than one). If not, then stop the backtrace as stack switching
169 // should be the only reason as to why the next FP would be lower
170 // than the current FP.
171 if (!ml_addr_in_non_xnu_stack((uintptr_t)fp) &&
172 !ml_addr_in_non_xnu_stack((uintptr_t)next_fp)) {
173 break;
174 }
175 }
176 fp = next_fp;
177 }
178
179 if (info_out) {
180 backtrace_info_t info = BTI_NONE;
181 #if __LP64__
182 info |= BTI_64_BIT;
183 #endif
184 if (fp != NULL && size_used >= btsize) {
185 info |= BTI_TRUNCATED;
186 }
187 *info_out = info;
188 }
189
190 return size_used;
191 #undef IN_STK_BOUNDS
192 }
193
194 static kern_return_t
interrupted_kernel_pc_fp(uintptr_t * pc,uintptr_t * fp)195 interrupted_kernel_pc_fp(uintptr_t *pc, uintptr_t *fp)
196 {
197 #if defined(__x86_64__)
198 x86_saved_state_t *state;
199 bool state_64;
200 uint64_t cs;
201
202 state = current_cpu_datap()->cpu_int_state;
203 if (!state) {
204 return KERN_FAILURE;
205 }
206
207 state_64 = is_saved_state64(state);
208
209 if (state_64) {
210 cs = saved_state64(state)->isf.cs;
211 } else {
212 cs = saved_state32(state)->cs;
213 }
214 // Return early if interrupted a thread in user space.
215 if ((cs & SEL_PL) == SEL_PL_U) {
216 return KERN_FAILURE;
217 }
218
219 if (state_64) {
220 *pc = saved_state64(state)->isf.rip;
221 *fp = saved_state64(state)->rbp;
222 } else {
223 *pc = saved_state32(state)->eip;
224 *fp = saved_state32(state)->ebp;
225 }
226
227 #elif defined(__arm64__)
228
229 struct arm_saved_state *state;
230
231 state = getCpuDatap()->cpu_int_state;
232 if (!state) {
233 return KERN_FAILURE;
234 }
235
236 // Return early if interrupted a thread in user space.
237 if (PSR64_IS_USER(get_saved_state_cpsr(state))) {
238 return KERN_FAILURE;
239 }
240
241 *pc = ml_get_backtrace_pc(state);
242 *fp = get_saved_state_fp(state);
243
244 #else // !defined(__arm64__) && !defined(__x86_64__)
245 #error "unsupported architecture"
246 #endif // !defined(__arm64__) && !defined(__x86_64__)
247
248 return KERN_SUCCESS;
249 }
250
251 __attribute__((always_inline))
252 static uintptr_t
_backtrace_preamble(struct backtrace_control * ctl,uintptr_t * start_frame_out)253 _backtrace_preamble(struct backtrace_control *ctl, uintptr_t *start_frame_out)
254 {
255 backtrace_flags_t flags = ctl ? ctl->btc_flags : 0;
256 uintptr_t start_frame = ctl ? ctl->btc_frame_addr : 0;
257 uintptr_t pc = 0;
258 if (flags & BTF_KERN_INTERRUPTED) {
259 assert(ml_at_interrupt_context() == TRUE);
260
261 uintptr_t fp;
262 kern_return_t kr = interrupted_kernel_pc_fp(&pc, &fp);
263 if (kr != KERN_SUCCESS) {
264 return 0;
265 }
266 *start_frame_out = start_frame ?: fp;
267 } else if (start_frame == 0) {
268 *start_frame_out = (uintptr_t)__builtin_frame_address(0);
269 } else {
270 *start_frame_out = start_frame;
271 }
272 return pc;
273 }
274
275 unsigned int __attribute__((noinline))
backtrace(uintptr_t * bt,unsigned int max_frames,struct backtrace_control * ctl,backtrace_info_t * info_out)276 backtrace(uintptr_t *bt, unsigned int max_frames,
277 struct backtrace_control *ctl, backtrace_info_t *info_out)
278 {
279 unsigned int len_adj = 0;
280 uintptr_t start_frame = ctl ? ctl->btc_frame_addr : 0;
281 uintptr_t pc = _backtrace_preamble(ctl, &start_frame);
282 if (pc) {
283 bt[0] = pc;
284 if (max_frames == 1) {
285 return 1;
286 }
287 bt += 1;
288 max_frames -= 1;
289 len_adj += 1;
290 }
291
292 size_t size = backtrace_internal(BTP_NONE, (uint8_t *)bt,
293 max_frames * sizeof(uintptr_t), (void *)start_frame,
294 ctl ? ctl->btc_addr_offset : 0, info_out);
295 // NULL-terminate the list, if space is available.
296 unsigned int len = size / sizeof(uintptr_t);
297 if (len != max_frames) {
298 bt[len] = 0;
299 }
300
301 return len + len_adj;
302 }
303
304 // Backtrace the current thread's kernel stack as a packed representation.
305 size_t
backtrace_packed(backtrace_pack_t packing,uint8_t * bt,size_t btsize,struct backtrace_control * ctl,backtrace_info_t * info_out)306 backtrace_packed(backtrace_pack_t packing, uint8_t *bt, size_t btsize,
307 struct backtrace_control *ctl,
308 backtrace_info_t *info_out)
309 {
310 unsigned int size_adj = 0;
311 uintptr_t start_frame = ctl ? ctl->btc_frame_addr : 0;
312 uintptr_t pc = _backtrace_preamble(ctl, &start_frame);
313 if (pc) {
314 size_adj = _backtrace_pack_addr(packing, bt, btsize, pc);
315 if (size_adj >= btsize) {
316 return size_adj;
317 }
318 btsize -= size_adj;
319 }
320
321 size_t written_size = backtrace_internal(packing, (uint8_t *)bt, btsize,
322 (void *)start_frame, ctl ? ctl->btc_addr_offset : 0, info_out);
323 return written_size + size_adj;
324 }
325
326 // Convert an array of addresses to a packed representation.
327 size_t
backtrace_pack(backtrace_pack_t packing,uint8_t * dst,size_t dst_size,const uintptr_t * src,unsigned int src_len)328 backtrace_pack(backtrace_pack_t packing, uint8_t *dst, size_t dst_size,
329 const uintptr_t *src, unsigned int src_len)
330 {
331 size_t dst_offset = 0;
332 for (unsigned int i = 0; i < src_len; i++) {
333 size_t pack_size = _backtrace_pack_addr(packing, dst + dst_offset,
334 dst_size - dst_offset, src[i]);
335 if (dst_offset + pack_size >= dst_size) {
336 return dst_offset;
337 }
338 dst_offset += pack_size;
339 }
340 return dst_offset;
341 }
342
343 // Convert a packed backtrace to an array of addresses.
344 unsigned int
backtrace_unpack(backtrace_pack_t packing,uintptr_t * dst,unsigned int dst_len,const uint8_t * src,size_t src_size)345 backtrace_unpack(backtrace_pack_t packing, uintptr_t *dst, unsigned int dst_len,
346 const uint8_t *src, size_t src_size)
347 {
348 switch (packing) {
349 case BTP_NONE:;
350 size_t unpack_size = MIN(dst_len * sizeof(uintptr_t), src_size);
351 memmove(dst, src, unpack_size);
352 return (unsigned int)(unpack_size / sizeof(uintptr_t));
353 case BTP_KERN_OFFSET_32:;
354 unsigned int src_len = src_size / sizeof(int32_t);
355 unsigned int unpack_len = MIN(src_len, dst_len);
356 for (unsigned int i = 0; i < unpack_len; i++) {
357 int32_t addr = 0;
358 memcpy(&addr, src + i * sizeof(int32_t), sizeof(int32_t));
359 dst[i] = vm_kernel_stext + (uintptr_t)addr;
360 }
361 return unpack_len;
362 default:
363 panic("backtrace: unknown packing format %d", packing);
364 }
365 }
366
367 static errno_t
_backtrace_copyin(void * __unused ctx,void * dst,user_addr_t src,size_t size)368 _backtrace_copyin(void * __unused ctx, void *dst, user_addr_t src, size_t size)
369 {
370 #if HAS_MTE
371 mte_disable_tag_checking();
372 #endif // HAS_MTE
373 int error = copyin((user_addr_t)src, dst, size);
374 #if HAS_MTE
375 mte_enable_tag_checking();
376 #endif // HAS_MTE
377 return error;
378 }
379
380 errno_t
backtrace_user_copy_error(void * ctx,void * dst,user_addr_t src,size_t size)381 backtrace_user_copy_error(void *ctx, void *dst, user_addr_t src, size_t size)
382 {
383 #pragma unused(ctx, dst, src, size)
384 return EFAULT;
385 }
386
387 unsigned int
backtrace_user(uintptr_t * bt,unsigned int max_frames,const struct backtrace_control * ctl_in,struct backtrace_user_info * info_out)388 backtrace_user(uintptr_t *bt, unsigned int max_frames,
389 const struct backtrace_control *ctl_in,
390 struct backtrace_user_info *info_out)
391 {
392 static const struct backtrace_control ctl_default = {
393 .btc_user_copy = _backtrace_copyin,
394 };
395 const struct backtrace_control *ctl = ctl_in ?: &ctl_default;
396 uintptr_t pc = 0, next_fp = 0;
397 uintptr_t fp = ctl->btc_frame_addr;
398 int64_t addr_offset = ctl ? ctl->btc_addr_offset : 0;
399 vm_map_t map = NULL;
400 vm_map_switch_context_t switch_ctx;
401 bool switched_map = false;
402 unsigned int frame_index = 0;
403 int error = 0;
404 size_t frame_size = 0;
405 bool truncated = false;
406 bool user_64 = false;
407 bool allow_async = true;
408 bool has_async = false;
409 uintptr_t async_frame_addr = 0;
410 unsigned int async_index = 0;
411
412 backtrace_user_copy_fn copy = ctl->btc_user_copy ?: _backtrace_copyin;
413 bool custom_copy = copy != _backtrace_copyin;
414 void *ctx = ctl->btc_user_copy_context;
415
416 void *thread = ctl->btc_user_thread;
417 void *cur_thread = NULL;
418 if (thread == NULL) {
419 cur_thread = current_thread();
420 thread = cur_thread;
421 }
422 task_t task = get_threadtask(thread);
423
424 assert(task != NULL);
425 assert(bt != NULL);
426 assert(max_frames > 0);
427
428 if (!custom_copy) {
429 bool interrupts_enabled = ml_get_interrupts_enabled();
430 assert(interrupts_enabled);
431 if (!interrupts_enabled) {
432 error = EDEADLK;
433 goto out;
434 }
435
436 if (cur_thread == NULL) {
437 cur_thread = current_thread();
438 }
439 bool const must_switch_maps = thread != cur_thread;
440 if (must_switch_maps) {
441 map = get_task_map_reference(task);
442 if (map == NULL) {
443 error = ENOMEM;
444 goto out;
445 }
446 switched_map = true;
447 switch_ctx = vm_map_switch_to(map);
448 }
449 }
450
451 #define SWIFT_ASYNC_FP_BIT (0x1ULL << 60)
452 #define SWIFT_ASYNC_FP(FP) (((FP) & SWIFT_ASYNC_FP_BIT) != 0)
453 #define SWIFT_ASYNC_FP_CLEAR(FP) ((FP) & ~SWIFT_ASYNC_FP_BIT)
454
455 #if defined(__x86_64__)
456
457 // Don't allow a malformed user stack to copy arbitrary kernel data.
458 #define INVALID_USER_FP(FP) ((FP) == 0 || !IS_USERADDR64_CANONICAL((FP)))
459
460 x86_saved_state_t *state = get_user_regs(thread);
461 if (!state) {
462 error = EINVAL;
463 goto out;
464 }
465
466 user_64 = is_saved_state64(state);
467 if (user_64) {
468 pc = saved_state64(state)->isf.rip;
469 fp = fp != 0 ? fp : saved_state64(state)->rbp;
470 } else {
471 pc = saved_state32(state)->eip;
472 fp = fp != 0 ? fp : saved_state32(state)->ebp;
473 }
474
475 #elif defined(__arm64__)
476
477 struct arm_saved_state *state = get_user_regs(thread);
478 if (!state) {
479 error = EINVAL;
480 goto out;
481 }
482
483 user_64 = is_saved_state64(state);
484 pc = get_saved_state_pc(state);
485 fp = fp != 0 ? fp : get_saved_state_fp(state);
486
487 // ARM expects stack frames to be aligned to 16 bytes.
488 #define INVALID_USER_FP(FP) (((FP) & 0x3UL) != 0UL)
489
490 #else // defined(__arm64__) || defined(__x86_64__)
491 #error "unsupported architecture"
492 #endif // !defined(__arm64__) && !defined(__x86_64__)
493
494 // Only capture the save state PC without a custom frame pointer to walk.
495 if (!ctl || ctl->btc_frame_addr == 0) {
496 bt[frame_index++] = pc + addr_offset;
497 }
498
499 if (frame_index >= max_frames) {
500 goto out;
501 }
502
503 if (fp == 0) {
504 // If the FP is zeroed, then there's no stack to walk, by design. This
505 // happens for workq threads that are being sent back to user space or
506 // during boot-strapping operations on other kinds of threads.
507 goto out;
508 } else if (INVALID_USER_FP(fp)) {
509 // Still capture the PC in this case, but mark the stack as truncated
510 // and "faulting." (Using the frame pointer on a call stack would cause
511 // an exception.)
512 error = EFAULT;
513 truncated = true;
514 goto out;
515 }
516
517 union {
518 struct {
519 uint64_t fp;
520 uint64_t ret;
521 } u64;
522 struct {
523 uint32_t fp;
524 uint32_t ret;
525 } u32;
526 } frame;
527
528 frame_size = 2 * (user_64 ? 8 : 4);
529
530 while (fp != 0 && frame_index < max_frames) {
531 error = copy(ctx, (char *)&frame, fp, frame_size);
532 if (error) {
533 truncated = true;
534 goto out;
535 }
536
537 // Capture this return address before tripping over any errors finding
538 // the next frame to follow.
539 uintptr_t ret_addr = user_64 ? frame.u64.ret : frame.u32.ret;
540 #if defined(HAS_APPLE_PAC)
541 // Return addresses are signed by arm64e ABI, so strip off the auth
542 // bits.
543 bt[frame_index++] = (uintptr_t)ptrauth_strip((void *)ret_addr,
544 ptrauth_key_return_address) + addr_offset;
545 #else // defined(HAS_APPLE_PAC)
546 bt[frame_index++] = ret_addr + addr_offset;
547 #endif // !defined(HAS_APPLE_PAC)
548
549 // Find the next frame to follow.
550 next_fp = user_64 ? frame.u64.fp : frame.u32.fp;
551 bool async_frame = allow_async && SWIFT_ASYNC_FP(next_fp);
552 // There is no 32-bit ABI for Swift async call stacks.
553 if (user_64 && async_frame) {
554 async_index = frame_index - 1;
555 // The async context pointer is just below the stack frame.
556 user_addr_t async_ctx_ptr = fp - 8;
557 user_addr_t async_ctx = 0;
558 error = copy(ctx, (char *)&async_ctx, async_ctx_ptr,
559 sizeof(async_ctx));
560 if (error) {
561 goto out;
562 }
563 #if defined(HAS_APPLE_PAC)
564 async_frame_addr = (uintptr_t)ptrauth_strip((void *)async_ctx,
565 ptrauth_key_process_dependent_data);
566 #else // defined(HAS_APPLE_PAC)
567 async_frame_addr = (uintptr_t)async_ctx;
568 #endif // !defined(HAS_APPLE_PAC)
569 has_async = true;
570 allow_async = false;
571 }
572 next_fp = SWIFT_ASYNC_FP_CLEAR(next_fp);
573 #if defined(HAS_APPLE_PAC)
574 next_fp = (uintptr_t)ptrauth_strip((void *)next_fp,
575 ptrauth_key_frame_pointer);
576 #endif // defined(HAS_APPLE_PAC)
577 if (INVALID_USER_FP(next_fp)) {
578 break;
579 }
580
581 // User space stacks generally grow down, but in some cases can jump to a different stack.
582 // Skip the check that the frame pointer moves downward here.
583
584 if (next_fp == fp) {
585 break;
586 }
587 fp = next_fp;
588 }
589
590 out:
591 if (switched_map) {
592 vm_map_switch_back(switch_ctx);
593 vm_map_deallocate(map);
594 }
595
596 // NULL-terminate the list, if space is available.
597 if (frame_index < max_frames) {
598 bt[frame_index] = 0;
599 }
600
601 if (info_out) {
602 info_out->btui_error = error;
603 backtrace_info_t info = user_64 ? BTI_64_BIT : BTI_NONE;
604 bool out_of_space = !INVALID_USER_FP(fp) && frame_index == max_frames;
605 if (truncated || out_of_space) {
606 info |= BTI_TRUNCATED;
607 }
608 if (out_of_space && error == 0) {
609 info_out->btui_next_frame_addr = fp;
610 }
611 info_out->btui_info = info;
612 info_out->btui_async_start_index = async_index;
613 info_out->btui_async_frame_addr = async_frame_addr;
614 }
615
616 return frame_index;
617 }
618