IOReturn IOI2CInterfaceUserClient::extAcquireBus( void ) { IOReturn ret = kIOReturnNotReady; IOI2CInterface * provider; if ((provider = (IOI2CInterface *) copyParentEntry(gIOServicePlane))) { ret = provider->open( this ) ? kIOReturnSuccess : kIOReturnBusy; provider->release(); } return (ret); }
IOReturn IOI2CInterfaceUserClient::extReleaseBus( void ) { IOReturn ret = kIOReturnNotReady; IOI2CInterface * provider; if ((provider = (IOI2CInterface *) copyParentEntry(gIOServicePlane))) { provider->close( this ); provider->release(); ret = kIOReturnSuccess; } return (ret); }
bool IOHIDInterface::matchPropertyTable( OSDictionary * table, SInt32 * score) { IOService * provider; bool ret; RETAIN_ON_STACK(this); if ( !super::matchPropertyTable(table, score) || !(provider = OSDynamicCast(IOService, copyParentEntry(gIOServicePlane))) ) return false; // We should retain a reference to our provider while calling matchPropertyTable. // This is necessary in a situation where a user space process could be searching // the registry during termination. ret = provider->matchPropertyTable(table, score); provider->release(); return ret; }
IOReturn IOI2CInterfaceUserClient::extIO( void * inStruct, void * outStruct, IOByteCount inSize, IOByteCount * outSize ) { IOReturn err = kIOReturnNotReady; IOI2CInterface * provider; IOI2CBuffer * buffer; IOI2CRequest * request; IOI2CRequest_10_5_0 * requestV1 = NULL; IOI2CRequest requestV2; if (inSize < sizeof(IOI2CBuffer)) return (kIOReturnNoSpace); if (*outSize < inSize) return (kIOReturnNoSpace); buffer = (IOI2CBuffer *) inStruct; request = &buffer->request; if (!request->sendTransactionType && !request->replyTransactionType) { requestV1 = (typeof (requestV1)) &buffer->request; bzero(&requestV2, sizeof(requestV2)); request = &requestV2; request->sendTransactionType = requestV1->sendTransactionType; request->replyTransactionType = requestV1->replyTransactionType; request->sendAddress = requestV1->sendAddress; request->replyAddress = requestV1->replyAddress; request->sendBytes = requestV1->sendBytes; request->replyBytes = requestV1->replyBytes; request->sendSubAddress = requestV1->sendSubAddress; request->replySubAddress = requestV1->replySubAddress; request->commFlags = requestV1->commFlags; request->minReplyDelay = requestV1->minReplyDelay; } else { /* <rdar://problem/23955672> ZDI-CAN-3453: Apple OS X IOGraphicsFamily Untrusted Pointer Dereference Privilege Escalation Vulnerability IOI2CInterfaceUserClient::extIO <rdar://problem/24172232> ZDI-CAN-3453: Apple OS X IOGraphicsFamily Untrusted Pointer Dereference Privilege Escalation Vulnerability IOI2CInterfaceUserClient::extIO <rdar://problem/24065934> ZDI- CAN-3489: Apple OS X IOGraphicsFamily Untrusted Pointer Dereference Privilege Escalation Vulnerability <rdar://problem/24172270> ZDI- CAN-3489: Apple OS X IOGraphicsFamily Untrusted Pointer Dereference Privilege Escalation Vulnerability Force completion to NULL if passed in from user land (V1 only case), V2 case handled by the bzero of the V2 structure (above). */ request->completion = NULL; } if ((provider = (IOI2CInterface *) copyParentEntry(gIOServicePlane))) do { if (!provider->isOpen(this)) { err = kIOReturnNotOpen; continue; } if (request->sendBytes) { if (!request->sendBuffer) request->sendBuffer = (vm_address_t) &buffer->inlineBuffer[0]; else { err = kIOReturnMessageTooLarge; continue; } } if (request->replyBytes) { if (!request->replyBuffer) request->replyBuffer = (vm_address_t) &buffer->inlineBuffer[0]; else { err = kIOReturnMessageTooLarge; continue; } } err = provider->startIO( request ); if (requestV1) requestV1->result = request->result; } while (false); if (provider) provider->release(); if (kIOReturnSuccess == err) { *outSize = inSize; bcopy(inStruct, outStruct, inSize); } else *outSize = 0; return (err); }