When user closes a handle of
AppleHVClient
the kernel will call
AppleHVClient::free
via
IOService::terminateWorker
, and this free function will
call
hv_vmx_vm_t::free
as follow.
1 |
hv_vmx_vm_t::free(): |
hv_vmx_vm_t::free
function will fetch the lock and free
this lock. But at the same time, user can use this lock via
machdep
system call
hv_vmx_vm_t::TRAP_hv_destroy_vm
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
hv_vmx_vm_t::TRAP_hv_destroy_vm(hv_vmx_vm_t*):
0000000000001772 pushq %rbp
0000000000001773 movq %rsp, %rbp
0000000000001776 pushq %r14
0000000000001778 pushq %rbx
0000000000001779 movq %rdi, %rbx
000000000000177c testq %rbx, %rbx
000000000000177f je 0x17a7
0000000000001781 movq 0x80(%rbx), %rdi
0000000000001788 callq _IOLockLock
000000000000178d cmpl $0x0, 0x40(%rbx)
0000000000001791 jle 0x17af
0000000000001793 movq 0x80(%rbx), %rdi
000000000000179a callq _IOLockUnlock
000000000000179f movl $0xfae94001, %r14d
00000000000017a5 jmp 0x17c5
00000000000017a7 movl $0xfae94006, %r14d
00000000000017ad jmp 0x17c5
00000000000017af xorl %r14d, %r14d
00000000000017b2 xorl %edi, %edi
00000000000017b4 callq _hv_set_task_target
So UaF happens. Details about this issue and some basic knowledges about XNU which powers iOS/macOS are discussed in the complete write-up.
And PoC of this issue is also available on Github.