There is a violation of MIG semantics in IOUserUserClient::externalMethod
: Assuming an asyncWakePort is given, _ExternalMethod
will be called and if it returns success, the port will be released:
if (MACH_PORT_NULL != wake_port) {
// this release is for the mig created send right
iokit_release_port_send(wake_port);
}
However, the method is still able to fail after this point (when _ExternalMethod
returned something in structureOutput and the length of this data is more than the client application expected), resulting in an over-release of the asyncWakePort because it will also be freed by MIG (due to the error response).