Mac OS X Expert Challenge — 2005.1
Winner: Alexey Proskuryakov
Analysis
Panpipes creates a Mach task, then calls exit() from it. In a more detailed manner:
- It runs from a static init routine, thus attempts to break on
main()fail. I usedDYLD_PRINT_INITIALIZERSenvironment variable to ask dyld to display all initializers. - The init routine deciphers in RAM (syscalls for
mach_reply_port,thread_self,mach_msg,mach_msg_overwrite,exit,ptrace). I simply stepped through the routine, then usedx/ito display the code. - Then, it calls
task_set_exception_portsto disable debugging. It does this manually, via amach_msg trap, making it pretty hard to guess what's going on. Again, some stepping, plus grepping Mach sources to find the function for thismsgh_id. I removed the call from the binary to simplify further investigation. - Then, it creates a new thread (with
main()as the routine). Obviously, this also makes debugging somewhat harder. main()creates a new Mach task, and three threads in it (obviously all Mach calls are still performed manually).- For one of the threads, it changes the state (
srr0,spandlrregisters) and resumes it. - The functions in
srr0andlrpretend to do something with IOKit, but this seems to be red herring — a plainexit(0)gives the same kernel panic for me.
Proposed Fix
As I understand the issue, it's unix_syscall expecting that the current task is a BSD one (I looked at the exception state in panic log for the addresses, then used gdb on /mach_kernel to find out symbolic names.
0x002a6b68 <unix_syscall+184>: bl 0x40e70 <get_bsdtask_info>
0x002a6b6c <unix_syscall+188>: b 0x2a6b74 <unix_syscall+196>
0x002a6b70 <unix_syscall+192>: bl 0x2a8228 <current_proc>
0x002a6b74 <unix_syscall+196>: lwz r30,256(r31)
0x002a6b78 <unix_syscall+200>: mr r28,r3
0x002a6b7c <unix_syscall+204>: lwz r0,8(r3) <panic here>
Thus, there should be a check that get_bsdtask_info returns a non-zero value.
On 10.3, the panic happens in a different place (in proc_is_classic). Again, the function does not check its input parameter for being zero, so the basic mechanism appears to be the same.
Time Spent
It took me about 15 hours to write this letter.
Bio
I graduated from the Moscow State University, where I studied Mathematics, in 1999. I have been a Mac user, admin, and developer since 1993 — mostly C++/Carbon, with small trips into Cocoa and UNIX lands.
Alexey ProskuryakovAmit: The astute reader will notice some minor discrepancies between this analysis and my description of panpipes. However, I point this out for technical accuracy: given that Alexey essentially started with a black box, the amount of detail he extracted is amazing.