Exemplo n.º 1
0
/*
 * fileport_notify
 *
 * Description: Handle a no-senders notification for a fileport.  Unless
 * 		the message is spoofed, destroys the port and releases
 * 		its reference on the fileglob.
 *
 * Parameters: msg		A Mach no-senders notification message.
 */
void
fileport_notify(mach_msg_header_t *msg)
{
	mach_no_senders_notification_t *notification = (void *)msg;
	ipc_port_t port = notification->not_header.msgh_remote_port;
	struct fileglob *fg = NULL;

	if (!IP_VALID(port))
		panic("Invalid port passed to fileport_notify()\n");

	ip_lock(port);

	fg = (struct fileglob *)port->ip_kobject;

	if (!ip_active(port)) 
		panic("Inactive port passed to fileport_notify()\n");
	if (ip_kotype(port) != IKOT_FILEPORT) 
		panic("Port of type other than IKOT_FILEPORT passed to fileport_notify()\n");
	if (fg == NULL) 
		panic("fileport without an assocated fileglob\n");

	if (port->ip_srights == 0) {
		ip_unlock(port);

		fileport_releasefg(fg);
		ipc_port_dealloc_kernel(port);
	} else {
		ip_unlock(port);
	}

	return;
}
Exemplo n.º 2
0
ipc_port_t
retrieve_task_self_fast(
	register task_t		task)
{
	register ipc_port_t port;

	assert(task == current_task());

	itk_lock(task);
	assert(task->itk_self != IP_NULL);

	if ((port = task->itk_sself) == task->itk_self) {
		/* no interposing */

		ip_lock(port);
		assert(ip_active(port));
		ip_reference(port);
		port->ip_srights++;
		ip_unlock(port);
	} else
		port = ipc_port_copy_send(port);
	itk_unlock(task);

	return port;
}
Exemplo n.º 3
0
EXTERN ipc_port_t
iokit_alloc_object_port( io_object_t obj, ipc_kobject_type_t type )
{
    ipc_port_t		notify;
    ipc_port_t		port;

    do {

	/* Allocate port, keeping a reference for it. */
        port = ipc_port_alloc_kernel();
        if( port == IP_NULL)
            continue;

        /* set kobject & type */
//	iokit_add_reference( obj );
	ipc_kobject_set( port, (ipc_kobject_t) obj, type);

        /* Request no-senders notifications on the port. */
        ip_lock( port);
        notify = ipc_port_make_sonce_locked( port);
        ipc_port_nsrequest( port, 1, notify, &notify);
	/* port unlocked */
        assert( notify == IP_NULL);
	gIOKitPortCount++;

    } while( FALSE);

    return( port );
}
Exemplo n.º 4
0
void
ipc_port_release_send(
	ipc_port_t	port)
{
	ipc_port_t nsrequest = IP_NULL;
	mach_port_mscount_t mscount;

	if (!IP_VALID(port))
		return;

	ip_lock(port);

	if (!ip_active(port)) {
		ip_unlock(port);
		ip_release(port);
		return;
	}

	assert(port->ip_srights > 0);

	if (--port->ip_srights == 0 &&
	    port->ip_nsrequest != IP_NULL) {
		nsrequest = port->ip_nsrequest;
		port->ip_nsrequest = IP_NULL;
		mscount = port->ip_mscount;
		ip_unlock(port);
		ip_release(port);
		ipc_notify_no_senders(nsrequest, mscount);
	} else {
		ip_unlock(port);
		ip_release(port);
	}
}
Exemplo n.º 5
0
/*  Called when an ACKMESSAGE packet is received. <name> indicates
 *	the flipc name of the port holding the messages to be acknowledged.
 *	<msg_count> indicates the number of messages being acked for this node:port.
 */
