Skip to content

Latest commit

 

History

History
115 lines (104 loc) · 11.9 KB

kernel_stack_overflow.md

File metadata and controls

115 lines (104 loc) · 11.9 KB

An example of a kernel stack overflow caused by nested calls. This type of stack overflow usually manifests itself as a kernel panic with a double fault error.

    frame #0: 0xffffff802485002c kernel`panic_trap_to_debugger [inlined] current_cpu_datap at cpu_data.h:401 [opt]
    frame #1: 0xffffff802485002c kernel`panic_trap_to_debugger [inlined] current_processor at cpu.c:220 [opt]
    frame #2: 0xffffff802485002c kernel`panic_trap_to_debugger [inlined] DebuggerTrapWithState(db_op=DBOP_PANIC, db_message=<unavailable>, db_panic_str="\"%s at 0x%016llx, registers:\\n\" \"CR0: 0x%016lx, CR2: 0x%016lx, CR3: 0x%016lx, CR4: 0x%016lx\\n\" \"RAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\\n\" \"RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\\n\" \"R8:  0x%016llx, R9:  0x%016llx, R10: 0x%016llx, R11: 0x%016llx\\n\" \"R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\\n\" \"RFL: 0x%016llx, RIP: 0x%016llx, CS:  0x%016llx, SS:  0x%016llx\\n\" \"Error code: 0x%016llx%s\\n\"@/BuildRoot/Library/Caches/com.apple.xbs/Sources/xnu/xnu-4570.31.3/osfmk/i386/trap_native.c:168", db_panic_args=<unavailable>, db_panic_options=<unavailable>, db_proceed_on_sync_failure=1, db_panic_caller=<unavailable>) at debug.c:463 [opt]
    frame #3: 0xffffff802485000d kernel`panic_trap_to_debugger(panic_format_str="\"%s at 0x%016llx, registers:\\n\" \"CR0: 0x%016lx, CR2: 0x%016lx, CR3: 0x%016lx, CR4: 0x%016lx\\n\" \"RAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\\n\" \"RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\\n\" \"R8:  0x%016llx, R9:  0x%016llx, R10: 0x%016llx, R11: 0x%016llx\\n\" \"R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\\n\" \"RFL: 0x%016llx, RIP: 0x%016llx, CS:  0x%016llx, SS:  0x%016llx\\n\" \"Error code: 0x%016llx%s\\n\"@/BuildRoot/Library/Caches/com.apple.xbs/Sources/xnu/xnu-4570.31.3/osfmk/i386/trap_native.c:168", panic_args=<unavailable>, reason=<unavailable>, ctx=0x0000000000000000, panic_options_mask=<unavailable>, panic_caller=0) at debug.c:724 [opt]
    frame #4: 0xffffff802484fdac kernel`panic(str=<unavailable>) at debug.c:611 [opt]
    frame #5: 0xffffff802496fd1a kernel`panic_64(sp=0xffffff802454c6e0, pc=<unavailable>, msg="Double fault", do_mca_dump=<unavailable>) at trap_native.c:152 [opt]
    frame #6: 0xffffff80248029dd kernel`hndl_double_fault + 29
    frame #7: 0x000000000000000f
    frame #8: 0xffffff802485c204 kernel`kalloc_canblock [inlined] zalloc_canblock_tag(zone=0x0000000000000008, canblock=<unavailable>) at zalloc.c:3366 [opt]
    frame #9: 0xffffff802485c1fa kernel`kalloc_canblock(psize=0xffffff802c328140, canblock=<unavailable>, site=<unavailable>) at kalloc.c:720 [opt]
    frame #10: 0xffffff80249016e5 kernel`upl_create(type=2, flags=512, size=<unavailable>) at vm_pageout.c:4794 [opt]
    frame #11: 0xffffff8024902449 kernel`vm_object_iopl_request(object=0xffffff802523f540, offset=<unavailable>, size=<unavailable>, upl_ptr=0xffffff802c328748, user_page_list=<unavailable>, page_list_count=0xffffff802c3287bc, cntrl_flags=5120, tag=<unavailable>) at vm_pageout.c:8242 [opt]
    frame #12: 0xffffff8024902297 kernel`vm_map_create_upl(map=<unavailable>, offset=<unavailable>, upl_size=0xffffff802c3287b8, upl=0xffffff802c328748, page_list=0xffffff8039ab6bb0, count=0xffffff802c3287bc, flags=<unavailable>, tag=<unavailable>) at vm_pageout.c:6286 [opt]
    frame #13: 0xffffff802490216e kernel`vm_map_create_upl(map=<unavailable>, offset=<unavailable>, upl_size=0xffffff802c3287b8, upl=0xffffff802c328748, page_list=0xffffff8039ab6bb0, count=0xffffff802c3287bc, flags=<unavailable>, tag=<unavailable>) at vm_pageout.c:6152 [opt]
    frame #14: 0xffffff8024ea430b kernel`IOGeneralMemoryDescriptor::wireVirtual(this=<unavailable>, forDirection=<unavailable>) at IOMemoryDescriptor.cpp:3173 [opt]
    frame #15: 0xffffff8024ea20ba kernel`IOGeneralMemoryDescriptor::prepare(this=0xffffff80347b72c0, forDirection=0) at IOMemoryDescriptor.cpp:3488 [opt]
    frame #16: 0xffffff7fa5275479 IOStorageFamily`dkreadwrite(dkr=0xffffff80b9c9f110, dkrtype=DKRTYPE_BUF) at IOMediaBSDClient.cpp:2915 [opt]
    frame #17: 0xffffff8024ac8b04 kernel`spec_strategy(ap=<unavailable>) at spec_vnops.c:2404 [opt]
  * frame #18: 0xffffff8024ac0712 kernel`VNOP_STRATEGY(bp=<unavailable>) at kpi_vfs.c:5696 [opt]
    frame #19: 0xffffff7fa5eaeb9e
    frame #20: 0xffffff7fa5eae92c
    frame #21: 0xffffff7fa5ead970
    frame #22: 0xffffff7fa5eb8a57
    frame #23: 0xffffff7fa5eb7f74
    frame #24: 0xffffff7fa5e9c108
    frame #25: 0xffffff7fa5e9bf7b
    frame #26: 0xffffff7fa5ea468f
    frame #27: 0xffffff7fa5ea4d86
    frame #28: 0xffffff7fa5e7d7ca
    frame #29: 0xffffff7fa5e83f63
    frame #30: 0xffffff7fa5e882ca
    frame #31: 0xffffff7fa5e5a827
    frame #32: 0xffffff7fa5e5b5f6
    frame #33: 0xffffff7fa5e4e8a3
    frame #34: 0xffffff7fa7a4f0fa VFSFilter`CmdVnopLookupHook(ap=0xffffff802c329d78) at VFSHooks.cpp:497
    frame #35: 0xffffff8024a82bf9 kernel`lookup [inlined] VNOP_LOOKUP(cnp=<unavailable>, ctx=<unavailable>) at kpi_vfs.c:3010 [opt]
    frame #36: 0xffffff8024a82bab kernel`lookup(ndp=<unavailable>) at vfs_lookup.c:1150 [opt]
    frame #37: 0xffffff8024a81dc2 kernel`namei(ndp=0xffffff802c329f50) at vfs_lookup.c:390 [opt]
    frame #38: 0xffffff8024a8dd35 kernel`vnode_lookup(path=<unavailable>, flags=<unavailable>, vpp=0xffffff802c32a680, ctx=<unavailable>) at vfs_subr.c:5544 [opt]
    frame #39: 0xffffff7fa7a502c7 VFSFilter`CmdVnopLookupHook(ap=0xffffff802c32acb8) at VFSHooks.cpp:702
    frame #40: 0xffffff8024a82bf9 kernel`lookup [inlined] VNOP_LOOKUP(cnp=<unavailable>, ctx=<unavailable>) at kpi_vfs.c:3010 [opt]
    frame #41: 0xffffff8024a82bab kernel`lookup(ndp=<unavailable>) at vfs_lookup.c:1150 [opt]
    frame #42: 0xffffff8024a81dc2 kernel`namei(ndp=0xffffff802c32af48) at vfs_lookup.c:390 [opt]
    frame #43: 0xffffff8024ab22ea kernel`open_xattrfile(vp=0xffffff8030fbe8b8, fileflags=<unavailable>, xvpp=0xffffff802c32b340, context=<unavailable>) at vfs_xattr.c:2539 [opt]
    frame #44: 0xffffff8024ab1b02 kernel`vn_getxattr [inlined] default_getxattr(options=0) at vfs_xattr.c:1621 [opt]
    frame #45: 0xffffff8024ab1aaa kernel`vn_getxattr(vp=0xffffff8030fbe8b8, name="com.apple.FinderInfo", uio=0xffffff802c32b500, size=0xffffff802c32b450, options=912436912, context=0xffffff803662aeb0) at vfs_xattr.c:169 [opt]
    frame #46: 0xffffff8024a655b5 kernel`vfs_attr_pack_internal at vfs_attrlist.c:1706 [opt]
    frame #47: 0xffffff8024a654f1 kernel`vfs_attr_pack_internal(vp=<unavailable>, auio=<unavailable>, alp=<unavailable>, options=<unavailable>, vap=<unavailable>, fndesc=<unavailable>, ctx=<unavailable>, is_bulk=<unavailable>, vtype=<unavailable>, fixedsize=<unavailable>) at vfs_attrlist.c:2625 [opt]
    frame #48: 0xffffff8024a67fc2 kernel`getattrlist_internal(ctx=0xffffff803662aeb0, vp=0xffffff8030fbe8b8, alp=<unavailable>, attributeBuffer=4408281593728, bufferSize=<unavailable>, options=37, segflg=<unavailable>, authoritative_name=<unavailable>, file_cred=<unavailable>) at vfs_attrlist.c:2956 [opt]
    frame #49: 0xffffff8024a6a6bf kernel`getattrlistat_internal(ctx=0xffffff803662aeb0, path=<unavailable>, alp=0xffffff802c32bf18, attributeBuffer=140549983849064, bufferSize=1016, options=37, segflg=<unavailable>, pathsegflg=<unavailable>, fd=<unavailable>) at vfs_attrlist.c:3042 [opt]
    frame #50: 0xffffff8024a6a590 kernel`getattrlist(p=<unavailable>, uap=0xffffff803662ad58, retval=<unavailable>) at vfs_attrlist.c:3067 [opt]
    frame #51: 0xffffff8024dfb3e8 kernel`unix_syscall64(state=<unavailable>) at systemcalls.c:382 [opt]
    frame #52: 0xffffff8024802906 kernel`hndl_unix_scall64 + 22

