kern_return_t ipc_object_alloc( ipc_space_t space, ipc_object_type_t otype, mach_port_type_t type, mach_port_urefs_t urefs, mach_port_name_t *namep, ipc_object_t *objectp) { ipc_object_t object; ipc_entry_t entry; kern_return_t kr; assert(otype < IOT_NUMBER); assert((type & MACH_PORT_TYPE_ALL_RIGHTS) == type); assert(type != MACH_PORT_TYPE_NONE); assert(urefs <= MACH_PORT_UREFS_MAX); object = io_alloc(otype); if (object == IO_NULL) return KERN_RESOURCE_SHORTAGE; if (otype == IOT_PORT) { ipc_port_t port = (ipc_port_t)object; bzero((char *)port, sizeof(*port)); #if CONFIG_MACF_MACH mac_port_label_init(&port->ip_label); #endif } else if (otype == IOT_PORT_SET) { ipc_pset_t pset = (ipc_pset_t)object; bzero((char *)pset, sizeof(*pset)); } io_lock_init(object); *namep = CAST_MACH_PORT_TO_NAME(object); kr = ipc_entry_alloc(space, namep, &entry); if (kr != KERN_SUCCESS) { io_free(otype, object); return kr; } /* space is write-locked */ entry->ie_bits |= type | urefs; entry->ie_object = object; io_lock(object); is_write_unlock(space); object->io_references = 1; /* for entry, not caller */ object->io_bits = io_makebits(TRUE, otype, 0); *objectp = object; return KERN_SUCCESS; }
kern_return_t ipc_object_alloc( ipc_space_t space, ipc_object_type_t otype, mach_port_type_t type, mach_port_urefs_t urefs, mach_port_t *namep, ipc_object_t *objectp) { ipc_object_t object; ipc_entry_t entry; kern_return_t kr; assert(otype < IOT_NUMBER); assert((type & MACH_PORT_TYPE_ALL_RIGHTS) == type); assert(type != MACH_PORT_TYPE_NONE); assert(urefs <= MACH_PORT_UREFS_MAX); object = io_alloc(otype); if (object == IO_NULL) return KERN_RESOURCE_SHORTAGE; if (otype == IOT_PORT) { ipc_port_t port = (ipc_port_t)object; memset(port, 0, sizeof(*port)); } else if (otype == IOT_PORT_SET) { ipc_pset_t pset = (ipc_pset_t)object; memset(pset, 0, sizeof(*pset)); } is_write_lock(space); kr = ipc_entry_alloc(space, namep, &entry); if (kr != KERN_SUCCESS) { is_write_unlock(space); io_free(otype, object); return kr; } entry->ie_bits |= type | urefs; entry->ie_object = object; io_lock_init(object); io_lock(object); is_write_unlock(space); object->io_references = 1; /* for entry, not caller */ object->io_bits = io_makebits(TRUE, otype, 0); *objectp = object; return KERN_SUCCESS; }
kern_return_t ipc_object_alloc_dead( ipc_space_t space, mach_port_name_t *namep) { ipc_entry_t entry; kern_return_t kr; kr = ipc_entry_alloc(space, namep, &entry); if (kr != KERN_SUCCESS) return kr; /* space is write-locked */ /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */ assert(entry->ie_object == IO_NULL); entry->ie_bits |= MACH_PORT_TYPE_DEAD_NAME | 1; ipc_entry_modified(space, *namep, entry); is_write_unlock(space); return KERN_SUCCESS; }
kern_return_t ipc_object_copyout( ipc_space_t space, ipc_object_t object, mach_msg_type_name_t msgt_name, boolean_t overflow, mach_port_t *namep) { mach_port_t name; ipc_entry_t entry; kern_return_t kr; assert(IO_VALID(object)); assert(io_otype(object) == IOT_PORT); is_write_lock(space); for (;;) { if (!space->is_active) { is_write_unlock(space); return KERN_INVALID_TASK; } if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) && ipc_right_reverse(space, object, &name, &entry)) { /* object is locked and active */ assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE); break; } kr = ipc_entry_alloc(space, &name, &entry); if (kr != KERN_SUCCESS) { is_write_unlock(space); return kr; } assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); assert(entry->ie_object == IO_NULL); io_lock(object); if (!io_active(object)) { io_unlock(object); ipc_entry_dealloc(space, name, entry); is_write_unlock(space); return KERN_INVALID_CAPABILITY; } entry->ie_object = object; break; } /* space is write-locked and active, object is locked and active */ kr = ipc_right_copyout(space, name, entry, msgt_name, overflow, object); /* object is unlocked */ is_write_unlock(space); if (kr == KERN_SUCCESS) *namep = name; return kr; }