Loading...
--- xnu/xnu-12377.101.15/iokit/Kernel/IOUserClient.cpp
+++ xnu/xnu-8792.61.2/iokit/Kernel/IOUserClient.cpp
@@ -48,8 +48,6 @@
#include <sys/proc.h>
#include <sys/kauth.h>
#include <sys/codesign.h>
-#include <sys/code_signing.h>
-#include <vm/vm_kern_xnu.h>
#include <mach/sdt.h>
#include <os/hash.h>
@@ -136,67 +134,44 @@
extern "C" {
#include <mach/mach_traps.h>
-#include <vm/vm_map_xnu.h>
+#include <vm/vm_map.h>
} /* extern "C" */
struct IOMachPortHashList;
+static_assert(IKOT_MAX_TYPE <= 255);
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// IOMachPort maps OSObjects to ports, avoiding adding an ivar to OSObject.
-class IOMachPort final : public OSObject
+class IOMachPort : public OSObject
{
OSDeclareDefaultStructors(IOMachPort);
public:
- bool hashed;
SLIST_ENTRY(IOMachPort) link;
ipc_port_t port;
- OSObject* XNU_PTRAUTH_SIGNED_PTR("IOMachPort.object") object;
-
- static IOMachPort* withObject(OSObject *obj);
-
- static IOMachPortHashList* bucketForObject(OSObject *obj);
+ OSObject* object;
+ UInt32 mscount;
+ UInt8 holdDestroy;
+ UInt8 type;
+
+ static IOMachPort* withObjectAndType(OSObject *obj, ipc_kobject_type_t type);
+
+ static IOMachPortHashList* bucketForObject(OSObject *obj,
+ ipc_kobject_type_t type);
static LIBKERN_RETURNS_NOT_RETAINED IOMachPort* portForObjectInBucket(IOMachPortHashList *bucket, OSObject *obj, ipc_kobject_type_t type);
- static IOMachPort *noMoreSenders( ipc_port_t port,
- ipc_kobject_type_t type, mach_port_mscount_t mscount );
+ static bool noMoreSendersForObject( OSObject * obj,
+ ipc_kobject_type_t type, mach_port_mscount_t * mscount );
static void releasePortForObject( OSObject * obj,
ipc_kobject_type_t type );
+ static void setHoldDestroy( OSObject * obj, ipc_kobject_type_t type );
static mach_port_name_t makeSendRightForTask( task_t task,
io_object_t obj, ipc_kobject_type_t type );
virtual void free() APPLE_KEXT_OVERRIDE;
-
- void
- makePort(ipc_kobject_type_t type)
- {
- port = iokit_alloc_object_port(this, type);
- }
-
- void
- adoptPort(IOMachPort *other, ipc_kobject_type_t type)
- {
- port = other->port;
- ipc_kobject_enable(port, this, IKOT_IOKIT_CONNECT);
- other->port = NULL;
- }
-
- void
- disablePort(ipc_kobject_type_t type)
- {
- __assert_only ipc_kobject_t kobj;
- kobj = ipc_kobject_disable(port, type);
- assert(kobj == this);
- }
-
- template<typename T>
- inline T *
- getAs() const
- {
- return OSDynamicCast(T, object);
- }
};
#define super OSObject
@@ -228,7 +203,7 @@
}
IOMachPortHashList*
-IOMachPort::bucketForObject(OSObject *obj)
+IOMachPort::bucketForObject(OSObject *obj, ipc_kobject_type_t type )
{
return &gIOMachPortHash[os_hash_kernel_pointer(obj) % PORT_HASH_SIZE];
}
@@ -239,7 +214,7 @@
IOMachPort *machPort;
SLIST_FOREACH(machPort, bucket, link) {
- if (machPort->object == obj && iokit_port_type(machPort->port) == type) {
+ if (machPort->object == obj && machPort->type == type) {
return machPort;
}
}
@@ -247,150 +222,183 @@
}
IOMachPort*
-IOMachPort::withObject(OSObject *obj)
+IOMachPort::withObjectAndType(OSObject *obj, ipc_kobject_type_t type)
{
IOMachPort *machPort = NULL;
machPort = new IOMachPort;
- release_assert(machPort->init());
+ if (__improbable(machPort && !machPort->init())) {
+ OSSafeReleaseNULL(machPort);
+ return NULL;
+ }
+
machPort->object = obj;
+ machPort->type = (typeof(machPort->type))type;
+ machPort->port = iokit_alloc_object_port(obj, type);
obj->taggedRetain(OSTypeID(OSCollection));
+ machPort->mscount++;
return machPort;
}
-IOMachPort *
-IOMachPort::noMoreSenders( ipc_port_t port, ipc_kobject_type_t type,
- mach_port_mscount_t mscount )
-{
- IOUserClient *uc = NULL;
- IOMachPort *machPort;
- bool destroyed;
+bool
+IOMachPort::noMoreSendersForObject( OSObject * obj,
+ ipc_kobject_type_t type, mach_port_mscount_t * mscount )
+{
+ IOMachPort *machPort = NULL;
+ IOUserClient *uc;
+ OSAction *action;
+ bool destroyed = true;
+
+ IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
+
+ obj->retain();
lck_mtx_lock(gIOObjectPortLock);
- iokit_lock_port(port);
- machPort = (IOMachPort *)ipc_kobject_get_locked(port, type);
- destroyed = ipc_kobject_is_mscount_current_locked(port, mscount);
- iokit_unlock_port(port);
+ machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
+
+ if (machPort) {
+ destroyed = (machPort->mscount <= *mscount);
+ if (!destroyed) {
+ *mscount = machPort->mscount;
+ lck_mtx_unlock(gIOObjectPortLock);
+ } else {
+ if ((IKOT_IOKIT_CONNECT == type) && (uc = OSDynamicCast(IOUserClient, obj))) {
+ uc->noMoreSenders();
+ }
+ SLIST_REMOVE(bucket, machPort, IOMachPort, link);
+
+ lck_mtx_unlock(gIOObjectPortLock);
+
+ OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+
+ obj->taggedRelease(OSTypeID(OSCollection));
+ }
+ } else {
+ lck_mtx_unlock(gIOObjectPortLock);
+ }
+
+ if ((IKOT_UEXT_OBJECT == type) && (action = OSDynamicCast(OSAction, obj))) {
+ action->Aborted();
+ }
+
+ if (IKOT_UEXT_OBJECT == type && IOUserServer::shouldLeakObjects()) {
+ // Leak object
+ obj->retain();
+ }
+
+ obj->release();
+
+ return destroyed;
+}
+
+void
+IOMachPort::releasePortForObject( OSObject * obj,
+ ipc_kobject_type_t type )
+{
+ IOMachPort *machPort;
+ IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
+
+ assert(IKOT_IOKIT_CONNECT != type);
+
+ lck_mtx_lock(gIOObjectPortLock);
+
+ machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
+
+ if (machPort && !machPort->holdDestroy) {
+ obj->retain();
+ SLIST_REMOVE(bucket, machPort, IOMachPort, link);
+
+ lck_mtx_unlock(gIOObjectPortLock);
+
+ OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+
+ obj->taggedRelease(OSTypeID(OSCollection));
+ obj->release();
+ } else {
+ lck_mtx_unlock(gIOObjectPortLock);
+ }
+}
+
+void
+IOMachPort::setHoldDestroy( OSObject * obj, ipc_kobject_type_t type )
+{
+ IOMachPort * machPort;
+
+ IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
+ lck_mtx_lock(gIOObjectPortLock);
+
+ machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
+
+ if (machPort) {
+ machPort->holdDestroy = true;
+ }
+
+ lck_mtx_unlock(gIOObjectPortLock);
+}
+
+void
+IOMachPortDestroyUserReferences(OSObject * obj, natural_t type)
+{
+ IOMachPort::releasePortForObject(obj, type);
+}
+
+void
+IOUserClient::destroyUserReferences( OSObject * obj )
+{
+ IOMachPort *machPort;
+
+ IOMachPort::releasePortForObject( obj, IKOT_IOKIT_OBJECT );
+
+ // panther, 3160200
+ // IOMachPort::releasePortForObject( obj, IKOT_IOKIT_CONNECT );
+
+ obj->retain();
+ IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, IKOT_IOKIT_CONNECT);
+ IOMachPortHashList *mappingBucket = NULL;
+
+ lck_mtx_lock(gIOObjectPortLock);
+
+ IOUserClient * uc = OSDynamicCast(IOUserClient, obj);
+ if (uc && uc->mappings) {
+ mappingBucket = IOMachPort::bucketForObject(uc->mappings, IKOT_IOKIT_CONNECT);
+ }
+
+ machPort = IOMachPort::portForObjectInBucket(bucket, obj, IKOT_IOKIT_CONNECT);
if (machPort == NULL) {
lck_mtx_unlock(gIOObjectPortLock);
- return NULL;
- }
-
- assert(machPort->port == port);
-
- if (destroyed) {
- if (machPort->hashed) {
- IOMachPortHashList *bucket;
-
- bucket = IOMachPort::bucketForObject(machPort->object);
- machPort->hashed = false;
- SLIST_REMOVE(bucket, machPort, IOMachPort, link);
- }
-
- machPort->disablePort(type);
-
- if (IKOT_IOKIT_CONNECT == type) {
- uc = machPort->getAs<IOUserClient>();
- }
- }
+ goto end;
+ }
+
+ SLIST_REMOVE(bucket, machPort, IOMachPort, link);
+ obj->taggedRelease(OSTypeID(OSCollection));
if (uc) {
uc->noMoreSenders();
- }
-
- lck_mtx_unlock(gIOObjectPortLock);
-
- if (IKOT_UEXT_OBJECT == type) {
- if (OSAction *action = machPort->getAs<OSAction>()) {
- action->Aborted();
- }
-
- if (IOUserServer::shouldLeakObjects()) {
- // Leak object
- machPort->object->retain();
- }
- }
-
- return destroyed ? machPort : NULL;
-}
-
-void
-IOMachPort::releasePortForObject( OSObject * obj, ipc_kobject_type_t type )
-{
- bool destroyed = false;
- IOMachPort *machPort;
- IOService *service;
- IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj);
-
- assert(IKOT_IOKIT_CONNECT != type);
-
- lck_mtx_lock(gIOObjectPortLock);
-
- machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
-
- if (machPort
- && ((type != IKOT_IOKIT_OBJECT)
- || !(service = OSDynamicCast(IOService, obj))
- || !service->machPortHoldDestroy())) {
- machPort->hashed = false;
- SLIST_REMOVE(bucket, machPort, IOMachPort, link);
- machPort->disablePort(type);
- destroyed = true;
- }
-
- lck_mtx_unlock(gIOObjectPortLock);
-
- if (destroyed) {
- machPort->release();
- }
-}
-
-void
-IOUserClient::destroyUserReferences( OSObject * obj )
-{
- IOMachPort *machPort = NULL;
- OSObject *mappings = NULL;
-
- IOMachPort::releasePortForObject( obj, IKOT_IOKIT_OBJECT );
-
- IOUserClient * uc = OSDynamicCast(IOUserClient, obj);
- IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj);
-
- lck_mtx_lock(gIOObjectPortLock);
-
- machPort = IOMachPort::portForObjectInBucket(bucket, obj, IKOT_IOKIT_CONNECT);
-
- if (machPort == NULL) {
+ if (uc->mappings) {
+ uc->mappings->taggedRetain(OSTypeID(OSCollection));
+ machPort->object = uc->mappings;
+ SLIST_INSERT_HEAD(mappingBucket, machPort, link);
+ iokit_switch_object_port(machPort->port, uc->mappings, IKOT_IOKIT_CONNECT);
+
+ lck_mtx_unlock(gIOObjectPortLock);
+
+ OSSafeReleaseNULL(uc->mappings);
+ } else {
+ lck_mtx_unlock(gIOObjectPortLock);
+ OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+ }
+ } else {
lck_mtx_unlock(gIOObjectPortLock);
- return;
- }
-
- machPort->hashed = false;
- SLIST_REMOVE(bucket, machPort, IOMachPort, link);
- machPort->disablePort(IKOT_IOKIT_CONNECT);
-
- if (uc) {
- mappings = uc->mappings;
- uc->mappings = NULL;
-
- uc->noMoreSenders();
-
- if (mappings) {
- IOMachPort *newPort;
-
- newPort = IOMachPort::withObject(mappings);
- newPort->adoptPort(machPort, IKOT_IOKIT_CONNECT);
- }
- }
-
- lck_mtx_unlock(gIOObjectPortLock);
-
- OSSafeReleaseNULL(mappings);
- machPort->release();
+ OS_ANALYZER_SUPPRESS("77508635") OSSafeReleaseNULL(machPort);
+ }
+
+
+end:
+ OSSafeReleaseNULL(obj);
}
mach_port_name_t
@@ -404,12 +412,10 @@
IOMachPort::free( void )
{
if (port) {
- iokit_destroy_object_port(port, iokit_port_type(port));
- }
- object->taggedRelease(OSTypeID(OSCollection));
+ iokit_destroy_object_port( port, type );
+ }
super::free();
}
-
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -463,7 +469,11 @@
return false;
}
- IOLockInlineInit(&lock);
+ lock = IOLockAlloc();
+ if (!lock) {
+ return false;
+ }
+
return true;
}
@@ -473,17 +483,19 @@
if (userIteratorObject) {
userIteratorObject->release();
}
- IOLockInlineDestroy(&lock);
+ if (lock) {
+ IOLockFree(lock);
+ }
OSObject::free();
}
void
IOUserIterator::reset()
{
- IOLockLock(&lock);
+ IOLockLock(lock);
assert(OSDynamicCast(OSIterator, userIteratorObject));
((OSIterator *)userIteratorObject)->reset();
- IOLockUnlock(&lock);
+ IOLockUnlock(lock);
}
bool
@@ -491,10 +503,10 @@
{
bool ret;
- IOLockLock(&lock);
+ IOLockLock(lock);
assert(OSDynamicCast(OSIterator, userIteratorObject));
ret = ((OSIterator *)userIteratorObject)->isValid();
- IOLockUnlock(&lock);
+ IOLockUnlock(lock);
return ret;
}
@@ -511,14 +523,14 @@
{
OSObject * ret = NULL;
- IOLockLock(&lock);
+ IOLockLock(lock);
if (userIteratorObject) {
ret = ((OSIterator *)userIteratorObject)->getNextObject();
if (ret) {
ret->retain();
}
}
- IOLockUnlock(&lock);
+ IOLockUnlock(lock);
return ret;
}
@@ -567,11 +579,19 @@
// for retain and release.
#ifndef __clang_analyzer__
void
-iokit_add_reference( io_object_t obj )
-{
+iokit_add_reference( io_object_t obj, natural_t type )
+{
+ IOUserClient * uc;
+
if (!obj) {
return;
}
+
+ if ((IKOT_IOKIT_CONNECT == type)
+ && (uc = OSDynamicCast(IOUserClient, obj))) {
+ OSIncrementAtomic(&uc->__ipc);
+ }
+
obj->retain();
}
@@ -587,87 +607,27 @@
void
iokit_remove_connect_reference(LIBKERN_CONSUMED io_object_t obj )
{
+ IOUserClient * uc;
+ bool finalize = false;
+
if (!obj) {
return;
}
+
+ if ((uc = OSDynamicCast(IOUserClient, obj))) {
+ if (1 == OSDecrementAtomic(&uc->__ipc) && uc->isInactive()) {
+ IOLockLock(gIOObjectPortLock);
+ if ((finalize = uc->__ipcFinal)) {
+ uc->__ipcFinal = false;
+ }
+ IOLockUnlock(gIOObjectPortLock);
+ }
+ if (finalize) {
+ uc->scheduleFinalize(true);
+ }
+ }
+
obj->release();
-}
-
-enum {
- kIPCLockNone = 0,
- kIPCLockRead = 1,
- kIPCLockWrite = 2
-};
-
-void
-IOUserClient::ipcEnter(int locking)
-{
- switch (locking) {
- case kIPCLockWrite:
- IORWLockWrite(&lock);
- break;
- case kIPCLockRead:
- IORWLockRead(&lock);
- break;
- case kIPCLockNone:
- break;
- default:
- panic("ipcEnter");
- }
-
- OSIncrementAtomic(&__ipc);
-}
-
-void
-IOUserClient::ipcExit(int locking)
-{
- bool finalize = false;
-
- assert(__ipc);
- if (1 == OSDecrementAtomic(&__ipc) && isInactive()) {
- IOLockLock(gIOObjectPortLock);
- if ((finalize = __ipcFinal)) {
- __ipcFinal = false;
- }
- IOLockUnlock(gIOObjectPortLock);
- if (finalize) {
- scheduleFinalize(true);
- }
- }
- switch (locking) {
- case kIPCLockWrite:
- case kIPCLockRead:
- IORWLockUnlock(&lock);
- break;
- case kIPCLockNone:
- break;
- default:
- panic("ipcExit");
- }
-}
-
-void
-iokit_kobject_retain(io_kobject_t machPort)
-{
- assert(OSDynamicCast(IOMachPort, machPort));
- machPort->retain();
-}
-
-io_object_t
-iokit_copy_object_for_consumed_kobject(LIBKERN_CONSUMED io_kobject_t machPort)
-{
- io_object_t result;
-
- assert(OSDynamicCast(IOMachPort, machPort));
-
- /*
- * IOMachPort::object is never nil-ed, so this just borrows its port
- * reference to make new rights.
- */
- result = machPort->object;
- iokit_add_reference(result);
- machPort->release();
- return result;
}
bool
@@ -687,110 +647,73 @@
}
ipc_port_t
-iokit_port_make_send_for_object( io_object_t obj, ipc_kobject_type_t type )
+iokit_port_for_object( io_object_t obj, ipc_kobject_type_t type )
{
IOMachPort *machPort = NULL;
- ipc_port_t port = NULL;
-
- IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj);
+ ipc_port_t port = NULL;
+
+ IOMachPortHashList *bucket = IOMachPort::bucketForObject(obj, type);
lck_mtx_lock(gIOObjectPortLock);
machPort = IOMachPort::portForObjectInBucket(bucket, obj, type);
if (__improbable(machPort == NULL)) {
- machPort = IOMachPort::withObject(obj);
- machPort->makePort(type);
- machPort->hashed = true;
+ machPort = IOMachPort::withObjectAndType(obj, type);
+ if (__improbable(machPort == NULL)) {
+ goto end;
+ }
SLIST_INSERT_HEAD(bucket, machPort, link);
- }
-
- port = ipc_kobject_make_send( machPort->port, machPort, type );
-
+ } else {
+ machPort->mscount++;
+ }
+
+ iokit_retain_port(machPort->port);
+ port = machPort->port;
+
+end:
lck_mtx_unlock(gIOObjectPortLock);
return port;
}
-/*
- * Handle the No-More_Senders notification generated from a device port destroy.
- * Since there are no longer any tasks which hold a send right to this device
- * port a NMS notification has been generated.
- */
-
-void
-iokit_ident_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
- IOMachPort *machPort;
-
- machPort = IOMachPort::noMoreSenders(port, IKOT_IOKIT_IDENT, mscount);
-
- if (machPort) {
- if (IOUserServerCheckInToken *token =
- machPort->getAs<IOUserServerCheckInToken>()) {
+kern_return_t
+iokit_client_died( io_object_t obj, ipc_port_t /* port */,
+ ipc_kobject_type_t type, mach_port_mscount_t * mscount )
+{
+ IOUserClient * client;
+ IOMemoryMap * map;
+ IOUserNotification * notify;
+ IOUserServerCheckInToken * token;
+
+ if (!IOMachPort::noMoreSendersForObject( obj, type, mscount )) {
+ return kIOReturnNotReady;
+ }
+
+ switch (type) {
+ case IKOT_IOKIT_CONNECT:
+ if ((client = OSDynamicCast( IOUserClient, obj ))) {
+ IOStatisticsClientCall();
+ IORWLockWrite(client->lock);
+ client->clientDied();
+ IORWLockUnlock(client->lock);
+ }
+ break;
+ case IKOT_IOKIT_OBJECT:
+ if ((map = OSDynamicCast( IOMemoryMap, obj ))) {
+ map->taskDied();
+ } else if ((notify = OSDynamicCast( IOUserNotification, obj ))) {
+ notify->setNotification( NULL );
+ }
+ break;
+ case IKOT_IOKIT_IDENT:
+ if ((token = OSDynamicCast( IOUserServerCheckInToken, obj ))) {
token->cancel();
}
- machPort->release();
- }
-}
-
-void
-iokit_object_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
- IOMachPort *machPort;
-
- machPort = IOMachPort::noMoreSenders(port, IKOT_IOKIT_OBJECT, mscount);
-
- if (machPort) {
- if (IOMemoryMap *map = machPort->getAs<IOMemoryMap>()) {
- map->taskDied();
- } else if (IOUserNotification *notify =
- machPort->getAs<IOUserNotification>()) {
- notify->setNotification( NULL );
- }
- machPort->release();
- }
-}
-
-void
-iokit_connect_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
- IOMachPort *machPort;
-
- machPort = IOMachPort::noMoreSenders(port, IKOT_IOKIT_CONNECT, mscount);
-
- if (machPort) {
- if (IOUserClient *client = machPort->getAs<IOUserClient>()) {
- IOStatisticsClientCall();
- IORWLockWrite(&client->lock);
- client->clientDied();
- IORWLockUnlock(&client->lock);
- }
- machPort->release();
- }
-}
-
-void
-iokit_uext_no_senders( ipc_port_t port, mach_port_mscount_t mscount )
-{
- IOMachPort *machPort;
-
- machPort = IOMachPort::noMoreSenders(port, IKOT_UEXT_OBJECT, mscount);
-
- if (machPort) {
- if (IOUserClient *uc = machPort->getAs<IOUserUserClient>()) {
- IOService *provider = NULL;
- uc->lockForArbitration();
- provider = uc->getProvider();
- if (provider) {
- provider->retain();
- }
- uc->unlockForArbitration();
- uc->setTerminateDefer(provider, false);
- OSSafeReleaseNULL(provider);
- }
- machPort->release();
- }
+ break;
+ }
+
+ return kIOReturnSuccess;
}
}; /* extern "C" */
@@ -1028,7 +951,7 @@
bool sendPing = false;
mach_msg_size_t msgSize, payloadSize;
- IOTakeLock( &lock );
+ IOTakeLock( lock );
count = newSet->getCount();
if (count < kMaxOutstanding) {
@@ -1038,27 +961,21 @@
}
}
- IOUnlock( &lock );
+ IOUnlock( lock );
if (kIOServiceTerminatedNotificationType == msgType) {
- lck_mtx_lock(gIOObjectPortLock);
- newService->setMachPortHoldDestroy(true);
- lck_mtx_unlock(gIOObjectPortLock);
+ IOMachPort::setHoldDestroy( newService, IKOT_IOKIT_OBJECT );
}
if (sendPing) {
- /*
- * This right will be consumed when the message we form below
- * is sent by kernel_mach_msg_send_with_builder_internal(),
- * because we make the disposition for the right move-send.
- */
- port = iokit_port_make_send_for_object( this, IKOT_IOKIT_OBJECT );
+ port = iokit_port_for_object( this, IKOT_IOKIT_OBJECT );
payloadSize = sizeof(PingMsgUdata) - sizeof(OSAsyncReference64) + msgReferenceSize;
msgSize = (mach_msg_size_t)(sizeof(PingMsgKdata) + payloadSize);
kr = kernel_mach_msg_send_with_builder_internal(0, payloadSize,
- MACH_SEND_KERNEL_IMPORTANCE, MACH_MSG_TIMEOUT_NONE, NULL,
+ (MACH_SEND_MSG | MACH_SEND_ALWAYS | MACH_SEND_IMPORTANCE),
+ MACH_MSG_TIMEOUT_NONE, NULL,
^(mach_msg_header_t *hdr, __assert_only mach_msg_descriptor_t *descs, void *payload){
PingMsgUdata *udata = (PingMsgUdata *)payload;
@@ -1066,7 +983,7 @@
hdr->msgh_local_port = port;
hdr->msgh_bits = MACH_MSGH_BITS(
MACH_MSG_TYPE_COPY_SEND /*remote*/,
- MACH_MSG_TYPE_MOVE_SEND /*local*/);
+ MACH_MSG_TYPE_MAKE_SEND /*local*/);
hdr->msgh_size = msgSize;
hdr->msgh_id = kOSNotificationMessageID;
@@ -1080,6 +997,10 @@
bcopy( msgReference, udata->notifyHeader.reference, msgReferenceSize );
});
+ if (port) {
+ iokit_release_port( port );
+ }
+
if ((KERN_SUCCESS != kr) && !ipcLogged) {
ipcLogged = true;
IOLog("%s: kernel_mach_msg_send (0x%x)\n", __PRETTY_FUNCTION__, kr );
@@ -1101,7 +1022,7 @@
unsigned int count;
OSObject * result;
- IOLockLock(&lock);
+ IOLockLock(lock);
count = newSet->getCount();
if (count) {
@@ -1113,7 +1034,7 @@
armed = true;
}
- IOLockUnlock(&lock);
+ IOLockUnlock(lock);
return result;
}
@@ -1228,16 +1149,12 @@
}
mach_msg_size_t payloadSize = thisMsgSize - sizeof(PingMsgKdata);
- /*
- * These rights will be consumed when the message we form below
- * is sent by kernel_mach_msg_send_with_builder_internal(),
- * because we make the disposition for the rights move-send.
- */
- providerPort = iokit_port_make_send_for_object( provider, IKOT_IOKIT_OBJECT );
- thisPort = iokit_port_make_send_for_object( this, IKOT_IOKIT_OBJECT );
+ providerPort = iokit_port_for_object( provider, IKOT_IOKIT_OBJECT );
+ thisPort = iokit_port_for_object( this, IKOT_IOKIT_OBJECT );
kr = kernel_mach_msg_send_with_builder_internal(1, payloadSize,
- MACH_SEND_KERNEL_IMPORTANCE, MACH_MSG_TIMEOUT_NONE, NULL,
+ (MACH_SEND_MSG | MACH_SEND_ALWAYS | MACH_SEND_IMPORTANCE),
+ MACH_MSG_TIMEOUT_NONE, NULL,
^(mach_msg_header_t *hdr, mach_msg_descriptor_t *descs, void *payload){
mach_msg_port_descriptor_t *port_desc = (mach_msg_port_descriptor_t *)descs;
PingMsgUdata *udata = (PingMsgUdata *)payload;
@@ -1246,18 +1163,17 @@
hdr->msgh_remote_port = remotePort;
hdr->msgh_local_port = thisPort;
- hdr->msgh_bits = MACH_MSGH_BITS_SET(
+ hdr->msgh_bits = MACH_MSGH_BITS_COMPLEX
+ | MACH_MSGH_BITS(
MACH_MSG_TYPE_COPY_SEND /*remote*/,
- MACH_MSG_TYPE_MOVE_SEND /*local*/,
- MACH_MSG_TYPE_NONE /*voucher*/,
- MACH_MSGH_BITS_COMPLEX);
+ MACH_MSG_TYPE_MAKE_SEND /*local*/);
hdr->msgh_size = thisMsgSize;
hdr->msgh_id = kOSNotificationMessageID;
/* body.msgh_descriptor_count is set automatically after the closure */
port_desc[0].name = providerPort;
- port_desc[0].disposition = MACH_MSG_TYPE_MOVE_SEND;
+ port_desc[0].disposition = MACH_MSG_TYPE_MAKE_SEND;
port_desc[0].type = MACH_MSG_PORT_DESCRIPTOR;
/* End of kernel processed data */
@@ -1282,6 +1198,13 @@
}
});
+ if (thisPort) {
+ iokit_release_port( thisPort );
+ }
+ if (providerPort) {
+ iokit_release_port( providerPort );
+ }
+
if (kr == MACH_SEND_NO_BUFFER) {
return kIOReturnNoMemory;
}
@@ -1313,12 +1236,6 @@
OSDefineMetaClassAndAbstractStructors( IOUserClient, IOService )
IOLock * gIOUserClientOwnersLock;
-
-static TUNABLE(bool, gEnforcePowerEntitlement, "enforce-power-entitlement", false);
-
-static_assert(offsetof(IOUserClient, __opaque_end) -
- offsetof(IOUserClient, __opaque_start) == sizeof(void *) * 9,
- "ABI check: Opaque ivars for IOUserClient must be 9 void * big");
void
IOUserClient::initialize( void )
@@ -1333,6 +1250,7 @@
IOTrackingQueueCollectUser(IOServiceMessageUserNotification::gMetaClass.getTracking());
IOTrackingQueueCollectUser(IOServiceUserNotification::gMetaClass.getTracking());
IOTrackingQueueCollectUser(IOUserClient::gMetaClass.getTracking());
+ IOTrackingQueueCollectUser(IOMachPort::gMetaClass.getTracking());
#endif /* IOTRACKING */
}
@@ -1575,33 +1493,54 @@
IOUserClient::copyClientEntitlement( task_t task,
const char * entitlement )
{
- void *entitlement_object = NULL;
-
- if (task == NULL) {
- task = current_task();
- }
-
- /* Validate input arguments */
- if (task == kernel_task || entitlement == NULL) {
+ OSDictionary *entitlements;
+ OSObject *value;
+
+ #if PMAP_CS_ENABLE && !CONFIG_X86_64_COMPAT
+ if (pmap_cs_enabled() && amfi->query_context_to_object) {
+ struct CEQueryContext queryCtx = {};
+ size_t entlen = strlen(entitlement);
+ CEQuery_t query = {
+ /*
+ * We only select the dict value, if it exists this we will get
+ * a value CEQueryContext back to points to pmap backed memory
+ */
+ CESelectDictValueDynamic((const uint8_t*)entitlement, entlen)
+ };
+ if (task == current_task()) {
+ // NULL task means current task, which translated to the current pmap
+ if (!pmap_query_entitlements(NULL, query, 1, &queryCtx)) {
+ return NULL;
+ }
+ } else {
+ vm_map_t task_map = get_task_map_reference(task);
+ if (task_map) {
+ pmap_t pmap = vm_map_get_pmap(task_map);
+ if (!pmap || !pmap_query_entitlements(pmap, query, 1, &queryCtx)) {
+ vm_map_deallocate(task_map);
+ return NULL;
+ }
+ vm_map_deallocate(task_map);
+ }
+ }
+ value = (OSObject*)amfi->query_context_to_object(&queryCtx);
+ return value;
+ }
+ #endif
+
+ entitlements = copyClientEntitlements(task);
+ if (entitlements == NULL) {
return NULL;
}
- proc_t proc = (proc_t)get_bsdtask_info(task);
-
- if (proc == NULL) {
- return NULL;
- }
-
- kern_return_t ret = amfi->OSEntitlements.copyEntitlementAsOSObjectWithProc(
- proc,
- entitlement,
- &entitlement_object);
-
- if (ret != KERN_SUCCESS) {
- return NULL;
- }
- assert(entitlement_object != NULL);
-
- return (OSObject*)entitlement_object;
+
+ /* Fetch the entitlement value from the dictionary. */
+ value = entitlements->getObject(entitlement);
+ if (value != NULL) {
+ value->retain();
+ }
+
+ entitlements->release();
+ return value;
}
OSObject *
@@ -1682,8 +1621,6 @@
}
setTerminateDefer(NULL, true);
IOStatisticsRegisterCounter();
- IORWLockInlineInit(&lock);
- IOLockInlineInit(&filterLock);
return true;
}
@@ -1817,46 +1754,16 @@
}
}
-static kern_return_t
-iokit_task_terminate_phase1(task_t task)
-{
- queue_head_t * taskque;
- IOUserClientOwner * iter;
- OSSet * userServers = NULL;
-
- if (!task_is_driver(task)) {
- return KERN_SUCCESS;
- }
- userServers = OSSet::withCapacity(1);
-
- IOLockLock(gIOUserClientOwnersLock);
-
- taskque = task_io_user_clients(task);
- queue_iterate(taskque, iter, IOUserClientOwner *, taskLink) {
- userServers->setObject(iter->uc);
- }
- IOLockUnlock(gIOUserClientOwnersLock);
-
- if (userServers) {
- IOUserServer * userServer;
- while ((userServer = OSRequiredCast(IOUserServer, userServers->getAnyObject()))) {
- userServer->clientDied();
- userServers->removeObject(userServer);
- }
- userServers->release();
- }
- return KERN_SUCCESS;
-}
-
-static kern_return_t
-iokit_task_terminate_phase2(task_t task)
-{
- queue_head_t * taskque;
+extern "C" kern_return_t
+iokit_task_terminate(task_t task)
+{
IOUserClientOwner * owner;
IOUserClient * dead;
IOUserClient * uc;
+ queue_head_t * taskque;
IOLockLock(gIOUserClientOwnersLock);
+
taskque = task_io_user_clients(task);
dead = NULL;
while (!queue_empty(taskque)) {
@@ -1875,6 +1782,7 @@
}
IOFreeType(owner, IOUserClientOwner);
}
+
IOLockUnlock(gIOUserClientOwnersLock);
while (dead) {
@@ -1890,19 +1798,6 @@
return KERN_SUCCESS;
}
-extern "C" kern_return_t
-iokit_task_terminate(task_t task, int phase)
-{
- switch (phase) {
- case 1:
- return iokit_task_terminate_phase1(task);
- case 2:
- return iokit_task_terminate_phase2(task);
- default:
- panic("iokit_task_terminate phase %d", phase);
- }
-}
-
struct IOUCFilterPolicy {
task_t task;
io_filter_policy_t filterPolicy;
@@ -1916,7 +1811,7 @@
io_filter_policy_t filterPolicy;
filterPolicy = 0;
- IOLockLock(&filterLock);
+ IOLockLock(filterLock);
for (elem = reserved->filterPolicies; elem && (elem->task != task); elem = elem->next) {
}
@@ -1935,7 +1830,7 @@
filterPolicy = addFilterPolicy;
}
- IOLockUnlock(&filterLock);
+ IOLockUnlock(filterLock);
return filterPolicy;
}
@@ -1944,6 +1839,12 @@
{
if (mappings) {
mappings->release();
+ }
+ if (lock) {
+ IORWLockFree(lock);
+ }
+ if (filterLock) {
+ IOLockFree(filterLock);
}
IOStatisticsUnregisterCounter();
@@ -1962,8 +1863,6 @@
IOFreeType(elem, IOUCFilterPolicy);
}
IOFreeType(reserved, ExpansionData);
- IORWLockInlineDestroy(&lock);
- IOLockInlineDestroy(&filterLock);
}
super::free();
@@ -2076,7 +1975,7 @@
err = clientMemoryForType((UInt32) type, &options, &memory );
- if ((kIOReturnSuccess == err) && memory && !memory->hasSharingContext()) {
+ if (memory && (kIOReturnSuccess == err)) {
FAKE_STACK_FRAME(getMetaClass());
options = (options & ~kIOMapUserOptionsMask)
@@ -2371,15 +2270,15 @@
if ((options & kIOUserNotifyOptionCanDrop) != 0) {
kr = mach_msg_send_from_kernel_with_options( &replyMsg.msgHdr,
- replyMsg.msgHdr.msgh_size, MACH64_SEND_TIMEOUT, MACH_MSG_TIMEOUT_NONE);
+ replyMsg.msgHdr.msgh_size, MACH_SEND_TIMEOUT, MACH_MSG_TIMEOUT_NONE);
} else {
/* Fail on full queue. */
- kr = mach_msg_send_from_kernel(&replyMsg.msgHdr,
+ kr = mach_msg_send_from_kernel_proper( &replyMsg.msgHdr,
replyMsg.msgHdr.msgh_size);
}
if ((KERN_SUCCESS != kr) && (MACH_SEND_TIMED_OUT != kr) && !(kIOUCAsyncErrorLoggedFlag & reference[0])) {
reference[0] |= kIOUCAsyncErrorLoggedFlag;
- IOLog("%s: mach_msg_send_from_kernel(0x%x)\n", __PRETTY_FUNCTION__, kr );
+ IOLog("%s: mach_msg_send_from_kernel_proper(0x%x)\n", __PRETTY_FUNCTION__, kr );
}
return kr;
}
@@ -3169,6 +3068,7 @@
matching, port, &ref, 1, notification );
}
+
static kern_return_t
internal_io_service_add_interest_notification(
io_object_t _service,
@@ -3189,21 +3089,6 @@
err = kIOReturnNoResources;
if ((sym = OSSymbol::withCString( type_of_interest ))) {
do {
-#if XNU_PLATFORM_WatchOS
- if (sym == gIOAppPowerStateInterest &&
- !(IOCurrentTaskHasEntitlement("com.apple.private.power.notifications") || IOCurrentTaskHasEntitlement("com.apple.private.power.notifications-temp"))) {
- OSString * taskName = IOCopyLogNameForPID(proc_selfpid());
- IOLog("IORegisterForSystemPower called by %s without \"com.apple.private.power.notifications\" entitlement\n",
- taskName ? taskName->getCStringNoCopy() : "???");
- OSSafeReleaseNULL(taskName);
-
- if (gEnforcePowerEntitlement) {
- err = kIOReturnNotPermitted;
- continue;
- }
- }
-#endif // XNU_PLATFORM_WatchOS
-
userNotify = new IOServiceMessageUserNotification;
if (userNotify && !userNotify->init( port, kIOServiceMessageNotificationType,
@@ -3308,10 +3193,10 @@
CHECK( IOUserClient, connection, client );
IOStatisticsClientCall();
- client->ipcEnter(kIPCLockWrite);
+ IORWLockWrite(client->lock);
ret = client->getNotificationSemaphore((UInt32) notification_type,
semaphore );
- client->ipcExit(kIPCLockWrite);
+ IORWLockUnlock(client->lock);
return ret;
}
@@ -3380,9 +3265,9 @@
{
CHECKLOCKED( IORegistryIterator, iterator, iter );
- IOLockLock(&oIter->lock);
+ IOLockLock(oIter->lock);
iter->enterEntry();
- IOLockUnlock(&oIter->lock);
+ IOLockUnlock(oIter->lock);
return kIOReturnSuccess;
}
@@ -3396,9 +3281,9 @@
CHECKLOCKED( IORegistryIterator, iterator, iter );
- IOLockLock(&oIter->lock);
+ IOLockLock(oIter->lock);
didIt = iter->exitEntry();
- IOLockUnlock(&oIter->lock);
+ IOLockUnlock(oIter->lock);
return didIt ? kIOReturnSuccess : kIOReturnNoDevice;
}
@@ -4182,7 +4067,7 @@
client = OSDynamicCast(IOUserClient, entry);
if (client && client->defaultLockingSetProperties) {
- IORWLockWrite(&client->lock);
+ IORWLockWrite(client->lock);
}
if (!client && (kOSBooleanTrue == entry->getProperty(gIORegistryEntryDefaultLockingSetPropertiesKey))) {
@@ -4194,7 +4079,7 @@
}
if (client && client->defaultLockingSetProperties) {
- IORWLockUnlock(&client->lock);
+ IORWLockUnlock(client->lock);
}
if (service && props && service->hasUserServer()) {
res = service->UserSetProperties(props);
@@ -4347,12 +4232,7 @@
return kr;
}
-#if defined(XNU_TARGET_OS_OSX)
*authorization_id = service->getAuthorizationID();
-#else /* defined(XNU_TARGET_OS_OSX) */
- *authorization_id = 0;
- kr = kIOReturnUnsupported;
-#endif /* defined(XNU_TARGET_OS_OSX) */
return kr;
}
@@ -4365,11 +4245,7 @@
{
CHECK( IOService, _service, service );
-#if defined(XNU_TARGET_OS_OSX)
return service->setAuthorizationID( authorization_id );
-#else /* defined(XNU_TARGET_OS_OSX) */
- return kIOReturnUnsupported;
-#endif /* defined(XNU_TARGET_OS_OSX) */
}
/* Routine io_service_open_ndr */
@@ -4471,8 +4347,9 @@
if (client->sharedInstance) {
IOLockLock(gIOUserClientOwnersLock);
}
- if (!client->opened) {
- client->opened = true;
+ if (!client->lock) {
+ client->lock = IORWLockAlloc();
+ client->filterLock = IOLockAlloc();
client->messageAppSuspended = (NULL != client->getProperty(kIOUserClientMessageAppSuspendedKey));
{
@@ -4611,7 +4488,7 @@
/* Routine io_service_close */
kern_return_t
is_io_service_close(
- io_connect_t connection )
+ io_object_t connection )
{
OSSet * mappings;
if ((mappings = OSDynamicCast(OSSet, connection))) {
@@ -4623,9 +4500,9 @@
IOStatisticsClientCall();
if (client->sharedInstance || OSCompareAndSwap8(0, 1, &client->closed)) {
- client->ipcEnter(kIPCLockWrite);
+ IORWLockWrite(client->lock);
client->clientClose();
- client->ipcExit(kIPCLockWrite);
+ IORWLockUnlock(client->lock);
} else {
IOLog("ignored is_io_service_close(0x%qx,%s)\n",
client->getRegistryEntryID(), client->getName());
@@ -4637,22 +4514,18 @@
/* Routine io_connect_get_service */
kern_return_t
is_io_connect_get_service(
- io_connect_t connection,
+ io_object_t connection,
io_object_t *service )
{
IOService * theService;
CHECK( IOUserClient, connection, client );
-
- client->ipcEnter(kIPCLockNone);
theService = client->getService();
if (theService) {
theService->retain();
}
- client->ipcExit(kIPCLockNone);
-
*service = theService;
return theService ? kIOReturnSuccess : kIOReturnUnsupported;
@@ -4661,7 +4534,7 @@
/* Routine io_connect_set_notification_port */
kern_return_t
is_io_connect_set_notification_port(
- io_connect_t connection,
+ io_object_t connection,
uint32_t notification_type,
mach_port_t port,
uint32_t reference)
@@ -4670,19 +4543,17 @@
CHECK( IOUserClient, connection, client );
IOStatisticsClientCall();
-
- client->ipcEnter(kIPCLockWrite);
+ IORWLockWrite(client->lock);
ret = client->registerNotificationPort( port, notification_type,
(io_user_reference_t) reference );
- client->ipcExit(kIPCLockWrite);
-
+ IORWLockUnlock(client->lock);
return ret;
}
/* Routine io_connect_set_notification_port */
kern_return_t
is_io_connect_set_notification_port_64(
- io_connect_t connection,
+ io_object_t connection,
uint32_t notification_type,
mach_port_t port,
io_user_reference_t reference)
@@ -4691,107 +4562,13 @@
CHECK( IOUserClient, connection, client );
IOStatisticsClientCall();
-
- client->ipcEnter(kIPCLockWrite);
+ IORWLockWrite(client->lock);
ret = client->registerNotificationPort( port, notification_type,
reference );
- client->ipcExit(kIPCLockWrite);
-
+ IORWLockUnlock(client->lock);
return ret;
}
-
-/* Routine io_connect_map_shared_memory */
-kern_return_t
-is_io_connect_map_shared_memory
-(
- io_connect_t connection,
- uint32_t memory_type,
- task_t into_task,
- mach_vm_address_t *address,
- mach_vm_size_t *size,
- uint32_t map_flags,
- io_name_t property_name,
- io_struct_inband_t inband_output,
- mach_msg_type_number_t *inband_outputCnt
-)
-{
- IOReturn err;
- IOMemoryMap * map = NULL;
- IOOptionBits options = 0;
- IOMemoryDescriptor * memory = NULL;
-
- CHECK( IOUserClient, connection, client );
-
- if (!into_task) {
- return kIOReturnBadArgument;
- }
- if (client->sharedInstance
- || (into_task != current_task())) {
- return kIOReturnUnsupported;
- }
-
- IOStatisticsClientCall();
-
- client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
- err = client->clientMemoryForType(memory_type, &options, &memory );
-
- if (memory && (kIOReturnSuccess == err)) {
- OSObject * context = memory->copySharingContext(property_name);
- OSData * desc;
- if (!(desc = OSDynamicCast(OSData, context))) {
- err = kIOReturnNotReady;
- } else {
- if (!(kIOMapReadOnly & options)
- && !IOCurrentTaskHasEntitlement(kIOMapSharedMemoryWritableEntitlement)) {
- err = kIOReturnNotPermitted;
- } else if (desc->getLength() > *inband_outputCnt) {
- err = kIOReturnOverrun;
- } else {
- memcpy(inband_output, desc->getBytesNoCopy(), desc->getLength());
- *inband_outputCnt = desc->getLength();
- }
- OSSafeReleaseNULL(context);
- }
- if (kIOReturnSuccess == err) {
- FAKE_STACK_FRAME(client->getMetaClass());
-
- options = (options & ~kIOMapUserOptionsMask)
- | (map_flags & kIOMapUserOptionsMask)
- | kIOMapAnywhere;
- map = memory->createMappingInTask( into_task, 0, options );
-
- FAKE_STACK_FRAME_END();
- if (!map) {
- err = kIOReturnNotReadable;
- }
- }
- memory->release();
- }
-
- if (map) {
- *address = map->getAddress();
- if (size) {
- *size = map->getSize();
- }
- // keep it with the user client
- IOLockLock( gIOObjectPortLock);
- if (NULL == client->mappings) {
- client->mappings = OSSet::withCapacity(2);
- }
- if (client->mappings) {
- client->mappings->setObject( map);
- }
- IOLockUnlock( gIOObjectPortLock);
- map->release();
- err = kIOReturnSuccess;
- }
-
- client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
- return err;
-}
/* Routine io_connect_map_memory_into_task */
kern_return_t
is_io_connect_map_memory_into_task
@@ -4814,9 +4591,13 @@
}
IOStatisticsClientCall();
-
- client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
+ if (client->defaultLocking) {
+ IORWLockWrite(client->lock);
+ }
map = client->mapClientMemory64( memory_type, into_task, flags, *address );
+ if (client->defaultLocking) {
+ IORWLockUnlock(client->lock);
+ }
if (map) {
*address = map->getAddress();
@@ -4849,8 +4630,6 @@
err = kIOReturnBadArgument;
}
- client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
return err;
}
@@ -4927,9 +4706,13 @@
}
IOStatisticsClientCall();
-
- client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
+ if (client->defaultLocking) {
+ IORWLockWrite(client->lock);
+ }
err = client->clientMemoryForType((UInt32) memory_type, &options, &memory );
+ if (client->defaultLocking) {
+ IORWLockUnlock(client->lock);
+ }
if (memory && (kIOReturnSuccess == err)) {
options = (options & ~kIOMapUserOptionsMask)
@@ -4966,8 +4749,6 @@
}
}
- client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
return err;
}
@@ -4992,7 +4773,7 @@
/* Routine io_connect_add_client */
kern_return_t
is_io_connect_add_client(
- io_connect_t connection,
+ io_object_t connection,
io_object_t connect_to)
{
CHECK( IOUserClient, connection, client );
@@ -5001,11 +4782,13 @@
IOReturn ret;
IOStatisticsClientCall();
-
- client->ipcEnter(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
+ if (client->defaultLocking) {
+ IORWLockWrite(client->lock);
+ }
ret = client->connectClient( to );
- client->ipcExit(client->defaultLocking ? kIPCLockWrite : kIPCLockNone);
-
+ if (client->defaultLocking) {
+ IORWLockUnlock(client->lock);
+ }
return ret;
}
@@ -5013,7 +4796,7 @@
/* Routine io_connect_set_properties */
kern_return_t
is_io_connect_set_properties(
- io_connect_t connection,
+ io_object_t connection,
io_buf_ptr_t properties,
mach_msg_type_number_t propertiesCnt,
kern_return_t * result)
@@ -6405,8 +6188,7 @@
unsigned int size;
size = s->getLength();
- kr = mach_vm_allocate_kernel(kernel_map, &data, size,
- VM_MAP_KERNEL_FLAGS_ANYWHERE(.vm_tag = VM_KERN_MEMORY_IOKIT));
+ kr = mach_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, data, size, true, ©);
@@ -6550,29 +6332,13 @@
boolean_t *exists )
{
OSCollectionIterator *iter;
- IORegistryEntry *entry;
- io_name_t namebuf;
- const char *entryname;
- const char *propname;
if (main_port != main_device_port) {
return kIOReturnNotPrivileged;
}
- if ((propname = strchr(name, ':'))) {
- propname++;
- strlcpy(namebuf, name, propname - name);
- entryname = namebuf;
- } else {
- entryname = name;
- }
-
- iter = IODTFindMatchingEntries(IORegistryEntry::getRegistryRoot(), kIODTRecursive, entryname);
- if (iter && (entry = (IORegistryEntry *) iter->getNextObject())) {
- *exists = !propname || entry->propertyExists(propname);
- } else {
- *exists = FALSE;
- }
+ iter = IODTFindMatchingEntries(IORegistryEntry::getRegistryRoot(), kIODTRecursive, name);
+ *exists = iter && iter->getNextObject();
OSSafeReleaseNULL(iter);
return kIOReturnSuccess;
@@ -6584,14 +6350,21 @@
{
IOReturn ret;
- ipcEnter(defaultLocking ? (defaultLockingSingleThreadExternalMethod ? kIPCLockWrite : kIPCLockRead) : kIPCLockNone);
+ if (defaultLocking) {
+ if (defaultLockingSingleThreadExternalMethod) {
+ IORWLockWrite(lock);
+ } else {
+ IORWLockRead(lock);
+ }
+ }
if (uc2022) {
ret = ((IOUserClient2022 *) this)->externalMethod(selector, (IOExternalMethodArgumentsOpaque *) args);
} else {
ret = externalMethod(selector, args);
}
- ipcExit(defaultLocking ? (defaultLockingSingleThreadExternalMethod ? kIPCLockWrite : kIPCLockRead) : kIPCLockNone);
-
+ if (defaultLocking) {
+ IORWLockUnlock(lock);
+ }
return ret;
}