static void
flipc_cmd_ack(flipc_ack_msg_t   fmsg,
              mach_node_t       node    __unused,
              uint32_t          flags   __unused)
{
    unsigned int msg_count = fmsg->msg_count;
    thread_t thread = current_thread();
    boolean_t kick = FALSE;

    flipc_port_t fport = (flipc_port_t)mnl_obj_lookup(fmsg->mnl.object);

    ipc_port_t lport = fport->lport;
    ip_lock(lport);

    ipc_mqueue_t lport_mq = &lport->ip_messages;
    imq_lock(lport_mq);

    assert(fport->peek_count >= msg_count); // Can't ack what we haven't peeked!

    while (msg_count--) {
        ipc_mqueue_select_on_thread(lport_mq, IMQ_NULL, 0, 0, thread);
        fport->peek_count--;
        kick |= ipc_kmsg_delayed_destroy(thread->ith_kmsg);
    }

    imq_unlock(lport_mq);
    ip_unlock(lport);

    if (kick)
        ipc_kmsg_reap_delayed();
}
Exemplo n.º 6
0
ipc_port_t
retrieve_thread_self_fast(
	thread_t		thread)
{
	register ipc_port_t port;

	assert(thread == current_thread());

	thread_mtx_lock(thread);

	assert(thread->ith_self != IP_NULL);

	if ((port = thread->ith_sself) == thread->ith_self) {
		/* no interposing */

		ip_lock(port);
		assert(ip_active(port));
		ip_reference(port);
		port->ip_srights++;
		ip_unlock(port);
	}
	else
		port = ipc_port_copy_send(port);

	thread_mtx_unlock(thread);

	return port;
}
Exemplo n.º 7
0
/*
 *	Routine: convert_port_to_locked_task
 *	Purpose:
 *		Internal helper routine to convert from a port to a locked
 *		task.  Used by several routines that try to convert from a
 *		task port to a reference on some task related object.
 *	Conditions:
 *		Nothing locked, blocking OK.
 */
task_t
convert_port_to_locked_task(ipc_port_t port)
{
        int try_failed_count = 0;

	while (IP_VALID(port)) {
		task_t task;

		ip_lock(port);
		if (!ip_active(port) || (ip_kotype(port) != IKOT_TASK)) {
			ip_unlock(port);
			return TASK_NULL;
		}
		task = (task_t) port->ip_kobject;
		assert(task != TASK_NULL);

		/*
		 * Normal lock ordering puts task_lock() before ip_lock().
		 * Attempt out-of-order locking here.
		 */
		if (task_lock_try(task)) {
			ip_unlock(port);
			return(task);
		}
		try_failed_count++;

		ip_unlock(port);
		mutex_pause(try_failed_count);
	}
	return TASK_NULL;
}
Exemplo n.º 8
0
void
host_notify_port_destroy(
	ipc_port_t			port)
{
	host_notify_t		entry;

	mutex_lock(&host_notify_lock);

	ip_lock(port);
	if (ip_kotype(port) == IKOT_HOST_NOTIFY) {
		entry = (host_notify_t)port->ip_kobject;
		assert(entry != NULL);
		ipc_kobject_set_atomically(port, IKO_NULL, IKOT_NONE);
		ip_unlock(port);

		assert(entry->port == port);
		remqueue(NULL, (queue_entry_t)entry);
		mutex_unlock(&host_notify_lock);
		zfree(host_notify_zone, (vm_offset_t)entry);

		ipc_port_release_sonce(port);
		return;
	}
	ip_unlock(port);

	mutex_unlock(&host_notify_lock);
}
Exemplo n.º 9
0
void
mach_port_gst_helper(
	ipc_pset_t		pset,
	ipc_port_t		port,
	ipc_entry_num_t		maxnames,
	mach_port_name_t	*names,
	ipc_entry_num_t		*actualp)
{
	ipc_pset_t ip_pset;
	mach_port_name_t name;

	assert(port != IP_NULL);

	ip_lock(port);
	assert(ip_active(port));

	name = port->ip_receiver_name;
	assert(name != MACH_PORT_NULL);

	ip_unlock(port);

	if (ipc_pset_member(pset, port)) {
		ipc_entry_num_t actual = *actualp;

		if (actual < maxnames)
			names[actual] = name;

		*actualp = actual+1;
	}
}
Exemplo n.º 10
0
void
mk_timer_port_destroy(
	ipc_port_t			port)
{
	mk_timer_t			timer = NULL;

	ip_lock(port);
	if (ip_kotype(port) == IKOT_TIMER) {
		timer = (mk_timer_t)port->ip_kobject;
		assert(timer != NULL);
		ipc_kobject_set_atomically(port, IKO_NULL, IKOT_NONE);
		simple_lock(&timer->lock);
		assert(timer->port == port);
	}
	ip_unlock(port);

	if (timer != NULL) {
		if (thread_call_cancel(&timer->call_entry))
			timer->active--;
		timer->is_armed = FALSE;

		timer->is_dead = TRUE;
		if (timer->active == 0) {
			simple_unlock(&timer->lock);
			zfree(mk_timer_zone, timer);

			ipc_port_release_send(port);
			return;
		}

		simple_unlock(&timer->lock);
	}
}
Exemplo n.º 11
0
/*
 * fileport_alloc
 *
 * Description: Obtain a send right for the given fileglob, which must be
 *		referenced.
 *
 * Parameters: 	fg		A fileglob.
 *
 * Returns: 	Port of type IKOT_FILEPORT with fileglob set as its kobject. 
 * 		Port is returned with a send right.
 */
