Userspace MIG services often use mach_msg_server or mach_msg_server_once to implent an RPC server.
These two functions are also responsible for managing the resources associated with each message
similar to the ipc_kobject_server routine in the kernel.
If a MIG handler method returns an error code then it is assumed to not have take ownership of any
of the resources in the message and both mach_msg_server and mach_msg_server_once will pass the message
to mach_msg_destroy:
If the message had and OOL memory descriptor it reaches this code:
case MACH_MSG_OOL_DESCRIPTOR : {
mach_msg_ool_descriptor_t *dsc;
dsc = &saddr->out_of_line;
if (dsc->deallocate) {
mach_msg_destroy_memory((vm_offset_t)dsc->address,
dsc->size);
}
break;
}
...
static void
mach_msg_destroy_memory(vm_offset_t addr, vm_size_t size)
{
if (size != 0)
(void) vm_deallocate(mach_task_self(), addr, size);
}
If the deallocate flag is set in the ool descriptor then this will pass the address contained in the descriptor
to vm_deallocate.
By default MIG client code passes OOL memory with the copy type set to MACH_MSG_PHYSICAL_COPY which ends up with the
receiver getting a 0 value for deallocate (meaning that you *do* need vm_deallocate it in the handler even if you return
and error) but by setting the copy type to MACH_MSG_VIRTUAL_COPY in the sender deallocate will be 1 in the receiver meaning
that in cases where the MIG handler vm_deallocate's the ool memory and returns an error code the mach_msg_* code will
deallocate it again.
Exploitability hinges on being able to get the memory reallocated inbetween the two vm_deallocate calls, probably in another thread.
This PoC only demonstrates that an instance of the bug does exist in the first service I looked at,
com.apple.system.DirectoryService.legacy hosted by /usr/libexec/dspluginhelperd. Trace through in a debugger and you'll see the
two calls to vm_deallocate, first in _receive_session_create which returns an error code via the MIG reply message then in
mach_msg_destroy.
Note that this service has multiple threads interacting with mach messages in parallel.
I will have a play with some other services and try to exploit an instance of this bug class but the severity should
be clear from this PoC alone.
Tested on MacOS Sierra 10.12 16A323
|
Deleted:
dsplug.c
4.4 KB
|
Comment 1 by ianbeer@google.com, Sep 26 2016
Project Member