#include <IOKit/IOMemoryDescriptor.h>
#include <IOKit/IOBufferMemoryDescriptor.h>
#include <IOKit/IOLib.h>
+#include <IOKit/IOBSD.h>
#include <IOKit/IOStatisticsPrivate.h>
#include <IOKit/IOTimeStamp.h>
#include <IOKit/system.h>
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 );
bool clientIs64 );
virtual void free() APPLE_KEXT_OVERRIDE;
+ void invalidatePort(void);
static IOReturn _handler( void * target, void * ref,
UInt32 messageType, IOService * provider,
return( true );
}
+void IOServiceUserNotification::invalidatePort(void)
+{
+ if (pingMsg) pingMsg->msgHdr.msgh_remote_port = MACH_PORT_NULL;
+}
+
void IOServiceUserNotification::free( void )
{
PingMsg * _pingMsg;
return( true );
}
+void IOServiceMessageUserNotification::invalidatePort(void)
+{
+ if (pingMsg) pingMsg->msgHdr.msgh_remote_port = MACH_PORT_NULL;
+}
+
void IOServiceMessageUserNotification::free( void )
{
PingMsg * _pingMsg;
}
else
{
+ if( callerArgSize > kIOUserNotifyMaxMessageSize)
+ callerArgSize = kIOUserNotifyMaxMessageSize;
argSize = callerArgSize;
- if( argSize > kIOUserNotifyMaxMessageSize)
- argSize = kIOUserNotifyMaxMessageSize;
}
// adjust message size for ipc restrictions
{
IOReturn err;
IOOptionBits options = 0;
- IOMemoryDescriptor * memory;
+ IOMemoryDescriptor * memory = 0;
IOMemoryMap * map = 0;
err = clientMemoryForType( (UInt32) type, &options, &memory );
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 */
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 */
do {
err = kIOReturnNoResources;
+ if (matching_size > (sizeof(io_struct_inband_t) * 1024)) return(kIOReturnMessageTooLarge);
+
if( !(sym = OSSymbol::withCString( notification_type )))
err = kIOReturnNoResources;
else if( (sym == gIOMatchedNotification)
|| (sym == gIOFirstMatchNotification))
userMsgType = kIOServiceMatchedNotificationType;
- else if( sym == gIOTerminatedNotification)
+ else if ((sym == gIOTerminatedNotification)
+ || (sym == gIOWillTerminateNotification))
userMsgType = kIOServiceTerminatedNotificationType;
else
userMsgType = kLastIOKitNotificationType;
if( userNotify && !userNotify->init( port, userMsgType,
reference, referenceSize, client64)) {
- iokit_release_port_send(port);
userNotify->release();
userNotify = 0;
}
} while( false );
+ if ((kIOReturnSuccess != err) && userNotify)
+ {
+ userNotify->invalidatePort();
+ userNotify->release();
+ userNotify = 0;
+ }
+
if( sym)
sym->release();
if( dict)
reference, referenceSize,
kIOUserNotifyMaxMessageSize,
client64 )) {
- iokit_release_port_send(port);
userNotify->release();
userNotify = 0;
}
} while( false );
+ if ((kIOReturnSuccess != err) && userNotify)
+ {
+ userNotify->invalidatePort();
+ userNotify->release();
+ userNotify = 0;
+ }
+
return( err );
}
if( (data = OSDynamicCast( OSData, obj ))) {
len = data->getLength();
bytes = data->getBytesNoCopy();
+ if (!data->isSerializable()) len = 0;
} else if( (str = OSDynamicCast( OSString, obj ))) {
len = str->getLength() + 1;
do
{
- if (properties)
+ if (properties) return (kIOReturnUnsupported);
+#if 0
{
OSObject * obj;
vm_offset_t data;
if (kIOReturnSuccess != res)
break;
}
-
+#endif
crossEndian = (ndr.int_rep != NDR_record.int_rep);
if (crossEndian)
{
{
IOReturn err;
IOOptionBits options = 0;
- IOMemoryDescriptor * memory;
+ IOMemoryDescriptor * memory = 0;
IOMemoryMap * map;
CHECK( IOUserClient, connection, client );
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, current_task());
+ kIODirectionOut | kIOMemoryMapCopyOnWrite,
+ current_task());
args.structureInputDescriptor = inputMD;
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, current_task());
+ kIODirectionOut | kIOMemoryMapCopyOnWrite,
+ current_task());
args.structureInputDescriptor = inputMD;
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, current_task());
+ kIODirectionOut | kIOMemoryMapCopyOnWrite,
+ current_task());
args.structureInputDescriptor = inputMD;
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;
return kIOReturnBadArgument;
}
+ if (!IOTaskHasEntitlement(current_task(), "com.apple.rootless.kext-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 <rdar://problem/32554970> for more details.
+ return kIOReturnSuccess;
+ }
+
if (inData) {
vm_map_offset_t map_data;
}
if (obj) obj->release();
-
+
*result = kr;
return( KERN_SUCCESS);
+#endif /* NO_KEXTD */
}
/* Routine io_catalog_terminate */
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,