ipc_port_t
fileport_alloc(struct fileglob *fg)
{
	ipc_port_t fileport;
	ipc_port_t sendport;
	ipc_port_t notifyport;

	fileport = ipc_port_alloc_kernel();
	if (fileport == IP_NULL) {
		goto out;
	}

	ipc_kobject_set(fileport, (ipc_kobject_t)fg, IKOT_FILEPORT);
	notifyport = ipc_port_make_sonce(fileport);
	ip_lock(fileport); /* unlocked by ipc_port_nsrequest */
	ipc_port_nsrequest(fileport, 1, notifyport, &notifyport);

	sendport = ipc_port_make_send(fileport);
	if (!IP_VALID(sendport)) {
		panic("Couldn't allocate send right for fileport!\n");
	}

out:
	return fileport;
}
Exemplo n.º 12
0
ipc_port_t
ipc_port_lookup_notify(
	ipc_space_t		space,
	mach_port_name_t	name)
{
	ipc_port_t port;
	ipc_entry_t entry;

	assert(is_active(space));

	entry = ipc_entry_lookup(space, name);
	if (entry == IE_NULL)
		return IP_NULL;
	if ((entry->ie_bits & MACH_PORT_TYPE_RECEIVE) == 0)
		return IP_NULL;

	port = (ipc_port_t) entry->ie_object;
	assert(port != IP_NULL);

	ip_lock(port);
	assert(ip_active(port));
	assert(port->ip_receiver_name == name);
	assert(port->ip_receiver == space);

	ip_reference(port);
	port->ip_sorights++;
	ip_unlock(port);

	return port;
}
Exemplo n.º 13
0
/*
 *	Routine:	convert_port_to_mig_object [interface]
 *	Purpose:
 *		Base implementation of MIG intrans routine to convert from
 *		an incoming port reference to a new reference on the
 *		underlying object. A new reference must be created, because
 *		the port's reference could go away asynchronously.
 *	Returns:
 *		NULL - Not an active MIG object port or iid not supported
 *		Otherwise, a reference to the underlying MIG interface
 *	Conditions:
 *		Nothing locked.
 */
