1/*
2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31/*
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34 * All Rights Reserved.
35 *
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
41 *
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
49 *  School of Computer Science
50 *  Carnegie Mellon University
51 *  Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56/*
57 * NOTICE: This file was modified by McAfee Research in 2004 to introduce
58 * support for mandatory and extensible security protections.  This notice
59 * is included in support of clause 2.2 (b) of the Apple Public License,
60 * Version 2.0.
61 * Copyright (c) 2005 SPARTA, Inc.
62 */
63/*
64 */
65/*
66 *	File:	ipc/ipc_kmsg.c
67 *	Author:	Rich Draves
68 *	Date:	1989
69 *
70 *	Operations on kernel messages.
71 */
72
73#include <norma_vm.h>
74
75#include <mach/mach_types.h>
76#include <mach/boolean.h>
77#include <mach/kern_return.h>
78#include <mach/message.h>
79#include <mach/port.h>
80#include <mach/vm_map.h>
81#include <mach/mach_vm.h>
82#include <mach/vm_statistics.h>
83
84#include <kern/kern_types.h>
85#include <kern/assert.h>
86#include <kern/debug.h>
87#include <kern/ipc_kobject.h>
88#include <kern/kalloc.h>
89#include <kern/zalloc.h>
90#include <kern/processor.h>
91#include <kern/thread.h>
92#include <kern/sched_prim.h>
93#include <kern/spl.h>
94#include <kern/misc_protos.h>
95#include <kern/counters.h>
96#include <kern/cpu_data.h>
97
98#include <machine/machlimits.h>
99
100#include <vm/vm_map.h>
101#include <vm/vm_object.h>
102#include <vm/vm_kern.h>
103
104#include <ipc/port.h>
105#include <ipc/ipc_types.h>
106#include <ipc/ipc_entry.h>
107#include <ipc/ipc_kmsg.h>
108#include <ipc/ipc_notify.h>
109#include <ipc/ipc_object.h>
110#include <ipc/ipc_space.h>
111#include <ipc/ipc_port.h>
112#include <ipc/ipc_right.h>
113#include <ipc/ipc_hash.h>
114#include <ipc/ipc_table.h>
115
116#include <security/mac_mach_internal.h>
117
118#include <string.h>
119
120#ifdef ppc
121#include <ppc/Firmware.h>
122#include <ppc/low_trace.h>
123#endif
124
125#if DEBUG
126#define DEBUG_MSGS_K64 1
127#endif
128
129#pragma pack(4)
130
131typedef	struct
132{
133  mach_msg_bits_t	msgh_bits;
134  mach_msg_size_t	msgh_size;
135  uint32_t		msgh_remote_port;
136  uint32_t		msgh_local_port;
137  mach_msg_size_t 	msgh_reserved;
138  mach_msg_id_t		msgh_id;
139} mach_msg_legacy_header_t;
140
141typedef struct
142{
143        mach_msg_legacy_header_t       header;
144        mach_msg_body_t         body;
145} mach_msg_legacy_base_t;
146
147typedef struct
148{
149  mach_port_name_t				name;
150  mach_msg_size_t				pad1;
151  uint32_t						pad2 : 16;
152  mach_msg_type_name_t			disposition : 8;
153  mach_msg_descriptor_type_t	type : 8;
154} mach_msg_legacy_port_descriptor_t;
155
156
157typedef union
158{
159  mach_msg_legacy_port_descriptor_t			port;
160  mach_msg_ool_descriptor32_t		out_of_line32;
161  mach_msg_ool_ports_descriptor32_t	ool_ports32;
162  mach_msg_type_descriptor_t			type;
163} mach_msg_legacy_descriptor_t;
164
165#pragma pack()
166
167#define LEGACY_HEADER_SIZE_DELTA ((mach_msg_size_t)(sizeof(mach_msg_header_t) - sizeof(mach_msg_legacy_header_t)))
168// END LP64 fixes
169
170
171#if DEBUG_MSGS_K64
172extern void ipc_pset_print64(
173			ipc_pset_t	pset);
174
175extern void	ipc_kmsg_print64(
176			ipc_kmsg_t      kmsg,
177			const char	*str);
178
179extern void	ipc_msg_print64(
180		mach_msg_header_t       *msgh);
181
182extern ipc_port_t ipc_name_to_data64(
183			task_t			task,
184			mach_port_name_t	name);
185
186/*
187 * Forward declarations
188 */
189void ipc_msg_print_untyped64(
190	mach_msg_body_t		*body);
191
192const char * ipc_type_name64(
193	int		type_name,
194	boolean_t	received);
195
196void ipc_print_type_name64(
197	int	type_name);
198
199const char *
200msgh_bit_decode64(
201	mach_msg_bits_t	bit);
202
203const char *
204mm_copy_options_string64(
205	mach_msg_copy_options_t	option);
206
207void db_print_msg_uid64(mach_msg_header_t *);
208
209static void
210ipc_msg_body_print64(void *body, int size)
211{
212	uint32_t	*word = (uint32_t *) body;
213	uint32_t	*end  = (uint32_t *)(((uintptr_t) body) + size
214						- sizeof(mach_msg_header_t));
215	int		i;
216
217	kprintf("  body(%p-%p):\n    %p: ", body, end, word);
218	for (;;) {
219		for (i = 0; i < 8; i++, word++) {
220			if (word >= end) {
221				kprintf("\n");
222				return;
223			}
224			kprintf("%08x ", *word);
225		}
226		kprintf("\n    %p: ", word);
227	}
228}
229
230
231const char *
232ipc_type_name64(
233	int		type_name,
234	boolean_t	received)
235{
236	switch (type_name) {
237		case MACH_MSG_TYPE_PORT_NAME:
238		return "port_name";
239
240		case MACH_MSG_TYPE_MOVE_RECEIVE:
241		if (received) {
242			return "port_receive";
243		} else {
244			return "move_receive";
245		}
246
247		case MACH_MSG_TYPE_MOVE_SEND:
248		if (received) {
249			return "port_send";
250		} else {
251			return "move_send";
252		}
253
254		case MACH_MSG_TYPE_MOVE_SEND_ONCE:
255		if (received) {
256			return "port_send_once";
257		} else {
258			return "move_send_once";
259		}
260
261		case MACH_MSG_TYPE_COPY_SEND:
262		return "copy_send";
263
264		case MACH_MSG_TYPE_MAKE_SEND:
265		return "make_send";
266
267		case MACH_MSG_TYPE_MAKE_SEND_ONCE:
268		return "make_send_once";
269
270		default:
271		return (char *) 0;
272	}
273}
274
275void
276ipc_print_type_name64(
277	int	type_name)
278{
279	const char *name = ipc_type_name64(type_name, TRUE);
280	if (name) {
281		kprintf("%s", name);
282	} else {
283		kprintf("type%d", type_name);
284	}
285}
286
287/*
288 * ipc_kmsg_print64	[ debug ]
289 */
290void
291ipc_kmsg_print64(
292	ipc_kmsg_t	kmsg,
293	const char	*str)
294{
295	kprintf("%s kmsg=%p:\n", str, kmsg);
296	kprintf("  next=%p, prev=%p, size=%d",
297		kmsg->ikm_next,
298		kmsg->ikm_prev,
299		kmsg->ikm_size);
300	kprintf("\n");
301	ipc_msg_print64(kmsg->ikm_header);
302}
303
304const char *
305msgh_bit_decode64(
306	mach_msg_bits_t	bit)
307{
308	switch (bit) {
309	    case MACH_MSGH_BITS_COMPLEX:	return "complex";
310	    case MACH_MSGH_BITS_CIRCULAR:	return "circular";
311	    default:				return (char *) 0;
312	}
313}
314
315/*
316 * ipc_msg_print64	[ debug ]
317 */
318void
319ipc_msg_print64(
320	mach_msg_header_t	*msgh)
321{
322	mach_msg_bits_t	mbits;
323	unsigned int	bit, i;
324	const char	*bit_name;
325	int		needs_comma;
326
327	mbits = msgh->msgh_bits;
328	kprintf("  msgh_bits=0x%x: l=0x%x,r=0x%x\n",
329		mbits,
330		MACH_MSGH_BITS_LOCAL(msgh->msgh_bits),
331		MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
332
333	mbits = MACH_MSGH_BITS_OTHER(mbits) & MACH_MSGH_BITS_USED;
334	kprintf("  decoded bits:  ");
335	needs_comma = 0;
336	for (i = 0, bit = 1; i < sizeof(mbits) * 8; ++i, bit <<= 1) {
337		if ((mbits & bit) == 0)
338			continue;
339		bit_name = msgh_bit_decode64((mach_msg_bits_t)bit);
340		if (bit_name)
341			kprintf("%s%s", needs_comma ? "," : "", bit_name);
342		else
343			kprintf("%sunknown(0x%x),", needs_comma ? "," : "", bit);
344		++needs_comma;
345	}
346	if (msgh->msgh_bits & ~MACH_MSGH_BITS_USED) {
347		kprintf("%sunused=0x%x,", needs_comma ? "," : "",
348		       msgh->msgh_bits & ~MACH_MSGH_BITS_USED);
349	}
350	kprintf("\n");
351
352	needs_comma = 1;
353	if (msgh->msgh_remote_port) {
354		kprintf("  remote=%p(", msgh->msgh_remote_port);
355		ipc_print_type_name64(MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
356		kprintf(")");
357	} else {
358		kprintf("  remote=null");
359	}
360
361	if (msgh->msgh_local_port) {
362		kprintf("%slocal=%p(", needs_comma ? "," : "",
363		       msgh->msgh_local_port);
364		ipc_print_type_name64(MACH_MSGH_BITS_LOCAL(msgh->msgh_bits));
365		kprintf(")\n");
366	} else {
367		kprintf("local=null\n");
368	}
369
370	kprintf("  msgh_id=%d, size=%d\n",
371		msgh->msgh_id,
372		msgh->msgh_size);
373
374	if (mbits & MACH_MSGH_BITS_COMPLEX) {
375		ipc_msg_print_untyped64((mach_msg_body_t *) (msgh + 1));
376	}
377
378	ipc_msg_body_print64((void *)(msgh + 1), msgh->msgh_size);
379}
380
381
382const char *
383mm_copy_options_string64(
384	mach_msg_copy_options_t	option)
385{
386	const char	*name;
387
388	switch (option) {
389	    case MACH_MSG_PHYSICAL_COPY:
390		name = "PHYSICAL";
391		break;
392	    case MACH_MSG_VIRTUAL_COPY:
393		name = "VIRTUAL";
394		break;
395	    case MACH_MSG_OVERWRITE:
396		name = "OVERWRITE";
397		break;
398	    case MACH_MSG_ALLOCATE:
399		name = "ALLOCATE";
400		break;
401	    case MACH_MSG_KALLOC_COPY_T:
402		name = "KALLOC_COPY_T";
403		break;
404	    default:
405		name = "unknown";
406		break;
407	}
408	return name;
409}
410
411void
412ipc_msg_print_untyped64(
413	mach_msg_body_t		*body)
414{
415    mach_msg_descriptor_t	*saddr, *send;
416    mach_msg_descriptor_type_t	type;
417
418    kprintf("  %d descriptors: \n", body->msgh_descriptor_count);
419
420    saddr = (mach_msg_descriptor_t *) (body + 1);
421    send = saddr + body->msgh_descriptor_count;
422
423    for ( ; saddr < send; saddr++ ) {
424
425	type = saddr->type.type;
426
427	switch (type) {
428
429	    case MACH_MSG_PORT_DESCRIPTOR: {
430		mach_msg_port_descriptor_t *dsc;
431
432		dsc = &saddr->port;
433		kprintf("    PORT name = %p disp = ", dsc->name);
434		ipc_print_type_name64(dsc->disposition);
435		kprintf("\n");
436		break;
437	    }
438	    case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
439	    case MACH_MSG_OOL_DESCRIPTOR: {
440		mach_msg_ool_descriptor_t *dsc;
441
442		dsc = (mach_msg_ool_descriptor_t *) &saddr->out_of_line;
443		kprintf("    OOL%s addr = %p size = 0x%x copy = %s %s\n",
444			type == MACH_MSG_OOL_DESCRIPTOR ? "" : " VOLATILE",
445			dsc->address, dsc->size,
446			mm_copy_options_string64(dsc->copy),
447			dsc->deallocate ? "DEALLOC" : "");
448		break;
449	    }
450	    case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
451		mach_msg_ool_ports_descriptor_t *dsc;
452
453		dsc = (mach_msg_ool_ports_descriptor_t *) &saddr->ool_ports;
454
455		kprintf("    OOL_PORTS addr = %p count = 0x%x ",
456		          dsc->address, dsc->count);
457		kprintf("disp = ");
458		ipc_print_type_name64(dsc->disposition);
459		kprintf(" copy = %s %s\n",
460		       mm_copy_options_string64(dsc->copy),
461		       dsc->deallocate ? "DEALLOC" : "");
462		break;
463	    }
464
465	    default: {
466		kprintf("    UNKNOWN DESCRIPTOR 0x%x\n", type);
467		break;
468	    }
469	}
470    }
471}
472
473#define	DEBUG_IPC_KMSG_PRINT(kmsg,string)	\
474	if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) {	\
475		ipc_kmsg_print64(kmsg, string);	\
476	}
477#define	DEBUG_IPC_MSG_BODY_PRINT(body,size)	\
478	if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { 	\
479		ipc_msg_body_print64(body,size);\
480	}
481#else /* !DEBUG_MSGS_K64 */
482#define DEBUG_IPC_KMSG_PRINT(kmsg,string)
483#define	DEBUG_IPC_MSG_BODY_PRINT(body,size)
484#endif  /* !DEBUG_MSGS_K64 */
485
486extern vm_map_t		ipc_kernel_copy_map;
487extern vm_size_t	ipc_kmsg_max_space;
488extern vm_size_t	ipc_kmsg_max_vm_space;
489extern vm_size_t	ipc_kmsg_max_body_space;
490extern vm_size_t	msg_ool_size_small;
491
492#define MSG_OOL_SIZE_SMALL	msg_ool_size_small
493
494#if defined(__LP64__)
495#define MAP_SIZE_DIFFERS(map)	(map->max_offset < MACH_VM_MAX_ADDRESS)
496#define OTHER_OOL_DESCRIPTOR	mach_msg_ool_descriptor32_t
497#define OTHER_OOL_PORTS_DESCRIPTOR	mach_msg_ool_ports_descriptor32_t
498#else
499#define MAP_SIZE_DIFFERS(map)	(map->max_offset > VM_MAX_ADDRESS)
500#define OTHER_OOL_DESCRIPTOR	mach_msg_ool_descriptor64_t
501#define OTHER_OOL_PORTS_DESCRIPTOR	mach_msg_ool_ports_descriptor64_t
502#endif
503
504#define DESC_SIZE_ADJUSTMENT	((mach_msg_size_t)(sizeof(mach_msg_ool_descriptor64_t) - \
505				 sizeof(mach_msg_ool_descriptor32_t)))
506
507/* scatter list macros */
508
509#define SKIP_PORT_DESCRIPTORS(s, c)					\
510MACRO_BEGIN								\
511	if ((s) != MACH_MSG_DESCRIPTOR_NULL) {				\
512		while ((c) > 0) {					\
513			if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR)	\
514				break;					\
515			(s)++; (c)--;					\
516		}							\
517		if (c == 0)						\
518			(s) = MACH_MSG_DESCRIPTOR_NULL;			\
519	}								\
520MACRO_END
521
522#define INCREMENT_SCATTER(s, c, d)					\
523MACRO_BEGIN								\
524	if ((s) != MACH_MSG_DESCRIPTOR_NULL) {				\
525	    s = (d) ? (mach_msg_descriptor_t *)				\
526		((OTHER_OOL_DESCRIPTOR *)(s) + 1) :			\
527		(s + 1);						\
528		(c)--;							\
529	}								\
530MACRO_END
531
532/* zone for cached ipc_kmsg_t structures */
533zone_t			ipc_kmsg_zone;
534
535/*
536 * Forward declarations
537 */
538
539void ipc_kmsg_clean(
540	ipc_kmsg_t	kmsg);
541
542void ipc_kmsg_clean_body(
543    	ipc_kmsg_t	kmsg,
544    	mach_msg_type_number_t	number,
545	mach_msg_descriptor_t	*desc);
546
547void ipc_kmsg_clean_partial(
548	ipc_kmsg_t		kmsg,
549	mach_msg_type_number_t	number,
550	mach_msg_descriptor_t	*desc,
551	vm_offset_t		paddr,
552	vm_size_t		length);
553
554mach_msg_return_t ipc_kmsg_copyin_body(
555	ipc_kmsg_t		kmsg,
556	ipc_space_t		space,
557	vm_map_t		map);
558
559/*
560 *	We keep a per-processor cache of kernel message buffers.
561 *	The cache saves the overhead/locking of using kalloc/kfree.
562 *	The per-processor cache seems to miss less than a per-thread cache,
563 *	and it also uses less memory.  Access to the cache doesn't
564 *	require locking.
565 */
566
567/*
568 *	Routine:	ipc_kmsg_alloc
569 *	Purpose:
570 *		Allocate a kernel message structure.  If we can get one from
571 *		the cache, that is best.  Otherwise, allocate a new one.
572 *	Conditions:
573 *		Nothing locked.
574 */
575ipc_kmsg_t
576ipc_kmsg_alloc(
577	mach_msg_size_t msg_and_trailer_size)
578{
579	mach_msg_size_t max_expanded_size;
580	ipc_kmsg_t kmsg;
581
582	/*
583	 * LP64support -
584	 * Pad the allocation in case we need to expand the
585	 * message descrptors for user spaces with pointers larger than
586	 * the kernel's own, or vice versa.  We don't know how many descriptors
587	 * there are yet, so just assume the whole body could be
588	 * descriptors (if there could be any at all).
589	 *
590	 * The expansion space is left in front of the header,
591	 * because it is easier to pull the header and descriptors
592	 * forward as we process them than it is to push all the
593	 * data backwards.
594	 */
595	mach_msg_size_t size = msg_and_trailer_size - MAX_TRAILER_SIZE;
596
597	/* compare against implementation upper limit for the body */
598	if (size > ipc_kmsg_max_body_space)
599		return IKM_NULL;
600
601	if (size > sizeof(mach_msg_base_t)) {
602		mach_msg_size_t max_desc = (mach_msg_size_t)(((size - sizeof(mach_msg_base_t)) /
603				           sizeof(mach_msg_ool_descriptor32_t)) *
604				           DESC_SIZE_ADJUSTMENT);
605
606		/* make sure expansion won't cause wrap */
607		if (msg_and_trailer_size > MACH_MSG_SIZE_MAX - max_desc)
608			return IKM_NULL;
609
610		max_expanded_size = msg_and_trailer_size + max_desc;
611	} else
612		max_expanded_size = msg_and_trailer_size;
613
614	if (max_expanded_size < IKM_SAVED_MSG_SIZE)
615		max_expanded_size = IKM_SAVED_MSG_SIZE; 	/* round up for ikm_cache */
616
617	if (max_expanded_size == IKM_SAVED_MSG_SIZE) {
618		struct ikm_cache	*cache;
619		unsigned int		i;
620
621		disable_preemption();
622		cache = &PROCESSOR_DATA(current_processor(), ikm_cache);
623		if ((i = cache->avail) > 0) {
624			assert(i <= IKM_STASH);
625			kmsg = cache->entries[--i];
626			cache->avail = i;
627			enable_preemption();
628			ikm_check_init(kmsg, max_expanded_size);
629			ikm_set_header(kmsg, msg_and_trailer_size);
630			return (kmsg);
631		}
632		enable_preemption();
633		kmsg = (ipc_kmsg_t)zalloc(ipc_kmsg_zone);
634	} else {
635		kmsg = (ipc_kmsg_t)kalloc(ikm_plus_overhead(max_expanded_size));
636	}
637
638	if (kmsg != IKM_NULL) {
639		ikm_init(kmsg, max_expanded_size);
640		ikm_set_header(kmsg, msg_and_trailer_size);
641	}
642
643	return(kmsg);
644}
645
646/*
647 *	Routine:	ipc_kmsg_free
648 *	Purpose:
649 *		Free a kernel message buffer.  If the kms is preallocated
650 *		to a port, just "put it back (marked unused)."  We have to
651 *		do this with the port locked.  The port may have its hold
652 *		on our message released.  In that case, we have to just
653 *		revert the message to a traditional one and free it normally.
654 *	Conditions:
655 *		Nothing locked.
656 */
657
658void
659ipc_kmsg_free(
660	ipc_kmsg_t	kmsg)
661{
662	mach_msg_size_t size = kmsg->ikm_size;
663	ipc_port_t port;
664
665#if CONFIG_MACF_MACH
666	if (kmsg->ikm_sender != NULL) {
667		task_deallocate(kmsg->ikm_sender);
668		kmsg->ikm_sender = NULL;
669	}
670#endif
671
672	/*
673	 * Check to see if the message is bound to the port.  If so,
674	 * mark it not in use.  If the port isn't already dead, then
675	 * leave the message associated with it.  Otherwise, free it.
676	 */
677	port = ikm_prealloc_inuse_port(kmsg);
678	if (port != IP_NULL) {
679		ip_lock(port);
680		ikm_prealloc_clear_inuse(kmsg, port);
681		if (ip_active(port) && (port->ip_premsg == kmsg)) {
682			assert(IP_PREALLOC(port));
683			ip_unlock(port);
684			ip_release(port);
685			return;
686		}
687                ip_unlock(port);
688		ip_release(port); /* May be last reference */
689	}
690
691	/*
692	 * Peek and see if it has to go back in the cache.
693	 */
694	if (kmsg->ikm_size == IKM_SAVED_MSG_SIZE) {
695		struct ikm_cache	*cache;
696		unsigned int		i;
697
698		disable_preemption();
699		cache = &PROCESSOR_DATA(current_processor(), ikm_cache);
700		if ((i = cache->avail) < IKM_STASH) {
701			cache->entries[i] = kmsg;
702			cache->avail = i + 1;
703			enable_preemption();
704			return;
705		}
706		enable_preemption();
707		zfree(ipc_kmsg_zone, kmsg);
708		return;
709	}
710	kfree(kmsg, ikm_plus_overhead(size));
711}
712
713
714/*
715 *	Routine:	ipc_kmsg_enqueue
716 *	Purpose:
717 *		Enqueue a kmsg.
718 */
719
720void
721ipc_kmsg_enqueue(
722	ipc_kmsg_queue_t	queue,
723	ipc_kmsg_t		kmsg)
724{
725	ipc_kmsg_enqueue_macro(queue, kmsg);
726}
727
728/*
729 *	Routine:	ipc_kmsg_dequeue
730 *	Purpose:
731 *		Dequeue and return a kmsg.
732 */
733
734ipc_kmsg_t
735ipc_kmsg_dequeue(
736	ipc_kmsg_queue_t	queue)
737{
738	ipc_kmsg_t first;
739
740	first = ipc_kmsg_queue_first(queue);
741
742	if (first != IKM_NULL)
743		ipc_kmsg_rmqueue_first_macro(queue, first);
744
745	return first;
746}
747
748/*
749 *	Routine:	ipc_kmsg_rmqueue
750 *	Purpose:
751 *		Pull a kmsg out of a queue.
752 */
753
754void
755ipc_kmsg_rmqueue(
756	ipc_kmsg_queue_t	queue,
757	ipc_kmsg_t		kmsg)
758{
759	ipc_kmsg_t next, prev;
760
761	assert(queue->ikmq_base != IKM_NULL);
762
763	next = kmsg->ikm_next;
764	prev = kmsg->ikm_prev;
765
766	if (next == kmsg) {
767		assert(prev == kmsg);
768		assert(queue->ikmq_base == kmsg);
769
770		queue->ikmq_base = IKM_NULL;
771	} else {
772		if (queue->ikmq_base == kmsg)
773			queue->ikmq_base = next;
774
775		next->ikm_prev = prev;
776		prev->ikm_next = next;
777	}
778	/* XXX Temporary debug logic */
779	assert((kmsg->ikm_next = IKM_BOGUS) == IKM_BOGUS);
780	assert((kmsg->ikm_prev = IKM_BOGUS) == IKM_BOGUS);
781}
782
783/*
784 *	Routine:	ipc_kmsg_queue_next
785 *	Purpose:
786 *		Return the kmsg following the given kmsg.
787 *		(Or IKM_NULL if it is the last one in the queue.)
788 */
789
790ipc_kmsg_t
791ipc_kmsg_queue_next(
792	ipc_kmsg_queue_t	queue,
793	ipc_kmsg_t		kmsg)
794{
795	ipc_kmsg_t next;
796
797	assert(queue->ikmq_base != IKM_NULL);
798
799	next = kmsg->ikm_next;
800	if (queue->ikmq_base == next)
801		next = IKM_NULL;
802
803	return next;
804}
805
806/*
807 *	Routine:	ipc_kmsg_destroy
808 *	Purpose:
809 *		Destroys a kernel message.  Releases all rights,
810 *		references, and memory held by the message.
811 *		Frees the message.
812 *	Conditions:
813 *		No locks held.
814 */
815
816void
817ipc_kmsg_destroy(
818	ipc_kmsg_t	kmsg)
819{
820	/*
821	 *	Destroying a message can cause more messages to be destroyed.
822	 *	Curtail recursion by putting messages on the deferred
823	 *	destruction queue.  If this was the first message on the
824	 *	queue, this instance must process the full queue.
825	 */
826	if (ipc_kmsg_delayed_destroy(kmsg))
827		ipc_kmsg_reap_delayed();
828}
829
830/*
831 *	Routine:	ipc_kmsg_delayed_destroy
832 *	Purpose:
833 *		Enqueues a kernel message for deferred destruction.
834 *	Returns:
835 *		Boolean indicator that the caller is responsible to reap
836 *		deferred messages.
837 */
838
839boolean_t ipc_kmsg_delayed_destroy(
840	ipc_kmsg_t kmsg)
841{
842	ipc_kmsg_queue_t queue = &(current_thread()->ith_messages);
843	boolean_t first = ipc_kmsg_queue_empty(queue);
844
845	ipc_kmsg_enqueue(queue, kmsg);
846	return first;
847}
848
849/*
850 *	Routine:	ipc_kmsg_destroy_queue
851 *	Purpose:
852 *		Destroys messages from the per-thread
853 *		deferred reaping queue.
854 *	Conditions:
855 *		No locks held.
856 */
857
858void
859ipc_kmsg_reap_delayed(void)
860{
861	ipc_kmsg_queue_t queue = &(current_thread()->ith_messages);
862	ipc_kmsg_t kmsg;
863
864	/*
865	 * must leave kmsg in queue while cleaning it to assure
866	 * no nested calls recurse into here.
867	 */
868	while ((kmsg = ipc_kmsg_queue_first(queue)) != IKM_NULL) {
869		ipc_kmsg_clean(kmsg);
870		ipc_kmsg_rmqueue(queue, kmsg);
871		ipc_kmsg_free(kmsg);
872	}
873}
874
875/*
876 *	Routine:	ipc_kmsg_clean_body
877 *	Purpose:
878 *		Cleans the body of a kernel message.
879 *		Releases all rights, references, and memory.
880 *
881 *	Conditions:
882 *		No locks held.
883 */
884static unsigned int _ipc_kmsg_clean_invalid_desc = 0;
885void
886ipc_kmsg_clean_body(
887	__unused ipc_kmsg_t	kmsg,
888	mach_msg_type_number_t	number,
889	mach_msg_descriptor_t	*saddr)
890{
891    mach_msg_type_number_t	i;
892
893    if ( number == 0 )
894	return;
895
896    for (i = 0 ; i < number; i++, saddr++ ) {
897
898	switch (saddr->type.type) {
899
900	    case MACH_MSG_PORT_DESCRIPTOR: {
901		mach_msg_port_descriptor_t *dsc;
902
903		dsc = &saddr->port;
904
905		/*
906		 * Destroy port rights carried in the message
907		 */
908		if (!IO_VALID((ipc_object_t) dsc->name))
909		    continue;
910		ipc_object_destroy((ipc_object_t) dsc->name, dsc->disposition);
911		break;
912	    }
913	    case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
914	    case MACH_MSG_OOL_DESCRIPTOR : {
915		mach_msg_ool_descriptor_t *dsc;
916
917		dsc = (mach_msg_ool_descriptor_t *)&saddr->out_of_line;
918
919		/*
920		 * Destroy memory carried in the message
921		 */
922		if (dsc->size == 0) {
923			assert(dsc->address == (void *) 0);
924		} else {
925		    	vm_map_copy_discard((vm_map_copy_t) dsc->address);
926		}
927		break;
928	    }
929	    case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
930		ipc_object_t             	*objects;
931		mach_msg_type_number_t   	j;
932		mach_msg_ool_ports_descriptor_t	*dsc;
933
934		dsc = (mach_msg_ool_ports_descriptor_t	*)&saddr->ool_ports;
935		objects = (ipc_object_t *) dsc->address;
936
937		if (dsc->count == 0) {
938			break;
939		}
940
941		assert(objects != (ipc_object_t *) 0);
942
943		/* destroy port rights carried in the message */
944
945		for (j = 0; j < dsc->count; j++) {
946		    ipc_object_t object = objects[j];
947
948		    if (!IO_VALID(object))
949			continue;
950
951		    ipc_object_destroy(object, dsc->disposition);
952		}
953
954		/* destroy memory carried in the message */
955
956		assert(dsc->count != 0);
957
958		kfree(dsc->address,
959		     (vm_size_t) dsc->count * sizeof(mach_port_t));
960		break;
961	    }
962	    default : {
963		    _ipc_kmsg_clean_invalid_desc++; /* don't understand this type of descriptor */
964	    }
965	}
966    }
967}
968
969/*
970 *	Routine:	ipc_kmsg_clean_partial
971 *	Purpose:
972 *		Cleans a partially-acquired kernel message.
973 *		number is the index of the type descriptor
974 *		in the body of the message that contained the error.
975 *		If dolast, the memory and port rights in this last
976 *		type spec are also cleaned.  In that case, number
977 *		specifies the number of port rights to clean.
978 *	Conditions:
979 *		Nothing locked.
980 */
981
982void
983ipc_kmsg_clean_partial(
984	ipc_kmsg_t		kmsg,
985	mach_msg_type_number_t	number,
986	mach_msg_descriptor_t	*desc,
987	vm_offset_t		paddr,
988	vm_size_t		length)
989{
990	ipc_object_t object;
991	mach_msg_bits_t mbits = kmsg->ikm_header->msgh_bits;
992
993	object = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
994	assert(IO_VALID(object));
995	ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits));
996
997	object = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
998	if (IO_VALID(object))
999		ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
1000
1001	if (paddr) {
1002		(void) vm_deallocate(ipc_kernel_copy_map, paddr, length);
1003	}
1004
1005	ipc_kmsg_clean_body(kmsg, number, desc);
1006}
1007
1008/*
1009 *	Routine:	ipc_kmsg_clean
1010 *	Purpose:
1011 *		Cleans a kernel message.  Releases all rights,
1012 *		references, and memory held by the message.
1013 *	Conditions:
1014 *		No locks held.
1015 */
1016
1017void
1018ipc_kmsg_clean(
1019	ipc_kmsg_t	kmsg)
1020{
1021	ipc_object_t object;
1022	mach_msg_bits_t mbits;
1023
1024	mbits = kmsg->ikm_header->msgh_bits;
1025	object = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
1026	if (IO_VALID(object))
1027		ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits));
1028
1029	object = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
1030	if (IO_VALID(object))
1031		ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
1032
1033	if (mbits & MACH_MSGH_BITS_COMPLEX) {
1034		mach_msg_body_t *body;
1035
1036		body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
1037		ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count,
1038				    (mach_msg_descriptor_t *)(body + 1));
1039	}
1040
1041#if CONFIG_MACF_MACH
1042	if (kmsg->ikm_sender != NULL) {
1043		task_deallocate(kmsg->ikm_sender);
1044		kmsg->ikm_sender = NULL;
1045	}
1046#endif
1047}
1048
1049/*
1050 *	Routine:	ipc_kmsg_set_prealloc
1051 *	Purpose:
1052 *		Assign a kmsg as a preallocated message buffer to a port.
1053 *	Conditions:
1054 *		port locked.
1055 */
1056
1057void
1058ipc_kmsg_set_prealloc(
1059	ipc_kmsg_t		kmsg,
1060	ipc_port_t		port)
1061{
1062	assert(kmsg->ikm_prealloc == IP_NULL);
1063
1064	kmsg->ikm_prealloc = IP_NULL;
1065	IP_SET_PREALLOC(port, kmsg);
1066}
1067
1068/*
1069 *	Routine:	ipc_kmsg_clear_prealloc
1070 *	Purpose:
1071 *		Release the Assignment of a preallocated message buffer from a port.
1072 *	Conditions:
1073 *		port locked.
1074 */
1075void
1076ipc_kmsg_clear_prealloc(
1077	ipc_kmsg_t		kmsg,
1078	ipc_port_t		port)
1079{
1080	assert(kmsg->ikm_prealloc == port);
1081
1082	kmsg->ikm_prealloc = IP_NULL;
1083	IP_CLEAR_PREALLOC(port, kmsg);
1084}
1085
1086/*
1087 *	Routine:	ipc_kmsg_prealloc
1088 *	Purpose:
1089 *		Wraper to ipc_kmsg_alloc() to account for
1090 *		header expansion requirements.
1091 */
1092ipc_kmsg_t
1093ipc_kmsg_prealloc(mach_msg_size_t size)
1094{
1095#if defined(__LP64__)
1096	if (size > MACH_MSG_SIZE_MAX - LEGACY_HEADER_SIZE_DELTA)
1097		return IKM_NULL;
1098
1099	size += LEGACY_HEADER_SIZE_DELTA;
1100#endif
1101	return ipc_kmsg_alloc(size);
1102}
1103
1104
1105/*
1106 *	Routine:	ipc_kmsg_get
1107 *	Purpose:
1108 *		Allocates a kernel message buffer.
1109 *		Copies a user message to the message buffer.
1110 *	Conditions:
1111 *		Nothing locked.
1112 *	Returns:
1113 *		MACH_MSG_SUCCESS	Acquired a message buffer.
1114 *		MACH_SEND_MSG_TOO_SMALL	Message smaller than a header.
1115 *		MACH_SEND_MSG_TOO_SMALL	Message size not long-word multiple.
1116 *		MACH_SEND_TOO_LARGE	Message too large to ever be sent.
1117 *		MACH_SEND_NO_BUFFER	Couldn't allocate a message buffer.
1118 *		MACH_SEND_INVALID_DATA	Couldn't copy message data.
1119 */
1120
1121mach_msg_return_t
1122ipc_kmsg_get(
1123	mach_vm_address_t	msg_addr,
1124	mach_msg_size_t	size,
1125	ipc_kmsg_t		*kmsgp)
1126{
1127	mach_msg_size_t			msg_and_trailer_size;
1128	ipc_kmsg_t 			kmsg;
1129	mach_msg_max_trailer_t	 	*trailer;
1130	mach_msg_legacy_base_t	    legacy_base;
1131	mach_msg_size_t             len_copied;
1132	legacy_base.body.msgh_descriptor_count = 0;
1133
1134	if ((size < sizeof(mach_msg_legacy_header_t)) || (size & 3))
1135		return MACH_SEND_MSG_TOO_SMALL;
1136
1137	if (size > ipc_kmsg_max_body_space)
1138		return MACH_SEND_TOO_LARGE;
1139
1140	if(size == sizeof(mach_msg_legacy_header_t))
1141		len_copied = sizeof(mach_msg_legacy_header_t);
1142	else
1143		len_copied = sizeof(mach_msg_legacy_base_t);
1144
1145	if (copyinmsg(msg_addr, (char *)&legacy_base, len_copied))
1146		return MACH_SEND_INVALID_DATA;
1147
1148	msg_addr += sizeof(legacy_base.header);
1149#if defined(__LP64__)
1150	size += LEGACY_HEADER_SIZE_DELTA;
1151#endif
1152	if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) {
1153		unsigned int j;
1154		for (j=0; j<sizeof(legacy_base.header); j++) {
1155			kprintf("%02x\n", ((unsigned char*)&legacy_base.header)[j]);
1156		}
1157	}
1158
1159	msg_and_trailer_size = size + MAX_TRAILER_SIZE;
1160	kmsg = ipc_kmsg_alloc(msg_and_trailer_size);
1161	if (kmsg == IKM_NULL)
1162		return MACH_SEND_NO_BUFFER;
1163
1164	kmsg->ikm_header->msgh_size			= size;
1165	kmsg->ikm_header->msgh_bits			= legacy_base.header.msgh_bits;
1166	kmsg->ikm_header->msgh_remote_port	= CAST_MACH_NAME_TO_PORT(legacy_base.header.msgh_remote_port);
1167	kmsg->ikm_header->msgh_local_port	= CAST_MACH_NAME_TO_PORT(legacy_base.header.msgh_local_port);
1168	kmsg->ikm_header->msgh_reserved		= legacy_base.header.msgh_reserved;
1169	kmsg->ikm_header->msgh_id			= legacy_base.header.msgh_id;
1170
1171	DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_get header:\n"
1172							 "  size:		0x%.8x\n"
1173							 "  bits:		0x%.8x\n"
1174							 "  remote_port:	%p\n"
1175							 "  local_port:	%p\n"
1176							 "  reserved:	0x%.8x\n"
1177							 "  id:		%.8d\n",
1178							 kmsg->ikm_header->msgh_size,
1179							 kmsg->ikm_header->msgh_bits,
1180							 kmsg->ikm_header->msgh_remote_port,
1181							 kmsg->ikm_header->msgh_local_port,
1182							 kmsg->ikm_header->msgh_reserved,
1183							 kmsg->ikm_header->msgh_id);
1184
1185	if (copyinmsg(msg_addr, (char *)(kmsg->ikm_header + 1), size - (mach_msg_size_t)sizeof(mach_msg_header_t))) {
1186		ipc_kmsg_free(kmsg);
1187		return MACH_SEND_INVALID_DATA;
1188	}
1189
1190	if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK))
1191	{
1192		kprintf("body: size: %lu\n", (size - sizeof(mach_msg_header_t)));
1193		uint32_t i;
1194		for(i=0;i*4 < (size - sizeof(mach_msg_header_t));i++)
1195		{
1196			kprintf("%.4x\n",((uint32_t *)(kmsg->ikm_header + 1))[i]);
1197		}
1198	}
1199	DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_get()");
1200
1201	/*
1202	 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
1203	 * However, the internal size field of the trailer (msgh_trailer_size)
1204	 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
1205	 * the cases where no implicit data is requested.
1206	 */
1207	trailer = (mach_msg_max_trailer_t *) ((vm_offset_t)kmsg->ikm_header + size);
1208	trailer->msgh_sender = current_thread()->task->sec_token;
1209	trailer->msgh_audit = current_thread()->task->audit_token;
1210	trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
1211	trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
1212
1213#ifdef ppc
1214	if(trcWork.traceMask) dbgTrace(0x1100, (unsigned int)kmsg->ikm_header->msgh_id,
1215		(unsigned int)kmsg->ikm_header->msgh_remote_port,
1216		(unsigned int)kmsg->ikm_header->msgh_local_port, 0);
1217#endif
1218
1219#if CONFIG_MACF_MACH
1220	/* XXX - why do we zero sender labels here instead of in mach_msg()? */
1221	task_t cur = current_task();
1222	if (cur) {
1223		task_reference(cur);
1224		kmsg->ikm_sender = cur;
1225	} else
1226		trailer->msgh_labels.sender = 0;
1227#else
1228	trailer->msgh_labels.sender = 0;
1229#endif
1230
1231	*kmsgp = kmsg;
1232	return MACH_MSG_SUCCESS;
1233}
1234
1235/*
1236 *	Routine:	ipc_kmsg_get_from_kernel
1237 *	Purpose:
1238 *		First checks for a preallocated message
1239 *		reserved for kernel clients.  If not found -
1240 *		allocates a new kernel message buffer.
1241 *		Copies a kernel message to the message buffer.
1242 *		Only resource errors are allowed.
1243 *	Conditions:
1244 *		Nothing locked.
1245 *		Ports in header are ipc_port_t.
1246 *	Returns:
1247 *		MACH_MSG_SUCCESS	Acquired a message buffer.
1248 *		MACH_SEND_NO_BUFFER	Couldn't allocate a message buffer.
1249 */
1250
1251mach_msg_return_t
1252ipc_kmsg_get_from_kernel(
1253	mach_msg_header_t	*msg,
1254	mach_msg_size_t	size,
1255	ipc_kmsg_t		*kmsgp)
1256{
1257	ipc_kmsg_t 	kmsg;
1258	mach_msg_size_t	msg_and_trailer_size;
1259	mach_msg_max_trailer_t *trailer;
1260	ipc_port_t	dest_port;
1261
1262	assert(size >= sizeof(mach_msg_header_t));
1263	assert((size & 3) == 0);
1264
1265	dest_port = (ipc_port_t)msg->msgh_remote_port;
1266
1267	msg_and_trailer_size = size + MAX_TRAILER_SIZE;
1268
1269	/*
1270	 * See if the port has a pre-allocated kmsg for kernel
1271	 * clients.  These are set up for those kernel clients
1272	 * which cannot afford to wait.
1273	 */
1274	if (IP_VALID(dest_port) && IP_PREALLOC(dest_port)) {
1275		mach_msg_size_t max_desc = 0;
1276
1277		ip_lock(dest_port);
1278		if (!ip_active(dest_port)) {
1279			ip_unlock(dest_port);
1280			return MACH_SEND_NO_BUFFER;
1281		}
1282		assert(IP_PREALLOC(dest_port));
1283		kmsg = dest_port->ip_premsg;
1284		if (ikm_prealloc_inuse(kmsg)) {
1285			ip_unlock(dest_port);
1286			return MACH_SEND_NO_BUFFER;
1287		}
1288#if !defined(__LP64__)
1289		if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
1290			assert(size > sizeof(mach_msg_base_t));
1291			max_desc = ((mach_msg_base_t *)msg)->body.msgh_descriptor_count *
1292				DESC_SIZE_ADJUSTMENT;
1293		}
1294#endif
1295		if (msg_and_trailer_size > kmsg->ikm_size - max_desc) {
1296			ip_unlock(dest_port);
1297			return MACH_SEND_TOO_LARGE;
1298		}
1299		ikm_prealloc_set_inuse(kmsg, dest_port);
1300		ikm_set_header(kmsg, msg_and_trailer_size);
1301		ip_unlock(dest_port);
1302	}
1303	else
1304	{
1305		kmsg = ipc_kmsg_alloc(msg_and_trailer_size);
1306		if (kmsg == IKM_NULL)
1307			return MACH_SEND_NO_BUFFER;
1308	}
1309
1310	(void) memcpy((void *) kmsg->ikm_header, (const void *) msg, size);
1311
1312	kmsg->ikm_header->msgh_size = size;
1313
1314	/*
1315	 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
1316	 * However, the internal size field of the trailer (msgh_trailer_size)
1317	 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
1318	 * optimize the cases where no implicit data is requested.
1319	 */
1320	trailer = (mach_msg_max_trailer_t *)
1321	          ((vm_offset_t)kmsg->ikm_header + size);
1322	trailer->msgh_sender = KERNEL_SECURITY_TOKEN;
1323	trailer->msgh_audit = KERNEL_AUDIT_TOKEN;
1324	trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
1325	trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
1326
1327	trailer->msgh_labels.sender = 0;
1328
1329#if CONFIG_MACF_MACH
1330	kmsg->ikm_sender = NULL;
1331#endif
1332	*kmsgp = kmsg;
1333	return MACH_MSG_SUCCESS;
1334}
1335
1336/*
1337 *	Routine:	ipc_kmsg_send
1338 *	Purpose:
1339 *		Send a message.  The message holds a reference
1340 *		for the destination port in the msgh_remote_port field.
1341 *
1342 *		If unsuccessful, the caller still has possession of
1343 *		the message and must do something with it.  If successful,
1344 *		the message is queued, given to a receiver, destroyed,
1345 *		or handled directly by the kernel via mach_msg.
1346 *	Conditions:
1347 *		Nothing locked.
1348 *	Returns:
1349 *		MACH_MSG_SUCCESS	The message was accepted.
1350 *		MACH_SEND_TIMED_OUT	Caller still has message.
1351 *		MACH_SEND_INTERRUPTED	Caller still has message.
1352 *		MACH_SEND_INVALID_DEST	Caller still has message.
1353 */
1354mach_msg_return_t
1355ipc_kmsg_send(
1356	ipc_kmsg_t		kmsg,
1357	mach_msg_option_t	option,
1358	mach_msg_timeout_t	send_timeout)
1359{
1360	ipc_port_t port;
1361	mach_msg_return_t error = MACH_MSG_SUCCESS;
1362	spl_t s;
1363
1364	port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port;
1365	assert(IP_VALID(port));
1366
1367	ip_lock(port);
1368
1369	if (port->ip_receiver == ipc_space_kernel) {
1370
1371		/*
1372		 *	We can check ip_receiver == ipc_space_kernel
1373		 *	before checking that the port is active because
1374		 *	ipc_port_dealloc_kernel clears ip_receiver
1375		 *	before destroying a kernel port.
1376		 */
1377		assert(ip_active(port));
1378		port->ip_messages.imq_seqno++;
1379		ip_unlock(port);
1380
1381		current_task()->messages_sent++;
1382
1383		/*
1384		 * Call the server routine, and get the reply message to send.
1385		 */
1386		kmsg = ipc_kobject_server(kmsg);
1387		if (kmsg == IKM_NULL)
1388			return MACH_MSG_SUCCESS;
1389
1390		port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port;
1391		assert(IP_VALID(port));
1392		ip_lock(port);
1393		/* fall thru with reply - same options */
1394	}
1395
1396	/*
1397	 *	Can't deliver to a dead port.
1398	 *	However, we can pretend it got sent
1399	 *	and was then immediately destroyed.
1400	 */
1401	if (!ip_active(port)) {
1402		/*
1403		 *	We can't let ipc_kmsg_destroy deallocate
1404		 *	the port right, because we might end up
1405		 *	in an infinite loop trying to deliver
1406		 *	a send-once notification.
1407		 */
1408		ip_unlock(port);
1409		ip_release(port);
1410		kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
1411		ipc_kmsg_destroy(kmsg);
1412		return MACH_MSG_SUCCESS;
1413	}
1414
1415	if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_CIRCULAR) {
1416		ip_unlock(port);
1417
1418		/* don't allow the creation of a circular loop */
1419
1420		ipc_kmsg_destroy(kmsg);
1421		return MACH_MSG_SUCCESS;
1422	}
1423
1424	/*
1425	 * We have a valid message and a valid reference on the port.
1426	 * we can unlock the port and call mqueue_send() on its message
1427	 * queue. Lock message queue while port is locked.
1428	 */
1429	s = splsched();
1430	imq_lock(&port->ip_messages);
1431	ip_unlock(port);
1432	error = ipc_mqueue_send(&port->ip_messages, kmsg, option,
1433			send_timeout, s);
1434
1435	/*
1436	 * If the port has been destroyed while we wait, treat the message
1437	 * as a successful delivery (like we do for an inactive port).
1438	 */
1439	if (error == MACH_SEND_INVALID_DEST) {
1440		kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
1441		ipc_kmsg_destroy(kmsg);
1442		return MACH_MSG_SUCCESS;
1443	}
1444	return error;
1445}
1446
1447/*
1448 *	Routine:	ipc_kmsg_put
1449 *	Purpose:
1450 *		Copies a message buffer to a user message.
1451 *		Copies only the specified number of bytes.
1452 *		Frees the message buffer.
1453 *	Conditions:
1454 *		Nothing locked.  The message buffer must have clean
1455 *		header fields.
1456 *	Returns:
1457 *		MACH_MSG_SUCCESS	Copied data out of message buffer.
1458 *		MACH_RCV_INVALID_DATA	Couldn't copy to user message.
1459 */
1460
1461mach_msg_return_t
1462ipc_kmsg_put(
1463	mach_vm_address_t	msg_addr,
1464	ipc_kmsg_t		kmsg,
1465	mach_msg_size_t		size)
1466{
1467	mach_msg_return_t mr;
1468
1469	DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_put()");
1470
1471	DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_put header:\n"
1472							 "  size:		0x%.8x\n"
1473							 "  bits:		0x%.8x\n"
1474							 "  remote_port:	%p\n"
1475							 "  local_port:	%p\n"
1476							 "  reserved:	0x%.8x\n"
1477							 "  id:		%.8d\n",
1478							 kmsg->ikm_header->msgh_size,
1479							 kmsg->ikm_header->msgh_bits,
1480							 kmsg->ikm_header->msgh_remote_port,
1481							 kmsg->ikm_header->msgh_local_port,
1482							 kmsg->ikm_header->msgh_reserved,
1483							 kmsg->ikm_header->msgh_id);
1484
1485#if defined(__LP64__)
1486	if (current_task() != kernel_task) { /* don't if receiver expects fully-cooked in-kernel msg; ux_exception */
1487		mach_msg_legacy_header_t *legacy_header =
1488			(mach_msg_legacy_header_t *)((vm_offset_t)(kmsg->ikm_header) + LEGACY_HEADER_SIZE_DELTA);
1489
1490		mach_msg_bits_t		bits		= kmsg->ikm_header->msgh_bits;
1491		mach_msg_size_t		msg_size	= kmsg->ikm_header->msgh_size;
1492		mach_port_name_t	remote_port	= CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_remote_port);
1493		mach_port_name_t	local_port	= CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_local_port);
1494		mach_msg_size_t 	reserved	= kmsg->ikm_header->msgh_reserved;
1495		mach_msg_id_t		id			= kmsg->ikm_header->msgh_id;
1496
1497		legacy_header->msgh_id			= id;
1498		legacy_header->msgh_reserved	= reserved;
1499		legacy_header->msgh_local_port	= local_port;
1500		legacy_header->msgh_remote_port	= remote_port;
1501		legacy_header->msgh_size		= msg_size - LEGACY_HEADER_SIZE_DELTA;
1502		legacy_header->msgh_bits		= bits;
1503
1504		size -= LEGACY_HEADER_SIZE_DELTA;
1505		kmsg->ikm_header = (mach_msg_header_t *)legacy_header;
1506	}
1507#endif
1508
1509	if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) {
1510		kprintf("ipc_kmsg_put header+body: %d\n", (size));
1511		uint32_t i;
1512		for(i=0;i*4 < size;i++)
1513		{
1514			kprintf("%.4x\n",((uint32_t *)kmsg->ikm_header)[i]);
1515		}
1516		kprintf("type: %d\n", ((mach_msg_type_descriptor_t *)(((mach_msg_base_t *)kmsg->ikm_header)+1))->type);
1517	}
1518	if (copyoutmsg((const char *) kmsg->ikm_header, msg_addr, size))
1519		mr = MACH_RCV_INVALID_DATA;
1520	else
1521		mr = MACH_MSG_SUCCESS;
1522
1523	ipc_kmsg_free(kmsg);
1524	return mr;
1525}
1526
1527/*
1528 *	Routine:	ipc_kmsg_put_to_kernel
1529 *	Purpose:
1530 *		Copies a message buffer to a kernel message.
1531 *		Frees the message buffer.
1532 *		No errors allowed.
1533 *	Conditions:
1534 *		Nothing locked.
1535 */
1536
1537void
1538ipc_kmsg_put_to_kernel(
1539	mach_msg_header_t	*msg,
1540	ipc_kmsg_t		kmsg,
1541	mach_msg_size_t		size)
1542{
1543	(void) memcpy((void *) msg, (const void *) kmsg->ikm_header, size);
1544
1545	ipc_kmsg_free(kmsg);
1546}
1547
1548/*
1549 *	Routine:	ipc_kmsg_copyin_header
1550 *	Purpose:
1551 *		"Copy-in" port rights in the header of a message.
1552 *		Operates atomically; if it doesn't succeed the
1553 *		message header and the space are left untouched.
1554 *		If it does succeed the remote/local port fields
1555 *		contain object pointers instead of port names,
1556 *		and the bits field is updated.  The destination port
1557 *		will be a valid port pointer.
1558 *
1559 *	Conditions:
1560 *		Nothing locked.
1561 *	Returns:
1562 *		MACH_MSG_SUCCESS	Successful copyin.
1563 *		MACH_SEND_INVALID_HEADER
1564 *			Illegal value in the message header bits.
1565 *		MACH_SEND_INVALID_DEST	The space is dead.
1566 *		MACH_SEND_INVALID_DEST	Can't copyin destination port.
1567 *			(Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1568 *		MACH_SEND_INVALID_REPLY	Can't copyin reply port.
1569 *			(Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1570 */
1571
1572mach_msg_return_t
1573ipc_kmsg_copyin_header(
1574	mach_msg_header_t	*msg,
1575	ipc_space_t		space,
1576	boolean_t		notify)
1577{
1578	mach_msg_bits_t mbits = msg->msgh_bits & MACH_MSGH_BITS_USER;
1579	mach_port_name_t dest_name = CAST_MACH_PORT_TO_NAME(msg->msgh_remote_port);
1580	mach_port_name_t reply_name = CAST_MACH_PORT_TO_NAME(msg->msgh_local_port);
1581	kern_return_t kr;
1582
1583	mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
1584	mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
1585	ipc_object_t dest_port, reply_port;
1586	ipc_entry_t dest_entry, reply_entry;
1587	ipc_port_t dest_soright, reply_soright;
1588	ipc_port_t release_port = IP_NULL;
1589
1590	queue_head_t links_data;
1591	queue_t links = &links_data;
1592	wait_queue_link_t wql;
1593
1594	queue_init(links);
1595
1596	if ((mbits != msg->msgh_bits) ||
1597	    (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type)) ||
1598	    ((reply_type == 0) ?
1599	     (reply_name != MACH_PORT_NULL) :
1600	     !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type)))
1601		return MACH_SEND_INVALID_HEADER;
1602
1603	reply_soright = IP_NULL; /* in case we go to invalid dest early */
1604
1605	is_write_lock(space);
1606	if (!is_active(space))
1607		goto invalid_dest;
1608
1609	if (!MACH_PORT_VALID(dest_name))
1610		goto invalid_dest;
1611
1612#if CONFIG_MACF_MACH
1613	/*
1614	 * We do the port send check here instead of in ipc_kmsg_send()
1615	 * because copying the header involves copying the port rights too
1616	 * and we need to do the send check before anything is actually copied.
1617	 */
1618	dest_entry = ipc_entry_lookup(space, dest_name);
1619	if (dest_entry != IE_NULL) {
1620		int error = 0;
1621		ipc_port_t port = (ipc_port_t) dest_entry->ie_object;
1622		if (port == IP_NULL)
1623			goto invalid_dest;
1624		ip_lock(port);
1625		if (ip_active(port)) {
1626			task_t self = current_task();
1627			tasklabel_lock(self);
1628			error = mac_port_check_send(&self->maclabel,
1629			    &port->ip_label);
1630			tasklabel_unlock(self);
1631		}
1632		ip_unlock(port);
1633		if (error != 0)
1634			goto invalid_dest;
1635	}
1636#endif
1637
1638	if (dest_name == reply_name) {
1639		mach_port_name_t name = dest_name;
1640
1641		/*
1642		 *	Destination and reply ports are the same!
1643		 *	This is a little tedious to make atomic, because
1644		 *	there are 25 combinations of dest_type/reply_type.
1645		 *	However, most are easy.  If either is move-sonce,
1646		 *	then there must be an error.  If either are
1647		 *	make-send or make-sonce, then we must be looking
1648		 *	at a receive right so the port can't die.
1649		 *	The hard cases are the combinations of
1650		 *	copy-send and make-send.
1651		 */
1652
1653		dest_entry = ipc_entry_lookup(space, name);
1654		if (dest_entry == IE_NULL)
1655			goto invalid_dest;
1656
1657		reply_entry = dest_entry;
1658		assert(reply_type != 0); /* because name not null */
1659
1660		if (!ipc_right_copyin_check(space, name, reply_entry, reply_type))
1661			goto invalid_reply;
1662
1663		if ((dest_type == MACH_MSG_TYPE_MOVE_SEND_ONCE) ||
1664		    (reply_type == MACH_MSG_TYPE_MOVE_SEND_ONCE)) {
1665			/*
1666			 *	Why must there be an error?  To get a valid
1667			 *	destination, this entry must name a live
1668			 *	port (not a dead name or dead port).  However
1669			 *	a successful move-sonce will destroy a
1670			 *	live entry.  Therefore the other copyin,
1671			 *	whatever it is, would fail.  We've already
1672			 *	checked for reply port errors above,
1673			 *	so report a destination error.
1674			 */
1675
1676			goto invalid_dest;
1677		} else if ((dest_type == MACH_MSG_TYPE_MAKE_SEND) ||
1678			   (dest_type == MACH_MSG_TYPE_MAKE_SEND_ONCE) ||
1679			   (reply_type == MACH_MSG_TYPE_MAKE_SEND) ||
1680			   (reply_type == MACH_MSG_TYPE_MAKE_SEND_ONCE)) {
1681			kr = ipc_right_copyin(space, name, dest_entry,
1682					      dest_type, FALSE,
1683					      &dest_port, &dest_soright,
1684					      &release_port,
1685					      links);
1686			if (kr != KERN_SUCCESS)
1687				goto invalid_dest;
1688
1689			/*
1690			 *	Either dest or reply needs a receive right.
1691			 *	We know the receive right is there, because
1692			 *	of the copyin_check and copyin calls.  Hence
1693			 *	the port is not in danger of dying.  If dest
1694			 *	used the receive right, then the right needed
1695			 *	by reply (and verified by copyin_check) will
1696			 *	still be there.
1697			 */
1698
1699			assert(IO_VALID(dest_port));
1700			assert(dest_soright == IP_NULL);
1701
1702			kr = ipc_right_copyin(space, name, reply_entry,
1703					      reply_type, TRUE,
1704					      &reply_port, &reply_soright,
1705					      &release_port,
1706					      links);
1707
1708			assert(kr == KERN_SUCCESS);
1709			assert(reply_port == dest_port);
1710			assert(reply_entry->ie_bits & MACH_PORT_TYPE_RECEIVE);
1711			assert(reply_soright == IP_NULL);
1712		} else if ((dest_type == MACH_MSG_TYPE_COPY_SEND) &&
1713			   (reply_type == MACH_MSG_TYPE_COPY_SEND)) {
1714			/*
1715			 *	To make this atomic, just do one copy-send,
1716			 *	and dup the send right we get out.
1717			 */
1718
1719			kr = ipc_right_copyin(space, name, dest_entry,
1720					      dest_type, FALSE,
1721					      &dest_port, &dest_soright,
1722					      &release_port,
1723					      links);
1724			if (kr != KERN_SUCCESS)
1725				goto invalid_dest;
1726
1727			assert(dest_entry->ie_bits & MACH_PORT_TYPE_SEND);
1728			assert(dest_soright == IP_NULL);
1729
1730			/*
1731			 *	It's OK if the port we got is dead now,
1732			 *	so reply_port is IP_DEAD, because the msg
1733			 *	won't go anywhere anyway.
1734			 */
1735
1736			reply_port = (ipc_object_t)
1737				ipc_port_copy_send((ipc_port_t) dest_port);
1738			reply_soright = IP_NULL;
1739		} else if ((dest_type == MACH_MSG_TYPE_MOVE_SEND) &&
1740			   (reply_type == MACH_MSG_TYPE_MOVE_SEND)) {
1741			/*
1742			 *	This is an easy case.  Just use our
1743			 *	handy-dandy special-purpose copyin call
1744			 *	to get two send rights for the price of one.
1745			 */
1746
1747			kr = ipc_right_copyin_two(space, name, dest_entry,
1748						  &dest_port, &dest_soright,
1749						  &release_port);
1750			if (kr != KERN_SUCCESS)
1751				goto invalid_dest;
1752
1753			/* the entry might need to be deallocated */
1754			if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1755				ipc_entry_dealloc(space, name, dest_entry);
1756				dest_entry = IE_NULL;
1757			}
1758
1759			reply_port = dest_port;
1760			reply_soright = IP_NULL;
1761		} else {
1762			ipc_port_t soright;
1763
1764			assert(((dest_type == MACH_MSG_TYPE_COPY_SEND) &&
1765				(reply_type == MACH_MSG_TYPE_MOVE_SEND)) ||
1766			       ((dest_type == MACH_MSG_TYPE_MOVE_SEND) &&
1767				(reply_type == MACH_MSG_TYPE_COPY_SEND)));
1768
1769			/*
1770			 *	To make this atomic, just do a move-send,
1771			 *	and dup the send right we get out.
1772			 */
1773
1774			kr = ipc_right_copyin(space, name, dest_entry,
1775					      MACH_MSG_TYPE_MOVE_SEND, FALSE,
1776					      &dest_port, &soright,
1777					      &release_port,
1778					      links);
1779			if (kr != KERN_SUCCESS)
1780				goto invalid_dest;
1781
1782			/* the entry might need to be deallocated */
1783
1784			if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1785				ipc_entry_dealloc(space, name, dest_entry);
1786				dest_entry = IE_NULL;
1787			}
1788
1789			/*
1790			 *	It's OK if the port we got is dead now,
1791			 *	so reply_port is IP_DEAD, because the msg
1792			 *	won't go anywhere anyway.
1793			 */
1794
1795			reply_port = (ipc_object_t)
1796				ipc_port_copy_send((ipc_port_t) dest_port);
1797
1798			if (dest_type == MACH_MSG_TYPE_MOVE_SEND) {
1799				dest_soright = soright;
1800				reply_soright = IP_NULL;
1801			} else {
1802				dest_soright = IP_NULL;
1803				reply_soright = soright;
1804			}
1805		}
1806	} else if (!MACH_PORT_VALID(reply_name)) {
1807		/*
1808		 *	No reply port!  This is an easy case
1809		 *	to make atomic.  Just copyin the destination.
1810		 */
1811
1812		dest_entry = ipc_entry_lookup(space, dest_name);
1813		if (dest_entry == IE_NULL)
1814			goto invalid_dest;
1815
1816		kr = ipc_right_copyin(space, dest_name, dest_entry,
1817				      dest_type, FALSE,
1818				      &dest_port, &dest_soright,
1819				      &release_port,
1820				      links);
1821		if (kr != KERN_SUCCESS)
1822			goto invalid_dest;
1823
1824		/* the entry might need to be deallocated */
1825		if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1826			ipc_entry_dealloc(space, dest_name, dest_entry);
1827			dest_entry = IE_NULL;
1828		}
1829
1830		reply_port = (ipc_object_t)CAST_MACH_NAME_TO_PORT(reply_name);
1831		reply_soright = IP_NULL;
1832	} else {
1833		/*
1834		 *	This is the tough case to make atomic.
1835		 *	The difficult problem is serializing with port death.
1836		 *	At the time we copyin dest_port, it must be alive.
1837		 *	If reply_port is alive when we copyin it, then
1838		 *	we are OK, because we serialize before the death
1839		 *	of both ports.  Assume reply_port is dead at copyin.
1840		 *	Then if dest_port dies/died after reply_port died,
1841		 *	we are OK, because we serialize between the death
1842		 *	of the two ports.  So the bad case is when dest_port
1843		 *	dies after its copyin, reply_port dies before its
1844		 *	copyin, and dest_port dies before reply_port.  Then
1845		 *	the copyins operated as if dest_port was alive
1846		 *	and reply_port was dead, which shouldn't have happened
1847		 *	because they died in the other order.
1848		 *
1849		 *	Note that it is easy for a user task to tell if
1850		 *	a copyin happened before or after a port died.
1851		 *	For example, suppose both dest and reply are
1852		 *	send-once rights (types are both move-sonce) and
1853		 *	both rights have dead-name requests registered.
1854		 *	If a port dies before copyin, a dead-name notification
1855		 *	is generated and the dead name's urefs are incremented,
1856		 *	and if the copyin happens first, a port-deleted
1857		 *	notification is generated.
1858		 *
1859		 *	Note that although the entries are different,
1860		 *	dest_port and reply_port might still be the same.
1861		 *
1862		 * JMM - The code to handle this was too expensive and, anyway,
1863		 * we intend to separate the dest lookup from the reply copyin
1864		 * by a wide margin, so the user will have to learn to deal!
1865		 * I will be making the change soon in rdar://problem/6275821.
1866		 */
1867
1868		dest_entry = ipc_entry_lookup(space, dest_name);
1869		if (dest_entry == IE_NULL)
1870			goto invalid_dest;
1871
1872		reply_entry = ipc_entry_lookup(space, reply_name);
1873		if (reply_entry == IE_NULL)
1874			goto invalid_reply;
1875
1876		assert(dest_entry != reply_entry); /* names are not equal */
1877		assert(reply_type != 0); /* because reply_name not null */
1878
1879		if (!ipc_right_copyin_check(space, reply_name, reply_entry,
1880					    reply_type))
1881			goto invalid_reply;
1882
1883		kr = ipc_right_copyin(space, dest_name, dest_entry,
1884				      dest_type, FALSE,
1885				      &dest_port, &dest_soright,
1886				      &release_port,
1887				      links);
1888		if (kr != KERN_SUCCESS)
1889			goto invalid_dest;
1890
1891		assert(IO_VALID(dest_port));
1892
1893		kr = ipc_right_copyin(space, reply_name, reply_entry,
1894				      reply_type, TRUE,
1895				      &reply_port, &reply_soright,
1896				      &release_port,
1897				      links);
1898		assert(kr == KERN_SUCCESS);
1899
1900		/* the entries might need to be deallocated */
1901
1902		if (IE_BITS_TYPE(reply_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1903			ipc_entry_dealloc(space, reply_name, reply_entry);
1904			reply_entry = IE_NULL;
1905		}
1906
1907		if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1908			ipc_entry_dealloc(space, dest_name, dest_entry);
1909			dest_entry = IE_NULL;
1910		}
1911	}
1912
1913	dest_type = ipc_object_copyin_type(dest_type);
1914	reply_type = ipc_object_copyin_type(reply_type);
1915
1916	/*
1917	 * JMM - Without rdar://problem/6275821, this is the last place we can
1918	 * re-arm the send-possible notifications.  It may trigger unexpectedly
1919	 * early (send may NOT have failed), but better than missing.
1920	 */
1921	if (notify && dest_type != MACH_MSG_TYPE_PORT_SEND_ONCE &&
1922	    dest_entry != IE_NULL && dest_entry->ie_request != IE_REQ_NONE) {
1923		ipc_port_t dport = (ipc_port_t)dest_port;
1924
1925		assert(dport != IP_NULL);
1926		ip_lock(dport);
1927		if (ip_active(dport) &&
1928		    dport->ip_receiver != ipc_space_kernel && ip_full(dport)) {
1929			ipc_port_request_sparm(dport, dest_name, dest_entry->ie_request);
1930		}
1931		ip_unlock(dport);
1932	}
1933
1934	is_write_unlock(space);
1935
1936	if (dest_soright != IP_NULL)
1937		ipc_notify_port_deleted(dest_soright, dest_name);
1938
1939	if (reply_soright != IP_NULL)
1940		ipc_notify_port_deleted(reply_soright, reply_name);
1941
1942	msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
1943			  MACH_MSGH_BITS(dest_type, reply_type));
1944	msg->msgh_remote_port = (ipc_port_t)dest_port;
1945	msg->msgh_local_port = (ipc_port_t)reply_port;
1946
1947	while(!queue_empty(links)) {
1948		wql = (wait_queue_link_t) dequeue(links);
1949		wait_queue_link_free(wql);
1950	}
1951
1952	if (release_port != IP_NULL)
1953		ip_release(release_port);
1954
1955	return MACH_MSG_SUCCESS;
1956
1957invalid_reply:
1958	is_write_unlock(space);
1959
1960	while(!queue_empty(links)) {
1961		wql = (wait_queue_link_t) dequeue(links);
1962		wait_queue_link_free(wql);
1963	}
1964
1965	if (release_port != IP_NULL)
1966		ip_release(release_port);
1967
1968	return MACH_SEND_INVALID_REPLY;
1969
1970invalid_dest:
1971	is_write_unlock(space);
1972
1973	while(!queue_empty(links)) {
1974		wql = (wait_queue_link_t) dequeue(links);
1975		wait_queue_link_free(wql);
1976	}
1977
1978	if (release_port != IP_NULL)
1979		ip_release(release_port);
1980
1981	if (reply_soright != IP_NULL)
1982		ipc_notify_port_deleted(reply_soright, reply_name);
1983
1984	return MACH_SEND_INVALID_DEST;
1985}
1986
1987mach_msg_descriptor_t *ipc_kmsg_copyin_port_descriptor(
1988        volatile mach_msg_port_descriptor_t *dsc,
1989        mach_msg_legacy_port_descriptor_t *user_dsc,
1990        ipc_space_t space,
1991        ipc_object_t dest,
1992        ipc_kmsg_t kmsg,
1993        mach_msg_return_t *mr);
1994
1995void ipc_print_type_name(
1996   int type_name);
1997mach_msg_descriptor_t *
1998ipc_kmsg_copyin_port_descriptor(
1999        volatile mach_msg_port_descriptor_t *dsc,
2000        mach_msg_legacy_port_descriptor_t *user_dsc_in,
2001        ipc_space_t space,
2002        ipc_object_t dest,
2003        ipc_kmsg_t kmsg,
2004        mach_msg_return_t *mr)
2005{
2006    volatile mach_msg_legacy_port_descriptor_t *user_dsc = user_dsc_in;
2007    mach_msg_type_name_t 	user_disp;
2008    mach_msg_type_name_t	result_disp;
2009    mach_port_name_t		name;
2010    ipc_object_t 			object;
2011
2012    user_disp = user_dsc->disposition;
2013    result_disp = ipc_object_copyin_type(user_disp);
2014
2015    name = (mach_port_name_t)user_dsc->name;
2016    if (MACH_PORT_VALID(name)) {
2017
2018        kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object);
2019        if (kr != KERN_SUCCESS) {
2020            *mr = MACH_SEND_INVALID_RIGHT;
2021            return NULL;
2022        }
2023
2024        if ((result_disp == MACH_MSG_TYPE_PORT_RECEIVE) &&
2025                ipc_port_check_circularity((ipc_port_t) object,
2026                    (ipc_port_t) dest)) {
2027            kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2028        }
2029        dsc->name = (ipc_port_t) object;
2030    } else {
2031        dsc->name = CAST_MACH_NAME_TO_PORT(name);
2032    }
2033    dsc->disposition = result_disp;
2034    dsc->type = MACH_MSG_PORT_DESCRIPTOR;
2035
2036    dsc->pad_end = 0; // debug, unnecessary
2037
2038    return (mach_msg_descriptor_t *)(user_dsc_in+1);
2039}
2040
2041mach_msg_descriptor_t * ipc_kmsg_copyin_ool_descriptor(
2042        mach_msg_ool_descriptor_t *dsc,
2043        mach_msg_descriptor_t *user_dsc,
2044        int is_64bit,
2045        vm_offset_t *paddr,
2046        vm_map_copy_t *copy,
2047        vm_size_t *space_needed,
2048        vm_map_t map,
2049        mach_msg_return_t *mr);
2050mach_msg_descriptor_t *
2051ipc_kmsg_copyin_ool_descriptor(
2052        mach_msg_ool_descriptor_t *dsc,
2053        mach_msg_descriptor_t *user_dsc,
2054        int is_64bit,
2055        vm_offset_t *paddr,
2056        vm_map_copy_t *copy,
2057        vm_size_t *space_needed,
2058        vm_map_t map,
2059        mach_msg_return_t *mr)
2060{
2061    vm_size_t            		length;
2062    boolean_t            		dealloc;
2063    mach_msg_copy_options_t		copy_options;
2064    mach_vm_offset_t		addr;
2065    mach_msg_descriptor_type_t	dsc_type;
2066
2067    if (is_64bit) {
2068        mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2069
2070        addr = (mach_vm_offset_t) user_ool_dsc->address;
2071        length = user_ool_dsc->size;
2072        dealloc = user_ool_dsc->deallocate;
2073        copy_options = user_ool_dsc->copy;
2074        dsc_type = user_ool_dsc->type;
2075
2076        user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2077    } else {
2078        mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2079
2080        addr = CAST_USER_ADDR_T(user_ool_dsc->address);
2081        dealloc = user_ool_dsc->deallocate;
2082        copy_options = user_ool_dsc->copy;
2083        dsc_type = user_ool_dsc->type;
2084        length = user_ool_dsc->size;
2085
2086        user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2087    }
2088
2089    dsc->size = (mach_msg_size_t)length;
2090    dsc->deallocate = dealloc;
2091    dsc->copy = copy_options;
2092    dsc->type = dsc_type;
2093
2094    if (length == 0) {
2095        dsc->address = NULL;
2096    } else if ((length >= MSG_OOL_SIZE_SMALL) &&
2097            (copy_options == MACH_MSG_PHYSICAL_COPY) && !dealloc) {
2098
2099        /*
2100         * If the request is a physical copy and the source
2101         * is not being deallocated, then allocate space
2102         * in the kernel's pageable ipc copy map and copy
2103         * the data in.  The semantics guarantee that the
2104         * data will have been physically copied before
2105         * the send operation terminates.  Thus if the data
2106         * is not being deallocated, we must be prepared
2107         * to page if the region is sufficiently large.
2108         */
2109        if (copyin(addr, (char *)*paddr, length)) {
2110            *mr = MACH_SEND_INVALID_MEMORY;
2111            return NULL;
2112        }
2113
2114        /*
2115         * The kernel ipc copy map is marked no_zero_fill.
2116         * If the transfer is not a page multiple, we need
2117         * to zero fill the balance.
2118         */
2119        if (!page_aligned(length)) {
2120            (void) memset((void *) (*paddr + length), 0,
2121                    round_page(length) - length);
2122        }
2123        if (vm_map_copyin(ipc_kernel_copy_map, (vm_map_address_t)*paddr,
2124                    (vm_map_size_t)length, TRUE, copy) != KERN_SUCCESS) {
2125            *mr = MACH_MSG_VM_KERNEL;
2126            return NULL;
2127        }
2128        dsc->address = (void *)*copy;
2129        *paddr += round_page(length);
2130        *space_needed -= round_page(length);
2131    } else {
2132
2133        /*
2134         * Make a vm_map_copy_t of the of the data.  If the
2135         * data is small, this will do an optimized physical
2136         * copy.  Otherwise, it will do a virtual copy.
2137         *
2138         * NOTE: A virtual copy is OK if the original is being
2139         * deallocted, even if a physical copy was requested.
2140         */
2141        kern_return_t kr = vm_map_copyin(map, addr,
2142                (vm_map_size_t)length, dealloc, copy);
2143        if (kr != KERN_SUCCESS) {
2144            *mr = (kr == KERN_RESOURCE_SHORTAGE) ?
2145                MACH_MSG_VM_KERNEL :
2146                MACH_SEND_INVALID_MEMORY;
2147            return NULL;
2148        }
2149        dsc->address = (void *)*copy;
2150    }
2151    return user_dsc;
2152}
2153
2154mach_msg_descriptor_t * ipc_kmsg_copyin_ool_ports_descriptor(
2155        mach_msg_ool_ports_descriptor_t *dsc,
2156        mach_msg_descriptor_t *user_dsc,
2157        int is_64bit,
2158        vm_map_t map,
2159        ipc_space_t space,
2160        ipc_object_t dest,
2161        ipc_kmsg_t kmsg,
2162        mach_msg_return_t *mr);
2163mach_msg_descriptor_t *
2164ipc_kmsg_copyin_ool_ports_descriptor(
2165        mach_msg_ool_ports_descriptor_t *dsc,
2166        mach_msg_descriptor_t *user_dsc,
2167        int is_64bit,
2168        vm_map_t map,
2169        ipc_space_t space,
2170        ipc_object_t dest,
2171        ipc_kmsg_t kmsg,
2172        mach_msg_return_t *mr)
2173{
2174    void					*data;
2175    ipc_object_t            		*objects;
2176    unsigned int				i;
2177    mach_vm_offset_t             		addr;
2178    mach_msg_type_name_t    		user_disp;
2179    mach_msg_type_name_t    		result_disp;
2180    mach_msg_type_number_t			count;
2181    mach_msg_copy_options_t			copy_option;
2182    boolean_t				deallocate;
2183    mach_msg_descriptor_type_t      type;
2184    vm_size_t 				ports_length, names_length;
2185
2186    if (is_64bit) {
2187        mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2188
2189        addr = (mach_vm_offset_t)user_ool_dsc->address;
2190        count = user_ool_dsc->count;
2191        deallocate = user_ool_dsc->deallocate;
2192        copy_option = user_ool_dsc->copy;
2193        user_disp = user_ool_dsc->disposition;
2194        type = user_ool_dsc->type;
2195
2196        user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2197    } else {
2198        mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2199
2200        addr = CAST_USER_ADDR_T(user_ool_dsc->address);
2201        count = user_ool_dsc->count;
2202        deallocate = user_ool_dsc->deallocate;
2203        copy_option = user_ool_dsc->copy;
2204        user_disp = user_ool_dsc->disposition;
2205        type = user_ool_dsc->type;
2206
2207        user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2208    }
2209
2210    dsc->deallocate = deallocate;
2211    dsc->copy = copy_option;
2212    dsc->type = type;
2213    dsc->count = count;
2214    dsc->address = NULL;  /* for now */
2215
2216    result_disp = ipc_object_copyin_type(user_disp);
2217    dsc->disposition = result_disp;
2218
2219    if (count > (INT_MAX / sizeof(mach_port_t))) {
2220        *mr = MACH_SEND_TOO_LARGE;
2221        return NULL;
2222    }
2223
2224    /* calculate length of data in bytes, rounding up */
2225    ports_length = count * sizeof(mach_port_t);
2226    names_length = count * sizeof(mach_port_name_t);
2227
2228    if (ports_length == 0) {
2229        return user_dsc;
2230    }
2231
2232    data = kalloc(ports_length);
2233
2234    if (data == NULL) {
2235        *mr = MACH_SEND_NO_BUFFER;
2236        return NULL;
2237    }
2238
2239#ifdef __LP64__
2240    mach_port_name_t *names = &((mach_port_name_t *)data)[count];
2241#else
2242    mach_port_name_t *names = ((mach_port_name_t *)data);
2243#endif
2244
2245    if (copyinmap(map, addr, names, names_length) != KERN_SUCCESS) {
2246        kfree(data, ports_length);
2247        *mr = MACH_SEND_INVALID_MEMORY;
2248        return NULL;
2249    }
2250
2251    if (deallocate) {
2252        (void) mach_vm_deallocate(map, addr, (mach_vm_size_t)ports_length);
2253    }
2254
2255    objects = (ipc_object_t *) data;
2256    dsc->address = data;
2257
2258    for ( i = 0; i < count; i++) {
2259        mach_port_name_t name = names[i];
2260        ipc_object_t object;
2261
2262        if (!MACH_PORT_VALID(name)) {
2263            objects[i] = (ipc_object_t)CAST_MACH_NAME_TO_PORT(name);
2264            continue;
2265        }
2266
2267        kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object);
2268
2269        if (kr != KERN_SUCCESS) {
2270            unsigned int j;
2271
2272            for(j = 0; j < i; j++) {
2273                object = objects[j];
2274                if (IPC_OBJECT_VALID(object))
2275                    ipc_object_destroy(object, result_disp);
2276            }
2277            kfree(data, ports_length);
2278            dsc->address = NULL;
2279            *mr = MACH_SEND_INVALID_RIGHT;
2280            return NULL;
2281        }
2282
2283        if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2284                ipc_port_check_circularity(
2285                    (ipc_port_t) object,
2286                    (ipc_port_t) dest))
2287            kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2288
2289        objects[i] = object;
2290    }
2291
2292    return user_dsc;
2293}
2294
2295/*
2296 *	Routine:	ipc_kmsg_copyin_body
2297 *	Purpose:
2298 *		"Copy-in" port rights and out-of-line memory
2299 *		in the message body.
2300 *
2301 *		In all failure cases, the message is left holding
2302 *		no rights or memory.  However, the message buffer
2303 *		is not deallocated.  If successful, the message
2304 *		contains a valid destination port.
2305 *	Conditions:
2306 *		Nothing locked.
2307 *	Returns:
2308 *		MACH_MSG_SUCCESS	Successful copyin.
2309 *		MACH_SEND_INVALID_MEMORY	Can't grab out-of-line memory.
2310 *		MACH_SEND_INVALID_RIGHT	Can't copyin port right in body.
2311 *		MACH_SEND_INVALID_TYPE	Bad type specification.
2312 *		MACH_SEND_MSG_TOO_SMALL	Body is too small for types/data.
2313 *		MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
2314 *		MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
2315 */
2316
2317mach_msg_return_t
2318ipc_kmsg_copyin_body(
2319	ipc_kmsg_t	kmsg,
2320	ipc_space_t	space,
2321	vm_map_t	map)
2322{
2323    ipc_object_t       		dest;
2324    mach_msg_body_t		*body;
2325    mach_msg_descriptor_t	*daddr, *naddr;
2326    mach_msg_descriptor_t	*user_addr, *kern_addr;
2327    mach_msg_type_number_t	dsc_count;
2328    boolean_t 			is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
2329    boolean_t 			complex = FALSE;
2330    vm_size_t			space_needed = 0;
2331    vm_offset_t			paddr = 0;
2332    vm_map_copy_t		copy = VM_MAP_COPY_NULL;
2333    mach_msg_type_number_t	i;
2334    mach_msg_return_t		mr = MACH_MSG_SUCCESS;
2335
2336    vm_size_t           descriptor_size = 0;
2337
2338    /*
2339     * Determine if the target is a kernel port.
2340     */
2341    dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2342    body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2343    naddr = (mach_msg_descriptor_t *) (body + 1);
2344
2345    dsc_count = body->msgh_descriptor_count;
2346    if (dsc_count == 0)
2347	return MACH_MSG_SUCCESS;
2348
2349    /*
2350     * Make an initial pass to determine kernal VM space requirements for
2351     * physical copies and possible contraction of the descriptors from
2352     * processes with pointers larger than the kernel's.
2353     */
2354    daddr = NULL;
2355    for (i = 0; i < dsc_count; i++) {
2356	daddr = naddr;
2357
2358	/* make sure the descriptor fits in the message */
2359	if (is_task_64bit) {
2360	    switch (daddr->type.type) {
2361	    case MACH_MSG_OOL_DESCRIPTOR:
2362	    case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2363	    case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2364		    descriptor_size += 16;
2365            naddr = (typeof(naddr))((vm_offset_t)daddr + 16);
2366            break;
2367	    default:
2368		    descriptor_size += 12;
2369            naddr = (typeof(naddr))((vm_offset_t)daddr + 12);
2370            break;
2371	    }
2372	} else {
2373        descriptor_size += 12;
2374        naddr = (typeof(naddr))((vm_offset_t)daddr + 12);
2375	}
2376
2377	if (naddr > (mach_msg_descriptor_t *)
2378	    ((vm_offset_t)kmsg->ikm_header + kmsg->ikm_header->msgh_size)) {
2379	    ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2380	    mr = MACH_SEND_MSG_TOO_SMALL;
2381	    goto out;
2382	}
2383
2384	switch (daddr->type.type) {
2385	    mach_msg_size_t size;
2386
2387	case MACH_MSG_OOL_DESCRIPTOR:
2388	case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2389        size = (is_task_64bit) ?
2390		((mach_msg_ool_descriptor64_t *)daddr)->size :
2391	    daddr->out_of_line.size;
2392
2393	    if (daddr->out_of_line.copy != MACH_MSG_PHYSICAL_COPY &&
2394		daddr->out_of_line.copy != MACH_MSG_VIRTUAL_COPY) {
2395		/*
2396		 * Invalid copy option
2397		 */
2398		ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2399		mr = MACH_SEND_INVALID_TYPE;
2400		goto out;
2401	    }
2402
2403	    if ((size >= MSG_OOL_SIZE_SMALL) &&
2404		(daddr->out_of_line.copy == MACH_MSG_PHYSICAL_COPY) &&
2405		!(daddr->out_of_line.deallocate)) {
2406
2407		/*
2408		 * Out-of-line memory descriptor, accumulate kernel
2409		 * memory requirements
2410		 */
2411		space_needed += round_page(size);
2412		if (space_needed > ipc_kmsg_max_vm_space) {
2413
2414		    /*
2415		     * Per message kernel memory limit exceeded
2416		     */
2417		    ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2418		    mr = MACH_MSG_VM_KERNEL;
2419		    goto out;
2420		}
2421	    }
2422	}
2423    }
2424
2425    /*
2426     * Allocate space in the pageable kernel ipc copy map for all the
2427     * ool data that is to be physically copied.  Map is marked wait for
2428     * space.
2429     */
2430    if (space_needed) {
2431        if (vm_allocate(ipc_kernel_copy_map, &paddr, space_needed,
2432                    VM_FLAGS_ANYWHERE) != KERN_SUCCESS) {
2433            ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2434            mr = MACH_MSG_VM_KERNEL;
2435            goto out;
2436        }
2437    }
2438
2439    /* user_addr = just after base as it was copied in */
2440    user_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2441    /* Shift the mach_msg_base_t down to make for dsc_count*16bytes of descriptors */
2442    if(descriptor_size != 16*dsc_count) {
2443        vm_offset_t dsc_adjust = 16*dsc_count - descriptor_size;
2444        memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
2445        kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust);
2446        /* Update the message size for the larger in-kernel representation */
2447        kmsg->ikm_header->msgh_size += (mach_msg_size_t)dsc_adjust;
2448    }
2449
2450
2451    /* kern_addr = just after base after it has been (conditionally) moved */
2452    kern_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2453
2454    /* handle the OOL regions and port descriptors. */
2455    for(i=0;i<dsc_count;i++) {
2456        switch (user_addr->type.type) {
2457            case MACH_MSG_PORT_DESCRIPTOR:
2458                user_addr = ipc_kmsg_copyin_port_descriptor((mach_msg_port_descriptor_t *)kern_addr,
2459                        (mach_msg_legacy_port_descriptor_t *)user_addr, space, dest, kmsg, &mr);
2460                kern_addr++;
2461                complex = TRUE;
2462                break;
2463            case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2464            case MACH_MSG_OOL_DESCRIPTOR:
2465                user_addr = ipc_kmsg_copyin_ool_descriptor((mach_msg_ool_descriptor_t *)kern_addr,
2466                        user_addr, is_task_64bit, &paddr, &copy, &space_needed, map, &mr);
2467                kern_addr++;
2468                complex = TRUE;
2469                break;
2470            case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2471                user_addr = ipc_kmsg_copyin_ool_ports_descriptor((mach_msg_ool_ports_descriptor_t *)kern_addr,
2472                        user_addr, is_task_64bit, map, space, dest, kmsg, &mr);
2473                kern_addr++;
2474                complex = TRUE;
2475                break;
2476            default:
2477                /* Invalid descriptor */
2478                mr = MACH_SEND_INVALID_TYPE;
2479                break;
2480        }
2481
2482        if (MACH_MSG_SUCCESS != mr) {
2483            /* clean from start of message descriptors to i */
2484            ipc_kmsg_clean_partial(kmsg, i,
2485                    (mach_msg_descriptor_t *)((mach_msg_base_t *)kmsg->ikm_header + 1),
2486                    paddr, space_needed);
2487            goto out;
2488        }
2489    } /* End of loop */
2490
2491    if (!complex) {
2492	kmsg->ikm_header->msgh_bits &= ~MACH_MSGH_BITS_COMPLEX;
2493    }
2494 out:
2495    return mr;
2496}
2497
2498
2499/*
2500 *	Routine:	ipc_kmsg_copyin
2501 *	Purpose:
2502 *		"Copy-in" port rights and out-of-line memory
2503 *		in the message.
2504 *
2505 *		In all failure cases, the message is left holding
2506 *		no rights or memory.  However, the message buffer
2507 *		is not deallocated.  If successful, the message
2508 *		contains a valid destination port.
2509 *	Conditions:
2510 *		Nothing locked.
2511 *	Returns:
2512 *		MACH_MSG_SUCCESS	Successful copyin.
2513 *		MACH_SEND_INVALID_HEADER
2514 *			Illegal value in the message header bits.
2515 *		MACH_SEND_INVALID_DEST	Can't copyin destination port.
2516 *		MACH_SEND_INVALID_REPLY	Can't copyin reply port.
2517 *		MACH_SEND_INVALID_MEMORY	Can't grab out-of-line memory.
2518 *		MACH_SEND_INVALID_RIGHT	Can't copyin port right in body.
2519 *		MACH_SEND_INVALID_TYPE	Bad type specification.
2520 *		MACH_SEND_MSG_TOO_SMALL	Body is too small for types/data.
2521 */
2522
2523mach_msg_return_t
2524ipc_kmsg_copyin(
2525	ipc_kmsg_t		kmsg,
2526	ipc_space_t		space,
2527	vm_map_t		map,
2528	boolean_t		notify)
2529{
2530    mach_msg_return_t 		mr;
2531
2532    mr = ipc_kmsg_copyin_header(kmsg->ikm_header, space, notify);
2533    if (mr != MACH_MSG_SUCCESS)
2534	return mr;
2535
2536	DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_copyin header:\n%.8x\n%.8x\n%p\n%p\n%.8x\n%.8x\n",
2537							 kmsg->ikm_header->msgh_size,
2538							 kmsg->ikm_header->msgh_bits,
2539							 kmsg->ikm_header->msgh_remote_port,
2540							 kmsg->ikm_header->msgh_local_port,
2541							 kmsg->ikm_header->msgh_reserved,
2542							 kmsg->ikm_header->msgh_id);
2543
2544    if ((kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0)
2545	return MACH_MSG_SUCCESS;
2546
2547	mr = ipc_kmsg_copyin_body( kmsg, space, map);
2548
2549	if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK))
2550	{
2551		kprintf("body:\n");
2552		uint32_t i;
2553		for(i=0;i*4 < (kmsg->ikm_header->msgh_size - sizeof(mach_msg_header_t));i++)
2554		{
2555			kprintf("%.4x\n",((uint32_t *)(kmsg->ikm_header + 1))[i]);
2556		}
2557	}
2558	return mr;
2559}
2560
2561/*
2562 *	Routine:	ipc_kmsg_copyin_from_kernel
2563 *	Purpose:
2564 *		"Copy-in" port rights and out-of-line memory
2565 *		in a message sent from the kernel.
2566 *
2567 *		Because the message comes from the kernel,
2568 *		the implementation assumes there are no errors
2569 *		or peculiarities in the message.
2570 *
2571 *		Returns TRUE if queueing the message
2572 *		would result in a circularity.
2573 *	Conditions:
2574 *		Nothing locked.
2575 */
2576
2577mach_msg_return_t
2578ipc_kmsg_copyin_from_kernel(
2579	ipc_kmsg_t	kmsg)
2580{
2581	mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
2582	mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
2583	mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
2584	ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2585	ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
2586
2587	/* translate the destination and reply ports */
2588	if (!IO_VALID(remote))
2589		return MACH_SEND_INVALID_DEST;
2590
2591	ipc_object_copyin_from_kernel(remote, rname);
2592	if (IO_VALID(local))
2593		ipc_object_copyin_from_kernel(local, lname);
2594
2595	/*
2596	 *	The common case is a complex message with no reply port,
2597	 *	because that is what the memory_object interface uses.
2598	 */
2599
2600	if (bits == (MACH_MSGH_BITS_COMPLEX |
2601		     MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
2602		bits = (MACH_MSGH_BITS_COMPLEX |
2603			MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
2604
2605		kmsg->ikm_header->msgh_bits = bits;
2606	} else {
2607		bits = (MACH_MSGH_BITS_OTHER(bits) |
2608			MACH_MSGH_BITS(ipc_object_copyin_type(rname),
2609				       ipc_object_copyin_type(lname)));
2610
2611		kmsg->ikm_header->msgh_bits = bits;
2612		if ((bits & MACH_MSGH_BITS_COMPLEX) == 0)
2613			return MACH_MSG_SUCCESS;
2614	}
2615    {
2616    	mach_msg_descriptor_t	*saddr;
2617    	mach_msg_body_t		*body;
2618	mach_msg_type_number_t	i, count;
2619
2620    	body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2621    	saddr = (mach_msg_descriptor_t *) (body + 1);
2622	count = body->msgh_descriptor_count;
2623
2624    	for (i = 0; i < count; i++, saddr++) {
2625
2626	    switch (saddr->type.type) {
2627
2628	        case MACH_MSG_PORT_DESCRIPTOR: {
2629		    mach_msg_type_name_t 	name;
2630		    ipc_object_t 		object;
2631		    mach_msg_port_descriptor_t 	*dsc;
2632
2633		    dsc = &saddr->port;
2634
2635		    /* this is really the type SEND, SEND_ONCE, etc. */
2636		    name = dsc->disposition;
2637		    object = (ipc_object_t) dsc->name;
2638		    dsc->disposition = ipc_object_copyin_type(name);
2639
2640		    if (!IO_VALID(object)) {
2641		        break;
2642		    }
2643
2644		    ipc_object_copyin_from_kernel(object, name);
2645
2646		    /* CDY avoid circularity when the destination is also */
2647		    /* the kernel.  This check should be changed into an  */
2648		    /* assert when the new kobject model is in place since*/
2649		    /* ports will not be used in kernel to kernel chats   */
2650
2651		    if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) {
2652		       if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2653		           ipc_port_check_circularity((ipc_port_t) object,
2654						(ipc_port_t) remote)) {
2655		           kmsg->ikm_header->msgh_bits |=
2656					MACH_MSGH_BITS_CIRCULAR;
2657		       }
2658		    }
2659		    break;
2660	        }
2661		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2662	        case MACH_MSG_OOL_DESCRIPTOR: {
2663		    /*
2664		     * The sender should supply ready-made memory, i.e.
2665		     * a vm_map_copy_t, so we don't need to do anything.
2666		     */
2667		    break;
2668	        }
2669	        case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
2670		    ipc_object_t            		*objects;
2671		    unsigned int			j;
2672		    mach_msg_type_name_t    		name;
2673		    mach_msg_ool_ports_descriptor_t 	*dsc;
2674
2675		    dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports;
2676
2677		    /* this is really the type SEND, SEND_ONCE, etc. */
2678		    name = dsc->disposition;
2679		    dsc->disposition = ipc_object_copyin_type(name);
2680
2681		    objects = (ipc_object_t *) dsc->address;
2682
2683		    for ( j = 0; j < dsc->count; j++) {
2684		        ipc_object_t object = objects[j];
2685
2686		        if (!IO_VALID(object))
2687			    continue;
2688
2689		        ipc_object_copyin_from_kernel(object, name);
2690
2691		        if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2692			    ipc_port_check_circularity(
2693						       (ipc_port_t) object,
2694						       (ipc_port_t) remote))
2695			    kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2696		    }
2697		    break;
2698	        }
2699	        default: {
2700#if	MACH_ASSERT
2701		    panic("ipc_kmsg_copyin_from_kernel:  bad descriptor");
2702#endif	/* MACH_ASSERT */
2703		}
2704	    }
2705	}
2706    }
2707    return MACH_MSG_SUCCESS;
2708}
2709
2710#if IKM_SUPPORT_LEGACY
2711mach_msg_return_t
2712ipc_kmsg_copyin_from_kernel_legacy(
2713	ipc_kmsg_t	kmsg)
2714{
2715	mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
2716	mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
2717	mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
2718	ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2719	ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
2720
2721	/* translate the destination and reply ports */
2722	if (!IO_VALID(remote))
2723		return MACH_SEND_INVALID_DEST;
2724
2725	ipc_object_copyin_from_kernel(remote, rname);
2726	if (IO_VALID(local))
2727		ipc_object_copyin_from_kernel(local, lname);
2728
2729	/*
2730	 *	The common case is a complex message with no reply port,
2731	 *	because that is what the memory_object interface uses.
2732	 */
2733
2734	if (bits == (MACH_MSGH_BITS_COMPLEX |
2735		     MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
2736		bits = (MACH_MSGH_BITS_COMPLEX |
2737			MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
2738
2739		kmsg->ikm_header->msgh_bits = bits;
2740	} else {
2741		bits = (MACH_MSGH_BITS_OTHER(bits) |
2742			MACH_MSGH_BITS(ipc_object_copyin_type(rname),
2743				       ipc_object_copyin_type(lname)));
2744
2745		kmsg->ikm_header->msgh_bits = bits;
2746		if ((bits & MACH_MSGH_BITS_COMPLEX) == 0)
2747			return MACH_MSG_SUCCESS;
2748	}
2749    {
2750    	mach_msg_legacy_descriptor_t	*saddr;
2751        mach_msg_descriptor_t	*daddr;
2752    	mach_msg_body_t		*body;
2753	mach_msg_type_number_t	i, count;
2754
2755    	body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2756    	saddr = (typeof(saddr)) (body + 1);
2757	count = body->msgh_descriptor_count;
2758
2759    if(count) {
2760        vm_offset_t dsc_adjust = 4*count;
2761        memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
2762        kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust);
2763        /* Update the message size for the larger in-kernel representation */
2764        kmsg->ikm_header->msgh_size += dsc_adjust;
2765    }
2766    daddr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2767
2768    	for (i = 0; i < count; i++, saddr++, daddr++) {
2769	    switch (saddr->type.type) {
2770
2771	        case MACH_MSG_PORT_DESCRIPTOR: {
2772		    mach_msg_type_name_t 	name;
2773		    ipc_object_t 		object;
2774		    mach_msg_legacy_port_descriptor_t 	*dsc;
2775		    mach_msg_port_descriptor_t 	*dest_dsc;
2776
2777		    dsc = (typeof(dsc))&saddr->port;
2778            dest_dsc = &daddr->port;
2779
2780		    /* this is really the type SEND, SEND_ONCE, etc. */
2781		    name = dsc->disposition;
2782		    object = (ipc_object_t) CAST_MACH_NAME_TO_PORT(dsc->name);
2783		    dest_dsc->disposition = ipc_object_copyin_type(name);
2784            dest_dsc->name = (mach_port_t)object;
2785            dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
2786
2787		    if (!IO_VALID(object)) {
2788		        break;
2789		    }
2790
2791		    ipc_object_copyin_from_kernel(object, name);
2792
2793		    /* CDY avoid circularity when the destination is also */
2794		    /* the kernel.  This check should be changed into an  */
2795		    /* assert when the new kobject model is in place since*/
2796		    /* ports will not be used in kernel to kernel chats   */
2797
2798		    if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) {
2799		       if ((dest_dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2800		           ipc_port_check_circularity((ipc_port_t) object,
2801						(ipc_port_t) remote)) {
2802		           kmsg->ikm_header->msgh_bits |=
2803					MACH_MSGH_BITS_CIRCULAR;
2804		       }
2805		    }
2806		    break;
2807	        }
2808		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2809        case MACH_MSG_OOL_DESCRIPTOR: {
2810		    /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
2811             * so we don't need to do anything special. */
2812
2813		    mach_msg_ool_descriptor32_t	*source_dsc = &saddr->out_of_line32;
2814		    mach_msg_ool_descriptor_t 	*dest_dsc = (typeof(dest_dsc))&daddr->out_of_line;
2815
2816            vm_offset_t		    address = source_dsc->address;
2817            vm_size_t            		size = source_dsc->size;
2818            boolean_t            		deallocate = source_dsc->deallocate;
2819            mach_msg_copy_options_t		copy = source_dsc->copy;
2820            mach_msg_descriptor_type_t  type = source_dsc->type;
2821
2822            dest_dsc->address = (void *)address;
2823            dest_dsc->size = size;
2824            dest_dsc->deallocate = deallocate;
2825            dest_dsc->copy = copy;
2826            dest_dsc->type = type;
2827		    break;
2828	        }
2829        case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
2830		    ipc_object_t            		*objects;
2831		    unsigned int			j;
2832		    mach_msg_type_name_t    		name;
2833		    mach_msg_ool_ports_descriptor_t 	*dest_dsc;
2834
2835		    mach_msg_ool_ports_descriptor32_t	*source_dsc = &saddr->ool_ports32;
2836            dest_dsc = (typeof(dest_dsc))&daddr->ool_ports;
2837
2838            boolean_t deallocate = source_dsc->deallocate;
2839            mach_msg_copy_options_t copy = source_dsc->copy;
2840            mach_msg_size_t port_count = source_dsc->count;
2841            mach_msg_type_name_t disposition = source_dsc->disposition;
2842
2843		    /* this is really the type SEND, SEND_ONCE, etc. */
2844		    name = disposition;
2845		    disposition = ipc_object_copyin_type(name);
2846
2847		    objects = (ipc_object_t *) (uintptr_t)source_dsc->address;
2848
2849		    for ( j = 0; j < port_count; j++) {
2850		        ipc_object_t object = objects[j];
2851
2852		        if (!IO_VALID(object))
2853			    continue;
2854
2855		        ipc_object_copyin_from_kernel(object, name);
2856
2857		        if ((disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2858			    ipc_port_check_circularity(
2859						       (ipc_port_t) object,
2860						       (ipc_port_t) remote))
2861			    kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2862		    }
2863
2864            dest_dsc->address = objects;
2865            dest_dsc->deallocate = deallocate;
2866            dest_dsc->copy = copy;
2867            dest_dsc->disposition = disposition;
2868            dest_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
2869            dest_dsc->count = port_count;
2870		    break;
2871	        }
2872	        default: {
2873#if	MACH_ASSERT
2874		    panic("ipc_kmsg_copyin_from_kernel:  bad descriptor");
2875#endif	/* MACH_ASSERT */
2876		}
2877	    }
2878	}
2879    }
2880    return MACH_MSG_SUCCESS;
2881}
2882#endif /* IKM_SUPPORT_LEGACY */
2883
2884/*
2885 *	Routine:	ipc_kmsg_copyout_header
2886 *	Purpose:
2887 *		"Copy-out" port rights in the header of a message.
2888 *		Operates atomically; if it doesn't succeed the
2889 *		message header and the space are left untouched.
2890 *		If it does succeed the remote/local port fields
2891 *		contain port names instead of object pointers,
2892 *		and the bits field is updated.
2893 *	Conditions:
2894 *		Nothing locked.
2895 *	Returns:
2896 *		MACH_MSG_SUCCESS	Copied out port rights.
2897 *		MACH_RCV_INVALID_NOTIFY
2898 *			Notify is non-null and doesn't name a receive right.
2899 *			(Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
2900 *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2901 *			The space is dead.
2902 *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
2903 *			No room in space for another name.
2904 *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2905 *			Couldn't allocate memory for the reply port.
2906 *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
2907 *			Couldn't allocate memory for the dead-name request.
2908 */
2909
2910mach_msg_return_t
2911ipc_kmsg_copyout_header(
2912	mach_msg_header_t	*msg,
2913	ipc_space_t		space)
2914{
2915	mach_msg_bits_t mbits = msg->msgh_bits;
2916	ipc_port_t dest = (ipc_port_t) msg->msgh_remote_port;
2917
2918	assert(IP_VALID(dest));
2919
2920	/*
2921	 * While we still hold a reference on the received-from port,
2922	 * process all send-possible notfications we received along with
2923	 * the message.
2924	 */
2925	ipc_port_spnotify(dest);
2926
2927    {
2928	mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
2929	mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
2930	ipc_port_t reply = (ipc_port_t) msg->msgh_local_port;
2931	ipc_port_t release_port = IP_NULL;
2932	mach_port_name_t dest_name, reply_name;
2933
2934	if (IP_VALID(reply)) {
2935		ipc_entry_t entry;
2936		kern_return_t kr;
2937
2938		/*
2939		 *	Get reply port entry (if none, skip to dest port
2940		 *	copyout).  This may require growing the space.
2941		 */
2942
2943		is_write_lock(space);
2944
2945		for (;;) {
2946			if (!is_active(space)) {
2947				is_write_unlock(space);
2948				return (MACH_RCV_HEADER_ERROR|
2949					MACH_MSG_IPC_SPACE);
2950			}
2951
2952			if ((reply_type != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
2953			    ipc_right_reverse(space, (ipc_object_t) reply,
2954					      &reply_name, &entry)) {
2955				/* reply port is locked and active */
2956				assert(entry->ie_bits &
2957				       MACH_PORT_TYPE_SEND_RECEIVE);
2958				break;
2959			}
2960
2961			ip_lock(reply);
2962			if (!ip_active(reply)) {
2963				ip_unlock(reply);
2964				ip_lock(dest);
2965				is_write_unlock(space);
2966
2967				release_port = reply;
2968				reply = IP_DEAD;
2969				reply_name = MACH_PORT_DEAD;
2970				goto copyout_dest;
2971			}
2972
2973			reply_name = CAST_MACH_PORT_TO_NAME(reply);
2974			kr = ipc_entry_get(space, &reply_name, &entry);
2975			if (kr != KERN_SUCCESS) {
2976				ip_unlock(reply);
2977
2978				/* space is locked */
2979				kr = ipc_entry_grow_table(space,
2980							  ITS_SIZE_NONE);
2981				if (kr != KERN_SUCCESS) {
2982					return (MACH_RCV_HEADER_ERROR|
2983						MACH_MSG_IPC_SPACE);
2984				}
2985				/* space is locked again; start over */
2986
2987				continue;
2988			}
2989			assert(IE_BITS_TYPE(entry->ie_bits) ==
2990			       MACH_PORT_TYPE_NONE);
2991			assert(entry->ie_object == IO_NULL);
2992
2993			entry->ie_object = (ipc_object_t) reply;
2994			break;
2995		}
2996
2997		/* space and reply port are locked and active */
2998
2999		ip_reference(reply);	/* hold onto the reply port */
3000
3001		kr = ipc_right_copyout(space, reply_name, entry,
3002				       reply_type, TRUE, (ipc_object_t) reply);
3003		/* reply port is unlocked */
3004		assert(kr == KERN_SUCCESS);
3005
3006		ip_lock(dest);
3007		is_write_unlock(space);
3008	} else {
3009		/*
3010		 *	No reply port!  This is an easy case.
3011		 *	We only need to have the space locked
3012		 *	when locking the destination.
3013		 */
3014
3015		is_read_lock(space);
3016		if (!is_active(space)) {
3017			is_read_unlock(space);
3018			return MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE;
3019		}
3020
3021		ip_lock(dest);
3022		is_read_unlock(space);
3023
3024		reply_name = CAST_MACH_PORT_TO_NAME(reply);
3025	}
3026
3027	/*
3028	 *	At this point, the space is unlocked and the destination
3029	 *	port is locked.  (Lock taken while space was locked.)
3030	 *	reply_name is taken care of; we still need dest_name.
3031	 *	We still hold a ref for reply (if it is valid).
3032	 *
3033	 *	If the space holds receive rights for the destination,
3034	 *	we return its name for the right.  Otherwise the task
3035	 *	managed to destroy or give away the receive right between
3036	 *	receiving the message and this copyout.  If the destination
3037	 *	is dead, return MACH_PORT_DEAD, and if the receive right
3038	 *	exists somewhere else (another space, in transit)
3039	 *	return MACH_PORT_NULL.
3040	 *
3041	 *	Making this copyout operation atomic with the previous
3042	 *	copyout of the reply port is a bit tricky.  If there was
3043	 *	no real reply port (it wasn't IP_VALID) then this isn't
3044	 *	an issue.  If the reply port was dead at copyout time,
3045	 *	then we are OK, because if dest is dead we serialize
3046	 *	after the death of both ports and if dest is alive
3047	 *	we serialize after reply died but before dest's (later) death.
3048	 *	So assume reply was alive when we copied it out.  If dest
3049	 *	is alive, then we are OK because we serialize before
3050	 *	the ports' deaths.  So assume dest is dead when we look at it.
3051	 *	If reply dies/died after dest, then we are OK because
3052	 *	we serialize after dest died but before reply dies.
3053	 *	So the hard case is when reply is alive at copyout,
3054	 *	dest is dead at copyout, and reply died before dest died.
3055	 *	In this case pretend that dest is still alive, so
3056	 *	we serialize while both ports are alive.
3057	 *
3058	 *	Because the space lock is held across the copyout of reply
3059	 *	and locking dest, the receive right for dest can't move
3060	 *	in or out of the space while the copyouts happen, so
3061	 *	that isn't an atomicity problem.  In the last hard case
3062	 *	above, this implies that when dest is dead that the
3063	 *	space couldn't have had receive rights for dest at
3064	 *	the time reply was copied-out, so when we pretend
3065	 *	that dest is still alive, we can return MACH_PORT_NULL.
3066	 *
3067	 *	If dest == reply, then we have to make it look like
3068	 *	either both copyouts happened before the port died,
3069	 *	or both happened after the port died.  This special
3070	 *	case works naturally if the timestamp comparison
3071	 *	is done correctly.
3072	 */
3073
3074    copyout_dest:
3075
3076	if (ip_active(dest)) {
3077		ipc_object_copyout_dest(space, (ipc_object_t) dest,
3078					dest_type, &dest_name);
3079		/* dest is unlocked */
3080	} else {
3081		ipc_port_timestamp_t timestamp;
3082
3083		timestamp = dest->ip_timestamp;
3084		ip_unlock(dest);
3085		ip_release(dest);
3086
3087		if (IP_VALID(reply)) {
3088			ip_lock(reply);
3089			if (ip_active(reply) ||
3090			    IP_TIMESTAMP_ORDER(timestamp,
3091					       reply->ip_timestamp))
3092				dest_name = MACH_PORT_DEAD;
3093			else
3094				dest_name = MACH_PORT_NULL;
3095			ip_unlock(reply);
3096		} else
3097			dest_name = MACH_PORT_DEAD;
3098	}
3099
3100	if (IP_VALID(reply))
3101		ip_release(reply);
3102
3103	if (IP_VALID(release_port))
3104		ip_release(release_port);
3105
3106	msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
3107			  MACH_MSGH_BITS(reply_type, dest_type));
3108	msg->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
3109	msg->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3110    }
3111
3112	return MACH_MSG_SUCCESS;
3113}
3114
3115/*
3116 *	Routine:	ipc_kmsg_copyout_object
3117 *	Purpose:
3118 *		Copy-out a port right.  Always returns a name,
3119 *		even for unsuccessful return codes.  Always
3120 *		consumes the supplied object.
3121 *	Conditions:
3122 *		Nothing locked.
3123 *	Returns:
3124 *		MACH_MSG_SUCCESS	The space acquired the right
3125 *			(name is valid) or the object is dead (MACH_PORT_DEAD).
3126 *		MACH_MSG_IPC_SPACE	No room in space for the right,
3127 *			or the space is dead.  (Name is MACH_PORT_NULL.)
3128 *		MACH_MSG_IPC_KERNEL	Kernel resource shortage.
3129 *			(Name is MACH_PORT_NULL.)
3130 */
3131
3132mach_msg_return_t
3133ipc_kmsg_copyout_object(
3134	ipc_space_t		space,
3135	ipc_object_t		object,
3136	mach_msg_type_name_t	msgt_name,
3137	mach_port_name_t	*namep)
3138{
3139	kern_return_t kr;
3140
3141	if (!IO_VALID(object)) {
3142		*namep = CAST_MACH_PORT_TO_NAME(object);
3143		return MACH_MSG_SUCCESS;
3144	}
3145
3146	kr = ipc_object_copyout(space, object, msgt_name, TRUE, namep);
3147	if (kr != KERN_SUCCESS) {
3148		ipc_object_destroy(object, msgt_name);
3149
3150		if (kr == KERN_INVALID_CAPABILITY)
3151			*namep = MACH_PORT_DEAD;
3152		else {
3153			*namep = MACH_PORT_NULL;
3154
3155			if (kr == KERN_RESOURCE_SHORTAGE)
3156				return MACH_MSG_IPC_KERNEL;
3157			else
3158				return MACH_MSG_IPC_SPACE;
3159		}
3160	}
3161
3162	return MACH_MSG_SUCCESS;
3163}
3164
3165mach_msg_descriptor_t *
3166ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc,
3167        mach_msg_descriptor_t *user_dsc,
3168        ipc_space_t space,
3169        kern_return_t *mr);
3170mach_msg_descriptor_t *
3171ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc,
3172        mach_msg_descriptor_t *dest_dsc,
3173        ipc_space_t space,
3174        kern_return_t *mr)
3175{
3176    mach_port_t			port;
3177    mach_port_name_t		name;
3178    mach_msg_type_name_t		disp;
3179
3180
3181    /* Copyout port right carried in the message */
3182    port = dsc->port.name;
3183    disp = dsc->port.disposition;
3184    *mr |= ipc_kmsg_copyout_object(space,
3185            (ipc_object_t)port,
3186            disp,
3187            &name);
3188
3189    if(current_task() == kernel_task)
3190    {
3191        mach_msg_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc;
3192        user_dsc--; // point to the start of this port descriptor
3193        user_dsc->name = CAST_MACH_NAME_TO_PORT(name);
3194        user_dsc->disposition = disp;
3195        user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
3196        dest_dsc = (typeof(dest_dsc))user_dsc;
3197    } else {
3198        mach_msg_legacy_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc;
3199        user_dsc--; // point to the start of this port descriptor
3200        user_dsc->name = CAST_MACH_PORT_TO_NAME(name);
3201        user_dsc->disposition = disp;
3202        user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
3203        dest_dsc = (typeof(dest_dsc))user_dsc;
3204    }
3205
3206    return (mach_msg_descriptor_t *)dest_dsc;
3207}
3208
3209mach_msg_descriptor_t *
3210ipc_kmsg_copyout_ool_descriptor(mach_msg_ool_descriptor_t *dsc, mach_msg_descriptor_t *user_dsc, int is_64bit, vm_map_t map, mach_msg_return_t *mr);
3211mach_msg_descriptor_t *
3212ipc_kmsg_copyout_ool_descriptor(mach_msg_ool_descriptor_t *dsc, mach_msg_descriptor_t *user_dsc, int is_64bit, vm_map_t map, mach_msg_return_t *mr)
3213{
3214    vm_map_copy_t			copy;
3215    vm_map_address_t			rcv_addr;
3216    mach_msg_copy_options_t		copy_options;
3217    mach_msg_size_t			size;
3218    mach_msg_descriptor_type_t	dsc_type;
3219
3220    //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3221
3222    copy = (vm_map_copy_t) dsc->address;
3223    size = dsc->size;
3224    copy_options = dsc->copy;
3225    assert(copy_options != MACH_MSG_KALLOC_COPY_T);
3226    dsc_type = dsc->type;
3227    rcv_addr = 0;
3228
3229    if (copy != VM_MAP_COPY_NULL) {
3230        /*
3231         * Check to see if there is an overwrite descriptor
3232         * specified in the scatter list for this ool data.
3233         * The descriptor has already been verified.
3234         */
3235#if 0
3236        if (saddr != MACH_MSG_DESCRIPTOR_NULL) {
3237            if (differs) {
3238                OTHER_OOL_DESCRIPTOR *scatter_dsc;
3239
3240                scatter_dsc = (OTHER_OOL_DESCRIPTOR *)saddr;
3241                if (scatter_dsc->copy == MACH_MSG_OVERWRITE) {
3242                    rcv_addr = (mach_vm_offset_t) scatter_dsc->address;
3243                    copy_options = MACH_MSG_OVERWRITE;
3244                } else {
3245                    copy_options = MACH_MSG_VIRTUAL_COPY;
3246                }
3247            } else {
3248                mach_msg_ool_descriptor_t *scatter_dsc;
3249
3250                scatter_dsc = &saddr->out_of_line;
3251                if (scatter_dsc->copy == MACH_MSG_OVERWRITE) {
3252                    rcv_addr = CAST_USER_ADDR_T(scatter_dsc->address);
3253                    copy_options = MACH_MSG_OVERWRITE;
3254                } else {
3255                    copy_options = MACH_MSG_VIRTUAL_COPY;
3256                }
3257            }
3258            INCREMENT_SCATTER(saddr, sdsc_count, differs);
3259        }
3260#endif
3261
3262
3263        /*
3264         * Whether the data was virtually or physically
3265         * copied we have a vm_map_copy_t for it.
3266         * If there's an overwrite region specified
3267         * overwrite it, otherwise do a virtual copy out.
3268         */
3269        kern_return_t kr;
3270        if (copy_options == MACH_MSG_OVERWRITE && rcv_addr != 0) {
3271            kr = vm_map_copy_overwrite(map, rcv_addr,
3272                    copy, TRUE);
3273        } else {
3274            kr = vm_map_copyout(map, &rcv_addr, copy);
3275        }
3276        if (kr != KERN_SUCCESS) {
3277            if (kr == KERN_RESOURCE_SHORTAGE)
3278                *mr |= MACH_MSG_VM_KERNEL;
3279            else
3280                *mr |= MACH_MSG_VM_SPACE;
3281            vm_map_copy_discard(copy);
3282            rcv_addr = 0;
3283            size = 0;
3284        }
3285    } else {
3286        rcv_addr = 0;
3287        size = 0;
3288    }
3289
3290    /*
3291     * Now update the descriptor as the user would see it.
3292     * This may require expanding the descriptor to the user
3293     * visible size.  There is already space allocated for
3294     * this in what naddr points to.
3295     */
3296    if(current_task() == kernel_task)
3297    {
3298        mach_msg_ool_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3299        user_ool_dsc--;
3300
3301        user_ool_dsc->address = (void *)(uintptr_t)rcv_addr;
3302        user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3303            TRUE : FALSE;
3304        user_ool_dsc->copy = copy_options;
3305        user_ool_dsc->type = dsc_type;
3306        user_ool_dsc->size = size;
3307
3308        user_dsc = (typeof(user_dsc))user_ool_dsc;
3309    } else if (is_64bit) {
3310        mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3311        user_ool_dsc--;
3312
3313        user_ool_dsc->address = rcv_addr;
3314        user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3315            TRUE : FALSE;
3316        user_ool_dsc->copy = copy_options;
3317        user_ool_dsc->type = dsc_type;
3318        user_ool_dsc->size = size;
3319
3320        user_dsc = (typeof(user_dsc))user_ool_dsc;
3321    } else {
3322        mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3323        user_ool_dsc--;
3324
3325        user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
3326        user_ool_dsc->size = size;
3327        user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3328            TRUE : FALSE;
3329        user_ool_dsc->copy = copy_options;
3330        user_ool_dsc->type = dsc_type;
3331
3332        user_dsc = (typeof(user_dsc))user_ool_dsc;
3333    }
3334    return user_dsc;
3335}
3336
3337mach_msg_descriptor_t *
3338ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc,
3339        mach_msg_descriptor_t *user_dsc,
3340        int is_64bit,
3341        vm_map_t map,
3342        ipc_space_t space,
3343        ipc_kmsg_t kmsg,
3344        mach_msg_return_t *mr);
3345mach_msg_descriptor_t *
3346ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc,
3347        mach_msg_descriptor_t *user_dsc,
3348        int is_64bit,
3349        vm_map_t map,
3350        ipc_space_t space,
3351        ipc_kmsg_t kmsg,
3352        mach_msg_return_t *mr)
3353{
3354    mach_vm_offset_t		rcv_addr;
3355    mach_msg_type_name_t		disp;
3356    mach_msg_type_number_t 		count, i;
3357    vm_size_t           		ports_length, names_length;
3358
3359    mach_msg_copy_options_t copy_options = MACH_MSG_VIRTUAL_COPY;
3360
3361    //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3362
3363    count = dsc->count;
3364    disp = dsc->disposition;
3365    ports_length = count * sizeof(mach_port_t);
3366    names_length = count * sizeof(mach_port_name_t);
3367
3368    if (ports_length != 0 && dsc->address != 0) {
3369
3370        /*
3371         * Check to see if there is an overwrite descriptor
3372         * specified in the scatter list for this ool data.
3373         * The descriptor has already been verified.
3374         */
3375#if 0
3376        if (saddr != MACH_MSG_DESCRIPTOR_NULL) {
3377            if (differs) {
3378                OTHER_OOL_DESCRIPTOR *scatter_dsc;
3379
3380                scatter_dsc = (OTHER_OOL_DESCRIPTOR *)saddr;
3381                rcv_addr = (mach_vm_offset_t) scatter_dsc->address;
3382                copy_options = scatter_dsc->copy;
3383            } else {
3384                mach_msg_ool_descriptor_t *scatter_dsc;
3385
3386                scatter_dsc = &saddr->out_of_line;
3387                rcv_addr = CAST_USER_ADDR_T(scatter_dsc->address);
3388                copy_options = scatter_dsc->copy;
3389            }
3390            INCREMENT_SCATTER(saddr, sdsc_count, differs);
3391        }
3392#endif
3393
3394        if (copy_options == MACH_MSG_VIRTUAL_COPY) {
3395            /*
3396             * Dynamically allocate the region
3397             */
3398            int anywhere = VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|
3399                VM_FLAGS_ANYWHERE;
3400
3401            kern_return_t kr;
3402            if ((kr = mach_vm_allocate(map, &rcv_addr,
3403                            (mach_vm_size_t)names_length,
3404                            anywhere)) != KERN_SUCCESS) {
3405                ipc_kmsg_clean_body(kmsg, 1, (mach_msg_descriptor_t *)dsc);
3406                rcv_addr = 0;
3407
3408                if (kr == KERN_RESOURCE_SHORTAGE){
3409                    *mr |= MACH_MSG_VM_KERNEL;
3410                } else {
3411                    *mr |= MACH_MSG_VM_SPACE;
3412                }
3413            }
3414        }
3415
3416        /*
3417         * Handle the port rights and copy out the names
3418         * for those rights out to user-space.
3419         */
3420        if (rcv_addr != 0) {
3421            mach_port_t *objects = (mach_port_t *) dsc->address;
3422            mach_port_name_t *names = (mach_port_name_t *) dsc->address;
3423
3424            /* copyout port rights carried in the message */
3425
3426            for ( i = 0; i < count ; i++) {
3427                ipc_object_t object = (ipc_object_t)objects[i];
3428
3429                *mr |= ipc_kmsg_copyout_object(space, object,
3430                        disp, &names[i]);
3431            }
3432
3433            /* copyout to memory allocated above */
3434            void *data = dsc->address;
3435            if (copyoutmap(map, data, rcv_addr, names_length) != KERN_SUCCESS)
3436                *mr |= MACH_MSG_VM_SPACE;
3437            kfree(data, ports_length);
3438        }
3439    } else {
3440        rcv_addr = 0;
3441    }
3442
3443    /*
3444     * Now update the descriptor based on the information
3445     * calculated above.
3446     */
3447    if(current_task() == kernel_task) {
3448        mach_msg_ool_ports_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3449        user_ool_dsc--;
3450
3451        user_ool_dsc->address = (void *)(uintptr_t)rcv_addr;
3452        user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3453            TRUE : FALSE;
3454        user_ool_dsc->copy = copy_options;
3455        user_ool_dsc->disposition = disp;
3456        user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3457        user_ool_dsc->count = count;
3458
3459        user_dsc = (typeof(user_dsc))user_ool_dsc;
3460    } if (is_64bit) {
3461        mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3462        user_ool_dsc--;
3463
3464        user_ool_dsc->address = rcv_addr;
3465        user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3466            TRUE : FALSE;
3467        user_ool_dsc->copy = copy_options;
3468        user_ool_dsc->disposition = disp;
3469        user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3470        user_ool_dsc->count = count;
3471
3472        user_dsc = (typeof(user_dsc))user_ool_dsc;
3473    } else {
3474        mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3475        user_ool_dsc--;
3476
3477        user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
3478        user_ool_dsc->count = count;
3479        user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3480            TRUE : FALSE;
3481        user_ool_dsc->copy = copy_options;
3482        user_ool_dsc->disposition = disp;
3483        user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3484
3485        user_dsc = (typeof(user_dsc))user_ool_dsc;
3486    }
3487    return user_dsc;
3488}
3489
3490/*
3491 *	Routine:	ipc_kmsg_copyout_body
3492 *	Purpose:
3493 *		"Copy-out" port rights and out-of-line memory
3494 *		in the body of a message.
3495 *
3496 *		The error codes are a combination of special bits.
3497 *		The copyout proceeds despite errors.
3498 *	Conditions:
3499 *		Nothing locked.
3500 *	Returns:
3501 *		MACH_MSG_SUCCESS	Successful copyout.
3502 *		MACH_MSG_IPC_SPACE	No room for port right in name space.
3503 *		MACH_MSG_VM_SPACE	No room for memory in address space.
3504 *		MACH_MSG_IPC_KERNEL	Resource shortage handling port right.
3505 *		MACH_MSG_VM_KERNEL	Resource shortage handling memory.
3506 *		MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
3507 */
3508
3509mach_msg_return_t
3510ipc_kmsg_copyout_body(
3511    	ipc_kmsg_t		kmsg,
3512	ipc_space_t		space,
3513	vm_map_t		map,
3514	mach_msg_body_t		*slist)
3515{
3516    mach_msg_body_t 		*body;
3517    mach_msg_descriptor_t 	*kern_dsc, *user_dsc;
3518    mach_msg_descriptor_t	*saddr;
3519    mach_msg_type_number_t	dsc_count, sdsc_count;
3520    int i;
3521    mach_msg_return_t 		mr = MACH_MSG_SUCCESS;
3522    boolean_t 			is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
3523
3524    body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3525    dsc_count = body->msgh_descriptor_count;
3526    kern_dsc = (mach_msg_descriptor_t *) (body + 1);
3527    /* Point user_dsc just after the end of all the descriptors */
3528    user_dsc = &kern_dsc[dsc_count];
3529
3530    /* Do scatter list setup */
3531    if (slist != MACH_MSG_BODY_NULL) {
3532    panic("Scatter lists disabled");
3533	saddr = (mach_msg_descriptor_t *) (slist + 1);
3534	sdsc_count = slist->msgh_descriptor_count;
3535    }
3536    else {
3537	saddr = MACH_MSG_DESCRIPTOR_NULL;
3538	sdsc_count = 0;
3539    }
3540
3541    /* Now process the descriptors */
3542    for (i = dsc_count-1; i >= 0; i--) {
3543        switch (kern_dsc[i].type.type) {
3544
3545            case MACH_MSG_PORT_DESCRIPTOR:
3546                user_dsc = ipc_kmsg_copyout_port_descriptor(&kern_dsc[i], user_dsc, space, &mr);
3547                break;
3548            case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3549            case MACH_MSG_OOL_DESCRIPTOR :
3550                user_dsc = ipc_kmsg_copyout_ool_descriptor(
3551                        (mach_msg_ool_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, &mr);
3552                break;
3553            case MACH_MSG_OOL_PORTS_DESCRIPTOR :
3554                user_dsc = ipc_kmsg_copyout_ool_ports_descriptor(
3555                        (mach_msg_ool_ports_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, space, kmsg, &mr);
3556                break;
3557            default : {
3558                          panic("untyped IPC copyout body: invalid message descriptor");
3559                      }
3560        }
3561    }
3562
3563    if(user_dsc != kern_dsc) {
3564        vm_offset_t dsc_adjust = (vm_offset_t)user_dsc - (vm_offset_t)kern_dsc;
3565        memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
3566        kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust);
3567        /* Update the message size for the smaller user representation */
3568        kmsg->ikm_header->msgh_size -= (mach_msg_size_t)dsc_adjust;
3569    }
3570
3571    return mr;
3572}
3573
3574/*
3575 *	Routine:	ipc_kmsg_copyout_size
3576 *	Purpose:
3577 *		Compute the size of the message as copied out to the given
3578 *		map. If the destination map's pointers are a different size
3579 *		than the kernel's, we have to allow for expansion/
3580 *		contraction of the descriptors as appropriate.
3581 *	Conditions:
3582 *		Nothing locked.
3583 *	Returns:
3584 *		size of the message as it would be received.
3585 */
3586
3587mach_msg_size_t
3588ipc_kmsg_copyout_size(
3589	ipc_kmsg_t		kmsg,
3590	vm_map_t		map)
3591{
3592    mach_msg_size_t		send_size;
3593
3594    send_size = kmsg->ikm_header->msgh_size;
3595
3596    boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
3597
3598#if defined(__LP64__)
3599	send_size -= LEGACY_HEADER_SIZE_DELTA;
3600#endif
3601
3602    if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3603
3604        mach_msg_body_t *body;
3605        mach_msg_descriptor_t *saddr, *eaddr;
3606
3607        body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3608        saddr = (mach_msg_descriptor_t *) (body + 1);
3609        eaddr = saddr + body->msgh_descriptor_count;
3610
3611        for ( ; saddr < eaddr; saddr++ ) {
3612            switch (saddr->type.type) {
3613                case MACH_MSG_OOL_DESCRIPTOR:
3614                case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3615                case MACH_MSG_OOL_PORTS_DESCRIPTOR:
3616                    if(!is_task_64bit)
3617                        send_size -= DESC_SIZE_ADJUSTMENT;
3618                    break;
3619                case MACH_MSG_PORT_DESCRIPTOR:
3620                    send_size -= DESC_SIZE_ADJUSTMENT;
3621                    break;
3622                default:
3623                    break;
3624            }
3625        }
3626    }
3627    return send_size;
3628}
3629
3630/*
3631 *	Routine:	ipc_kmsg_copyout
3632 *	Purpose:
3633 *		"Copy-out" port rights and out-of-line memory
3634 *		in the message.
3635 *	Conditions:
3636 *		Nothing locked.
3637 *	Returns:
3638 *		MACH_MSG_SUCCESS	Copied out all rights and memory.
3639 *		MACH_RCV_HEADER_ERROR + special bits
3640 *			Rights and memory in the message are intact.
3641 *		MACH_RCV_BODY_ERROR + special bits
3642 *			The message header was successfully copied out.
3643 *			As much of the body was handled as possible.
3644 */
3645
3646mach_msg_return_t
3647ipc_kmsg_copyout(
3648	ipc_kmsg_t		kmsg,
3649	ipc_space_t		space,
3650	vm_map_t		map,
3651	mach_msg_body_t		*slist)
3652{
3653	mach_msg_return_t mr;
3654
3655	mr = ipc_kmsg_copyout_header(kmsg->ikm_header, space);
3656	if (mr != MACH_MSG_SUCCESS) {
3657		return mr;
3658	}
3659
3660	if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3661		mr = ipc_kmsg_copyout_body(kmsg, space, map, slist);
3662
3663		if (mr != MACH_MSG_SUCCESS)
3664			mr |= MACH_RCV_BODY_ERROR;
3665	}
3666
3667	return mr;
3668}
3669
3670/*
3671 *	Routine:	ipc_kmsg_copyout_pseudo
3672 *	Purpose:
3673 *		Does a pseudo-copyout of the message.
3674 *		This is like a regular copyout, except
3675 *		that the ports in the header are handled
3676 *		as if they are in the body.  They aren't reversed.
3677 *
3678 *		The error codes are a combination of special bits.
3679 *		The copyout proceeds despite errors.
3680 *	Conditions:
3681 *		Nothing locked.
3682 *	Returns:
3683 *		MACH_MSG_SUCCESS	Successful copyout.
3684 *		MACH_MSG_IPC_SPACE	No room for port right in name space.
3685 *		MACH_MSG_VM_SPACE	No room for memory in address space.
3686 *		MACH_MSG_IPC_KERNEL	Resource shortage handling port right.
3687 *		MACH_MSG_VM_KERNEL	Resource shortage handling memory.
3688 */
3689
3690mach_msg_return_t
3691ipc_kmsg_copyout_pseudo(
3692	ipc_kmsg_t		kmsg,
3693	ipc_space_t		space,
3694	vm_map_t		map,
3695	mach_msg_body_t		*slist)
3696{
3697	mach_msg_bits_t mbits = kmsg->ikm_header->msgh_bits;
3698	ipc_object_t dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
3699	ipc_object_t reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
3700	mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3701	mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3702	mach_port_name_t dest_name, reply_name;
3703	mach_msg_return_t mr;
3704
3705	assert(IO_VALID(dest));
3706
3707	mr = (ipc_kmsg_copyout_object(space, dest, dest_type, &dest_name) |
3708	      ipc_kmsg_copyout_object(space, reply, reply_type, &reply_name));
3709
3710	kmsg->ikm_header->msgh_bits = mbits &~ MACH_MSGH_BITS_CIRCULAR;
3711	kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(dest_name);
3712	kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(reply_name);
3713
3714	if (mbits & MACH_MSGH_BITS_COMPLEX) {
3715		mr |= ipc_kmsg_copyout_body(kmsg, space, map, slist);
3716	}
3717
3718	return mr;
3719}
3720
3721/*
3722 *	Routine:	ipc_kmsg_copyout_dest
3723 *	Purpose:
3724 *		Copies out the destination port in the message.
3725 *		Destroys all other rights and memory in the message.
3726 *	Conditions:
3727 *		Nothing locked.
3728 */
3729
3730void
3731ipc_kmsg_copyout_dest(
3732	ipc_kmsg_t	kmsg,
3733	ipc_space_t	space)
3734{
3735	mach_msg_bits_t mbits;
3736	ipc_object_t dest;
3737	ipc_object_t reply;
3738	mach_msg_type_name_t dest_type;
3739	mach_msg_type_name_t reply_type;
3740	mach_port_name_t dest_name, reply_name;
3741
3742	mbits = kmsg->ikm_header->msgh_bits;
3743	dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
3744	reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
3745	dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3746	reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3747
3748	assert(IO_VALID(dest));
3749
3750	io_lock(dest);
3751	if (io_active(dest)) {
3752		ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
3753		/* dest is unlocked */
3754	} else {
3755		io_unlock(dest);
3756		io_release(dest);
3757		dest_name = MACH_PORT_DEAD;
3758	}
3759
3760	if (IO_VALID(reply)) {
3761		ipc_object_destroy(reply, reply_type);
3762		reply_name = MACH_PORT_NULL;
3763	} else
3764		reply_name = CAST_MACH_PORT_TO_NAME(reply);
3765
3766	kmsg->ikm_header->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
3767				      MACH_MSGH_BITS(reply_type, dest_type));
3768	kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
3769	kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3770
3771	if (mbits & MACH_MSGH_BITS_COMPLEX) {
3772		mach_msg_body_t *body;
3773
3774		body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3775		ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count,
3776				    (mach_msg_descriptor_t *)(body + 1));
3777	}
3778}
3779
3780/*
3781 *      Routine:        ipc_kmsg_copyin_scatter
3782 *      Purpose:
3783 *              allocate and copyin a scatter list
3784 *      Algorithm:
3785 *              The gather (kmsg) is valid since it has been copied in.
3786 *              Gather list descriptors are sequentially paired with scatter
3787 *              list descriptors, with port descriptors in either list ignored.
3788 *              Descriptors are consistent if the type fileds match and size
3789 *              of the scatter descriptor is less than or equal to the
3790 *              size of the gather descriptor.  A MACH_MSG_ALLOCATE copy
3791 *              strategy in a scatter descriptor matches any size in the
3792 *              corresponding gather descriptor assuming they are the same type.
3793 *              Either list may be larger than the other.  During the
3794 *              subsequent copy out, excess scatter descriptors are ignored
3795 *              and excess gather descriptors default to dynamic allocation.
3796 *
3797 *              In the case of a size error, the scatter list is released.
3798 *      Conditions:
3799 *              Nothing locked.
3800 *      Returns:
3801 *              the allocated message body containing the scatter list.
3802 */
3803
3804mach_msg_body_t *
3805ipc_kmsg_get_scatter(
3806	mach_vm_address_t       msg_addr,
3807       mach_msg_size_t         slist_size,
3808	ipc_kmsg_t              kmsg)
3809{
3810        mach_msg_body_t         *slist;
3811        mach_msg_body_t         *body;
3812        mach_msg_descriptor_t   *gstart, *gend;
3813        mach_msg_descriptor_t   *sstart, *send;
3814
3815#if defined(__LP64__)
3816        panic("ipc_kmsg_get_scatter called!");
3817#endif
3818
3819        if (slist_size < sizeof(mach_msg_base_t))
3820                return MACH_MSG_BODY_NULL;
3821
3822        slist_size -= (mach_msg_size_t)sizeof(mach_msg_header_t);
3823        slist = (mach_msg_body_t *)kalloc(slist_size);
3824        if (slist == MACH_MSG_BODY_NULL)
3825                return slist;
3826
3827        if (copyin(msg_addr + sizeof(mach_msg_header_t), (char *)slist, slist_size)) {
3828                kfree(slist, slist_size);
3829                return MACH_MSG_BODY_NULL;
3830        }
3831
3832        if ((slist->msgh_descriptor_count* sizeof(mach_msg_descriptor_t)
3833             + sizeof(mach_msg_size_t)) > slist_size) {
3834                kfree(slist, slist_size);
3835                return MACH_MSG_BODY_NULL;
3836        }
3837
3838        body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3839        gstart = (mach_msg_descriptor_t *) (body + 1);
3840        gend = gstart + body->msgh_descriptor_count;
3841
3842        sstart = (mach_msg_descriptor_t *) (slist + 1);
3843        send = sstart + slist->msgh_descriptor_count;
3844
3845        while (gstart < gend) {
3846            mach_msg_descriptor_type_t  g_type;
3847
3848            /*
3849             * Skip port descriptors in gather list.
3850             */
3851            g_type = gstart->type.type;
3852
3853            if (g_type != MACH_MSG_PORT_DESCRIPTOR) {
3854
3855	      /*
3856	       * A scatter list with a 0 descriptor count is treated as an
3857	       * automatic size mismatch.
3858	       */
3859	      if (slist->msgh_descriptor_count == 0) {
3860                        kfree(slist, slist_size);
3861                        return MACH_MSG_BODY_NULL;
3862	      }
3863
3864	      /*
3865	       * Skip port descriptors in  scatter list.
3866	       */
3867	      while (sstart < send) {
3868                    if (sstart->type.type != MACH_MSG_PORT_DESCRIPTOR)
3869                        break;
3870                    sstart++;
3871	      }
3872
3873	      /*
3874	       * No more scatter descriptors, we're done
3875	       */
3876	      if (sstart >= send) {
3877                    break;
3878	      }
3879
3880	      /*
3881	       * Check type, copy and size fields
3882	       */
3883                if (g_type == MACH_MSG_OOL_DESCRIPTOR ||
3884                    g_type == MACH_MSG_OOL_VOLATILE_DESCRIPTOR) {
3885                    if (sstart->type.type != MACH_MSG_OOL_DESCRIPTOR &&
3886                        sstart->type.type != MACH_MSG_OOL_VOLATILE_DESCRIPTOR) {
3887                        kfree(slist, slist_size);
3888                        return MACH_MSG_BODY_NULL;
3889                    }
3890                    if (sstart->out_of_line.copy == MACH_MSG_OVERWRITE &&
3891                        gstart->out_of_line.size > sstart->out_of_line.size) {
3892                        kfree(slist, slist_size);
3893                        return MACH_MSG_BODY_NULL;
3894                    }
3895                }
3896                else {
3897		  if (sstart->type.type != MACH_MSG_OOL_PORTS_DESCRIPTOR) {
3898                        kfree(slist, slist_size);
3899                        return MACH_MSG_BODY_NULL;
3900		  }
3901                    if (sstart->ool_ports.copy == MACH_MSG_OVERWRITE &&
3902                        gstart->ool_ports.count > sstart->ool_ports.count) {
3903                        kfree(slist, slist_size);
3904                        return MACH_MSG_BODY_NULL;
3905                    }
3906                }
3907                sstart++;
3908            }
3909            gstart++;
3910        }
3911        return slist;
3912}
3913
3914
3915/*
3916 *      Routine:        ipc_kmsg_free_scatter
3917 *      Purpose:
3918 *              Deallocate a scatter list.  Since we actually allocated
3919 *              a body without a header, and since the header was originally
3920 *              accounted for in slist_size, we have to ajust it down
3921 *              before freeing the scatter list.
3922 */
3923void
3924ipc_kmsg_free_scatter(
3925        mach_msg_body_t *slist,
3926        mach_msg_size_t slist_size)
3927{
3928#if defined(__LP64__)
3929        panic("%s called; halting!", __func__);
3930#endif
3931
3932        slist_size -= (mach_msg_size_t)sizeof(mach_msg_header_t);
3933        kfree(slist, slist_size);
3934}
3935
3936
3937/*
3938 *	Routine:	ipc_kmsg_copyout_to_kernel
3939 *	Purpose:
3940 *		Copies out the destination and reply ports in the message.
3941 *		Leaves all other rights and memory in the message alone.
3942 *	Conditions:
3943 *		Nothing locked.
3944 *
3945 *	Derived from ipc_kmsg_copyout_dest.
3946 *	Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
3947 *	We really do want to save rights and memory.
3948 */
3949
3950void
3951ipc_kmsg_copyout_to_kernel(
3952	ipc_kmsg_t	kmsg,
3953	ipc_space_t	space)
3954{
3955	ipc_object_t dest;
3956	ipc_object_t reply;
3957	mach_msg_type_name_t dest_type;
3958	mach_msg_type_name_t reply_type;
3959	mach_port_name_t dest_name, reply_name;
3960
3961	dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
3962	reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
3963	dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits);
3964	reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits);
3965
3966	assert(IO_VALID(dest));
3967
3968	io_lock(dest);
3969	if (io_active(dest)) {
3970		ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
3971		/* dest is unlocked */
3972	} else {
3973		io_unlock(dest);
3974		io_release(dest);
3975		dest_name = MACH_PORT_DEAD;
3976	}
3977
3978	reply_name = CAST_MACH_PORT_TO_NAME(reply);
3979
3980	kmsg->ikm_header->msgh_bits =
3981		(MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) |
3982					MACH_MSGH_BITS(reply_type, dest_type));
3983	kmsg->ikm_header->msgh_local_port =  CAST_MACH_NAME_TO_PORT(dest_name);
3984	kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3985}
3986
3987#if IKM_SUPPORT_LEGACY
3988void
3989ipc_kmsg_copyout_to_kernel_legacy(
3990	ipc_kmsg_t	kmsg,
3991	ipc_space_t	space)
3992{
3993	ipc_object_t dest;
3994	ipc_object_t reply;
3995	mach_msg_type_name_t dest_type;
3996	mach_msg_type_name_t reply_type;
3997	mach_port_name_t dest_name, reply_name;
3998
3999	dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
4000	reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
4001	dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits);
4002	reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits);
4003
4004	assert(IO_VALID(dest));
4005
4006	io_lock(dest);
4007	if (io_active(dest)) {
4008		ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
4009		/* dest is unlocked */
4010	} else {
4011		io_unlock(dest);
4012		io_release(dest);
4013		dest_name = MACH_PORT_DEAD;
4014	}
4015
4016	reply_name = CAST_MACH_PORT_TO_NAME(reply);
4017
4018	kmsg->ikm_header->msgh_bits =
4019		(MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) |
4020					MACH_MSGH_BITS(reply_type, dest_type));
4021	kmsg->ikm_header->msgh_local_port =  CAST_MACH_NAME_TO_PORT(dest_name);
4022	kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
4023
4024    mach_msg_descriptor_t *saddr;
4025    mach_msg_legacy_descriptor_t *daddr;
4026    mach_msg_type_number_t i, count = ((mach_msg_base_t *)kmsg->ikm_header)->body.msgh_descriptor_count;
4027    saddr = (mach_msg_descriptor_t *) (((mach_msg_base_t *)kmsg->ikm_header) + 1);
4028    saddr = &saddr[count-1];
4029    daddr = (mach_msg_legacy_descriptor_t *)&saddr[count];
4030    daddr--;
4031
4032    vm_offset_t dsc_adjust = 0;
4033
4034    for (i = 0; i < count; i++, saddr--, daddr--) {
4035    switch (saddr->type.type) {
4036        case MACH_MSG_PORT_DESCRIPTOR: {
4037        mach_msg_port_descriptor_t *dsc = &saddr->port;
4038        mach_msg_legacy_port_descriptor_t *dest_dsc = &daddr->port;
4039
4040        mach_port_t name = dsc->name;
4041        mach_msg_type_name_t disposition = dsc->disposition;
4042
4043        dest_dsc->name = CAST_MACH_PORT_TO_NAME(name);
4044        dest_dsc->disposition = disposition;
4045        dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
4046        break;
4047        }
4048    case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4049    case MACH_MSG_OOL_DESCRIPTOR: {
4050        /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
4051         * so we don't need to do anything special. */
4052
4053        mach_msg_ool_descriptor_t 	*source_dsc = (typeof(source_dsc))&saddr->out_of_line;
4054
4055            mach_msg_ool_descriptor32_t	*dest_dsc = &daddr->out_of_line32;
4056
4057        vm_offset_t		            address = (vm_offset_t)source_dsc->address;
4058        vm_size_t            		size = source_dsc->size;
4059        boolean_t            		deallocate = source_dsc->deallocate;
4060        mach_msg_copy_options_t		copy = source_dsc->copy;
4061        mach_msg_descriptor_type_t  type = source_dsc->type;
4062
4063        dest_dsc->address = address;
4064        dest_dsc->size = size;
4065        dest_dsc->deallocate = deallocate;
4066        dest_dsc->copy = copy;
4067        dest_dsc->type = type;
4068        break;
4069        }
4070    case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
4071        mach_msg_ool_ports_descriptor_t 	*source_dsc = (typeof(source_dsc))&saddr->ool_ports;
4072
4073            mach_msg_ool_ports_descriptor32_t	*dest_dsc = &daddr->ool_ports32;
4074
4075        vm_offset_t		            address = (vm_offset_t)source_dsc->address;
4076        vm_size_t            		port_count = source_dsc->count;
4077        boolean_t            		deallocate = source_dsc->deallocate;
4078        mach_msg_copy_options_t		copy = source_dsc->copy;
4079        mach_msg_descriptor_type_t  type = source_dsc->type;
4080
4081        dest_dsc->address = address;
4082        dest_dsc->count = port_count;
4083        dest_dsc->deallocate = deallocate;
4084        dest_dsc->copy = copy;
4085        dest_dsc->type = type;
4086        break;
4087        }
4088        default: {
4089#if	MACH_ASSERT
4090        panic("ipc_kmsg_copyin_from_kernel:  bad descriptor");
4091#endif	/* MACH_ASSERT */
4092                 }
4093    }
4094    }
4095
4096    if(count) {
4097        dsc_adjust = 4*count;
4098        memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
4099        kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust);
4100        /* Update the message size for the smaller user representation */
4101        kmsg->ikm_header->msgh_size -= dsc_adjust;
4102    }
4103}
4104#endif /* IKM_SUPPORT_LEGACY */
4105
4106mach_msg_trailer_size_t
4107ipc_kmsg_add_trailer(ipc_kmsg_t kmsg, ipc_space_t space,
4108		mach_msg_option_t option, thread_t thread,
4109		mach_port_seqno_t seqno, boolean_t minimal_trailer,
4110		mach_vm_offset_t context)
4111{
4112	mach_msg_max_trailer_t *trailer;
4113
4114	(void)thread;
4115	trailer = (mach_msg_max_trailer_t *)
4116		((vm_offset_t)kmsg->ikm_header +
4117		 round_msg(kmsg->ikm_header->msgh_size));
4118
4119	if (!(option & MACH_RCV_TRAILER_MASK)) {
4120		return trailer->msgh_trailer_size;
4121	}
4122
4123	trailer->msgh_seqno = seqno;
4124	trailer->msgh_context = context;
4125	trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit(thread), option);
4126
4127	if (minimal_trailer) {
4128		goto done;
4129	}
4130
4131	if (MACH_RCV_TRAILER_ELEMENTS(option) >=
4132			MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV)){
4133#if CONFIG_MACF_MACH
4134		if (kmsg->ikm_sender != NULL &&
4135				IP_VALID(kmsg->ikm_header->msgh_remote_port) &&
4136				mac_port_check_method(kmsg->ikm_sender,
4137					&kmsg->ikm_sender->maclabel,
4138					&kmsg->ikm_header->msgh_remote_port->ip_label,
4139					kmsg->ikm_header->msgh_id) == 0)
4140			trailer->msgh_ad = 1;
4141		else
4142#endif
4143			trailer->msgh_ad = 0;
4144	}
4145
4146	/*
4147	 * The ipc_kmsg_t holds a reference to the label of a label
4148	 * handle, not the port. We must get a reference to the port
4149	 * and a send right to copyout to the receiver.
4150	 */
4151
4152	if (option & MACH_RCV_TRAILER_ELEMENTS (MACH_RCV_TRAILER_LABELS)) {
4153#if CONFIG_MACF_MACH
4154		if (kmsg->ikm_sender != NULL) {
4155			ipc_labelh_t  lh = kmsg->ikm_sender->label;
4156			kern_return_t kr;
4157
4158			ip_lock(lh->lh_port);
4159			lh->lh_port->ip_mscount++;
4160			lh->lh_port->ip_srights++;
4161			ip_reference(lh->lh_port);
4162			ip_unlock(lh->lh_port);
4163
4164			kr = ipc_object_copyout(space, (ipc_object_t)lh->lh_port,
4165					MACH_MSG_TYPE_PORT_SEND, 0,
4166					&trailer->msgh_labels.sender);
4167			if (kr != KERN_SUCCESS) {
4168				ip_release(lh->lh_port);
4169				trailer->msgh_labels.sender = 0;
4170			}
4171		} else {
4172			trailer->msgh_labels.sender = 0;
4173		}
4174#else
4175		(void)space;
4176		trailer->msgh_labels.sender = 0;
4177#endif
4178	}
4179
4180
4181done:
4182	return trailer->msgh_trailer_size;
4183}
4184