Let's get the system kernel stack size.

(lldb) p/x kernel_stack_size
(vm_offset_t) $14 = 0x0000000000004000

Get the current thread stack base. First get the list of the threads executed on each CPU and locate a thread of interest with the showcurrentthreads commands. Alternatively you can use the showcurrentstacks command.

(lldb) showcurrentthreads
Processor 0xffffff80251e03b8 cpu_id  0x0 AST:        State RUNNING      Preemption Disabled
task                 vm_map               ipc_space            #acts flags    pid       process             io_policy  wq_state  command             
0xffffff8037164648   0xffffff8035b65a00   0xffffff8035eaf9c0      18 DB       458   0xffffff8038976910              Q -1 -1 -1    Safari              
	thread                   thread_id  processor            base   pri    sched_mode      io_policy       state    ast          waitq                            wait_event           wmesg                thread_name         
	0xffffff8035ab0000  [WQ] 0x2321     0xffffff80251e03b8   37     37     timeshare                       R                                                                                                                    
Processor 0xffffff80b7d96000 cpu_id  0x1 AST:        State IDLE         Preemption Disabled
task                 vm_map               ipc_space            #acts flags    pid       process             io_policy  wq_state  command             
0xffffff803062ec28   0xffffff8028888520   0xffffff802fc8ccc0     152            0   0xffffff80252117f8                -1 -1 -1    kernel_task         
	thread                   thread_id  processor            base   pri    sched_mode      io_policy       state    ast          waitq                            wait_event           wmesg                thread_name         
	0xffffff8030bdb650       0x93       0xffffff80b7d96000   0      0      fixed bound                     RI                                                                                               idle #1             