mig_object_t
convert_port_to_mig_object(
	ipc_port_t	port,
	const MIGIID	*iid)
{
	mig_object_t	mig_object;
	void 		*ppv;

	if (!IP_VALID(port))
		return NULL;

	ip_lock(port);
	if (!ip_active(port) || (ip_kotype(port) != IKOT_MIG)) {
		ip_unlock(port);
		return NULL;
	}

	/*
	 * Our port points to some MIG object interface.  Now
	 * query it to get a reference to the desired interface.
	 */
	ppv = NULL;
	mig_object = (mig_object_t)port->ip_kobject;
	mig_object->pVtbl->QueryInterface((IMIGObject *)mig_object, iid, &ppv);
	ip_unlock(port);
	return (mig_object_t)ppv;
}
Exemplo n.º 14
0
boolean_t
ipc_right_check(
	ipc_space_t 	space,
	ipc_port_t 	port,
	mach_port_t 	name,
	ipc_entry_t 	entry)
{
	ipc_entry_bits_t bits;

	assert(space->is_active);
	assert(port == (ipc_port_t) entry->ie_object);

	ip_lock(port);
	if (ip_active(port))
		return FALSE;
	ip_unlock(port);

	/* this was either a pure send right or a send-once right */

	bits = entry->ie_bits;
	assert((bits & MACH_PORT_TYPE_RECEIVE) == 0);
	assert(IE_BITS_UREFS(bits) > 0);

	if (bits & MACH_PORT_TYPE_SEND) {
		assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND);

		/* clean up msg-accepted request */

		if (bits & IE_BITS_MAREQUEST) {
			bits &= ~IE_BITS_MAREQUEST;

			ipc_marequest_cancel(space, name);
		}

		ipc_reverse_remove(space, (ipc_object_t) port);
	} else {
		assert(IE_BITS_TYPE(bits) == MACH_PORT_TYPE_SEND_ONCE);
		assert(IE_BITS_UREFS(bits) == 1);
		assert((bits & IE_BITS_MAREQUEST) == 0);
	}

	ipc_port_release(port);

	/* convert entry to dead name */

	bits = (bits &~ IE_BITS_TYPE_MASK) | MACH_PORT_TYPE_DEAD_NAME;

	if (entry->ie_request != 0) {
		assert(IE_BITS_UREFS(bits) < MACH_PORT_UREFS_MAX);

		entry->ie_request = 0;
		bits++;		/* increment urefs */
	}

	entry->ie_bits = bits;
	entry->ie_object = IO_NULL;

	return TRUE;
}
Exemplo n.º 15
0
void
exception(
	integer_t _exception, 
	integer_t code, 
	integer_t subcode)
{
	ipc_thread_t self = current_thread();
	ipc_port_t exc_port;

	if (_exception == KERN_SUCCESS)
		panic("exception");

	/*
	 *	Optimized version of retrieve_thread_exception.
	 */

	ith_lock(self);
	assert(self->ith_self != IP_NULL);
	exc_port = self->ith_exception;
	if (!IP_VALID(exc_port)) {
		ith_unlock(self);
		exception_try_task(_exception, code, subcode);
		/*NOTREACHED*/
	}

	ip_lock(exc_port);
	ith_unlock(self);
	if (!ip_active(exc_port)) {
		ip_unlock(exc_port);
		exception_try_task(_exception, code, subcode);
		/*NOTREACHED*/
	}

	/*
	 *	Make a naked send right for the exception port.
	 */

	ip_reference(exc_port);
	exc_port->ip_srights++;
	ip_unlock(exc_port);

	/*
	 *	If this exception port doesn't work,
	 *	we will want to try the task's exception port.
	 *	Indicate this by saving the exception state.
	 */

	self->ith_exc = _exception;
	self->ith_exc_code = code;
	self->ith_exc_subcode = subcode;

	exception_raise(exc_port,
			retrieve_thread_self_fast(self),
			retrieve_task_self_fast(self->task),
			_exception, code, subcode);
	/*NOTREACHED*/
}
Exemplo n.º 16
0
void
mach_port_names_helper(
	ipc_port_timestamp_t	timestamp,
	ipc_entry_t		entry,
	mach_port_name_t	name,
	mach_port_name_t	*names,
	mach_port_type_t	*types,
	ipc_entry_num_t		*actualp,
	ipc_space_t		space)
{
	ipc_entry_bits_t bits;
	ipc_port_request_index_t request;
	mach_port_type_t type;
	ipc_entry_num_t actual;

	bits = entry->ie_bits;
	request = entry->ie_request;
	if (bits & MACH_PORT_TYPE_SEND_RIGHTS) {
		ipc_port_t port;
		boolean_t died;

		port = (ipc_port_t) entry->ie_object;
		assert(port != IP_NULL);

		/*
		 *	The timestamp serializes mach_port_names
		 *	with ipc_port_destroy.  If the port died,
		 *	but after mach_port_names started, pretend
		 *	that it isn't dead.
		 */

		ip_lock(port);
		died = (!ip_active(port) &&
			IP_TIMESTAMP_ORDER(port->ip_timestamp, timestamp));
		ip_unlock(port);

		if (died) {
			/* pretend this is a dead-name entry */

			bits &= ~(IE_BITS_TYPE_MASK);
			bits |= MACH_PORT_TYPE_DEAD_NAME;
			if (request != 0)
				bits++;
			request = 0;
		}
	}

	type = IE_BITS_TYPE(bits);
	if (request != 0)
		type |= MACH_PORT_TYPE_DNREQUEST;

	actual = *actualp;
	names[actual] = name;
	types[actual] = type;
	*actualp = actual+1;
}
Exemplo n.º 17
0
/*
 *	Routine:	ipc_kobject_set
 *	Purpose:
 *		Make a port represent a kernel object of the given type.
 *		The caller is responsible for handling refs for the
 *		kernel object, if necessary.
 *	Conditions:
 *		Nothing locked.  The port must be active if setting
 *		a kobject linkage.  Clearing a linkage is OK on an
 *		inactive port.
 */
