X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d190cdc3f5544636abb56dc1874be391d3e1b148..e8c3f78193f1895ea514044358b93b1add9322f3:/iokit/Kernel/IOUserClient.cpp diff --git a/iokit/Kernel/IOUserClient.cpp b/iokit/Kernel/IOUserClient.cpp index d568aaca2..b99f027dd 100644 --- a/iokit/Kernel/IOUserClient.cpp +++ b/iokit/Kernel/IOUserClient.cpp @@ -37,8 +37,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -123,45 +125,13 @@ do { \ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -// definitions we should get from osfmk - -//typedef struct ipc_port * ipc_port_t; -typedef natural_t ipc_kobject_type_t; - -#define IKOT_IOKIT_SPARE 27 -#define IKOT_IOKIT_CONNECT 29 -#define IKOT_IOKIT_OBJECT 30 - extern "C" { -extern ipc_port_t iokit_alloc_object_port( io_object_t obj, - ipc_kobject_type_t type ); - -extern kern_return_t iokit_destroy_object_port( ipc_port_t port ); - -extern mach_port_name_t iokit_make_send_right( task_t task, - io_object_t obj, ipc_kobject_type_t type ); - -extern kern_return_t iokit_mod_send_right( task_t task, mach_port_name_t name, mach_port_delta_t delta ); - -extern io_object_t iokit_lookup_connect_ref(io_object_t clientRef, ipc_space_t task); - -extern io_object_t iokit_lookup_connect_ref_current_task(io_object_t clientRef); - -extern ipc_port_t master_device_port; - -extern void iokit_retain_port( ipc_port_t port ); -extern void iokit_release_port( ipc_port_t port ); -extern void iokit_release_port_send( ipc_port_t port ); - -extern kern_return_t iokit_switch_object_port( ipc_port_t port, io_object_t obj, ipc_kobject_type_t type ); - #include #include } /* extern "C" */ - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject. @@ -201,17 +171,28 @@ static IOLock * gIOObjectPortLock; // not in dictForType() for debugging ease static OSDictionary * gIOObjectPorts; static OSDictionary * gIOConnectPorts; +static OSDictionary * gIOIdentifierPorts; OSDictionary * IOMachPort::dictForType( ipc_kobject_type_t type ) { OSDictionary ** dict; - if( IKOT_IOKIT_OBJECT == type ) - dict = &gIOObjectPorts; - else if( IKOT_IOKIT_CONNECT == type ) - dict = &gIOConnectPorts; - else - return( 0 ); + switch (type) + { + case IKOT_IOKIT_OBJECT: + dict = &gIOObjectPorts; + break; + case IKOT_IOKIT_CONNECT: + dict = &gIOConnectPorts; + break; + case IKOT_IOKIT_IDENT: + dict = &gIOIdentifierPorts; + break; + default: + panic("dictForType %d", type); + dict = NULL; + break; + } if( 0 == *dict) *dict = OSDictionary::withCapacity( 1 ); @@ -402,6 +383,7 @@ public: virtual void reset() APPLE_KEXT_OVERRIDE; virtual bool isValid() APPLE_KEXT_OVERRIDE; virtual OSObject * getNextObject() APPLE_KEXT_OVERRIDE; + virtual OSObject * copyNextObject(); }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -490,11 +472,20 @@ IOUserIterator::isValid() OSObject * IOUserIterator::getNextObject() { - OSObject * ret; + assert(false); + return (NULL); +} + +OSObject * +IOUserIterator::copyNextObject() +{ + OSObject * ret = NULL; IOLockLock(lock); - assert(OSDynamicCast(OSIterator, userIteratorObject)); - ret = ((OSIterator *)userIteratorObject)->getNextObject(); + if (userIteratorObject) { + ret = ((OSIterator *)userIteratorObject)->getNextObject(); + if (ret) ret->retain(); + } IOLockUnlock(lock); return (ret); @@ -506,10 +497,19 @@ extern "C" { // functions called from osfmk/device/iokit_rpc.c void -iokit_add_reference( io_object_t obj ) +iokit_add_reference( io_object_t obj, ipc_kobject_type_t type ) { - if( obj) - obj->retain(); + IOUserClient * uc; + + if (!obj) return; + + if ((IKOT_IOKIT_CONNECT == type) + && (uc = OSDynamicCast(IOUserClient, obj))) + { + OSIncrementAtomic(&uc->__ipc); + } + + obj->retain(); } void @@ -519,18 +519,6 @@ iokit_remove_reference( io_object_t obj ) obj->release(); } -void -iokit_add_connect_reference( io_object_t obj ) -{ - IOUserClient * uc; - - if (!obj) return; - - if ((uc = OSDynamicCast(IOUserClient, obj))) OSIncrementAtomic(&uc->__ipc); - - obj->retain(); -} - void iokit_remove_connect_reference( io_object_t obj ) { @@ -604,7 +592,9 @@ iokit_client_died( io_object_t obj, ipc_port_t /* port */, if( (client = OSDynamicCast( IOUserClient, obj ))) { IOStatisticsClientCall(); + IOLockLock(client->lock); client->clientDied(); + IOLockUnlock(client->lock); } } else if( IKOT_IOKIT_OBJECT == type) @@ -636,7 +626,6 @@ class IOServiceUserNotification : public IOUserNotification PingMsg * pingMsg; vm_size_t msgSize; OSArray * newSet; - OSObject * lastEntry; bool armed; bool ipcLogged; @@ -646,12 +635,14 @@ public: void * reference, vm_size_t referenceSize, bool clientIs64 ); virtual void free() APPLE_KEXT_OVERRIDE; + void invalidatePort(void); static bool _handler( void * target, void * ref, IOService * newService, IONotifier * notifier ); virtual bool handler( void * ref, IOService * newService ); virtual OSObject * getNextObject() APPLE_KEXT_OVERRIDE; + virtual OSObject * copyNextObject() APPLE_KEXT_OVERRIDE; }; class IOServiceMessageUserNotification : public IOUserNotification @@ -679,6 +670,7 @@ public: bool clientIs64 ); virtual void free() APPLE_KEXT_OVERRIDE; + void invalidatePort(void); static IOReturn _handler( void * target, void * ref, UInt32 messageType, IOService * provider, @@ -688,6 +680,7 @@ public: void * messageArgument, vm_size_t argSize ); virtual OSObject * getNextObject() APPLE_KEXT_OVERRIDE; + virtual OSObject * copyNextObject() APPLE_KEXT_OVERRIDE; }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -784,16 +777,19 @@ bool IOServiceUserNotification::init( mach_port_t port, natural_t type, return( true ); } +void IOServiceUserNotification::invalidatePort(void) +{ + if (pingMsg) pingMsg->msgHdr.msgh_remote_port = MACH_PORT_NULL; +} + void IOServiceUserNotification::free( void ) { PingMsg * _pingMsg; vm_size_t _msgSize; OSArray * _newSet; - OSObject * _lastEntry; _pingMsg = pingMsg; _msgSize = msgSize; - _lastEntry = lastEntry; _newSet = newSet; super::free(); @@ -805,9 +801,6 @@ void IOServiceUserNotification::free( void ) IOFree(_pingMsg, _msgSize); } - if( _lastEntry) - _lastEntry->release(); - if( _newSet) _newSet->release(); } @@ -863,16 +856,19 @@ bool IOServiceUserNotification::handler( void * ref, return( true ); } - OSObject * IOServiceUserNotification::getNextObject() +{ + assert(false); + return (NULL); +} + +OSObject * IOServiceUserNotification::copyNextObject() { unsigned int count; OSObject * result; - OSObject * releaseEntry; IOLockLock(lock); - releaseEntry = lastEntry; count = newSet->getCount(); if( count ) { result = newSet->getObject( count - 1 ); @@ -882,12 +878,9 @@ OSObject * IOServiceUserNotification::getNextObject() result = 0; armed = true; } - lastEntry = result; IOLockUnlock(lock); - if (releaseEntry) releaseEntry->release(); - return( result ); } @@ -940,6 +933,11 @@ bool IOServiceMessageUserNotification::init( mach_port_t port, natural_t type, return( true ); } +void IOServiceMessageUserNotification::invalidatePort(void) +{ + if (pingMsg) pingMsg->msgHdr.msgh_remote_port = MACH_PORT_NULL; +} + void IOServiceMessageUserNotification::free( void ) { PingMsg * _pingMsg; @@ -993,9 +991,9 @@ IOReturn IOServiceMessageUserNotification::handler( void * ref, } else { + if( callerArgSize > kIOUserNotifyMaxMessageSize) + callerArgSize = kIOUserNotifyMaxMessageSize; argSize = callerArgSize; - if( argSize > kIOUserNotifyMaxMessageSize) - argSize = kIOUserNotifyMaxMessageSize; } // adjust message size for ipc restrictions @@ -1076,6 +1074,11 @@ OSObject * IOServiceMessageUserNotification::getNextObject() return( 0 ); } +OSObject * IOServiceMessageUserNotification::copyNextObject() +{ + return( NULL ); +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #undef super @@ -1446,7 +1449,7 @@ IOUserClient::registerOwner(task_t task) if (newOwner) { owner = IONew(IOUserClientOwner, 1); - if (!newOwner) ret = kIOReturnNoMemory; + if (!owner) ret = kIOReturnNoMemory; else { owner->task = task; @@ -1531,6 +1534,7 @@ iokit_task_terminate(task_t task) void IOUserClient::free() { if( mappings) mappings->release(); + if (lock) IOLockFree(lock); IOStatisticsUnregisterCounter(); @@ -1617,7 +1621,7 @@ IOMemoryMap * IOUserClient::mapClientMemory64( { IOReturn err; IOOptionBits options = 0; - IOMemoryDescriptor * memory; + IOMemoryDescriptor * memory = 0; IOMemoryMap * map = 0; err = clientMemoryForType( (UInt32) type, &options, &memory ); @@ -1645,9 +1649,41 @@ IOReturn IOUserClient::exportObjectToClient(task_t task, name = IOMachPort::makeSendRightForTask( task, obj, IKOT_IOKIT_OBJECT ); *(mach_port_name_t *)clientObj = name; + + if (obj) obj->release(); + return kIOReturnSuccess; } +IOReturn IOUserClient::copyPortNameForObjectInTask(task_t task, + OSObject *obj, mach_port_name_t * port_name) +{ + mach_port_name_t name; + + name = IOMachPort::makeSendRightForTask( task, obj, IKOT_IOKIT_IDENT ); + + *(mach_port_name_t *) port_name = name; + + return kIOReturnSuccess; +} + +IOReturn IOUserClient::copyObjectForPortNameInTask(task_t task, mach_port_name_t port_name, + OSObject **obj) +{ + OSObject * object; + + object = iokit_lookup_object_with_port_name(port_name, IKOT_IOKIT_IDENT, task); + + *obj = object; + + return (object ? kIOReturnSuccess : kIOReturnIPCError); +} + +IOReturn IOUserClient::adjustPortNameReferencesInTask(task_t task, mach_port_name_t port_name, mach_port_delta_t delta) +{ + return (iokit_mod_send_right(task, port_name, delta)); +} + IOExternalMethod * IOUserClient::getExternalMethodForIndex( UInt32 /* index */) { return( 0 ); @@ -1921,38 +1957,36 @@ kern_return_t is_io_object_get_superclass( io_name_t obj_name, io_name_t class_name) { - const OSMetaClass* my_obj = NULL; - const OSMetaClass* superclass = NULL; - const OSSymbol *my_name = NULL; - const char *my_cstr = NULL; + IOReturn ret; + const OSMetaClass * meta; + const OSMetaClass * super; + const OSSymbol * name; + const char * cstr; - if (!obj_name || !class_name) - return (kIOReturnBadArgument); + if (!obj_name || !class_name) return (kIOReturnBadArgument); + if (master_port != master_device_port) return( kIOReturnNotPrivileged); - if( master_port != master_device_port) - return( kIOReturnNotPrivileged); + ret = kIOReturnNotFound; + meta = 0; + do + { + name = OSSymbol::withCString(obj_name); + if (!name) break; + meta = OSMetaClass::copyMetaClassWithName(name); + if (!meta) break; + super = meta->getSuperClass(); + if (!super) break; + cstr = super->getClassName(); + if (!cstr) break; + strlcpy(class_name, cstr, sizeof(io_name_t)); + ret = kIOReturnSuccess; + } + while (false); - my_name = OSSymbol::withCString(obj_name); - - if (my_name) { - my_obj = OSMetaClass::getMetaClassWithName(my_name); - my_name->release(); - } - if (my_obj) { - superclass = my_obj->getSuperClass(); - } - - if (!superclass) { - return( kIOReturnNotFound ); - } + OSSafeReleaseNULL(name); + if (meta) meta->releaseMetaClass(); - my_cstr = superclass->getClassName(); - - if (my_cstr) { - strlcpy(class_name, my_cstr, sizeof(io_name_t)); - return( kIOReturnSuccess ); - } - return (kIOReturnNotFound); + return (ret); } /* Routine io_object_get_bundle_identifier */ @@ -1961,38 +1995,36 @@ kern_return_t is_io_object_get_bundle_identifier( io_name_t obj_name, io_name_t bundle_name) { - const OSMetaClass* my_obj = NULL; - const OSSymbol *my_name = NULL; - const OSSymbol *identifier = NULL; - const char *my_cstr = NULL; + IOReturn ret; + const OSMetaClass * meta; + const OSSymbol * name; + const OSSymbol * identifier; + const char * cstr; - if (!obj_name || !bundle_name) - return (kIOReturnBadArgument); + if (!obj_name || !bundle_name) return (kIOReturnBadArgument); + if (master_port != master_device_port) return( kIOReturnNotPrivileged); - if( master_port != master_device_port) - return( kIOReturnNotPrivileged); - - my_name = OSSymbol::withCString(obj_name); - - if (my_name) { - my_obj = OSMetaClass::getMetaClassWithName(my_name); - my_name->release(); - } + ret = kIOReturnNotFound; + meta = 0; + do + { + name = OSSymbol::withCString(obj_name); + if (!name) break; + meta = OSMetaClass::copyMetaClassWithName(name); + if (!meta) break; + identifier = meta->getKmodName(); + if (!identifier) break; + cstr = identifier->getCStringNoCopy(); + if (!cstr) break; + strlcpy(bundle_name, identifier->getCStringNoCopy(), sizeof(io_name_t)); + ret = kIOReturnSuccess; + } + while (false); - if (my_obj) { - identifier = my_obj->getKmodName(); - } - if (!identifier) { - return( kIOReturnNotFound ); - } - - my_cstr = identifier->getCStringNoCopy(); - if (my_cstr) { - strlcpy(bundle_name, identifier->getCStringNoCopy(), sizeof(io_name_t)); - return( kIOReturnSuccess ); - } + OSSafeReleaseNULL(name); + if (meta) meta->releaseMetaClass(); - return (kIOReturnBadArgument); + return (ret); } /* Routine io_object_conforms_to */ @@ -2028,12 +2060,24 @@ kern_return_t is_io_iterator_next( { IOReturn ret; OSObject * obj; + OSIterator * iter; + IOUserIterator * uiter; - CHECK( OSIterator, iterator, iter ); + if ((uiter = OSDynamicCast(IOUserIterator, iterator))) + { + obj = uiter->copyNextObject(); + } + else if ((iter = OSDynamicCast(OSIterator, iterator))) + { + obj = iter->getNextObject(); + if (obj) obj->retain(); + } + else + { + return( kIOReturnBadArgument ); + } - obj = iter->getNextObject(); if( obj) { - obj->retain(); *object = obj; ret = kIOReturnSuccess; } else @@ -2311,6 +2355,8 @@ static kern_return_t internal_io_service_add_notification( do { err = kIOReturnNoResources; + if (matching_size > (sizeof(io_struct_inband_t) * 1024)) return(kIOReturnMessageTooLarge); + if( !(sym = OSSymbol::withCString( notification_type ))) err = kIOReturnNoResources; @@ -2327,7 +2373,8 @@ static kern_return_t internal_io_service_add_notification( else if( (sym == gIOMatchedNotification) || (sym == gIOFirstMatchNotification)) userMsgType = kIOServiceMatchedNotificationType; - else if( sym == gIOTerminatedNotification) + else if ((sym == gIOTerminatedNotification) + || (sym == gIOWillTerminateNotification)) userMsgType = kIOServiceTerminatedNotificationType; else userMsgType = kLastIOKitNotificationType; @@ -2336,7 +2383,6 @@ static kern_return_t internal_io_service_add_notification( if( userNotify && !userNotify->init( port, userMsgType, reference, referenceSize, client64)) { - iokit_release_port_send(port); userNotify->release(); userNotify = 0; } @@ -2354,6 +2400,13 @@ static kern_return_t internal_io_service_add_notification( } while( false ); + if ((kIOReturnSuccess != err) && userNotify) + { + userNotify->invalidatePort(); + userNotify->release(); + userNotify = 0; + } + if( sym) sym->release(); if( dict) @@ -2529,7 +2582,6 @@ static kern_return_t internal_io_service_add_interest_notification( reference, referenceSize, kIOUserNotifyMaxMessageSize, client64 )) { - iokit_release_port_send(port); userNotify->release(); userNotify = 0; } @@ -2549,6 +2601,13 @@ static kern_return_t internal_io_service_add_interest_notification( } while( false ); + if ((kIOReturnSuccess != err) && userNotify) + { + userNotify->invalidatePort(); + userNotify->release(); + userNotify = 0; + } + return( err ); } @@ -3256,8 +3315,8 @@ kern_return_t is_io_registry_entry_get_child_iterator( { CHECK( IORegistryEntry, registry_entry, entry ); - *iterator = entry->getChildIterator( - IORegistryEntry::getPlane( plane )); + *iterator = IOUserIterator::withIterator(entry->getChildIterator( + IORegistryEntry::getPlane( plane ))); return( kIOReturnSuccess ); } @@ -3270,8 +3329,8 @@ kern_return_t is_io_registry_entry_get_parent_iterator( { CHECK( IORegistryEntry, registry_entry, entry ); - *iterator = entry->getParentIterator( - IORegistryEntry::getPlane( plane )); + *iterator = IOUserIterator::withIterator(entry->getParentIterator( + IORegistryEntry::getPlane( plane ))); return( kIOReturnSuccess ); } @@ -3441,6 +3500,7 @@ kern_return_t is_io_service_open_extended( client->sharedInstance = (0 != client->getProperty(kIOUserClientSharedInstanceKey)); client->closed = false; + client->lock = IOLockAlloc(); disallowAccess = (crossEndian && (kOSBooleanTrue != service->getProperty(kIOUserClientCrossEndianCompatibleKey)) @@ -3492,7 +3552,9 @@ kern_return_t is_io_service_close( if (client->sharedInstance || OSCompareAndSwap8(0, 1, &client->closed)) { + IOLockLock(client->lock); client->clientClose(); + IOLockUnlock(client->lock); } else { @@ -3528,11 +3590,15 @@ kern_return_t is_io_connect_set_notification_port( mach_port_t port, uint32_t reference) { + kern_return_t ret; CHECK( IOUserClient, connection, client ); IOStatisticsClientCall(); - return( client->registerNotificationPort( port, notification_type, - (io_user_reference_t) reference )); + IOLockLock(client->lock); + ret = client->registerNotificationPort( port, notification_type, + (io_user_reference_t) reference ); + IOLockUnlock(client->lock); + return (ret); } /* Routine io_connect_set_notification_port */ @@ -3542,11 +3608,15 @@ kern_return_t is_io_connect_set_notification_port_64( mach_port_t port, io_user_reference_t reference) { + kern_return_t ret; CHECK( IOUserClient, connection, client ); IOStatisticsClientCall(); - return( client->registerNotificationPort( port, notification_type, - reference )); + IOLockLock(client->lock); + ret = client->registerNotificationPort( port, notification_type, + reference ); + IOLockUnlock(client->lock); + return (ret); } /* Routine io_connect_map_memory_into_task */ @@ -3582,6 +3652,7 @@ kern_return_t is_io_connect_map_memory_into_task mach_port_name_t name __unused = IOMachPort::makeSendRightForTask( into_task, map, IKOT_IOKIT_OBJECT ); + map->release(); } else { // keep it with the user client @@ -3666,7 +3737,7 @@ kern_return_t is_io_connect_unmap_memory_from_task { IOReturn err; IOOptionBits options = 0; - IOMemoryDescriptor * memory; + IOMemoryDescriptor * memory = 0; IOMemoryMap * map; CHECK( IOUserClient, connection, client ); @@ -3692,7 +3763,11 @@ kern_return_t is_io_connect_unmap_memory_from_task mach_port_name_t name = 0; if (from_task != current_task()) + { name = IOMachPort::makeSendRightForTask( from_task, map, IKOT_IOKIT_OBJECT ); + map->release(); + } + if (name) { map->userClientUnmap(); @@ -3793,6 +3868,8 @@ kern_return_t is_io_connect_method_var_output args.structureInput = inband_input; args.structureInputSize = inband_inputCnt; + if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError); + if (ool_input) inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size, kIODirectionOut | kIOMemoryMapCopyOnWrite, @@ -3888,6 +3965,9 @@ kern_return_t is_io_connect_method args.structureInput = inband_input; args.structureInputSize = inband_inputCnt; + if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError); + if (ool_output && (*ool_output_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError); + if (ool_input) inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size, kIODirectionOut | kIOMemoryMapCopyOnWrite, @@ -3968,11 +4048,16 @@ kern_return_t is_io_connect_async_method args.asyncReference = reference; args.asyncReferenceCount = referenceCnt; + args.structureVariableOutputData = 0; + args.scalarInput = scalar_input; args.scalarInputCount = scalar_inputCnt; args.structureInput = inband_input; args.structureInputSize = inband_inputCnt; + if (ool_input && (ool_input_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError); + if (ool_output && (*ool_output_size <= sizeof(io_struct_inband_t))) return (kIOReturnIPCError); + if (ool_input) inputMD = IOMemoryDescriptor::withAddressRange(ool_input, ool_input_size, kIODirectionOut | kIOMemoryMapCopyOnWrite, @@ -4862,6 +4947,9 @@ kern_return_t is_io_catalog_send_data( mach_msg_type_number_t inDataCount, kern_return_t * result) { +#if NO_KEXTD + return kIOReturnNotPrivileged; +#else /* NO_KEXTD */ OSObject * obj = 0; vm_offset_t data; kern_return_t kr = kIOReturnError; @@ -4879,6 +4967,16 @@ kern_return_t is_io_catalog_send_data( return kIOReturnBadArgument; } + if (!IOTaskHasEntitlement(current_task(), "com.apple.rootless.kext-secure-management")) + { + OSString * taskName = IOCopyLogNameForPID(proc_selfpid()); + IOLog("IOCatalogueSendData(%s): Not entitled\n", taskName ? taskName->getCStringNoCopy() : ""); + OSSafeReleaseNULL(taskName); + // For now, fake success to not break applications relying on this function succeeding. + // See for more details. + return kIOReturnSuccess; + } + if (inData) { vm_map_offset_t map_data; @@ -5008,9 +5106,10 @@ kern_return_t is_io_catalog_send_data( } if (obj) obj->release(); - + *result = kr; return( KERN_SUCCESS); +#endif /* NO_KEXTD */ } /* Routine io_catalog_terminate */ @@ -5097,7 +5196,7 @@ kern_return_t is_io_catalog_get_data( vm_size_t size; size = s->getLength(); - kr = vm_allocate(kernel_map, &data, size, VM_FLAGS_ANYWHERE); + kr = vm_allocate_kernel(kernel_map, &data, size, VM_FLAGS_ANYWHERE, VM_KERN_MEMORY_IOKIT); if ( kr == kIOReturnSuccess ) { bcopy(s->text(), (void *)data, size); kr = vm_map_copyin(kernel_map, (vm_map_address_t)data, @@ -5175,7 +5274,7 @@ kern_return_t iokit_user_client_trap(struct iokit_user_client_trap_args *args) IOUserClient *userClient; if ((userClient = OSDynamicCast(IOUserClient, - iokit_lookup_connect_ref_current_task((OSObject *)(args->userClientRef))))) { + iokit_lookup_connect_ref_current_task((mach_port_name_t)(uintptr_t)args->userClientRef)))) { IOExternalTrap *trap; IOService *target = NULL; @@ -5197,6 +5296,24 @@ kern_return_t iokit_user_client_trap(struct iokit_user_client_trap_args *args) return result; } +/* Routine io_device_tree_entry_exists_with_name */ +kern_return_t is_io_device_tree_entry_exists_with_name( + mach_port_t master_port, + io_name_t name, + boolean_t *exists ) +{ + OSCollectionIterator *iter; + + if (master_port != master_device_port) + return (kIOReturnNotPrivileged); + + iter = IODTFindMatchingEntries(IORegistryEntry::getRegistryRoot(), kIODTRecursive, name); + *exists = iter && iter->getNextObject(); + OSSafeReleaseNULL(iter); + + return kIOReturnSuccess; +} + } /* extern "C" */ IOReturn IOUserClient::externalMethod( uint32_t selector, IOExternalMethodArguments * args,