Processor 0xffffff80b7d95000 cpu_id  0x2 AST:        State IDLE         Preemption Disabled
task                 vm_map               ipc_space            #acts flags    pid       process             io_policy  wq_state  command             
0xffffff803062ec28   0xffffff8028888520   0xffffff802fc8ccc0     152            0   0xffffff80252117f8                -1 -1 -1    kernel_task         
	thread                   thread_id  processor            base   pri    sched_mode      io_policy       state    ast          waitq                            wait_event           wmesg                thread_name         
	0xffffff8030bdb160       0x90       0xffffff80b7d95000   0      0      fixed bound                     RI                                                                                               idle #2             
Processor 0xffffff80b7d9d000 cpu_id  0x3 AST:        State IDLE         Preemption Disabled
task                 vm_map               ipc_space            #acts flags    pid       process             io_policy  wq_state  command             
0xffffff803062ec28   0xffffff8028888520   0xffffff802fc8ccc0     152            0   0xffffff80252117f8                -1 -1 -1    kernel_task         
	thread                   thread_id  processor            base   pri    sched_mode      io_policy       state    ast          waitq                            wait_event           wmesg                thread_name         
	0xffffff8030bdca10       0x96       0xffffff80b7d9d000   0      0      fixed bound                     RI                                                                                               idle #3     

Get the thread's stack base

(lldb) p/x ((struct thread*)0xffffff8035ab0000)->kernel_stack
(vm_offset_t) $15 = 0xffffff802c328000

Check that at the top of a call stack we have a full stack available

(lldb) f 50
frame #50: 0xffffff8024a6a590 kernel`getattrlist(p=<unavailable>, uap=0xffffff803662ad58, retval=<unavailable>) at vfs_attrlist.c:3067 [opt]
(lldb) p/x $rsp-0xffffff802c328000
(unsigned long) $16 = 0x0000000000003ef0

Check that at the bottom of the call stack the stack has been depleted

(lldb) f 8
frame #8: 0xffffff802485c204 kernel`kalloc_canblock [inlined] zalloc_canblock_tag(zone=0x0000000000000008, canblock=<unavailable>) at zalloc.c:3366 [opt]
(lldb) p/x $rsp-0xffffff802c328000
(unsigned long) $17 = 0x00000000000000f0