void
ipc_kobject_set(
	ipc_port_t			port,
	ipc_kobject_t		kobject,
	ipc_kobject_type_t	type)
{
	ip_lock(port);
	ipc_kobject_set_atomically(port, kobject, type);
	ip_unlock(port);
}
Exemplo n.º 18
0
/*
 *	Routine:	convert_mig_object_to_port [interface]
 *	Purpose:
 *		Base implementation of MIG outtrans routine to convert from
 *		a mig object reference to a new send right on the object's
 *		port.  The object reference is consumed.
 *	Returns:
 *		IP_NULL - Null MIG object supplied
 *		Otherwise, a newly made send right for the port
 *	Conditions:
 *		Nothing locked.
 */
ipc_port_t
convert_mig_object_to_port(
	mig_object_t	mig_object)
{
	ipc_port_t	port;
	boolean_t	deallocate = TRUE;

	if (mig_object == MIG_OBJECT_NULL)
		return IP_NULL;

	port = mig_object->port;
	while ((port == IP_NULL) ||
	       ((port = ipc_port_make_send(port)) == IP_NULL)) {
		ipc_port_t	previous;

		/*
		 * Either the port was never set up, or it was just
		 * deallocated out from under us by the no-senders
		 * processing.  In either case, we must:
		 *	Attempt to make one
		 * 	Arrange for no senders
		 *	Try to atomically register it with the object
		 *		Destroy it if we are raced.
		 */
		port = ipc_port_alloc_kernel();
		ip_lock(port);
		ipc_kobject_set_atomically(port,
					   (ipc_kobject_t) mig_object,
					   IKOT_MIG);

		/* make a sonce right for the notification */
		port->ip_sorights++;
		ip_reference(port);

		ipc_port_nsrequest(port, 1, port, &previous);
		/* port unlocked */

		assert(previous == IP_NULL);

		if (OSCompareAndSwapPtr((void *)IP_NULL, (void *)port,
											(void * volatile *)&mig_object->port)) {
			deallocate = FALSE;
		} else {
			ipc_port_dealloc_kernel(port);
			port = mig_object->port;
		}
	}

	if (deallocate)
		mig_object->pVtbl->Release((IMIGObject *)mig_object);

	return (port);
}
Exemplo n.º 19
0
boolean_t
ipc_right_reverse(
	ipc_space_t	space,
	ipc_object_t	object,
	mach_port_t	*namep,
	ipc_entry_t	*entryp)
{
	ipc_port_t port;
	mach_port_t name;
	ipc_entry_t entry;

	/* would switch on io_otype to handle multiple types of object */

	assert(space->is_active);
	assert(io_otype(object) == IOT_PORT);

	port = (ipc_port_t) object;

	ip_lock(port);
	if (!ip_active(port)) {
		ip_unlock(port);

		return FALSE;
	}

	if (port->ip_receiver == space) {
		name = port->ip_receiver_name;
		assert(name != MACH_PORT_NULL);

		entry = ipc_entry_lookup(space, name);

		assert(entry != IE_NULL);
		assert(entry->ie_bits & MACH_PORT_TYPE_RECEIVE);
		assert(port == (ipc_port_t) entry->ie_object);

		*namep = name;
		*entryp = entry;
		return TRUE;
	}

	if ((*entryp = ipc_reverse_lookup(space, (ipc_object_t) port))) {
		*namep = (*entryp)->ie_name;
		assert((entry = *entryp) != IE_NULL);
		assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_SEND);
		assert(port == (ipc_port_t) entry->ie_object);

		return TRUE;
	}

	ip_unlock(port);
	return FALSE;
}
Exemplo n.º 20
0
void
exception_try_task(
	integer_t _exception, 
	integer_t code, 
	integer_t subcode)
{
	ipc_thread_t self = current_thread();
	task_t task = self->task;
	ipc_port_t exc_port;

	/*
	 *	Optimized version of retrieve_task_exception.
	 */

	itk_lock(task);
	assert(task->itk_self != IP_NULL);
	exc_port = task->itk_exception;
	if (!IP_VALID(exc_port)) {
		itk_unlock(task);
		exception_no_server();
		/*NOTREACHED*/
	}

	ip_lock(exc_port);
	itk_unlock(task);
	if (!ip_active(exc_port)) {
		ip_unlock(exc_port);
		exception_no_server();
		/*NOTREACHED*/
	}

	/*
	 *	Make a naked send right for the exception port.
	 */

	ip_reference(exc_port);
	exc_port->ip_srights++;
	ip_unlock(exc_port);

	/*
	 *	This is the thread's last chance.
	 *	Clear the saved exception state.
	 */

	self->ith_exc = KERN_SUCCESS;

	exception_raise(exc_port,
			retrieve_thread_self_fast(self),
			retrieve_task_self_fast(task),
			_exception, code, subcode);
	/*NOTREACHED*/
}
Exemplo n.º 21
0
kern_return_t
mach_set_port_label(
	ipc_space_t		space,
	mach_port_name_t	name,
	vm_offset_t		labelstr)
{
#ifdef MAC
	ipc_entry_t entry;
	kern_return_t kr;
	struct label inl;
	int rc;

	if (space == IS_NULL || space->is_task == NULL)
		return KERN_INVALID_TASK;

	if (!MACH_PORT_VALID(name))
		return KERN_INVALID_NAME;

	mac_init_port_label(&inl);
	rc = mac_internalize_port_label(&inl, labelstr);
	if (rc)
		return KERN_INVALID_ARGUMENT;

	kr = ipc_right_lookup_write(space, name, &entry);
	if (kr != KERN_SUCCESS)
		return kr;

	if (io_otype(entry->ie_object) != IOT_PORT) {
		is_write_unlock(space);
		return KERN_INVALID_RIGHT;
	}

	ipc_port_t port = (ipc_port_t) entry->ie_object;

	ip_lock(port);

	rc = mac_check_port_relabel(&space->is_task->maclabel,
	    &port->ip_label, &inl);
	if (rc)
		kr = KERN_NO_ACCESS;
	else
		mac_copy_port_label(&inl, &port->ip_label);

	ip_unlock(port);
	is_write_unlock(space);
	return kr;
#else
	return KERN_INVALID_ARGUMENT;
#endif
}
Exemplo n.º 22
0
ipc_port_t
ipc_port_make_sonce(
	ipc_port_t	port)
{
	assert(IP_VALID(port));

	ip_lock(port);
	assert(ip_active(port));
	port->ip_sorights++;
	ip_reference(port);
	ip_unlock(port);

	return port;
}
Exemplo n.º 23
0
static void
host_notify_all(
	host_flavor_t		notify_type,
	mach_msg_header_t	*msg,
	mach_msg_size_t		msg_size)
{
	queue_t		notify_queue = &host_notify_queue[notify_type];

	mutex_lock(&host_notify_lock);

	if (!queue_empty(notify_queue)) {
		queue_head_t		send_queue;
		host_notify_t		entry;

		send_queue = *notify_queue;
		queue_init(notify_queue);

		send_queue.next->prev = &send_queue;
		send_queue.prev->next = &send_queue;

		msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0);
		msg->msgh_local_port = MACH_PORT_NULL;
		msg->msgh_id = host_notify_replyid[notify_type];
		msg->msgh_reserved = 0;

		while ((entry = (host_notify_t)dequeue(&send_queue)) != NULL) {
			ipc_port_t		port;

			port = entry->port;
			assert(port != IP_NULL);

			ip_lock(port);
			assert(ip_kotype(port) == IKOT_HOST_NOTIFY);
			assert(port->ip_kobject == (ipc_kobject_t)entry);
			ipc_kobject_set_atomically(port, IKO_NULL, IKOT_NONE);
			ip_unlock(port);

			mutex_unlock(&host_notify_lock);
			zfree(host_notify_zone, (vm_offset_t)entry);

			msg->msgh_remote_port = port;

			(void) mach_msg_send_from_kernel(msg, msg_size);

			mutex_lock(&host_notify_lock);
		}
	}

	mutex_unlock(&host_notify_lock);
}
Exemplo n.º 24
0
kern_return_t
mach_port_kobject(
	ipc_space_t			space,
	mach_port_name_t		name,
	natural_t			*typep,
	mach_vm_address_t		*addrp)
{
	ipc_entry_t entry;
	ipc_port_t port;
	kern_return_t kr;
	mach_vm_address_t kaddr;

	if (space == IS_NULL)
		return KERN_INVALID_TASK;

	kr = ipc_right_lookup_read(space, name, &entry);
	if (kr != KERN_SUCCESS)
		return kr;
	/* space is read-locked and active */

	if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) {
		is_read_unlock(space);
		return KERN_INVALID_RIGHT;
	}

	__IGNORE_WCASTALIGN(port = (ipc_port_t) entry->ie_object);
	assert(port != IP_NULL);

	ip_lock(port);
	is_read_unlock(space);

	if (!ip_active(port)) {
		ip_unlock(port);
		return KERN_INVALID_RIGHT;
	}

	*typep = (unsigned int) ip_kotype(port);
	kaddr = (mach_vm_address_t)port->ip_kobject;
	ip_unlock(port);

#if (DEVELOPMENT || DEBUG)
	if (0 != kaddr && is_ipc_kobject(*typep))
		*addrp = VM_KERNEL_UNSLIDE_OR_PERM(kaddr);
	else
#endif
		*addrp = 0;

	return KERN_SUCCESS;
}
Exemplo n.º 25
0
/*
 *	Routine:	ipc_kobject_set
 *	Purpose:
 *		Make a port represent a kernel object of the given type.
 *		The caller is responsible for handling refs for the
 *		kernel object, if necessary.
 *	Conditions:
 *		Nothing locked.  The port must be active if setting
 *		a kobject linkage.  Clearing a linkage is OK on an
 *		inactive port.
 */
void
ipc_kobject_set(
	ipc_port_t			port,
	ipc_kobject_t		kobject,
	ipc_kobject_type_t	type)
{
	ip_lock(port);
	ipc_kobject_set_atomically(port, kobject, type);

#if CONFIG_MACF_MACH
	mac_port_label_update_kobject (&port->ip_label, type);
#endif

	ip_unlock(port);
}
Exemplo n.º 26
0
void
ipc_port_release_sonce(
	ipc_port_t	port)
{
	assert(IP_VALID(port));

	ip_lock(port);

	assert(port->ip_sorights > 0);

	port->ip_sorights--;

	ip_unlock(port);
	ip_release(port);
}
Exemplo n.º 27
0
/*
 * fileport_get_fileglob
 *
 * Description: Obtain the fileglob associated with a given port.
 *
 * Parameters: port		A Mach port of type IKOT_FILEPORT.
 *
 * Returns:    NULL		The given Mach port did not reference a
 *				fileglob.
 *	       !NULL		The fileglob that is associated with the
 *				Mach port.
 *
 * Notes: The caller must have a reference on the fileport.
 */
struct fileglob *
fileport_port_to_fileglob(ipc_port_t port)
{
	struct fileglob *fg = NULL;

	if (!IP_VALID(port))
		return NULL;

	ip_lock(port);
	if (ip_active(port) && IKOT_FILEPORT == ip_kotype(port))
		fg = (void *)port->ip_kobject;
	ip_unlock(port);

	return fg;
}
Exemplo n.º 28
0
processor_set_name_t
convert_port_to_pset_name(
	ipc_port_t	port)
{
	boolean_t r;
	processor_set_t pset = PROCESSOR_SET_NULL;

	r = FALSE;
	while (!r && IP_VALID(port)) {
		ip_lock(port);
		r = ref_pset_port_locked(port, TRUE, &pset);
		/* port unlocked */
	}
	return pset;
}
Exemplo n.º 29
0
void
ipc_kobject_set(
	ipc_port_t		port,
	ipc_kobject_t		kobject,
	ipc_kobject_type_t	type)
{
	ip_lock(port);
	assert(ip_active(port) || (ip_kotype(port) == IKOT_PAGER_TERMINATING));
#if	MACH_ASSERT
	port->ip_spares[2] = (port->ip_bits & IO_BITS_KOTYPE);
#endif	/* MACH_ASSERT */
	port->ip_bits = (port->ip_bits &~ IO_BITS_KOTYPE) | type;
	port->ip_kobject = kobject;
	ip_unlock(port);
}
Exemplo n.º 30
0
/*
 *	Routine:	convert_port_to_clock_ctrl
 *	Purpose:
 *		Convert from a port to a clock.
 *		Doesn't consume the port ref; produces a clock ref,
 *		which may be null.
 *	Conditions:
 *		Nothing locked.
 */
clock_t
convert_port_to_clock_ctrl(
	ipc_port_t	port)
{
	clock_t		clock = CLOCK_NULL;

	if (IP_VALID(port)) {
		ip_lock(port);
		if (ip_active(port) &&
		    (ip_kotype(port) == IKOT_CLOCK_CTRL)) {
			clock = (clock_t) port->ip_kobject;
		}
		ip_unlock(port);
	}
	return (clock);
}