xref: /xnu-11417.140.69/osfmk/ipc/ipc_kmsg.c (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1 /*
2  * Copyright (c) 2000-2020 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  [email protected]
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 <mach/mach_types.h>
74 #include <mach/boolean.h>
75 #include <mach/kern_return.h>
76 #include <mach/message.h>
77 #include <mach/port.h>
78 #include <mach/vm_map.h>
79 #include <mach/mach_vm.h>
80 #include <mach/vm_statistics.h>
81 
82 #include <kern/kern_types.h>
83 #include <kern/assert.h>
84 #include <kern/debug.h>
85 #include <kern/ipc_kobject.h>
86 #include <kern/kalloc.h>
87 #include <kern/zalloc.h>
88 #include <kern/processor.h>
89 #include <kern/thread.h>
90 #include <kern/thread_group.h>
91 #include <kern/sched_prim.h>
92 #include <kern/misc_protos.h>
93 #include <kern/cpu_data.h>
94 #include <kern/policy_internal.h>
95 #include <kern/mach_filter.h>
96 
97 #include <pthread/priority_private.h>
98 
99 #include <machine/limits.h>
100 
101 #include <vm/vm_map_xnu.h>
102 #include <vm/vm_object_xnu.h>
103 #include <vm/vm_kern_xnu.h>
104 #include <vm/vm_protos.h>
105 
106 #include <ipc/port.h>
107 #include <ipc/ipc_types.h>
108 #include <ipc/ipc_entry.h>
109 #include <ipc/ipc_kmsg.h>
110 #include <ipc/ipc_notify.h>
111 #include <ipc/ipc_object.h>
112 #include <ipc/ipc_space.h>
113 #include <ipc/ipc_policy.h>
114 #include <ipc/ipc_port.h>
115 #include <ipc/ipc_right.h>
116 #include <ipc/ipc_hash.h>
117 #include <ipc/ipc_importance.h>
118 #include <ipc/ipc_service_port.h>
119 
120 #if MACH_FLIPC
121 #include <kern/mach_node.h>
122 #include <ipc/flipc.h>
123 #endif
124 
125 #include <os/overflow.h>
126 
127 #include <security/mac_mach_internal.h>
128 
129 #include <device/device_server.h>
130 
131 #include <string.h>
132 
133 #include <sys/kdebug.h>
134 #include <libkern/OSAtomic.h>
135 
136 #include <ptrauth.h>
137 #if __has_feature(ptrauth_calls)
138 #include <libkern/ptrauth_utils.h>
139 #endif
140 
141 
142 /*
143  * In kernel, complex mach msg have a simpler representation than userspace:
144  *
145  * <header>
146  * <desc-count>
147  * <descriptors> * desc-count
148  * <body>
149  *
150  * And the descriptors are of type `mach_msg_kdescriptor_t`,
151  * that is large enough to accommodate for any possible representation.
152  *
153  * The `type` field of any descriptor is always at the same offset,
154  * and the smallest possible descriptor is of size USER_DESC_SIZE_MIN.
155  *
156  * Note:
157  * - KERN_DESC_SIZE is 16 on all kernels
158  * - USER_DESC_SIZE_MIN is 12 on all kernels
159  */
160 
161 #define KERNEL_DESC_SIZE        sizeof(mach_msg_kdescriptor_t)
162 #define USER_DESC_SIZE_MIN      sizeof(mach_msg_type_descriptor_t)
163 #define USER_DESC_SIZE_MAX      KERNEL_DESC_SIZE
164 #define USER_DESC_MAX_DELTA     (KERNEL_DESC_SIZE - USER_DESC_SIZE_MIN)
165 #define USER_HEADER_SIZE_DELTA  (sizeof(mach_msg_header_t) - sizeof(mach_msg_user_header_t))
166 
167 
168 #define mach_validate_desc_type(t, size) \
169 	static_assert(sizeof(t) == (size))
170 
171 mach_validate_desc_type(mach_msg_descriptor_t, KERNEL_DESC_SIZE);
172 mach_validate_desc_type(mach_msg_kdescriptor_t, KERNEL_DESC_SIZE);
173 mach_validate_desc_type(mach_msg_port_descriptor_t, KERNEL_DESC_SIZE);
174 mach_validate_desc_type(mach_msg_ool_descriptor_t, KERNEL_DESC_SIZE);
175 mach_validate_desc_type(mach_msg_ool_ports_descriptor_t, KERNEL_DESC_SIZE);
176 mach_validate_desc_type(mach_msg_guarded_port_descriptor_t, KERNEL_DESC_SIZE);
177 
178 extern vm_map_t         ipc_kernel_copy_map;
179 extern const vm_size_t  msg_ool_size_small;
180 
181 /* zone for cached ipc_kmsg_t structures */
182 ZONE_DEFINE_ID(ZONE_ID_IPC_KMSG, "ipc kmsgs", struct ipc_kmsg,
183     ZC_CACHING | ZC_ZFREE_CLEARMEM);
184 #define ikm_require(kmsg) \
185 	zone_id_require(ZONE_ID_IPC_KMSG, sizeof(struct ipc_kmsg), kmsg)
186 #define ikm_require_aligned(kmsg) \
187 	zone_id_require_aligned(ZONE_ID_IPC_KMSG, kmsg)
188 
189 KALLOC_TYPE_VAR_DEFINE(KT_IPC_KMSG_KDATA_OOL,
190     mach_msg_base_t, mach_msg_kdescriptor_t, KT_DEFAULT);
191 
192 static TUNABLE(bool, enforce_strict_reply, "ipc_strict_reply", false);
193 
194 
195 #pragma mark ipc_kmsg layout and accessors
196 
197 /* Whether header, body, content and trailer occupy contiguous memory space */
198 static inline bool
ikm_is_linear(ipc_kmsg_t kmsg)199 ikm_is_linear(ipc_kmsg_t kmsg)
200 {
201 	return kmsg->ikm_type == IKM_TYPE_ALL_INLINED ||
202 	       kmsg->ikm_type == IKM_TYPE_KDATA_OOL;
203 }
204 
205 /* Size of kmsg header (plus body and descriptors for complex messages) */
206 __attribute__((always_inline, overloadable))
207 static mach_msg_size_t
ikm_kdata_size(mach_msg_size_t dsc_count,bool complex)208 ikm_kdata_size(
209 	mach_msg_size_t dsc_count,
210 	bool            complex)
211 {
212 	if (complex) {
213 		return sizeof(mach_msg_kbase_t) + dsc_count * KERNEL_DESC_SIZE;
214 	} else {
215 		return sizeof(mach_msg_header_t);
216 	}
217 }
218 
219 __attribute__((always_inline, overloadable))
220 static mach_msg_size_t
ikm_kdata_size(mach_msg_header_t * hdr)221 ikm_kdata_size(
222 	mach_msg_header_t *hdr)
223 {
224 	if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
225 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
226 
227 		return ikm_kdata_size(kbase->msgb_dsc_count, true);
228 	}
229 	return ikm_kdata_size(0, false);
230 }
231 
232 /*
233  * Returns start address of user data for kmsg.
234  *
235  * Caller is responsible for checking the size of udata buffer before attempting
236  * to write to the address returned.
237  *
238  * Condition:
239  *   1. kmsg descriptors must have been validated and expanded, or is a message
240  *      originated from kernel.
241  *   2. ikm_header() content may or may not be populated
242  */
243 void *
ikm_udata(ipc_kmsg_t kmsg,mach_msg_size_t dsc_count,bool complex)244 ikm_udata(
245 	ipc_kmsg_t      kmsg,
246 	mach_msg_size_t dsc_count,
247 	bool            complex)
248 {
249 	if (ikm_is_linear(kmsg)) {
250 		mach_msg_header_t *hdr = ikm_header(kmsg);
251 
252 		return (char *)hdr + ikm_kdata_size(dsc_count, complex);
253 	}
254 	return kmsg->ikm_udata;
255 }
256 
257 /*
258  * Returns start address of user data for kmsg, given a populated kmsg.
259  *
260  * Caller is responsible for checking the size of udata buffer before attempting
261  * to write to the address returned.
262  *
263  * Condition:
264  *   kmsg must have a populated header.
265  */
266 void *
ikm_udata_from_header(ipc_kmsg_t kmsg)267 ikm_udata_from_header(ipc_kmsg_t kmsg)
268 {
269 	if (ikm_is_linear(kmsg)) {
270 		mach_msg_header_t *hdr = ikm_header(kmsg);
271 
272 		return (char *)hdr + ikm_kdata_size(hdr);
273 	}
274 	return kmsg->ikm_udata;
275 }
276 
277 #if (DEVELOPMENT || DEBUG)
278 /* Returns end of kdata buffer (may contain extra space) */
279 vm_offset_t
ikm_kdata_end(ipc_kmsg_t kmsg)280 ikm_kdata_end(ipc_kmsg_t kmsg)
281 {
282 	switch (kmsg->ikm_type) {
283 	case IKM_TYPE_ALL_INLINED:
284 		return (vm_offset_t)kmsg->ikm_big_data + IKM_BIG_MSG_SIZE;
285 	case IKM_TYPE_UDATA_OOL:
286 		return (vm_offset_t)kmsg->ikm_small_data + IKM_SMALL_MSG_SIZE;
287 	default:
288 		return (vm_offset_t)kmsg->ikm_kdata + kmsg->ikm_kdata_size;
289 	}
290 }
291 #endif
292 
293 /*
294  * Returns message header address.
295  */
296 inline mach_msg_header_t *
ikm_header(ipc_kmsg_t kmsg)297 ikm_header(
298 	ipc_kmsg_t         kmsg)
299 {
300 	switch (kmsg->ikm_type) {
301 	case IKM_TYPE_ALL_INLINED:
302 		return (mach_msg_header_t *)kmsg->ikm_big_data;
303 	case IKM_TYPE_UDATA_OOL:
304 		return (mach_msg_header_t *)kmsg->ikm_small_data;
305 	default:
306 		return (mach_msg_header_t *)kmsg->ikm_kdata;
307 	}
308 }
309 
310 static inline mach_msg_aux_header_t *
ikm_aux_header(ipc_kmsg_t kmsg)311 ikm_aux_header(
312 	ipc_kmsg_t         kmsg)
313 {
314 	if (!kmsg->ikm_aux_size) {
315 		return NULL;
316 	}
317 
318 	assert(kmsg->ikm_aux_size >= sizeof(mach_msg_aux_header_t));
319 
320 	if (kmsg->ikm_type == IKM_TYPE_ALL_INLINED) {
321 		return (mach_msg_aux_header_t *)((vm_offset_t)(kmsg + 1) -
322 		       kmsg->ikm_aux_size);
323 	} else {
324 		assert(kmsg->ikm_type != IKM_TYPE_KDATA_OOL);
325 		return (mach_msg_aux_header_t *)((vm_offset_t)kmsg->ikm_udata +
326 		       kmsg->ikm_udata_size - kmsg->ikm_aux_size);
327 	}
328 }
329 
330 /*!
331  * @brief
332  * Returns the size of a user descriptor for a given type
333  */
334 static inline mach_msg_size_t
ikm_user_desc_size(mach_msg_descriptor_type_t type,bool is_task_64bit)335 ikm_user_desc_size(mach_msg_descriptor_type_t type, bool is_task_64bit)
336 {
337 	/*
338 	 * User descriptors come in two sizes:
339 	 * - USER_DESC_SIZE_MIN (12)
340 	 * - USER_DESC_SIZE_MAX (16)
341 	 *
342 	 * Ideally this function would be implemented as a "switch",
343 	 * unfortunately this produces terrible codegen, so we instead write
344 	 * the optimal code by hand with tons of static asserts.
345 	 *
346 	 * As of now there are only two cases:
347 	 * - port descriptors are always 12 bytes
348 	 * - other descriptors are 12 bytes on 32bits, and 16 on 64bits.
349 	 *
350 	 * If one of the static asserts break because you are adding a new
351 	 * descriptor type, make sure to update this function properly.
352 	 */
353 	static_assert(MACH_MSG_DESCRIPTOR_MAX == MACH_MSG_GUARDED_PORT_DESCRIPTOR);
354 
355 	if (type == MACH_MSG_PORT_DESCRIPTOR) {
356 		mach_validate_desc_type(mach_msg_user_port_descriptor_t, USER_DESC_SIZE_MIN);
357 		return USER_DESC_SIZE_MIN;
358 	}
359 	if (is_task_64bit) {
360 		mach_validate_desc_type(mach_msg_ool_descriptor64_t, USER_DESC_SIZE_MAX);
361 		mach_validate_desc_type(mach_msg_ool_ports_descriptor64_t, USER_DESC_SIZE_MAX);
362 		mach_validate_desc_type(mach_msg_guarded_port_descriptor64_t, USER_DESC_SIZE_MAX);
363 		return USER_DESC_SIZE_MAX;
364 	} else {
365 		mach_validate_desc_type(mach_msg_ool_descriptor32_t, USER_DESC_SIZE_MIN);
366 		mach_validate_desc_type(mach_msg_ool_ports_descriptor32_t, USER_DESC_SIZE_MIN);
367 		mach_validate_desc_type(mach_msg_guarded_port_descriptor32_t, USER_DESC_SIZE_MIN);
368 		return USER_DESC_SIZE_MIN;
369 	}
370 }
371 
372 __abortlike
373 static void
__ipc_kmsg_descriptor_invalid_type_panic(const mach_msg_kdescriptor_t * kdesc)374 __ipc_kmsg_descriptor_invalid_type_panic(
375 	const mach_msg_kdescriptor_t *kdesc)
376 {
377 	panic("Invalid descriptor type (%p: %d)",
378 	    kdesc, mach_msg_kdescriptor_type(kdesc));
379 }
380 
381 mach_msg_trailer_size_t
ipc_kmsg_trailer_size(mach_msg_option64_t option,vm_map_t map __unused)382 ipc_kmsg_trailer_size(mach_msg_option64_t option, vm_map_t map __unused)
383 {
384 	return REQUESTED_TRAILER_SIZE(map->max_offset > VM_MAX_ADDRESS, option);
385 }
386 
387 
388 /*
389  * Get the trailer address of kmsg.
390  */
391 mach_msg_max_trailer_t *
ipc_kmsg_get_trailer(ipc_kmsg_t kmsg)392 ipc_kmsg_get_trailer(
393 	ipc_kmsg_t              kmsg)
394 {
395 	mach_msg_header_t *hdr = ikm_header(kmsg);
396 	mach_msg_size_t    trailer_pos = hdr->msgh_size;
397 	vm_offset_t        base;
398 
399 	if (ikm_is_linear(kmsg)) {
400 		base = (vm_offset_t)hdr;
401 	} else {
402 		base = (vm_offset_t)kmsg->ikm_udata;
403 		trailer_pos -= ikm_kdata_size(hdr);
404 	}
405 
406 	return (mach_msg_max_trailer_t *)(base + trailer_pos);
407 }
408 
409 void
ipc_kmsg_set_voucher_port(ipc_kmsg_t kmsg,ipc_port_t voucher_port,mach_msg_type_name_t type)410 ipc_kmsg_set_voucher_port(
411 	ipc_kmsg_t           kmsg,
412 	ipc_port_t           voucher_port,
413 	mach_msg_type_name_t type)
414 {
415 	if (IP_VALID(voucher_port)) {
416 		assert(ip_kotype(voucher_port) == IKOT_VOUCHER);
417 	}
418 	kmsg->ikm_voucher_port = voucher_port;
419 	kmsg->ikm_voucher_type = type;
420 }
421 
422 ipc_port_t
ipc_kmsg_get_voucher_port(ipc_kmsg_t kmsg)423 ipc_kmsg_get_voucher_port(ipc_kmsg_t kmsg)
424 {
425 	return kmsg->ikm_voucher_port;
426 }
427 
428 void
ipc_kmsg_clear_voucher_port(ipc_kmsg_t kmsg)429 ipc_kmsg_clear_voucher_port(ipc_kmsg_t kmsg)
430 {
431 	kmsg->ikm_voucher_port = IP_NULL;
432 	kmsg->ikm_voucher_type = MACH_MSGH_BITS_ZERO;
433 }
434 
435 /*
436  * Caller has a reference to the kmsg and the mqueue lock held.
437  *
438  * As such, we can safely return a pointer to the thread group in the kmsg and
439  * not an additional reference. It is up to the caller to decide to take an
440  * additional reference on the thread group while still holding the mqueue lock,
441  * if needed.
442  */
443 #if CONFIG_PREADOPT_TG
444 struct thread_group *
ipc_kmsg_get_thread_group(ipc_kmsg_t kmsg)445 ipc_kmsg_get_thread_group(ipc_kmsg_t kmsg)
446 {
447 	struct thread_group *tg = NULL;
448 	kern_return_t __assert_only kr;
449 
450 	ipc_voucher_t voucher = convert_port_to_voucher(ipc_kmsg_get_voucher_port(kmsg));
451 	kr = bank_get_preadopt_thread_group(voucher, &tg);
452 	ipc_voucher_release(voucher);
453 
454 	return tg;
455 }
456 #endif
457 
458 #pragma mark ipc_kmsg signing
459 
460 __abortlike
461 static void
__ikm_signature_check_panic(ipc_kmsg_t kmsg,uint32_t sig)462 __ikm_signature_check_panic(ipc_kmsg_t kmsg, uint32_t sig)
463 {
464 	mach_msg_header_t *hdr = ikm_header(kmsg);
465 
466 	panic("IPC kmsg header signature mismatch: "
467 	    "kmsg=%p, hdr=%p, id=%d, sig=0x%08x (expected 0x%08x)",
468 	    kmsg, hdr, hdr->msgh_id, sig, kmsg->ikm_signature);
469 }
470 
471 static uint32_t
__ipc_kmsg_sign(ipc_kmsg_t kmsg,mach_msg_max_trailer_t * trailer,mach_msg_size_t * dsc_count)472 __ipc_kmsg_sign(
473 	ipc_kmsg_t              kmsg,
474 	mach_msg_max_trailer_t *trailer,
475 	mach_msg_size_t        *dsc_count)
476 {
477 	uint32_t           signature = 0;
478 	mach_msg_header_t *hdr  = ikm_header(kmsg);
479 	mach_msg_base_t    base;
480 
481 	if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
482 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
483 
484 		/*
485 		 * the "atomic" load will also be volatile which prevents the
486 		 * compiler from re-fetching that value after optimization.
487 		 */
488 		base.header = kbase->msgb_header;
489 		base.body.msgh_descriptor_count =
490 		    os_atomic_load(&kbase->msgb_dsc_count, relaxed);
491 	} else {
492 		base.header = *hdr;
493 		base.body.msgh_descriptor_count = 0;
494 	}
495 
496 	/* compute sig of a copy of the header with all varying bits masked off */
497 	base.header.msgh_bits &= MACH_MSGH_BITS_USER;
498 	base.header.msgh_bits &= ~MACH_MSGH_BITS_VOUCHER_MASK;
499 
500 #if __has_feature(ptrauth_calls)
501 	{
502 		uintptr_t data = (uintptr_t)kmsg;
503 
504 		data &= ~(0xffffLL << 48); /* clear upper 16 bits */
505 		data |= OS_PTRAUTH_DISCRIMINATOR("kmsg.ikm_signature") << 48;
506 
507 		data  = ptrauth_utils_sign_blob_generic(&base, sizeof(base), data, 0);
508 		data  = ptrauth_utils_sign_blob_generic(trailer,
509 		    MAX_TRAILER_SIZE, data, PTRAUTH_ADDR_DIVERSIFY);
510 		signature = (uint32_t)(data >> 32);
511 	}
512 #else
513 	(void)kmsg;
514 	(void)trailer;
515 #endif
516 
517 	if (dsc_count) {
518 		*dsc_count = base.body.msgh_descriptor_count;
519 	}
520 	return signature;
521 }
522 
523 static void
ipc_kmsg_sign(ipc_kmsg_t kmsg,mach_msg_max_trailer_t * trailer)524 ipc_kmsg_sign(ipc_kmsg_t kmsg, mach_msg_max_trailer_t *trailer)
525 {
526 	kmsg->ikm_signature = __ipc_kmsg_sign(kmsg, trailer, NULL);
527 }
528 
529 /*
530  *	Routine:	ipc_kmsg_init_trailer_and_sign
531  *	Purpose:
532  *		Initiailizes a trailer in a message safely,
533  *		and sign its header and trailer.
534  */
535 static void
ipc_kmsg_init_trailer_and_sign(ipc_kmsg_t kmsg,task_t sender)536 ipc_kmsg_init_trailer_and_sign(
537 	ipc_kmsg_t          kmsg,
538 	task_t              sender)
539 {
540 	static const mach_msg_max_trailer_t KERNEL_TRAILER_TEMPLATE = {
541 		.msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0,
542 		.msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE,
543 		.msgh_sender = KERNEL_SECURITY_TOKEN_VALUE,
544 		.msgh_audit = KERNEL_AUDIT_TOKEN_VALUE
545 	};
546 
547 	mach_msg_max_trailer_t *trailer = ipc_kmsg_get_trailer(kmsg);
548 
549 	if (sender == TASK_NULL) {
550 		memcpy(trailer, &KERNEL_TRAILER_TEMPLATE, sizeof(*trailer));
551 	} else {
552 		bzero(trailer, sizeof(*trailer));
553 		trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
554 		trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
555 		trailer->msgh_sender = *task_get_sec_token(sender);
556 		trailer->msgh_audit = *task_get_audit_token(sender);
557 	}
558 
559 	ipc_kmsg_sign(kmsg, trailer);
560 }
561 
562 /*
563  * Purpose:
564  *       Validate kmsg signature.
565  */
566 mach_msg_size_t
ipc_kmsg_validate_signature(ipc_kmsg_t kmsg)567 ipc_kmsg_validate_signature(
568 	ipc_kmsg_t kmsg)
569 {
570 	uint32_t         sig;
571 	mach_msg_size_t  dsc_count;
572 
573 	ikm_require_aligned(kmsg);
574 	sig = __ipc_kmsg_sign(kmsg, ipc_kmsg_get_trailer(kmsg), &dsc_count);
575 	if (sig != kmsg->ikm_signature) {
576 		__ikm_signature_check_panic(kmsg, sig);
577 	}
578 
579 	return dsc_count;
580 }
581 
582 void
ipc_kmsg_sign_descriptors(mach_msg_kdescriptor_t * kdesc,mach_msg_size_t dsc_count)583 ipc_kmsg_sign_descriptors(
584 	mach_msg_kdescriptor_t *kdesc,
585 	mach_msg_size_t         dsc_count)
586 {
587 #if __has_feature(ptrauth_calls)
588 	for (mach_msg_size_t i = 0; i < dsc_count; i++, kdesc++) {
589 		switch (mach_msg_kdescriptor_type(kdesc)) {
590 		case MACH_MSG_PORT_DESCRIPTOR:
591 			kdesc->kdesc_port.name =
592 			    kdesc->kdesc_port.kext_name;
593 			break;
594 		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
595 		case MACH_MSG_OOL_DESCRIPTOR:
596 			kdesc->kdesc_memory.address =
597 			    kdesc->kdesc_memory.kext_address;
598 			break;
599 		case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
600 			mach_msg_ool_ports_descriptor_t *dsc = &kdesc->kdesc_port_array;
601 			ipc_port_t          *ports = dsc->kext_address;
602 			mach_port_array_t    array = dsc->kext_address;
603 
604 			for (mach_msg_size_t j = 0; j < dsc->count; j++) {
605 				array[i].port = ports[i];
606 			}
607 			dsc->address = array;
608 			break;
609 		}
610 		case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
611 			kdesc->kdesc_guarded_port.name =
612 			    kdesc->kdesc_guarded_port.kext_name;
613 			break;
614 		default:
615 			__ipc_kmsg_descriptor_invalid_type_panic(kdesc);
616 		}
617 	}
618 #else
619 #pragma unused(kdesc, dsc_count)
620 #endif /* __has_feature(ptrauth_calls) */
621 }
622 
623 static void
ipc_kmsg_relocate_descriptors(mach_msg_kdescriptor_t * dst_dsc,const mach_msg_kdescriptor_t * src_dsc,mach_msg_size_t dsc_count)624 ipc_kmsg_relocate_descriptors(
625 	mach_msg_kdescriptor_t *dst_dsc,
626 	const mach_msg_kdescriptor_t *src_dsc,
627 	mach_msg_size_t         dsc_count)
628 {
629 #if __has_feature(ptrauth_calls)
630 	for (mach_msg_size_t i = 0; i < dsc_count; i++, dst_dsc++, src_dsc++) {
631 		switch (mach_msg_kdescriptor_type(src_dsc)) {
632 		case MACH_MSG_PORT_DESCRIPTOR:
633 			dst_dsc->kdesc_port.name =
634 			    src_dsc->kdesc_port.name;
635 			break;
636 		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
637 		case MACH_MSG_OOL_DESCRIPTOR:
638 			dst_dsc->kdesc_memory.address =
639 			    src_dsc->kdesc_memory.address;
640 			break;
641 		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
642 			dst_dsc->kdesc_port_array.address =
643 			    src_dsc->kdesc_port_array.address;
644 			break;
645 		case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
646 			dst_dsc->kdesc_guarded_port.name =
647 			    src_dsc->kdesc_guarded_port.name;
648 			break;
649 		default:
650 			__ipc_kmsg_descriptor_invalid_type_panic(src_dsc);
651 		}
652 	}
653 #else
654 #pragma unused(dst_dsc, src_dsc, dsc_count)
655 #endif /* __has_feature(ptrauth_calls) */
656 }
657 
658 static void
ipc_kmsg_strip_descriptors(mach_msg_kdescriptor_t * dst_dsc,const mach_msg_kdescriptor_t * src_dsc,mach_msg_size_t dsc_count)659 ipc_kmsg_strip_descriptors(
660 	mach_msg_kdescriptor_t *dst_dsc,
661 	const mach_msg_kdescriptor_t *src_dsc,
662 	mach_msg_size_t         dsc_count)
663 {
664 #if __has_feature(ptrauth_calls)
665 	for (mach_msg_size_t i = 0; i < dsc_count; i++, dst_dsc++, src_dsc++) {
666 		switch (mach_msg_kdescriptor_type(src_dsc)) {
667 		case MACH_MSG_PORT_DESCRIPTOR:
668 			dst_dsc->kdesc_port.kext_name =
669 			    src_dsc->kdesc_port.name;
670 			break;
671 		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
672 		case MACH_MSG_OOL_DESCRIPTOR:
673 			dst_dsc->kdesc_memory.kext_address =
674 			    src_dsc->kdesc_memory.address;
675 			break;
676 		case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
677 			mach_msg_ool_ports_descriptor_t *dsc = &dst_dsc->kdesc_port_array;
678 			ipc_port_t          *ports = dsc->address;
679 			mach_port_array_t    array = dsc->address;
680 
681 			for (mach_msg_size_t j = 0; j < dsc->count; j++) {
682 				ports[i] = array[i].port;
683 			}
684 			dsc->kext_address = array;
685 			break;
686 		}
687 		case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
688 			dst_dsc->kdesc_guarded_port.kext_name =
689 			    src_dsc->kdesc_guarded_port.name;
690 			break;
691 		default:
692 			__ipc_kmsg_descriptor_invalid_type_panic(src_dsc);
693 		}
694 	}
695 #else
696 #pragma unused(dst_dsc, src_dsc, dsc_count)
697 #endif /* __has_feature(ptrauth_calls) */
698 }
699 
700 
701 #pragma mark ipc_kmsg alloc/clean/free
702 
703 static inline void *
ikm_alloc_kdata_ool(size_t size,zalloc_flags_t flags)704 ikm_alloc_kdata_ool(size_t size, zalloc_flags_t flags)
705 {
706 	return kalloc_type_var_impl(KT_IPC_KMSG_KDATA_OOL,
707 	           size, flags, NULL);
708 }
709 
710 static inline void
ikm_free_kdata_ool(void * ptr,size_t size)711 ikm_free_kdata_ool(void *ptr, size_t size)
712 {
713 	kfree_type_var_impl(KT_IPC_KMSG_KDATA_OOL, ptr, size);
714 }
715 
716 /*
717  *	Routine:	ipc_kmsg_alloc
718  *	Purpose:
719  *		Allocate a kernel message structure.  If the
720  *		message is scalar and all the data resides inline, that is best.
721  *      Otherwise, allocate out of line buffers to fit the message and
722  *      the optional auxiliary data.
723  *
724  *	Conditions:
725  *		Nothing locked.
726  *
727  *      kmsg_size doesn't take the trailer or descriptor
728  *		inflation into account, but already accounts for the mach
729  *		message header expansion.
730  */
731 ipc_kmsg_t
ipc_kmsg_alloc(mach_msg_size_t kmsg_size,mach_msg_size_t aux_size,mach_msg_size_t desc_count,ipc_kmsg_alloc_flags_t flags)732 ipc_kmsg_alloc(
733 	mach_msg_size_t         kmsg_size,
734 	mach_msg_size_t         aux_size,
735 	mach_msg_size_t         desc_count,
736 	ipc_kmsg_alloc_flags_t  flags)
737 {
738 	mach_msg_size_t max_kmsg_size, max_delta, max_kdata_size,
739 	    max_udata_size, max_kmsg_and_aux_size;
740 	ipc_kmsg_t kmsg;
741 
742 	void *msg_kdata = NULL, *msg_udata = NULL;
743 	zalloc_flags_t alloc_flags = Z_WAITOK;
744 	ipc_kmsg_type_t kmsg_type;
745 
746 	/*
747 	 * In kernel descriptors, are of the same size (KERNEL_DESC_SIZE),
748 	 * but in userspace, depending on 64-bitness, descriptors might be
749 	 * smaller.
750 	 *
751 	 * When handling a userspace message however, we know how many
752 	 * descriptors have been declared, and we pad for the maximum expansion.
753 	 *
754 	 * During descriptor expansion, message header stays at the same place
755 	 * while everything after it gets shifted to higher address.
756 	 */
757 	if (flags & IPC_KMSG_ALLOC_KERNEL) {
758 		assert(aux_size == 0);
759 		max_delta = 0;
760 	} else if (os_mul_and_add_overflow(desc_count, USER_DESC_MAX_DELTA,
761 	    USER_HEADER_SIZE_DELTA, &max_delta)) {
762 		return IKM_NULL;
763 	}
764 
765 	if (os_add3_overflow(kmsg_size, MAX_TRAILER_SIZE, max_delta, &max_kmsg_size)) {
766 		return IKM_NULL;
767 	}
768 	if (os_add_overflow(max_kmsg_size, aux_size, &max_kmsg_and_aux_size)) {
769 		return IKM_NULL;
770 	}
771 
772 	/* First, determine the layout of the kmsg to allocate */
773 	if (max_kmsg_and_aux_size <= IKM_BIG_MSG_SIZE) {
774 		kmsg_type = IKM_TYPE_ALL_INLINED;
775 		max_udata_size = 0;
776 		max_kdata_size = 0;
777 	} else if (flags & IPC_KMSG_ALLOC_ALL_INLINE) {
778 		panic("size too large for the fast kmsg zone (%d)", kmsg_size);
779 	} else if (flags & IPC_KMSG_ALLOC_LINEAR) {
780 		/*
781 		 * Caller sets MACH64_SEND_KOBJECT_CALL or MACH64_SEND_ANY, or that
782 		 * the call originates from kernel, or it's a mach_msg() call.
783 		 * In any case, message does not carry aux data.
784 		 * We have validated mach_msg2() call options in mach_msg2_trap().
785 		 */
786 		if (aux_size != 0) {
787 			panic("non-zero aux size for kmsg type IKM_TYPE_KDATA_OOL.");
788 		}
789 		kmsg_type = IKM_TYPE_KDATA_OOL;
790 		max_udata_size = 0;
791 		max_kdata_size = max_kmsg_size;
792 	} else {
793 		mach_msg_size_t min_kdata_size;
794 
795 		/*
796 		 * If message can be splitted from the middle, IOW does not need to
797 		 * occupy contiguous memory space, sequester (header + descriptors)
798 		 * from (content + trailer + aux) for memory security.
799 		 */
800 		assert(max_kmsg_and_aux_size > IKM_BIG_MSG_SIZE);
801 
802 		/*
803 		 * max_kdata_size: Maximum combined size of header plus (optional) descriptors.
804 		 * This is _base_ size + descriptor count * kernel descriptor size.
805 		 */
806 		if (os_mul_and_add_overflow(desc_count, KERNEL_DESC_SIZE,
807 		    sizeof(mach_msg_base_t), &max_kdata_size)) {
808 			return IKM_NULL;
809 		}
810 
811 		/*
812 		 * min_kdata_size: Minimum combined size of header plus (optional) descriptors.
813 		 * This is _header_ size + descriptor count * minimal descriptor size.
814 		 */
815 		mach_msg_size_t min_size = (flags & IPC_KMSG_ALLOC_KERNEL) ?
816 		    KERNEL_DESC_SIZE : USER_DESC_SIZE_MIN;
817 		if (os_mul_and_add_overflow(desc_count, min_size,
818 		    sizeof(mach_msg_header_t), &min_kdata_size)) {
819 			return IKM_NULL;
820 		}
821 
822 		/*
823 		 * max_udata_size: Maximum combined size of message content, trailer and aux.
824 		 * This is total kmsg and aux size (already accounts for max trailer size) minus
825 		 * _minimum_ (header + descs) size.
826 		 */
827 		if (os_sub_overflow(max_kmsg_and_aux_size, min_kdata_size, &max_udata_size)) {
828 			return IKM_NULL;
829 		}
830 
831 		if (max_kdata_size <= IKM_SMALL_MSG_SIZE) {
832 			kmsg_type = IKM_TYPE_UDATA_OOL;
833 		} else {
834 			kmsg_type = IKM_TYPE_ALL_OOL;
835 		}
836 	}
837 
838 	if (flags & IPC_KMSG_ALLOC_ZERO) {
839 		alloc_flags |= Z_ZERO;
840 	}
841 	if (flags & IPC_KMSG_ALLOC_NOFAIL) {
842 		alloc_flags |= Z_NOFAIL;
843 	}
844 
845 	/* Then, allocate memory for both udata and kdata if needed, as well as kmsg */
846 	if (max_udata_size > 0) {
847 		msg_udata = kalloc_data(max_udata_size, alloc_flags);
848 		if (__improbable(msg_udata == NULL)) {
849 			return IKM_NULL;
850 		}
851 	}
852 
853 	if (kmsg_type == IKM_TYPE_ALL_OOL || kmsg_type == IKM_TYPE_KDATA_OOL) {
854 		if (kmsg_type == IKM_TYPE_ALL_OOL) {
855 			msg_kdata = kalloc_type(mach_msg_base_t, mach_msg_kdescriptor_t,
856 			    desc_count, alloc_flags | Z_SPRAYQTN);
857 		} else {
858 			msg_kdata = ikm_alloc_kdata_ool(max_kdata_size, alloc_flags);
859 		}
860 
861 		if (__improbable(msg_kdata == NULL)) {
862 			kfree_data(msg_udata, max_udata_size);
863 			return IKM_NULL;
864 		}
865 	}
866 
867 	static_assert(IPC_KMSG_MAX_AUX_DATA_SPACE <= UINT16_MAX,
868 	    "casting aux_size won't truncate");
869 
870 	kmsg = zalloc_id(ZONE_ID_IPC_KMSG, Z_WAITOK | Z_ZERO | Z_NOFAIL);
871 	kmsg->ikm_type = kmsg_type;
872 	kmsg->ikm_aux_size = (uint16_t)aux_size;
873 
874 	if (flags & IPC_KMSG_ALLOC_USE_KEEP_ALIVE) {
875 		assert(kmsg_type == IKM_TYPE_ALL_INLINED);
876 		kmsg->ikm_keep_alive = IKM_KEEP_ALIVE_OWNED;
877 	}
878 
879 	/* Finally, set up pointers properly */
880 	if (kmsg_type == IKM_TYPE_ALL_INLINED) {
881 		assert(msg_udata == NULL && msg_kdata == NULL);
882 	} else {
883 		if (kmsg_type == IKM_TYPE_UDATA_OOL) {
884 			kmsg->ikm_kdata = kmsg->ikm_small_data;
885 		} else {
886 			kmsg->ikm_kdata = msg_kdata;
887 		}
888 		kmsg->ikm_udata = msg_udata;
889 		kmsg->ikm_kdata_size = max_kdata_size;
890 		kmsg->ikm_udata_size = max_udata_size;
891 	}
892 
893 	return kmsg;
894 }
895 
896 /* re-export for IOKit's c++ */
897 extern ipc_kmsg_t ipc_kmsg_alloc_uext_reply(mach_msg_size_t);
898 
899 ipc_kmsg_t
ipc_kmsg_alloc_uext_reply(mach_msg_size_t size)900 ipc_kmsg_alloc_uext_reply(
901 	mach_msg_size_t         size)
902 {
903 	return ipc_kmsg_alloc(size, 0, 0, IPC_KMSG_ALLOC_KERNEL | IPC_KMSG_ALLOC_LINEAR |
904 	           IPC_KMSG_ALLOC_ZERO | IPC_KMSG_ALLOC_NOFAIL);
905 }
906 
907 /*
908  *	Routine:	ipc_kmsg_keep_alive_try_reusing()
909  *	Purpose:
910  *		Attempt to mark a preallocated message in-use.
911  *		Returns true on success, false on failure.
912  */
913 bool
ipc_kmsg_keep_alive_try_reusing(ipc_kmsg_t kmsg)914 ipc_kmsg_keep_alive_try_reusing(ipc_kmsg_t kmsg)
915 {
916 	uintptr_t v;
917 
918 	v = os_atomic_or_orig(&kmsg->ikm_keep_alive,
919 	    IKM_KEEP_ALIVE_IN_USE, relaxed);
920 
921 	/* if the message isn't owned, it can't use keep-alive */
922 	ipc_release_assert(v & IKM_KEEP_ALIVE_OWNED);
923 
924 	return (v & IKM_KEEP_ALIVE_IN_USE) == 0;
925 }
926 
927 /*
928  *	Routine:	ipc_kmsg_keep_alive_done_using
929  *	Purpose:
930  *		Marks an ipc kmsg as no longer in flight.
931  *		Returns true if the message is also no longer owned.
932  */
933 static bool
ipc_kmsg_keep_alive_done_using(ipc_kmsg_t kmsg)934 ipc_kmsg_keep_alive_done_using(ipc_kmsg_t kmsg)
935 {
936 	uintptr_t v = os_atomic_load(&kmsg->ikm_keep_alive, relaxed);
937 
938 	if (v == IKM_KEEP_ALIVE_NONE) {
939 		/* fastpath for most messages not using the facility */
940 		return true;
941 	}
942 
943 	v = os_atomic_andnot_orig(&kmsg->ikm_keep_alive,
944 	    IKM_KEEP_ALIVE_IN_USE, release);
945 
946 	/* if the message wasn't in-use, something is wrong */
947 	ipc_release_assert(v & IKM_KEEP_ALIVE_IN_USE);
948 
949 	if (v & IKM_KEEP_ALIVE_OWNED) {
950 		return false;
951 	}
952 	os_atomic_thread_fence(acquire);
953 	return true;
954 }
955 
956 /*
957  *	Routine:	ipc_kmsg_keep_alive_abandon()
958  *	Purpose:
959  *		Abandons a message that was marked as OWNED
960  *		as part of allocating it with IPC_KMSG_ALLOC_USE_KEEP_ALIVE.
961  */
962 void
ipc_kmsg_keep_alive_abandon(ipc_kmsg_t kmsg)963 ipc_kmsg_keep_alive_abandon(
964 	ipc_kmsg_t              kmsg)
965 {
966 	uintptr_t v;
967 
968 	v = os_atomic_andnot_orig(&kmsg->ikm_keep_alive,
969 	    IKM_KEEP_ALIVE_OWNED, release);
970 
971 	/* if the message wasn't owned, something is wrong */
972 	ipc_release_assert(v & IKM_KEEP_ALIVE_OWNED);
973 
974 	if ((v & IKM_KEEP_ALIVE_IN_USE) == 0) {
975 		os_atomic_thread_fence(acquire);
976 		ipc_kmsg_free(kmsg);
977 	}
978 }
979 
980 /*
981  *	Routine:	ipc_kmsg_free_allocations
982  *	Purpose:
983  *		Free external allocations of a kmsg.
984  *	Conditions:
985  *		Nothing locked.
986  */
987 static void
ipc_kmsg_free_allocations(ipc_kmsg_t kmsg)988 ipc_kmsg_free_allocations(
989 	ipc_kmsg_t              kmsg)
990 {
991 	mach_msg_size_t dsc_count = 0;
992 
993 	switch (kmsg->ikm_type) {
994 	case IKM_TYPE_ALL_INLINED:
995 		break;
996 	case IKM_TYPE_UDATA_OOL:
997 		kfree_data(kmsg->ikm_udata, kmsg->ikm_udata_size);
998 		/* kdata is inlined, udata freed */
999 		break;
1000 	case IKM_TYPE_KDATA_OOL:
1001 		ikm_free_kdata_ool(kmsg->ikm_kdata, kmsg->ikm_kdata_size);
1002 		/* kdata freed, no udata */
1003 		break;
1004 	case IKM_TYPE_ALL_OOL:
1005 		dsc_count = (kmsg->ikm_kdata_size - sizeof(mach_msg_base_t)) /
1006 		    KERNEL_DESC_SIZE;
1007 		kfree_type(mach_msg_base_t, mach_msg_kdescriptor_t, dsc_count,
1008 		    kmsg->ikm_kdata);
1009 		/* kdata freed */
1010 		kfree_data(kmsg->ikm_udata, kmsg->ikm_udata_size);
1011 		/* udata freed */
1012 		break;
1013 	default:
1014 		panic("strange kmsg type");
1015 	}
1016 	kmsg->ikm_type = IKM_TYPE_ALL_INLINED;
1017 
1018 	/* leave nothing dangling or causing out of bounds */
1019 	kmsg->ikm_udata = NULL;
1020 	kmsg->ikm_kdata = NULL;
1021 	kmsg->ikm_udata_size = 0;
1022 	kmsg->ikm_kdata_size = 0;
1023 	kmsg->ikm_aux_size = 0;
1024 }
1025 
1026 /*
1027  *	Routine:	ipc_kmsg_free
1028  *	Purpose:
1029  *		Free a kernel message (and udata) buffer.
1030  *	Conditions:
1031  *		Nothing locked.
1032  */
1033 void
ipc_kmsg_free(ipc_kmsg_t kmsg)1034 ipc_kmsg_free(
1035 	ipc_kmsg_t      kmsg)
1036 {
1037 	assert(!IP_VALID(ipc_kmsg_get_voucher_port(kmsg)));
1038 
1039 	KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_FREE) | DBG_FUNC_NONE,
1040 	    VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
1041 	    0, 0, 0, 0);
1042 
1043 	/*
1044 	 * Check to see if an mk_timer asked for this message to stay
1045 	 * alive.
1046 	 */
1047 	if (kmsg->ikm_type == IKM_TYPE_ALL_INLINED &&
1048 	    !ipc_kmsg_keep_alive_done_using(kmsg)) {
1049 		return;
1050 	}
1051 
1052 	ipc_kmsg_free_allocations(kmsg);
1053 	zfree_id(ZONE_ID_IPC_KMSG, kmsg);
1054 	/* kmsg struct freed */
1055 }
1056 
1057 /*
1058  *	Routine:	ipc_kmsg_clean_header
1059  *	Purpose:
1060  *		Cleans the header of a kmsg.
1061  *	Conditions:
1062  *		Nothing locked.
1063  */
1064 static void
ipc_kmsg_clean_header(ipc_kmsg_t kmsg)1065 ipc_kmsg_clean_header(
1066 	ipc_kmsg_t              kmsg)
1067 {
1068 	ipc_port_t port;
1069 	mach_msg_header_t *hdr = ikm_header(kmsg);
1070 	mach_msg_bits_t mbits = hdr->msgh_bits;
1071 
1072 	/* deal with importance chain while we still have dest and voucher references */
1073 	ipc_importance_clean(kmsg);
1074 
1075 	port = hdr->msgh_remote_port;
1076 	if (IP_VALID(port)) {
1077 		ipc_object_destroy_dest(port, MACH_MSGH_BITS_REMOTE(mbits));
1078 	}
1079 
1080 	port = hdr->msgh_local_port;
1081 	if (IP_VALID(port)) {
1082 		ipc_object_destroy(port, MACH_MSGH_BITS_LOCAL(mbits));
1083 	}
1084 
1085 	port = ipc_kmsg_get_voucher_port(kmsg);
1086 	if (IP_VALID(port)) {
1087 		assert(MACH_MSGH_BITS_VOUCHER(mbits) == MACH_MSG_TYPE_MOVE_SEND);
1088 		ipc_object_destroy(port, MACH_MSG_TYPE_PORT_SEND);
1089 		ipc_kmsg_clear_voucher_port(kmsg);
1090 	}
1091 }
1092 
1093 /*
1094  *	Routine:	ipc_kmsg_clean_descriptors
1095  *	Purpose:
1096  *		Cleans the body of a kernel message.
1097  *		Releases all rights, references, and memory.
1098  *
1099  *	Conditions:
1100  *		No locks held.
1101  */
1102 void
ipc_kmsg_clean_descriptors(mach_msg_kdescriptor_t * kdesc __counted_by (number),mach_msg_type_number_t number)1103 ipc_kmsg_clean_descriptors(
1104 	mach_msg_kdescriptor_t *kdesc __counted_by(number),
1105 	mach_msg_type_number_t  number)
1106 {
1107 	for (mach_msg_type_number_t i = 0; i < number; i++, kdesc++) {
1108 		switch (mach_msg_kdescriptor_type(kdesc)) {
1109 		case MACH_MSG_PORT_DESCRIPTOR: {
1110 			mach_msg_port_descriptor_t *dsc = &kdesc->kdesc_port;
1111 
1112 			/*
1113 			 * Destroy port rights carried in the message
1114 			 */
1115 			if (IP_VALID(dsc->name)) {
1116 				ipc_object_destroy(dsc->name, dsc->disposition);
1117 				dsc->name = IP_NULL;
1118 			}
1119 			break;
1120 		}
1121 		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
1122 		case MACH_MSG_OOL_DESCRIPTOR: {
1123 			mach_msg_ool_descriptor_t *dsc = &kdesc->kdesc_memory;
1124 			vm_map_copy_t copy = dsc->address;
1125 
1126 			/*
1127 			 * Destroy memory carried in the message
1128 			 */
1129 			if (copy) {
1130 				vm_map_copy_discard(copy);
1131 				dsc->address = NULL;
1132 			} else {
1133 				assert(dsc->size == 0);
1134 			}
1135 			break;
1136 		}
1137 		case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
1138 			mach_msg_ool_ports_descriptor_t *dsc = &kdesc->kdesc_port_array;
1139 			mach_port_array_t array = dsc->address;
1140 
1141 			for (mach_msg_size_t j = 0; j < dsc->count; j++) {
1142 				ipc_port_t port = array[j].port;
1143 
1144 				if (IP_VALID(port)) {
1145 					ipc_object_destroy(port, dsc->disposition);
1146 				}
1147 			}
1148 			if (array) {
1149 				mach_port_array_free(array, dsc->count);
1150 				dsc->address = NULL;
1151 			} else {
1152 				assert(dsc->count == 0);
1153 			}
1154 			break;
1155 		}
1156 		case MACH_MSG_GUARDED_PORT_DESCRIPTOR: {
1157 			mach_msg_guarded_port_descriptor_t *dsc = &kdesc->kdesc_guarded_port;
1158 
1159 			/*
1160 			 * Destroy port rights carried in the message
1161 			 */
1162 			if (IP_VALID(dsc->name)) {
1163 				ipc_object_destroy(dsc->name, dsc->disposition);
1164 				dsc->name = IP_NULL;
1165 			}
1166 			break;
1167 		}
1168 		default:
1169 			__ipc_kmsg_descriptor_invalid_type_panic(kdesc);
1170 		}
1171 	}
1172 }
1173 
1174 /*
1175  *	Routine:	ipc_kmsg_clean
1176  *	Purpose:
1177  *		Cleans a kernel message.  Releases all rights,
1178  *		references, and memory held by the message.
1179  *	Conditions:
1180  *		No locks held.
1181  */
1182 
1183 static void
ipc_kmsg_clean(ipc_kmsg_t kmsg,mach_msg_size_t dsc_count)1184 ipc_kmsg_clean(ipc_kmsg_t kmsg, mach_msg_size_t dsc_count)
1185 {
1186 	ipc_kmsg_clean_header(kmsg);
1187 
1188 	if (dsc_count) {
1189 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(ikm_header(kmsg));
1190 
1191 		ipc_kmsg_clean_descriptors(kbase->msgb_dsc_array, dsc_count);
1192 	}
1193 }
1194 
1195 
1196 #pragma mark ipc_kmsg enqueue/destroy, qos, priority, voucher, ...
1197 
1198 /* we can't include the BSD <sys/persona.h> header here... */
1199 #ifndef PERSONA_ID_NONE
1200 #define PERSONA_ID_NONE ((uint32_t)-1)
1201 #endif
1202 
1203 /*
1204  *	Routine:	ipc_kmsg_enqueue_qos
1205  *	Purpose:
1206  *		Enqueue a kmsg, propagating qos
1207  *		overrides towards the head of the queue.
1208  *
1209  *	Returns:
1210  *		whether the head of the queue had
1211  *		it's override-qos adjusted because
1212  *		of this insertion.
1213  */
1214 
1215 bool
ipc_kmsg_enqueue_qos(ipc_kmsg_queue_t queue,ipc_kmsg_t kmsg)1216 ipc_kmsg_enqueue_qos(
1217 	ipc_kmsg_queue_t        queue,
1218 	ipc_kmsg_t              kmsg)
1219 {
1220 	mach_msg_qos_t qos_ovr = kmsg->ikm_qos_override;
1221 	ipc_kmsg_t     prev;
1222 
1223 	if (ipc_kmsg_enqueue(queue, kmsg)) {
1224 		return true;
1225 	}
1226 
1227 	/* apply QoS overrides towards the head */
1228 	prev = ipc_kmsg_queue_element(kmsg->ikm_link.prev);
1229 	while (prev != kmsg) {
1230 		if (qos_ovr <= prev->ikm_qos_override) {
1231 			return false;
1232 		}
1233 		prev->ikm_qos_override = qos_ovr;
1234 		prev = ipc_kmsg_queue_element(prev->ikm_link.prev);
1235 	}
1236 
1237 	return true;
1238 }
1239 
1240 /*
1241  *	Routine:	ipc_kmsg_override_qos
1242  *	Purpose:
1243  *		Update the override for a given kmsg already
1244  *		enqueued, propagating qos override adjustments
1245  *		towards	the head of the queue.
1246  *
1247  *	Returns:
1248  *		whether the head of the queue had
1249  *		it's override-qos adjusted because
1250  *		of this insertion.
1251  */
1252 
1253 bool
ipc_kmsg_override_qos(ipc_kmsg_queue_t queue,ipc_kmsg_t kmsg,mach_msg_qos_t qos_ovr)1254 ipc_kmsg_override_qos(
1255 	ipc_kmsg_queue_t    queue,
1256 	ipc_kmsg_t          kmsg,
1257 	mach_msg_qos_t      qos_ovr)
1258 {
1259 	ipc_kmsg_t first = ipc_kmsg_queue_first(queue);
1260 	ipc_kmsg_t cur = kmsg;
1261 
1262 	/* apply QoS overrides towards the head */
1263 	while (qos_ovr > cur->ikm_qos_override) {
1264 		cur->ikm_qos_override = qos_ovr;
1265 		if (cur == first) {
1266 			return true;
1267 		}
1268 		cur = ipc_kmsg_queue_element(cur->ikm_link.prev);
1269 	}
1270 
1271 	return false;
1272 }
1273 
1274 /*
1275  *	Routine:	ipc_kmsg_destroy
1276  *	Purpose:
1277  *		Destroys a kernel message.  Releases all rights,
1278  *		references, and memory held by the message.
1279  *		Frees the message.
1280  *	Conditions:
1281  *		No locks held.
1282  */
1283 
1284 void
ipc_kmsg_destroy(ipc_kmsg_t kmsg,ipc_kmsg_destroy_flags_t flags)1285 ipc_kmsg_destroy(
1286 	ipc_kmsg_t                     kmsg,
1287 	ipc_kmsg_destroy_flags_t       flags)
1288 {
1289 	/* sign the msg if it has not been signed */
1290 	boolean_t sign_msg = (flags & IPC_KMSG_DESTROY_NOT_SIGNED);
1291 	mach_msg_header_t *hdr = ikm_header(kmsg);
1292 
1293 	if (flags & IPC_KMSG_DESTROY_SKIP_REMOTE) {
1294 		hdr->msgh_remote_port = MACH_PORT_NULL;
1295 		/* re-sign the msg since content changed */
1296 		sign_msg = true;
1297 	}
1298 
1299 	if (flags & IPC_KMSG_DESTROY_SKIP_LOCAL) {
1300 		hdr->msgh_local_port = MACH_PORT_NULL;
1301 		/* re-sign the msg since content changed */
1302 		sign_msg = true;
1303 	}
1304 
1305 	if (sign_msg) {
1306 		ipc_kmsg_sign(kmsg, ipc_kmsg_get_trailer(kmsg));
1307 	}
1308 
1309 	/*
1310 	 *	Destroying a message can cause more messages to be destroyed.
1311 	 *	Curtail recursion by putting messages on the deferred
1312 	 *	destruction queue.  If this was the first message on the
1313 	 *	queue, this instance must process the full queue.
1314 	 */
1315 	if (ipc_kmsg_delayed_destroy(kmsg)) {
1316 		ipc_kmsg_reap_delayed();
1317 	}
1318 }
1319 
1320 /*
1321  *	Routine:	ipc_kmsg_delayed_destroy
1322  *	Purpose:
1323  *		Enqueues a kernel message for deferred destruction.
1324  *	Returns:
1325  *		Boolean indicator that the caller is responsible to reap
1326  *		deferred messages.
1327  */
1328 
1329 bool
ipc_kmsg_delayed_destroy(ipc_kmsg_t kmsg)1330 ipc_kmsg_delayed_destroy(
1331 	ipc_kmsg_t kmsg)
1332 {
1333 	return ipc_kmsg_enqueue(&current_thread()->ith_messages, kmsg);
1334 }
1335 
1336 /*
1337  *	Routine:	ipc_kmsg_delayed_destroy_queue
1338  *	Purpose:
1339  *		Enqueues a queue of kernel messages for deferred destruction.
1340  *	Returns:
1341  *		Boolean indicator that the caller is responsible to reap
1342  *		deferred messages.
1343  */
1344 
1345 bool
ipc_kmsg_delayed_destroy_queue(ipc_kmsg_queue_t queue)1346 ipc_kmsg_delayed_destroy_queue(
1347 	ipc_kmsg_queue_t        queue)
1348 {
1349 	return circle_queue_concat_tail(&current_thread()->ith_messages, queue);
1350 }
1351 
1352 /*
1353  *	Routine:	ipc_kmsg_reap_delayed
1354  *	Purpose:
1355  *		Destroys messages from the per-thread
1356  *		deferred reaping queue.
1357  *	Conditions:
1358  *		No locks held. kmsgs on queue must be signed.
1359  */
1360 
1361 void
ipc_kmsg_reap_delayed(void)1362 ipc_kmsg_reap_delayed(void)
1363 {
1364 	ipc_kmsg_queue_t queue = &(current_thread()->ith_messages);
1365 	ipc_kmsg_t kmsg;
1366 
1367 	/*
1368 	 * must leave kmsg in queue while cleaning it to assure
1369 	 * no nested calls recurse into here.
1370 	 */
1371 	while ((kmsg = ipc_kmsg_queue_first(queue)) != IKM_NULL) {
1372 		/*
1373 		 * Kmsgs queued for delayed destruction either come from
1374 		 * ipc_kmsg_destroy() or ipc_kmsg_delayed_destroy_queue(),
1375 		 * where we handover all kmsgs enqueued on port to destruction
1376 		 * queue in O(1). In either case, all kmsgs must have been
1377 		 * signed.
1378 		 *
1379 		 * For each unreceived msg, validate its signature before freeing.
1380 		 */
1381 		ipc_kmsg_clean(kmsg, ipc_kmsg_validate_signature(kmsg));
1382 		ipc_kmsg_rmqueue(queue, kmsg);
1383 		ipc_kmsg_free(kmsg);
1384 	}
1385 }
1386 
1387 static pthread_priority_compact_t
ipc_get_current_thread_priority(void)1388 ipc_get_current_thread_priority(void)
1389 {
1390 	thread_t thread = current_thread();
1391 	thread_qos_t qos;
1392 	int relpri;
1393 
1394 	qos = thread_get_requested_qos(thread, &relpri);
1395 	if (!qos) {
1396 		qos = thread_user_promotion_qos_for_pri(thread->base_pri);
1397 		relpri = 0;
1398 	}
1399 	return _pthread_priority_make_from_thread_qos(qos, relpri, 0);
1400 }
1401 
1402 static kern_return_t
ipc_kmsg_set_qos(ipc_kmsg_t kmsg,mach_msg_option64_t options,mach_msg_priority_t priority)1403 ipc_kmsg_set_qos(
1404 	ipc_kmsg_t kmsg,
1405 	mach_msg_option64_t options,
1406 	mach_msg_priority_t priority)
1407 {
1408 	kern_return_t kr;
1409 	mach_msg_header_t *hdr = ikm_header(kmsg);
1410 	ipc_port_t special_reply_port = hdr->msgh_local_port;
1411 	ipc_port_t dest_port = hdr->msgh_remote_port;
1412 
1413 	if ((options & MACH_SEND_OVERRIDE) &&
1414 	    !mach_msg_priority_is_pthread_priority(priority)) {
1415 		mach_msg_qos_t qos = mach_msg_priority_qos(priority);
1416 		int relpri = mach_msg_priority_relpri(priority);
1417 		mach_msg_qos_t ovr = mach_msg_priority_overide_qos(priority);
1418 
1419 		kmsg->ikm_ppriority = _pthread_priority_make_from_thread_qos(qos, relpri, 0);
1420 		kmsg->ikm_qos_override = MAX(qos, ovr);
1421 	} else {
1422 #if CONFIG_VOUCHER_DEPRECATED
1423 		kr = ipc_get_pthpriority_from_kmsg_voucher(kmsg, &kmsg->ikm_ppriority);
1424 #else
1425 		kr = KERN_FAILURE;
1426 #endif /* CONFIG_VOUCHER_DEPRECATED */
1427 		if (kr != KERN_SUCCESS) {
1428 			if (options & MACH_SEND_PROPAGATE_QOS) {
1429 				kmsg->ikm_ppriority = ipc_get_current_thread_priority();
1430 			} else {
1431 				kmsg->ikm_ppriority = MACH_MSG_PRIORITY_UNSPECIFIED;
1432 			}
1433 		}
1434 
1435 		if (options & MACH_SEND_OVERRIDE) {
1436 			mach_msg_qos_t qos = _pthread_priority_thread_qos(kmsg->ikm_ppriority);
1437 			mach_msg_qos_t ovr = _pthread_priority_thread_qos(priority);
1438 			kmsg->ikm_qos_override = MAX(qos, ovr);
1439 		} else {
1440 			kmsg->ikm_qos_override = _pthread_priority_thread_qos(kmsg->ikm_ppriority);
1441 		}
1442 	}
1443 
1444 	kr = KERN_SUCCESS;
1445 
1446 	if (IP_VALID(special_reply_port) &&
1447 	    special_reply_port->ip_specialreply &&
1448 	    !ip_is_kobject(dest_port) &&
1449 	    MACH_MSGH_BITS_LOCAL(hdr->msgh_bits) == MACH_MSG_TYPE_PORT_SEND_ONCE) {
1450 		boolean_t sync_bootstrap_checkin = !!(options & MACH_SEND_SYNC_BOOTSTRAP_CHECKIN);
1451 		/*
1452 		 * Link the destination port to special reply port and make sure that
1453 		 * dest port has a send turnstile, else allocate one.
1454 		 */
1455 		ipc_port_link_special_reply_port(special_reply_port, dest_port, sync_bootstrap_checkin);
1456 	}
1457 	return kr;
1458 }
1459 
1460 static kern_return_t
ipc_kmsg_set_qos_kernel(ipc_kmsg_t kmsg)1461 ipc_kmsg_set_qos_kernel(
1462 	ipc_kmsg_t kmsg)
1463 {
1464 	ipc_port_t dest_port = ikm_header(kmsg)->msgh_remote_port;
1465 	kmsg->ikm_qos_override = dest_port->ip_kernel_qos_override;
1466 	kmsg->ikm_ppriority = _pthread_priority_make_from_thread_qos(kmsg->ikm_qos_override, 0, 0);
1467 	return KERN_SUCCESS;
1468 }
1469 
1470 /*
1471  *	Routine:	ipc_kmsg_link_reply_context_locked
1472  *	Purpose:
1473  *		Link any required context from the sending voucher
1474  *		to the reply port. The ipc_kmsg_copyin_from_user function will
1475  *		enforce that the sender calls mach_msg in this context.
1476  *	Conditions:
1477  *		reply port is locked
1478  */
1479 static void
ipc_kmsg_link_reply_context_locked(ipc_port_t reply_port,ipc_port_t voucher_port)1480 ipc_kmsg_link_reply_context_locked(
1481 	ipc_port_t reply_port,
1482 	ipc_port_t voucher_port)
1483 {
1484 	kern_return_t __assert_only kr;
1485 	uint32_t persona_id = 0;
1486 	ipc_voucher_t voucher;
1487 
1488 	ip_mq_lock_held(reply_port);
1489 
1490 	if (!ip_active(reply_port)) {
1491 		return;
1492 	}
1493 
1494 	voucher = convert_port_to_voucher(voucher_port);
1495 
1496 	kr = bank_get_bank_ledger_thread_group_and_persona(voucher, NULL, NULL, &persona_id);
1497 	assert(kr == KERN_SUCCESS);
1498 	ipc_voucher_release(voucher);
1499 
1500 	if (persona_id == 0 || persona_id == PERSONA_ID_NONE) {
1501 		/* there was no persona context to record */
1502 		return;
1503 	}
1504 
1505 	/*
1506 	 * Set the persona_id as the context on the reply port.
1507 	 * This will force the thread that replies to have adopted a voucher
1508 	 * with a matching persona.
1509 	 */
1510 	reply_port->ip_reply_context = persona_id;
1511 
1512 	return;
1513 }
1514 
1515 static kern_return_t
ipc_kmsg_validate_reply_port_locked(ipc_port_t reply_port,mach_msg_option64_t options)1516 ipc_kmsg_validate_reply_port_locked(
1517 	ipc_port_t              reply_port,
1518 	mach_msg_option64_t     options)
1519 {
1520 	ip_mq_lock_held(reply_port);
1521 
1522 	if (!ip_active(reply_port)) {
1523 		/*
1524 		 * Ideally, we would enforce that the reply receive right is
1525 		 * active, but asynchronous XPC cancellation destroys the
1526 		 * receive right, so we just have to return success here.
1527 		 */
1528 		return KERN_SUCCESS;
1529 	}
1530 
1531 	if (options & MACH_SEND_MSG) {
1532 		/*
1533 		 * If the rely port is active, then it should not be
1534 		 * in-transit, and the receive right should be in the caller's
1535 		 * IPC space.
1536 		 */
1537 		if (!ip_in_space(reply_port, current_task()->itk_space)) {
1538 			return KERN_INVALID_CAPABILITY;
1539 		}
1540 
1541 		/*
1542 		 * A port used as a reply port in an RPC should have exactly 1
1543 		 * extant send-once right which we either just made or are
1544 		 * moving as part of the IPC.
1545 		 */
1546 		if (reply_port->ip_sorights != 1) {
1547 			return KERN_INVALID_CAPABILITY;
1548 		}
1549 		/*
1550 		 * XPC uses an extra send-right to keep the name of the reply
1551 		 * right around through cancellation.  That makes it harder to
1552 		 * enforce a particular semantic kere, so for now, we say that
1553 		 * you can have a maximum of 1 send right (in addition to your
1554 		 * send once right). In the future, it would be great to lock
1555 		 * this down even further.
1556 		 */
1557 		if (reply_port->ip_srights > 1) {
1558 			return KERN_INVALID_CAPABILITY;
1559 		}
1560 
1561 		/*
1562 		 * The sender can also specify that the receive right should
1563 		 * be immovable. Note that this check only applies to
1564 		 * send-only operations. Combined send/receive or rcv-only
1565 		 * operations can specify an immovable receive right by
1566 		 * opt-ing into guarded descriptors (MACH_RCV_GUARDED_DESC)
1567 		 * and using the MACH_MSG_STRICT_REPLY options flag.
1568 		 */
1569 		if (MACH_SEND_REPLY_IS_IMMOVABLE(options)) {
1570 			if (!reply_port->ip_immovable_receive) {
1571 				return KERN_INVALID_CAPABILITY;
1572 			}
1573 		}
1574 	}
1575 
1576 	/*
1577 	 * don't enforce this yet: need a better way of indicating the
1578 	 * receiver wants this...
1579 	 */
1580 #if 0
1581 	if (MACH_RCV_WITH_IMMOVABLE_REPLY(options)) {
1582 		if (!reply_port->ip_immovable_receive) {
1583 			return KERN_INVALID_CAPABILITY;
1584 		}
1585 	}
1586 #endif /* 0  */
1587 
1588 	return KERN_SUCCESS;
1589 }
1590 
1591 /*
1592  *	Routine:	ipc_kmsg_validate_reply_context_locked
1593  *	Purpose:
1594  *		Validate that the current thread is running in the context
1595  *		required by the destination port.
1596  *	Conditions:
1597  *		dest_port is locked
1598  *	Returns:
1599  *		MACH_MSG_SUCCESS on success.
1600  *		On error, an EXC_GUARD exception is also raised.
1601  *		This function *always* resets the port reply context.
1602  */
1603 static mach_msg_return_t
ipc_kmsg_validate_reply_context_locked(mach_msg_option64_t option,ipc_port_t dest_port,ipc_voucher_t voucher,mach_port_name_t voucher_name)1604 ipc_kmsg_validate_reply_context_locked(
1605 	mach_msg_option64_t option,
1606 	ipc_port_t dest_port,
1607 	ipc_voucher_t voucher,
1608 	mach_port_name_t voucher_name)
1609 {
1610 	uint32_t dest_ctx = dest_port->ip_reply_context;
1611 	dest_port->ip_reply_context = 0;
1612 
1613 	if (!ip_active(dest_port)) {
1614 		return MACH_MSG_SUCCESS;
1615 	}
1616 
1617 	if (voucher == IPC_VOUCHER_NULL || !MACH_PORT_VALID(voucher_name)) {
1618 		if ((option & MACH_SEND_KERNEL) == 0) {
1619 			mach_port_guard_exception(voucher_name,
1620 			    (MPG_FLAGS_STRICT_REPLY_INVALID_VOUCHER | dest_ctx),
1621 			    kGUARD_EXC_STRICT_REPLY);
1622 		}
1623 		return MACH_SEND_INVALID_CONTEXT;
1624 	}
1625 
1626 	kern_return_t __assert_only kr;
1627 	uint32_t persona_id = 0;
1628 	kr = bank_get_bank_ledger_thread_group_and_persona(voucher, NULL, NULL, &persona_id);
1629 	assert(kr == KERN_SUCCESS);
1630 
1631 	if (dest_ctx != persona_id) {
1632 		if ((option & MACH_SEND_KERNEL) == 0) {
1633 			mach_port_guard_exception(voucher_name,
1634 			    (MPG_FLAGS_STRICT_REPLY_MISMATCHED_PERSONA | ((((uint64_t)persona_id << 32) & MPG_FLAGS_STRICT_REPLY_MASK) | dest_ctx)),
1635 			    kGUARD_EXC_STRICT_REPLY);
1636 		}
1637 		return MACH_SEND_INVALID_CONTEXT;
1638 	}
1639 
1640 	return MACH_MSG_SUCCESS;
1641 }
1642 
1643 
1644 #pragma mark ipc_kmsg copyin and inflate (from user)
1645 /*!
1646  * @defgroup IPC kmsg copyin and inflate functions
1647  * @{
1648  *
1649  * IPC kmsg inflate
1650  * ~~~~~~~~~~~~~~~~
1651  *
1652  * This is the operation that turns the user representation of a message,
1653  * into a message in kernel representation, without any rights.
1654  *
1655  * This is driven by @c ipc_kmsg_get_and_inflate_from_user() which will:
1656  * - convert the message header into kernel layout (mach_msg_header_t),
1657  * - convert the descriptors into kernel layout,
1658  * - copy the body bytes.
1659  *
1660  *
1661  * IPC (right) copyin
1662  * ~~~~~~~~~~~~~~~~~~
1663  *
1664  * This is the operation that turns the userspace port names and VM addresses
1665  * in to actual IPC ports and vm_map_copy_t objects.
1666  *
1667  * This is done on an IPC kmsg in "kernel representation" and just replace
1668  * userspace scalar values with kernel pointers in place.
1669  *
1670  * @c ipc_kmsg_copyin_from_user() is the function that drives the entire
1671  * inflate and copyin logic, applying various filtering at each stage.
1672  */
1673 
1674 
1675 /*
1676  * Macros to help inflate descriptors in place.
1677  *
1678  * the `addr` parameters must be of type `char *` so that the compiler
1679  * must assume these addresses alias (and they do).
1680  */
1681 #define ikm_udsc_type(addr)         __IGNORE_WCASTALIGN(((const mach_msg_type_descriptor_t *)(addr))->type)
1682 #define ikm_udsc_get(dst, addr)     __IGNORE_WCASTALIGN(*(dst) = *(const typeof(*(dst)) *)(addr))
1683 #define ikm_kdsc_zero(addr, type)   ((type *)memset(addr, 0, sizeof(type)))
1684 
1685 typedef struct {
1686 	mach_msg_header_t      *msg;
1687 
1688 	mach_port_name_t        dest_name;
1689 	mach_msg_type_name_t    dest_type;
1690 	ipc_port_t              dest_port;
1691 	ipc_copyin_cleanup_t    dest_cleanup;
1692 
1693 	mach_port_name_t        reply_name;
1694 	mach_msg_type_name_t    reply_type;
1695 	ipc_port_t              reply_port;
1696 	ipc_copyin_cleanup_t    reply_cleanup;
1697 
1698 	mach_port_name_t        voucher_name;
1699 	mach_msg_type_name_t    voucher_type;
1700 	ipc_port_t              voucher_port;
1701 	ipc_copyin_cleanup_t    voucher_cleanup;
1702 
1703 	ipc_table_index_t       dest_request;
1704 	ipc_policy_violation_id_t reply_port_semantics_violation;
1705 } ikm_copyinhdr_state_t;
1706 
1707 /*
1708  *     Routine:        ipc_kmsg_copyin_header_validate
1709  *     Purpose:
1710  *             Perform various preflights on an IPC kmsg
1711  *     Conditions:
1712  *             Nothing locked.
1713  */
1714 static mach_msg_return_t
ipc_kmsg_copyin_header_validate(ipc_kmsg_t kmsg,mach_msg_option64_t options,ikm_copyinhdr_state_t * st)1715 ipc_kmsg_copyin_header_validate(
1716 	ipc_kmsg_t              kmsg,
1717 	mach_msg_option64_t     options,
1718 	ikm_copyinhdr_state_t  *st)
1719 {
1720 	mach_msg_header_t *msg = ikm_header(kmsg);
1721 
1722 	if (msg->msgh_bits & ~MACH_MSGH_BITS_USER) {
1723 		return MACH_SEND_INVALID_HEADER;
1724 	}
1725 
1726 	st->msg = msg;
1727 
1728 	/*
1729 	 *	Validate the reply port and its disposition.
1730 	 */
1731 	st->reply_name = CAST_MACH_PORT_TO_NAME(msg->msgh_local_port);
1732 	st->reply_type = MACH_MSGH_BITS_LOCAL(msg->msgh_bits);
1733 	if (st->reply_type == MACH_MSG_TYPE_NONE) {
1734 		if (st->reply_name != MACH_PORT_NULL) {
1735 			return MACH_SEND_INVALID_HEADER;
1736 		}
1737 	} else if (!MACH_MSG_TYPE_PORT_ANY_SEND(st->reply_type)) {
1738 		return MACH_SEND_INVALID_HEADER;
1739 	}
1740 
1741 	/*
1742 	 *	Validate the voucher and its disposition.
1743 	 *
1744 	 *      The validation is a little nuanced for backward compatbility
1745 	 *      reasons: once upon a time, the "msgh_voucher_port" field was
1746 	 *      reserved, and some clients were expecting it to round-trip.
1747 	 *
1748 	 *      However, for that case, the voucher_type would always be 0
1749 	 *      (because the MACH_MSGH_BITS_USER mask check would reject non
1750 	 *      zero bits), so when it is, we're careful to have the
1751 	 *      msgh_voucher_port value round trip unmodified.
1752 	 */
1753 	st->voucher_name = MACH_PORT_NULL;
1754 	st->voucher_type = MACH_MSGH_BITS_VOUCHER(msg->msgh_bits);
1755 	switch (st->voucher_type) {
1756 	case MACH_MSG_TYPE_NONE:
1757 		break;
1758 	case MACH_MSG_TYPE_MOVE_SEND:
1759 	case MACH_MSG_TYPE_COPY_SEND:
1760 		st->voucher_name = msg->msgh_voucher_port;
1761 		if (st->voucher_name != MACH_PORT_DEAD) {
1762 			break;
1763 		}
1764 		OS_FALLTHROUGH;
1765 	default:
1766 		return MACH_SEND_INVALID_VOUCHER;
1767 	}
1768 
1769 	/*
1770 	 *	Validate the destination and its disposition.
1771 	 */
1772 	st->dest_name = CAST_MACH_PORT_TO_NAME(msg->msgh_remote_port);
1773 	st->dest_type = MACH_MSGH_BITS_REMOTE(msg->msgh_bits);
1774 
1775 	if (!MACH_MSG_TYPE_PORT_ANY_SEND(st->dest_type)) {
1776 		return MACH_SEND_INVALID_HEADER;
1777 	}
1778 
1779 	if (!MACH_PORT_VALID(st->dest_name)) {
1780 		return MACH_SEND_INVALID_DEST;
1781 	}
1782 
1783 	if (st->dest_name == st->voucher_name) {
1784 		/*
1785 		 * If the voucher and destination are the same,
1786 		 * then the disposition for the destination
1787 		 * must be a valid disposition for a voucher!
1788 		 */
1789 		if (st->dest_type != MACH_MSG_TYPE_MOVE_SEND &&
1790 		    st->dest_type != MACH_MSG_TYPE_COPY_SEND) {
1791 			return MACH_SEND_INVALID_DEST;
1792 		}
1793 	}
1794 
1795 	if (st->dest_name == st->reply_name) {
1796 		/*
1797 		 * If the destination and reply port are the same,
1798 		 * no disposition can be a move-send-once.
1799 		 */
1800 		if (st->dest_type == MACH_MSG_TYPE_MOVE_SEND_ONCE ||
1801 		    st->reply_type == MACH_MSG_TYPE_MOVE_SEND_ONCE) {
1802 			return MACH_SEND_INVALID_DEST;
1803 		}
1804 	}
1805 
1806 	if (enforce_strict_reply &&
1807 	    MACH_SEND_WITH_STRICT_REPLY(options) &&
1808 	    (!MACH_PORT_VALID(st->reply_name) ||
1809 	    !MACH_MSG_TYPE_PORT_ANY_SEND_ONCE(st->reply_type))) {
1810 		/*
1811 		 * The caller cannot enforce a reply context with an invalid
1812 		 * reply port name, or a non-send_once reply disposition.
1813 		 */
1814 		mach_port_guard_exception(st->reply_name,
1815 		    (MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_DISP | st->reply_type),
1816 		    kGUARD_EXC_STRICT_REPLY);
1817 		return MACH_SEND_INVALID_REPLY;
1818 	}
1819 
1820 	if (MACH_PORT_VALID(st->reply_name) && st->reply_name == st->voucher_name) {
1821 		return MACH_SEND_INVALID_REPLY;
1822 	}
1823 
1824 	return MACH_MSG_SUCCESS;
1825 }
1826 
1827 /*
1828  *     Routine:        ipc_kmsg_copyin_header_cleanup
1829  *     Purpose:
1830  *             Cleans up the state used for an IPC kmsg header copyin
1831  *     Conditions:
1832  *             Nothing locked.
1833  */
1834 static void
ipc_kmsg_copyin_header_cleanup(ikm_copyinhdr_state_t * st)1835 ipc_kmsg_copyin_header_cleanup(ikm_copyinhdr_state_t *st)
1836 {
1837 	/* the caller must take care of these */
1838 	assert(st->dest_port == IP_NULL);
1839 	assert(st->reply_port == IP_NULL);
1840 	assert(st->voucher_port == IP_NULL);
1841 
1842 	ipc_right_copyin_cleanup_destroy(&st->dest_cleanup, st->dest_name);
1843 	ipc_right_copyin_cleanup_destroy(&st->reply_cleanup, st->reply_name);
1844 	ipc_right_copyin_cleanup_destroy(&st->voucher_cleanup, st->voucher_name);
1845 }
1846 
1847 static inline mach_msg_type_name_t
ipc_kmsg_copyin_dest_disposition(ikm_copyinhdr_state_t * st,ipc_object_copyin_flags_t * xtra)1848 ipc_kmsg_copyin_dest_disposition(
1849 	ikm_copyinhdr_state_t  *st,
1850 	ipc_object_copyin_flags_t *xtra)
1851 {
1852 	mach_msg_type_name_t disp1;
1853 	mach_msg_type_name_t disp2;
1854 
1855 	if (st->dest_name == st->voucher_name) {
1856 		/*
1857 		 *	Do the joint copyin of the dest disposition and
1858 		 *	voucher disposition from the one entry/port.
1859 		 *
1860 		 *	We already validated that the voucher copyin would
1861 		 *	succeed (above), and that the destination port
1862 		 *	disposition is valid for a voucher.
1863 		 */
1864 
1865 		disp1 = st->dest_type;
1866 		disp2 = st->voucher_type;
1867 	} else if (st->dest_name == st->reply_name) {
1868 		/*
1869 		 *	Destination and reply ports are the same!
1870 		 *	This is very similar to the case where the
1871 		 *	destination and voucher ports were the same.
1872 		 *
1873 		 *	ipc_kmsg_copyin_header_validate() tells us that
1874 		 *	neither dest_type nor reply_type is a move-send-once.
1875 		 *
1876 		 *	We need to consider any pair of these:
1877 		 *	{make-send, make-send-once, move-send, copy-send}
1878 		 *
1879 		 *	1. If any is a make-send, then it means one of the
1880 		 *	   dispositions requires a receive right:
1881 		 *
1882 		 *	   If the destination port disposition needs
1883 		 *	   a receive right, its copyin succeeding
1884 		 *	   means the receive right is there.
1885 		 *
1886 		 *	   If the reply port disposition needs a receive
1887 		 *	   right, then it was validated by
1888 		 *	   ipc_right_copyin_check_reply() and we know the
1889 		 *	   receive right is there too.
1890 		 *
1891 		 *	   Hence the port is not in danger of dying
1892 		 *	   while we hold the space lock, we can go
1893 		 *	   one at a time.
1894 		 *
1895 		 *	2. otherwise, we do the joint copyin dance.
1896 		 */
1897 
1898 		if ((st->dest_type == MACH_MSG_TYPE_MAKE_SEND) ||
1899 		    (st->dest_type == MACH_MSG_TYPE_MAKE_SEND_ONCE) ||
1900 		    (st->reply_type == MACH_MSG_TYPE_MAKE_SEND) ||
1901 		    (st->reply_type == MACH_MSG_TYPE_MAKE_SEND_ONCE)) {
1902 			*xtra = IPC_OBJECT_COPYIN_FLAGS_NONE;
1903 			return st->dest_type;
1904 		}
1905 
1906 		disp1 = st->dest_type;
1907 		disp2 = st->reply_type;
1908 	} else {
1909 		/*
1910 		 *	Handle destination and reply independently, as
1911 		 *	they are independent entries (even if the entries
1912 		 *	refer to the same port).
1913 		 *
1914 		 *	This can be the tough case to make atomic.
1915 		 *
1916 		 *	The difficult problem is serializing with port death.
1917 		 *	The bad case is when dest_port dies after its copyin,
1918 		 *	reply_port dies before its copyin, and dest_port dies before
1919 		 *	reply_port.  Then the copyins operated as if dest_port was
1920 		 *	alive and reply_port was dead, which shouldn't have happened
1921 		 *	because they died in the other order.
1922 		 *
1923 		 *	Note that it is easy for a user task to tell if
1924 		 *	a copyin happened before or after a port died.
1925 		 *	If a port dies before copyin, a dead-name notification
1926 		 *	is generated and the dead name's urefs are incremented,
1927 		 *	and if the copyin happens first, a port-deleted
1928 		 *	notification is generated.
1929 		 *
1930 		 *	Even so, avoiding that potentially detectable race is too
1931 		 *	expensive - and no known code cares about it.  So, we just
1932 		 *	do the expedient thing and copy them in one after the other.
1933 		 */
1934 
1935 		*xtra = IPC_OBJECT_COPYIN_FLAGS_NONE;
1936 		return st->dest_type;
1937 	}
1938 
1939 	if (disp1 == MACH_MSG_TYPE_MOVE_SEND && disp2 == MACH_MSG_TYPE_MOVE_SEND) {
1940 		*xtra |= IPC_OBJECT_COPYIN_FLAGS_DEST_EXTRA_MOVE;
1941 		return MACH_MSG_TYPE_MOVE_SEND;
1942 	}
1943 
1944 	if (disp1 == MACH_MSG_TYPE_MOVE_SEND && disp2 == MACH_MSG_TYPE_COPY_SEND) {
1945 		*xtra |= IPC_OBJECT_COPYIN_FLAGS_DEST_EXTRA_COPY;
1946 		return MACH_MSG_TYPE_MOVE_SEND;
1947 	}
1948 	if (disp1 == MACH_MSG_TYPE_COPY_SEND && disp2 == MACH_MSG_TYPE_MOVE_SEND) {
1949 		*xtra |= IPC_OBJECT_COPYIN_FLAGS_DEST_EXTRA_COPY;
1950 		return MACH_MSG_TYPE_MOVE_SEND;
1951 	}
1952 
1953 	if (disp1 == MACH_MSG_TYPE_COPY_SEND && disp2 == MACH_MSG_TYPE_COPY_SEND) {
1954 		*xtra |= IPC_OBJECT_COPYIN_FLAGS_DEST_EXTRA_COPY;
1955 		return MACH_MSG_TYPE_COPY_SEND;
1956 	}
1957 
1958 	ipc_unreachable("not a pair of copy/move-send");
1959 }
1960 
1961 /*
1962  *	Routine:	ipc_kmsg_copyin_header_rights
1963  *	Purpose:
1964  *		Core implementation of ipc_kmsg_copyin_header()
1965  *
1966  *	Conditions:
1967  *		Nothing locked.
1968  *		Returns with the destination port locked on success.
1969  */
1970 static mach_msg_return_t
ipc_kmsg_copyin_header_rights(ipc_space_t space,ikm_copyinhdr_state_t * st)1971 ipc_kmsg_copyin_header_rights(
1972 	ipc_space_t             space,
1973 	ikm_copyinhdr_state_t  *st)
1974 {
1975 	ipc_entry_t dest_entry = IE_NULL;
1976 	ipc_entry_t reply_entry = IE_NULL;
1977 	ipc_entry_t voucher_entry = IE_NULL;
1978 	mach_msg_type_name_t dest_type;
1979 	ipc_object_copyin_flags_t dest_xtra;
1980 	kern_return_t kr;
1981 
1982 	is_write_lock(space);
1983 	if (__improbable(!is_active(space))) {
1984 		is_write_unlock(space);
1985 		return MACH_SEND_INVALID_DEST;
1986 	}
1987 
1988 	/* space locked and active */
1989 
1990 	/*
1991 	 *      Step 1: lookup the various entries
1992 	 *
1993 	 *      Validate that copyins of the voucher and reply ports
1994 	 *      will always succeed.
1995 	 *
1996 	 *      Once we haved copied in the destination port,
1997 	 *      we can't back out.
1998 	 */
1999 
2000 	if (st->voucher_name != MACH_PORT_NULL) {
2001 		voucher_entry = ipc_entry_lookup(space, st->voucher_name);
2002 
2003 		if (voucher_entry == IE_NULL ||
2004 		    (voucher_entry->ie_bits & MACH_PORT_TYPE_SEND) == 0 ||
2005 		    ip_kotype(voucher_entry->ie_port) != IKOT_VOUCHER) {
2006 			is_write_unlock(space);
2007 			return MACH_SEND_INVALID_VOUCHER;
2008 		}
2009 	}
2010 
2011 	if (st->dest_name == st->voucher_name) {
2012 		dest_entry = voucher_entry;
2013 	} else {
2014 		dest_entry = ipc_entry_lookup(space, st->dest_name);
2015 	}
2016 	if (__improbable(dest_entry == IE_NULL ||
2017 	    (dest_entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS) == 0)) {
2018 		is_write_unlock(space);
2019 		return MACH_SEND_INVALID_DEST;
2020 	}
2021 
2022 	if (MACH_PORT_VALID(st->reply_name)) {
2023 		assert(st->reply_name != st->voucher_name);
2024 		if (st->reply_name == st->dest_name) {
2025 			reply_entry = dest_entry;
2026 		} else {
2027 			reply_entry = ipc_entry_lookup(space, st->reply_name);
2028 		}
2029 		if (__improbable(reply_entry == IE_NULL ||
2030 		    (reply_entry->ie_bits & MACH_PORT_TYPE_PORT_RIGHTS) == 0)) {
2031 			is_write_unlock(space);
2032 			return MACH_SEND_INVALID_REPLY;
2033 		}
2034 
2035 		if (__improbable(!ipc_right_copyin_check_reply(space,
2036 		    st->reply_name, reply_entry, st->reply_type, dest_entry,
2037 		    &st->reply_port_semantics_violation))) {
2038 			is_write_unlock(space);
2039 			return MACH_SEND_INVALID_REPLY;
2040 		}
2041 	}
2042 
2043 
2044 	/*
2045 	 *      Step 2: copyin the destination port
2046 	 *
2047 	 *      Handle combinations as required in order to respect
2048 	 *      atomicity with respect to MOVE_{SEND,SEND_ONCE,RECEIVE}
2049 	 *      (COPY/MAKE disposition cause no such headaches).
2050 	 */
2051 
2052 	dest_type = ipc_kmsg_copyin_dest_disposition(st, &dest_xtra);
2053 
2054 	kr = ipc_right_copyin(space, st->dest_name, dest_type,
2055 	    IPC_OBJECT_COPYIN_FLAGS_ALLOW_REPLY_MAKE_SEND_ONCE |
2056 	    IPC_OBJECT_COPYIN_FLAGS_ALLOW_REPLY_MOVE_SEND_ONCE |
2057 	    IPC_OBJECT_COPYIN_FLAGS_ALLOW_IMMOVABLE_SEND |
2058 	    IPC_OBJECT_COPYIN_FLAGS_ALLOW_DEAD_SEND_ONCE |
2059 	    dest_xtra, dest_entry,
2060 	    &st->dest_port, &st->dest_cleanup, NULL);
2061 	if (kr == KERN_SUCCESS) {
2062 		assert(IP_VALID(st->dest_port));
2063 		assert(!IP_VALID(st->dest_cleanup.icc_release_port));
2064 	} else {
2065 		ipc_space_unlock(space);
2066 		return MACH_SEND_INVALID_DEST;
2067 	}
2068 
2069 	/*
2070 	 *      Step 3: copyin the voucher and reply ports if needed.
2071 	 */
2072 	if (st->voucher_name == st->dest_name && dest_xtra) {
2073 		st->voucher_port = st->dest_port;
2074 	} else if (st->voucher_name) {
2075 		kr = ipc_right_copyin(space, st->voucher_name, st->voucher_type,
2076 		    IPC_OBJECT_COPYIN_FLAGS_NONE, voucher_entry,
2077 		    &st->voucher_port, &st->voucher_cleanup, NULL);
2078 
2079 		ipc_release_assert(kr == KERN_SUCCESS);
2080 		assert(IP_VALID(st->voucher_port));
2081 	}
2082 
2083 	if (st->reply_name == st->dest_name && dest_xtra) {
2084 		st->reply_port = st->dest_port;
2085 	} else if (MACH_PORT_VALID(st->reply_name)) {
2086 		kr = ipc_right_copyin(space, st->reply_name, st->reply_type,
2087 		    IPC_OBJECT_COPYIN_FLAGS_ALLOW_REPLY_MAKE_SEND_ONCE |
2088 		    IPC_OBJECT_COPYIN_FLAGS_DEADOK, reply_entry,
2089 		    &st->reply_port, &st->reply_cleanup, NULL);
2090 
2091 		/*
2092 		 * ipc_right_copyin_check_reply() succeding means the
2093 		 * copyin above should work.
2094 		 */
2095 		ipc_release_assert(kr == KERN_SUCCESS);
2096 	} else {
2097 		/* convert invalid name to equivalent ipc_object type */
2098 		st->reply_port = CAST_MACH_NAME_TO_PORT(st->reply_name);
2099 	}
2100 
2101 
2102 	/*
2103 	 *      Step 4: wrap up
2104 	 *
2105 	 *      unlock the space, lock the dest port.
2106 	 *      capture the destination entry "ie_request"
2107 	 */
2108 
2109 	ip_mq_lock(st->dest_port);
2110 
2111 	st->dest_request = dest_entry->ie_request;
2112 
2113 	is_write_unlock(space);
2114 
2115 	return KERN_SUCCESS;
2116 }
2117 
2118 /*
2119  *	Routine:	ipc_kmsg_copyin_header
2120  *	Purpose:
2121  *		"Copy-in" port rights in the header of a message.
2122  *		Operates atomically; if it doesn't succeed the
2123  *		message header and the space are left untouched.
2124  *		If it does succeed the remote/local port fields
2125  *		contain object pointers instead of port names,
2126  *		and the bits field is updated.  The destination port
2127  *		will be a valid port pointer.
2128  *
2129  *	Conditions:
2130  *		Nothing locked. May add MACH64_SEND_ALWAYS option.
2131  *	Returns:
2132  *		MACH_MSG_SUCCESS	Successful copyin.
2133  *		MACH_SEND_INVALID_HEADER
2134  *			Illegal value in the message header bits.
2135  *		MACH_SEND_INVALID_DEST	The space is dead.
2136  *		MACH_SEND_INVALID_DEST	Can't copyin destination port.
2137  *			(Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
2138  *		MACH_SEND_INVALID_REPLY	Can't copyin reply port.
2139  *			(Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
2140  */
2141 
2142 static mach_msg_return_t
ipc_kmsg_copyin_header(ipc_kmsg_t kmsg,ipc_space_t space,mach_msg_priority_t priority,mach_msg_option64_t * option64p)2143 ipc_kmsg_copyin_header(
2144 	ipc_kmsg_t              kmsg,
2145 	ipc_space_t             space,
2146 	mach_msg_priority_t     priority,
2147 	mach_msg_option64_t     *option64p)
2148 {
2149 	mach_msg_option64_t options = *option64p;
2150 	ikm_copyinhdr_state_t st = { };
2151 	struct mach_service_port_info sp_info = {};
2152 	bool needboost = false;
2153 	kern_return_t kr;
2154 
2155 	kr = ipc_kmsg_copyin_header_validate(kmsg, options, &st);
2156 	if (kr == KERN_SUCCESS) {
2157 		kr = ipc_kmsg_copyin_header_rights(space, &st);
2158 	}
2159 
2160 	if (__improbable(kr != KERN_SUCCESS)) {
2161 		if (kr == MACH_SEND_INVALID_VOUCHER) {
2162 			mach_port_guard_exception(st.voucher_name, 0,
2163 			    kGUARD_EXC_SEND_INVALID_VOUCHER);
2164 		}
2165 		if (kr == MACH_SEND_INVALID_REPLY) {
2166 			mach_port_guard_exception(st.reply_name, 0,
2167 			    kGUARD_EXC_SEND_INVALID_REPLY);
2168 		}
2169 		ipc_kmsg_copyin_header_cleanup(&st);
2170 		return kr;
2171 	}
2172 
2173 	/*
2174 	 *  Point of no return: past this point, the send won't fail,
2175 	 *  the message will be swallowed instead
2176 	 *
2177 	 *  The destination port is locked and active.
2178 	 */
2179 	ip_mq_lock_held(st.dest_port);
2180 
2181 	if (IP_VALID(st.voucher_port)) {
2182 		/*
2183 		 * No room to store voucher port in in-kernel msg header,
2184 		 * so we store it back in the kmsg itself.
2185 		 *
2186 		 * Store original voucher type there as well before the bits
2187 		 * are set to the post-copyin type.
2188 		 */
2189 		ipc_kmsg_set_voucher_port(kmsg, st.voucher_port, st.voucher_type);
2190 		st.voucher_port = IP_NULL; /* transfered to the kmsg */
2191 		st.voucher_type = MACH_MSG_TYPE_MOVE_SEND;
2192 	}
2193 	st.dest_type = ipc_object_copyin_type(st.dest_type);
2194 	st.reply_type = ipc_object_copyin_type(st.reply_type);
2195 
2196 #if CONFIG_SERVICE_PORT_INFO
2197 	/*
2198 	 * Service name is later used in CA telemetry in case of reply port security semantics violations.
2199 	 */
2200 	if (ip_active(st.dest_port) && st.dest_port->ip_service_port) {
2201 		assert(st.dest_port->ip_splabel);
2202 		ipc_service_port_label_get_info(st.dest_port->ip_splabel, &sp_info);
2203 	}
2204 #endif /* CONFIG_SERVICE_PORT_INFO */
2205 
2206 	if (!ip_active(st.dest_port) ||
2207 	    (ip_is_kobject(st.dest_port) &&
2208 	    ip_in_space(st.dest_port, ipc_space_kernel))) {
2209 		/*
2210 		 * If the dest port died, or is a kobject AND its receive right
2211 		 * belongs to kernel, allow copyin of immovable send rights
2212 		 * in the message body (port descriptor) to succeed since
2213 		 * those send rights are simply "moved" or "copied" into kernel.
2214 		 *
2215 		 * See: ipc_object_copyin().
2216 		 */
2217 		assert(ip_kotype(st.dest_port) != IKOT_TIMER);
2218 		kmsg->ikm_flags |= IPC_OBJECT_COPYIN_FLAGS_ALLOW_IMMOVABLE_SEND;
2219 	}
2220 
2221 	/*
2222 	 * JMM - Without rdar://problem/6275821, this is the last place we can
2223 	 * re-arm the send-possible notifications.  It may trigger unexpectedly
2224 	 * early (send may NOT have failed), but better than missing.  We assure
2225 	 * we won't miss by forcing MACH_SEND_ALWAYS if we got past arming.
2226 	 */
2227 	if (((options & MACH64_SEND_NOTIFY) != 0) &&
2228 	    st.dest_type != MACH_MSG_TYPE_PORT_SEND_ONCE &&
2229 	    st.dest_request != IE_REQ_NONE &&
2230 	    ip_active(st.dest_port) &&
2231 	    !ip_in_space(st.dest_port, ipc_space_kernel)) {
2232 		/* st.dest_port could be in-transit, or in an ipc space */
2233 		if (ip_full(st.dest_port)) {
2234 			needboost = ipc_port_request_sparm(st.dest_port,
2235 			    st.dest_name, st.dest_request, options, priority);
2236 		} else {
2237 			*option64p |= MACH64_SEND_ALWAYS;
2238 		}
2239 	}
2240 
2241 	/*
2242 	 * If our request is the first boosting send-possible
2243 	 * notification this cycle, push the boost down the
2244 	 * destination port.
2245 	 */
2246 	if (!needboost) {
2247 		ip_mq_unlock(st.dest_port);
2248 #if IMPORTANCE_INHERITANCE
2249 	} else if (!ipc_port_importance_delta(st.dest_port,
2250 	    IPID_OPTION_SENDPOSSIBLE, 1)) {
2251 		ip_mq_unlock(st.dest_port);
2252 #endif /* IMPORTANCE_INHERITANCE */
2253 	}
2254 
2255 	/* st.dest_port is unlocked */
2256 
2257 	st.msg->msgh_bits = MACH_MSGH_BITS_SET(st.dest_type, st.reply_type,
2258 	    st.voucher_type, st.msg->msgh_bits);
2259 	st.msg->msgh_remote_port = st.dest_port;
2260 	st.msg->msgh_local_port = st.reply_port;
2261 	st.dest_port = st.reply_port = IP_NULL; /* transferred to the message */
2262 
2263 	/*
2264 	 * capture the qos value(s) for the kmsg qos,
2265 	 * and apply any override before we enqueue the kmsg.
2266 	 */
2267 	ipc_kmsg_set_qos(kmsg, options, priority);
2268 
2269 	/* then sign the header and trailer as soon as possible */
2270 	ipc_kmsg_init_trailer_and_sign(kmsg, current_task());
2271 
2272 	ipc_kmsg_copyin_header_cleanup(&st);
2273 
2274 	if (enforce_strict_reply && MACH_SEND_WITH_STRICT_REPLY(options) &&
2275 	    IP_VALID(st.msg->msgh_local_port)) {
2276 		/*
2277 		 * We've already validated that the reply disposition is a
2278 		 * [make/move] send-once. Ideally, we should enforce that the
2279 		 * reply port is also not dead, but XPC asynchronous
2280 		 * cancellation can make the reply port dead before we
2281 		 * actually make it to the mach_msg send.
2282 		 *
2283 		 * Here, we ensure that if we have a non-dead reply port, then
2284 		 * the reply port's receive right should not be in-transit,
2285 		 * and should live in the caller's IPC space.
2286 		 */
2287 		ipc_port_t rport = st.msg->msgh_local_port;
2288 		ip_mq_lock(rport);
2289 		kr = ipc_kmsg_validate_reply_port_locked(rport, options);
2290 		ip_mq_unlock(rport);
2291 		if (kr != KERN_SUCCESS) {
2292 			/*
2293 			 * no descriptors have been copied in yet, but the
2294 			 * full header has been copied in: clean it up
2295 			 */
2296 			ipc_kmsg_clean_header(kmsg);
2297 			if ((options & MACH_SEND_KERNEL) == 0) {
2298 				mach_port_guard_exception(st.reply_name,
2299 				    (MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_PORT | kr),
2300 				    kGUARD_EXC_STRICT_REPLY);
2301 			}
2302 			return MACH_SEND_INVALID_REPLY;
2303 		}
2304 	}
2305 
2306 	if (st.reply_port_semantics_violation) {
2307 		/* Currently rate limiting it to sucess paths only. */
2308 		task_t task = current_task_early();
2309 		if (task && st.reply_port_semantics_violation == IPCPV_REPLY_PORT_SEMANTICS) {
2310 			task_lock(task);
2311 			if (!task_has_reply_port_telemetry(task)) {
2312 				/* Crash report rate limited to once per task per host. */
2313 				mach_port_guard_exception(st.reply_name, 0,
2314 				    kGUARD_EXC_REQUIRE_REPLY_PORT_SEMANTICS);
2315 				task_set_reply_port_telemetry(task);
2316 			}
2317 			task_unlock(task);
2318 		}
2319 
2320 		ipc_stash_policy_violations_telemetry(st.reply_port_semantics_violation,
2321 		    &sp_info, st.msg->msgh_id);
2322 	}
2323 
2324 	return MACH_MSG_SUCCESS;
2325 }
2326 
2327 
2328 static mach_msg_return_t
ipc_kmsg_inflate_port_descriptor(char * kdesc_addr,const char * udesc_addr,mach_msg_send_uctx_t * send_uctx)2329 ipc_kmsg_inflate_port_descriptor(
2330 	char                   *kdesc_addr,
2331 	const char             *udesc_addr,
2332 	mach_msg_send_uctx_t   *send_uctx)
2333 {
2334 	mach_msg_user_port_descriptor_t udesc;
2335 	mach_msg_port_descriptor_t *kdesc;
2336 
2337 	ikm_udsc_get(&udesc, udesc_addr);
2338 	if (os_add_overflow(send_uctx->send_dsc_port_count, 1,
2339 	    &send_uctx->send_dsc_port_count)) {
2340 		return MACH_SEND_TOO_LARGE;
2341 	}
2342 
2343 	kdesc = ikm_kdsc_zero(kdesc_addr, mach_msg_port_descriptor_t);
2344 	kdesc->u_name      = CAST_MACH_NAME_TO_PORT(udesc.name);
2345 	kdesc->disposition = udesc.disposition;
2346 	kdesc->type        = udesc.type;
2347 	return MACH_MSG_SUCCESS;
2348 }
2349 
2350 static mach_msg_return_t
ipc_kmsg_copyin_port_descriptor(mach_msg_port_descriptor_t * dsc,ipc_space_t space,ipc_port_t dest_port,ipc_kmsg_t kmsg)2351 ipc_kmsg_copyin_port_descriptor(
2352 	mach_msg_port_descriptor_t *dsc,
2353 	ipc_space_t             space,
2354 	ipc_port_t              dest_port,
2355 	ipc_kmsg_t              kmsg)
2356 {
2357 	mach_msg_type_name_t user_disp = dsc->disposition;
2358 	mach_port_name_t     name = CAST_MACH_PORT_TO_NAME(dsc->u_name);
2359 	mach_msg_type_name_t result_disp;
2360 	ipc_port_t           port;
2361 	kern_return_t        kr;
2362 
2363 	result_disp = ipc_object_copyin_type(user_disp);
2364 	if (MACH_PORT_VALID(name)) {
2365 		kr = ipc_object_copyin(space, name, user_disp,
2366 		    kmsg->ikm_flags, NULL, &port);
2367 		if (kr != KERN_SUCCESS) {
2368 			if (kr == KERN_INVALID_RIGHT) {
2369 				mach_port_guard_exception(name, 0, kGUARD_EXC_SEND_INVALID_RIGHT);
2370 			}
2371 			return MACH_SEND_INVALID_RIGHT;
2372 		}
2373 
2374 		if (result_disp == MACH_MSG_TYPE_PORT_RECEIVE &&
2375 		    ipc_port_check_circularity(port, dest_port)) {
2376 			ikm_header(kmsg)->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2377 		}
2378 		dsc->name = port;
2379 	} else {
2380 		dsc->name = CAST_MACH_NAME_TO_PORT(name);
2381 	}
2382 
2383 	dsc->disposition = result_disp;
2384 	return MACH_MSG_SUCCESS;
2385 }
2386 
2387 
2388 static mach_msg_return_t
ipc_kmsg_inflate_ool_descriptor(char * kdesc_addr,const char * udesc_addr,mach_msg_send_uctx_t * send_uctx,bool isU64)2389 ipc_kmsg_inflate_ool_descriptor(
2390 	char                   *kdesc_addr,
2391 	const char             *udesc_addr,
2392 	mach_msg_send_uctx_t   *send_uctx,
2393 	bool                    isU64)
2394 {
2395 	mach_msg_ool_descriptor64_t udesc;
2396 	mach_msg_ool_descriptor_t *kdesc;
2397 
2398 	if (isU64) {
2399 		ikm_udsc_get(&udesc, udesc_addr);
2400 	} else {
2401 		mach_msg_ool_descriptor32_t udesc32;
2402 
2403 		ikm_udsc_get(&udesc32, udesc_addr);
2404 		udesc = (mach_msg_ool_descriptor64_t){
2405 			.address     = udesc32.address,
2406 			.size        = udesc32.size,
2407 			.deallocate  = udesc32.deallocate,
2408 			.copy        = udesc32.copy,
2409 			.type        = udesc32.type,
2410 		};
2411 	}
2412 
2413 	switch (udesc.copy) {
2414 	case MACH_MSG_PHYSICAL_COPY:
2415 	case MACH_MSG_VIRTUAL_COPY:
2416 		break;
2417 	default:
2418 		return MACH_SEND_INVALID_TYPE;
2419 	}
2420 
2421 	if (udesc.size > msg_ool_size_small &&
2422 	    udesc.copy == MACH_MSG_PHYSICAL_COPY &&
2423 	    !udesc.deallocate) {
2424 		vm_size_t size;
2425 
2426 		if (round_page_overflow(udesc.size, &size) ||
2427 		    os_add_overflow(send_uctx->send_dsc_vm_size, size,
2428 		    &send_uctx->send_dsc_vm_size)) {
2429 			return MACH_MSG_VM_KERNEL;
2430 		}
2431 	}
2432 
2433 	kdesc = ikm_kdsc_zero(kdesc_addr, mach_msg_ool_descriptor_t);
2434 	kdesc->u_address  = udesc.address;
2435 	kdesc->size       = udesc.size;
2436 	kdesc->deallocate = udesc.deallocate;
2437 	kdesc->copy       = udesc.copy;
2438 	kdesc->type       = udesc.type;
2439 	return MACH_MSG_SUCCESS;
2440 }
2441 
2442 static mach_msg_return_t
ipc_kmsg_copyin_ool_descriptor(mach_msg_ool_descriptor_t * dsc,mach_vm_address_t * paddr,vm_size_t * space_needed,vm_map_t map)2443 ipc_kmsg_copyin_ool_descriptor(
2444 	mach_msg_ool_descriptor_t *dsc,
2445 	mach_vm_address_t      *paddr,
2446 	vm_size_t              *space_needed,
2447 	vm_map_t                map)
2448 {
2449 	mach_vm_size_t length = dsc->size;
2450 	vm_map_copy_t  copy = VM_MAP_COPY_NULL;
2451 
2452 	if (length == 0) {
2453 		/* nothing to do */
2454 	} else if (length > msg_ool_size_small &&
2455 	    (dsc->copy == MACH_MSG_PHYSICAL_COPY) && !dsc->deallocate) {
2456 		mach_vm_size_t    length_aligned = round_page(length);
2457 		mach_vm_address_t addr = *paddr;
2458 
2459 		/*
2460 		 * If the request is a physical copy and the source
2461 		 * is not being deallocated, then allocate space
2462 		 * in the kernel's pageable ipc copy map and copy
2463 		 * the data in.  The semantics guarantee that the
2464 		 * data will have been physically copied before
2465 		 * the send operation terminates.  Thus if the data
2466 		 * is not being deallocated, we must be prepared
2467 		 * to page if the region is sufficiently large.
2468 		 */
2469 		if (mach_copyin(dsc->u_address, (char *)addr, length)) {
2470 			return MACH_SEND_INVALID_MEMORY;
2471 		}
2472 
2473 		/*
2474 		 * The kernel ipc copy map is marked no_zero_fill.
2475 		 * If the transfer is not a page multiple, we need
2476 		 * to zero fill the balance.
2477 		 */
2478 		if (!page_aligned(length)) {
2479 			bzero((char *)addr + length, length_aligned - length);
2480 		}
2481 
2482 		if (vm_map_copyin(ipc_kernel_copy_map, addr, length,
2483 		    true, &copy) != KERN_SUCCESS) {
2484 			return MACH_MSG_VM_KERNEL;
2485 		}
2486 
2487 		*paddr        += length_aligned;
2488 		*space_needed -= length_aligned;
2489 	} else {
2490 		/*
2491 		 * Make a vm_map_copy_t of the of the data.  If the
2492 		 * data is small, this will do an optimized physical
2493 		 * copy.  Otherwise, it will do a virtual copy.
2494 		 *
2495 		 * NOTE: A virtual copy is OK if the original is being
2496 		 * deallocted, even if a physical copy was requested.
2497 		 */
2498 		switch (vm_map_copyin(map, dsc->u_address, length,
2499 		    dsc->deallocate, &copy)) {
2500 		case KERN_SUCCESS:
2501 			break;
2502 		case KERN_RESOURCE_SHORTAGE:
2503 			return MACH_MSG_VM_KERNEL;
2504 		default:
2505 			return MACH_SEND_INVALID_MEMORY;
2506 		}
2507 	}
2508 
2509 	dsc->address = copy;
2510 	return MACH_MSG_SUCCESS;
2511 }
2512 
2513 
2514 static mach_msg_return_t
ipc_kmsg_inflate_ool_ports_descriptor(char * kdesc_addr,const char * udesc_addr,mach_msg_send_uctx_t * send_uctx,bool isU64)2515 ipc_kmsg_inflate_ool_ports_descriptor(
2516 	char                   *kdesc_addr,
2517 	const char             *udesc_addr,
2518 	mach_msg_send_uctx_t   *send_uctx,
2519 	bool                    isU64)
2520 {
2521 	mach_msg_ool_ports_descriptor64_t udesc;
2522 	mach_msg_ool_ports_descriptor_t *kdesc;
2523 
2524 	if (isU64) {
2525 		ikm_udsc_get(&udesc, udesc_addr);
2526 	} else {
2527 		mach_msg_ool_ports_descriptor32_t udesc32;
2528 
2529 		ikm_udsc_get(&udesc32, udesc_addr);
2530 		udesc = (mach_msg_ool_ports_descriptor64_t){
2531 			.address     = udesc32.address,
2532 			.deallocate  = udesc32.deallocate,
2533 			.copy        = udesc32.copy,
2534 			.disposition = udesc32.disposition,
2535 			.type        = udesc32.type,
2536 			.count       = udesc32.count,
2537 		};
2538 	}
2539 
2540 	if (os_add_overflow(send_uctx->send_dsc_port_count, udesc.count,
2541 	    &send_uctx->send_dsc_port_count)) {
2542 		return MACH_SEND_TOO_LARGE;
2543 	}
2544 
2545 	kdesc = ikm_kdsc_zero(kdesc_addr, mach_msg_ool_ports_descriptor_t);
2546 	kdesc->u_address   = udesc.address;
2547 	kdesc->deallocate  = udesc.deallocate;
2548 	kdesc->copy        = udesc.copy;
2549 	kdesc->disposition = udesc.disposition;
2550 	kdesc->type        = udesc.type;
2551 	kdesc->count       = udesc.count;
2552 	return MACH_MSG_SUCCESS;
2553 }
2554 
2555 static mach_msg_return_t
ipc_kmsg_copyin_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t * dsc,vm_map_t map,ipc_space_t space,ipc_port_t dest_port,ipc_kmsg_t kmsg)2556 ipc_kmsg_copyin_ool_ports_descriptor(
2557 	mach_msg_ool_ports_descriptor_t *dsc,
2558 	vm_map_t                map,
2559 	ipc_space_t             space,
2560 	ipc_port_t              dest_port,
2561 	ipc_kmsg_t              kmsg)
2562 {
2563 	mach_msg_type_name_t user_disp = dsc->disposition;
2564 	mach_msg_size_t      count = dsc->count;
2565 	mach_msg_type_name_t result_disp;
2566 	mach_port_array_t    array = NULL;
2567 	mach_port_name_t    *names;
2568 	mach_vm_size_t       names_size;
2569 
2570 	result_disp = ipc_object_copyin_type(user_disp);
2571 	names_size  = count * sizeof(mach_port_name_t);
2572 
2573 	if (count) {
2574 		array = mach_port_array_alloc(count, Z_WAITOK | Z_SPRAYQTN);
2575 
2576 		/* use the end of the array to store names we will copy in */
2577 		names = (mach_port_name_t *)(array + count) - count;
2578 
2579 		if (mach_copyin(dsc->u_address, names, names_size)) {
2580 			mach_port_array_free(array, count);
2581 			return MACH_SEND_INVALID_MEMORY;
2582 		}
2583 	}
2584 
2585 	if (dsc->deallocate) {
2586 		(void)mach_vm_deallocate(map, dsc->u_address, names_size);
2587 	}
2588 
2589 	for (mach_msg_size_t i = 0; i < count; i++) {
2590 		mach_port_name_t name = names[i];
2591 		ipc_port_t       port;
2592 		kern_return_t    kr;
2593 
2594 		if (!MACH_PORT_VALID(name)) {
2595 			array[i].port = CAST_MACH_NAME_TO_PORT(name);
2596 			continue;
2597 		}
2598 
2599 		kr = ipc_object_copyin(space, name, user_disp,
2600 		    kmsg->ikm_flags, NULL, &port);
2601 
2602 		if (kr != KERN_SUCCESS) {
2603 			for (mach_msg_size_t j = 0; j < i; j++) {
2604 				port = array[j].port;
2605 				if (IP_VALID(port)) {
2606 					ipc_object_destroy(port, result_disp);
2607 				}
2608 			}
2609 			mach_port_array_free(array, count);
2610 
2611 			if (kr == KERN_INVALID_RIGHT) {
2612 				mach_port_guard_exception(name, 0, kGUARD_EXC_SEND_INVALID_RIGHT);
2613 			}
2614 			return MACH_SEND_INVALID_RIGHT;
2615 		}
2616 
2617 		if (result_disp == MACH_MSG_TYPE_PORT_RECEIVE &&
2618 		    ipc_port_check_circularity(port, dest_port)) {
2619 			ikm_header(kmsg)->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2620 		}
2621 
2622 		array[i].port = port;
2623 	}
2624 
2625 	dsc->disposition = result_disp;
2626 	dsc->address     = array;
2627 	return MACH_MSG_SUCCESS;
2628 }
2629 
2630 
2631 static mach_msg_return_t
ipc_kmsg_inflate_guarded_port_descriptor(char * kdesc_addr,const char * udesc_addr,mach_msg_send_uctx_t * send_uctx,bool isU64)2632 ipc_kmsg_inflate_guarded_port_descriptor(
2633 	char                   *kdesc_addr,
2634 	const char             *udesc_addr,
2635 	mach_msg_send_uctx_t   *send_uctx,
2636 	bool                    isU64)
2637 {
2638 	mach_msg_guarded_port_descriptor64_t udesc;
2639 	mach_msg_guarded_port_descriptor_t *kdesc;
2640 
2641 	if (isU64) {
2642 		ikm_udsc_get(&udesc, udesc_addr);
2643 	} else {
2644 		mach_msg_guarded_port_descriptor32_t udesc32;
2645 
2646 		ikm_udsc_get(&udesc32, udesc_addr);
2647 		udesc = (mach_msg_guarded_port_descriptor64_t){
2648 			.context     = udesc32.context,
2649 			.flags       = udesc32.flags,
2650 			.disposition = udesc32.disposition,
2651 			.type        = udesc32.type,
2652 			.name        = udesc32.name,
2653 		};
2654 	}
2655 
2656 	if (os_add_overflow(send_uctx->send_dsc_port_count, 1,
2657 	    &send_uctx->send_dsc_port_count)) {
2658 		return MACH_SEND_TOO_LARGE;
2659 	}
2660 
2661 	/* Only MACH_MSG_TYPE_MOVE_RECEIVE is supported for now */
2662 	if (udesc.disposition != MACH_MSG_TYPE_MOVE_RECEIVE) {
2663 		return MACH_SEND_INVALID_TYPE;
2664 	}
2665 
2666 	if (!udesc.flags ||
2667 	    ((udesc.flags & ~MACH_MSG_GUARD_FLAGS_MASK) != 0) ||
2668 	    ((udesc.flags & MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND) && (udesc.context != 0))) {
2669 		return MACH_SEND_INVALID_TYPE;
2670 	}
2671 
2672 	kdesc = ikm_kdsc_zero(kdesc_addr, mach_msg_guarded_port_descriptor_t);
2673 	kdesc->u_context   = udesc.context;
2674 	kdesc->flags       = udesc.flags;
2675 	kdesc->disposition = udesc.disposition;
2676 	kdesc->type        = udesc.type;
2677 	kdesc->u_name      = udesc.name;
2678 	return MACH_MSG_SUCCESS;
2679 }
2680 
2681 static mach_msg_return_t
ipc_kmsg_copyin_guarded_port_descriptor(mach_msg_guarded_port_descriptor_t * dsc,ipc_space_t space,ipc_port_t dest_port,ipc_kmsg_t kmsg)2682 ipc_kmsg_copyin_guarded_port_descriptor(
2683 	mach_msg_guarded_port_descriptor_t *dsc,
2684 	ipc_space_t             space,
2685 	ipc_port_t              dest_port,
2686 	ipc_kmsg_t              kmsg)
2687 {
2688 	mach_msg_type_name_t   user_disp = dsc->disposition;
2689 	mach_port_name_t       name = dsc->u_name;
2690 	mach_msg_type_name_t   result_disp;
2691 	ipc_port_t             port;
2692 	kern_return_t          kr;
2693 
2694 	result_disp = ipc_object_copyin_type(user_disp);
2695 	if (MACH_PORT_VALID(name)) {
2696 		kr = ipc_object_copyin(space, name, user_disp,
2697 		    kmsg->ikm_flags, dsc, &port);
2698 		if (kr != KERN_SUCCESS) {
2699 			if (kr == KERN_INVALID_RIGHT) {
2700 				mach_port_guard_exception(name, 0, kGUARD_EXC_SEND_INVALID_RIGHT);
2701 			}
2702 			return MACH_SEND_INVALID_RIGHT;
2703 		}
2704 
2705 		if (result_disp == MACH_MSG_TYPE_PORT_RECEIVE &&
2706 		    ipc_port_check_circularity(port, dest_port)) {
2707 			ikm_header(kmsg)->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2708 		}
2709 		dsc->name = port;
2710 	} else {
2711 		dsc->name = CAST_MACH_NAME_TO_PORT(name);
2712 	}
2713 
2714 	/* dsc->flags were possibly modified by ipc_object_copyin() */
2715 	dsc->disposition = result_disp;
2716 	dsc->u_name      = 0;
2717 	return MACH_MSG_SUCCESS;
2718 }
2719 
2720 
2721 static mach_msg_return_t
ipc_kmsg_inflate_descriptor(char * kdesc,const char * udesc,mach_msg_send_uctx_t * send_uctx,bool isU64)2722 ipc_kmsg_inflate_descriptor(
2723 	char                   *kdesc,
2724 	const char             *udesc,
2725 	mach_msg_send_uctx_t   *send_uctx,
2726 	bool                    isU64)
2727 {
2728 	switch (ikm_udsc_type(udesc)) {
2729 	case MACH_MSG_PORT_DESCRIPTOR:
2730 		return ipc_kmsg_inflate_port_descriptor(kdesc, udesc, send_uctx);
2731 	case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2732 	case MACH_MSG_OOL_DESCRIPTOR:
2733 		return ipc_kmsg_inflate_ool_descriptor(kdesc, udesc, send_uctx, isU64);
2734 	case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2735 		return ipc_kmsg_inflate_ool_ports_descriptor(kdesc, udesc, send_uctx, isU64);
2736 	case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
2737 		return ipc_kmsg_inflate_guarded_port_descriptor(kdesc, udesc, send_uctx, isU64);
2738 	default:
2739 		/* verified by ipc_kmsg_measure_descriptors_from_user() */
2740 		__builtin_unreachable();
2741 	}
2742 }
2743 
2744 static mach_msg_return_t
ipc_kmsg_inflate_descriptors(char * const descs,mach_msg_send_uctx_t * send_uctx,bool isU64)2745 ipc_kmsg_inflate_descriptors(
2746 	char             *const descs,
2747 	mach_msg_send_uctx_t   *send_uctx,
2748 	bool                    isU64)
2749 {
2750 	const mach_msg_size_t   desc_count = send_uctx->send_dsc_count;
2751 	const mach_msg_size_t   desc_ksize = desc_count * KERNEL_DESC_SIZE;
2752 	const mach_msg_size_t   desc_usize = send_uctx->send_dsc_usize;
2753 	char                   *kdesc      = descs;
2754 	char                   *udesc      = descs;
2755 	mach_msg_return_t       mr         = MACH_MSG_SUCCESS;
2756 
2757 	if (__probable(desc_count <= 64)) {
2758 		/*
2759 		 * If there are less than 64 descriptors, then we can use
2760 		 * the udesc_mask to know by how much to shift data,
2761 		 * and inflate right to left.
2762 		 */
2763 		kdesc += desc_ksize;
2764 		udesc += desc_usize;
2765 
2766 		for (uint64_t bit = 1ull << (desc_count - 1); bit; bit >>= 1) {
2767 			kdesc -= KERNEL_DESC_SIZE;
2768 			if (send_uctx->send_dsc_mask & bit) {
2769 				udesc -= USER_DESC_SIZE_MAX;
2770 			} else {
2771 				udesc -= USER_DESC_SIZE_MIN;
2772 			}
2773 			mr = ipc_kmsg_inflate_descriptor(kdesc, udesc,
2774 			    send_uctx, isU64);
2775 			if (mr != MACH_MSG_SUCCESS) {
2776 				return mr;
2777 			}
2778 		}
2779 	} else {
2780 		/*
2781 		 * Else, move all descriptors at the end of the buffer,
2782 		 * and inflate them left to right.
2783 		 */
2784 
2785 		udesc += desc_ksize - desc_usize;
2786 		memmove(udesc, kdesc, desc_usize);
2787 
2788 		for (mach_msg_size_t i = 0; i < desc_count; i++) {
2789 			mach_msg_size_t dsize;
2790 
2791 			dsize = ikm_user_desc_size(ikm_udsc_type(udesc), isU64);
2792 			mr = ipc_kmsg_inflate_descriptor(kdesc, udesc,
2793 			    send_uctx, isU64);
2794 			if (mr != MACH_MSG_SUCCESS) {
2795 				return mr;
2796 			}
2797 			udesc += dsize;
2798 			kdesc += KERNEL_DESC_SIZE;
2799 		}
2800 	}
2801 
2802 	return MACH_MSG_SUCCESS;
2803 }
2804 
2805 static inline bool
ipc_kmsg_user_desc_type_is_valid(mach_msg_descriptor_type_t type,mach_msg_option64_t options)2806 ipc_kmsg_user_desc_type_is_valid(
2807 	mach_msg_descriptor_type_t type,
2808 	mach_msg_option64_t        options)
2809 {
2810 	switch (type) {
2811 	case MACH_MSG_PORT_DESCRIPTOR:
2812 	case MACH_MSG_OOL_DESCRIPTOR:
2813 	case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2814 		return true;
2815 	case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2816 	case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
2817 		/*
2818 		 * only allow port and memory descriptors for kobjects and
2819 		 * driverkit.
2820 		 */
2821 		return !(options & (MACH64_SEND_KOBJECT_CALL | MACH64_SEND_DK_CALL));
2822 	default:
2823 		return false;
2824 	}
2825 }
2826 
2827 /*!
2828  * @brief
2829  * Quickly validate and measure the layout of user descriptors.
2830  *
2831  * @description
2832  * This function fills:
2833  * - the send_dsc_usize field with the size of user descriptors,
2834  * - the send_dsc_mask field representing which of the first 64
2835  *   first descriptors whose size is 12 (bit is 0) or 16 (bit is 1).
2836  *
2837  * @param addr          the address of where user descriptors start.
2838  * @param size          the size of the data to parse (descriptors might
2839  *                      be less, but can't be more).
2840  * @param send_uctx     the context used for this MACH_SEND_MSG operation.
2841  * @param options       the options for this MACH_SEND_MSG operation.
2842  * @param isU64         whether the current user task is 64 bit.
2843  * @returns
2844  * - MACH_MSG_SUCCESS   if parsing was successful.
2845  * - MACH_SEND_MSG_TOO_SMALL
2846  *                      if there wasn't enough data to parse
2847  *                      send_dsc_count descriptors
2848  * - MACH_SEND_INVALID_TYPE
2849  *                      if descriptors types parsed aren't valid
2850  *                      or allowed by policy.
2851  */
2852 __result_use_check
2853 static mach_msg_return_t
ipc_kmsg_measure_descriptors_from_user(vm_address_t addr,mach_msg_size_t size,mach_msg_send_uctx_t * send_uctx,mach_msg_option64_t options,bool isU64)2854 ipc_kmsg_measure_descriptors_from_user(
2855 	vm_address_t            addr,
2856 	mach_msg_size_t         size,
2857 	mach_msg_send_uctx_t   *send_uctx,
2858 	mach_msg_option64_t     options,
2859 	bool                    isU64)
2860 {
2861 	mach_msg_size_t dcnt = send_uctx->send_dsc_count;
2862 	mach_msg_size_t dpos = 0;
2863 	uint64_t        mask = 0;
2864 	uint64_t        bit  = 1;
2865 
2866 	for (mach_msg_size_t i = 0; i < dcnt; i++, bit <<= 1) {
2867 		mach_msg_descriptor_type_t dtype;
2868 		mach_msg_size_t dsize;
2869 
2870 		if (dpos + USER_DESC_SIZE_MIN > size) {
2871 			return MACH_SEND_MSG_TOO_SMALL;
2872 		}
2873 		dtype = ikm_udsc_type(addr + dpos);
2874 		if (!ipc_kmsg_user_desc_type_is_valid(dtype, options)) {
2875 			return MACH_SEND_INVALID_TYPE;
2876 		}
2877 		dsize = ikm_user_desc_size(dtype, isU64);
2878 		if (dsize == USER_DESC_SIZE_MAX) {
2879 			mask |= bit;
2880 		}
2881 		dpos += dsize;
2882 		if (dpos > size) {
2883 			return MACH_SEND_MSG_TOO_SMALL;
2884 		}
2885 	}
2886 
2887 	send_uctx->send_dsc_usize = dpos;
2888 	send_uctx->send_dsc_mask  = mask;
2889 	return MACH_MSG_SUCCESS;
2890 }
2891 
2892 /*
2893  *	Routine:	ipc_kmsg_copyin_body
2894  *	Purpose:
2895  *		"Copy-in" port rights and out-of-line memory
2896  *		in the message body.
2897  *
2898  *		In all failure cases, the message is left holding
2899  *		no rights or memory.  However, the message buffer
2900  *		is not deallocated.  If successful, the message
2901  *		contains a valid destination port.
2902  *	Conditions:
2903  *		Nothing locked.
2904  *	Returns:
2905  *		MACH_MSG_SUCCESS	Successful copyin.
2906  *		MACH_SEND_INVALID_MEMORY	Can't grab out-of-line memory.
2907  *		MACH_SEND_INVALID_RIGHT	Can't copyin port right in body.
2908  *		MACH_SEND_INVALID_TYPE	Bad type specification.
2909  *		MACH_SEND_MSG_TOO_SMALL	Body is too small for types/data.
2910  *		MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
2911  *		MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
2912  *		MACH_SEND_NO_GRANT_DEST	Dest port doesn't accept ports in body
2913  */
2914 
2915 static mach_msg_return_t
ipc_kmsg_copyin_body(ipc_kmsg_t kmsg,mach_msg_send_uctx_t * send_uctx,ipc_space_t space,vm_map_t map)2916 ipc_kmsg_copyin_body(
2917 	ipc_kmsg_t              kmsg,
2918 	mach_msg_send_uctx_t   *send_uctx,
2919 	ipc_space_t             space,
2920 	vm_map_t                map)
2921 {
2922 	mach_msg_type_number_t  dsc_count = send_uctx->send_dsc_count;
2923 	vm_size_t               psize = send_uctx->send_dsc_vm_size;
2924 	mach_vm_address_t       paddr = 0;
2925 	mach_msg_header_t      *hdr   = ikm_header(kmsg);
2926 	mach_msg_kbase_t       *kbase = mach_msg_header_to_kbase(hdr);
2927 	ipc_port_t              dest_port = hdr->msgh_remote_port;
2928 
2929 	assert(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX);
2930 
2931 	/*
2932 	 * Allocate space in the pageable kernel ipc copy map for all the
2933 	 * ool data that is to be physically copied.  Map is marked wait for
2934 	 * space.
2935 	 */
2936 	if (psize) {
2937 		kern_return_t kr;
2938 
2939 		kr  = mach_vm_allocate_kernel(ipc_kernel_copy_map, &paddr, psize,
2940 		    VM_MAP_KERNEL_FLAGS_ANYWHERE(.vm_tag = VM_KERN_MEMORY_IPC));
2941 		if (kr != KERN_SUCCESS) {
2942 			ipc_kmsg_clean_header(kmsg);
2943 			return MACH_MSG_VM_KERNEL;
2944 		}
2945 	}
2946 
2947 	/*
2948 	 * Receive right of a libxpc connection port is moved as a part of kmsg's body
2949 	 * 1. from a client to a service during connection etsablishment.
2950 	 * 2. back to the client on service's death or port deallocation.
2951 	 *
2952 	 * Any other attempt to move this receive right is not allowed.
2953 	 */
2954 	kmsg->ikm_flags |= IPC_OBJECT_COPYIN_FLAGS_ALLOW_CONN_IMMOVABLE_RECEIVE;
2955 
2956 	for (mach_msg_size_t copied_in_dscs = 0; copied_in_dscs < dsc_count; copied_in_dscs++) {
2957 		mach_msg_kdescriptor_t *kdesc = &kbase->msgb_dsc_array[copied_in_dscs];
2958 		mach_msg_return_t mr;
2959 
2960 		switch (mach_msg_kdescriptor_type(kdesc)) {
2961 		case MACH_MSG_PORT_DESCRIPTOR:
2962 			mr = ipc_kmsg_copyin_port_descriptor(&kdesc->kdesc_port,
2963 			    space, dest_port, kmsg);
2964 			break;
2965 		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2966 		case MACH_MSG_OOL_DESCRIPTOR:
2967 			mr = ipc_kmsg_copyin_ool_descriptor(&kdesc->kdesc_memory,
2968 			    &paddr, &psize, map);
2969 			break;
2970 		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2971 			mr = ipc_kmsg_copyin_ool_ports_descriptor(&kdesc->kdesc_port_array,
2972 			    map, space, dest_port, kmsg);
2973 			break;
2974 		case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
2975 			mr = ipc_kmsg_copyin_guarded_port_descriptor(&kdesc->kdesc_guarded_port,
2976 			    space, dest_port, kmsg);
2977 			break;
2978 		default:
2979 			__builtin_unreachable();
2980 		}
2981 
2982 		if (MACH_MSG_SUCCESS != mr) {
2983 			/* clean from start of message descriptors to copied_in_dscs */
2984 			ipc_kmsg_clean_header(kmsg);
2985 			ipc_kmsg_clean_descriptors(kbase->msgb_dsc_array,
2986 			    copied_in_dscs);
2987 			if (psize) {
2988 				kmem_free(ipc_kernel_copy_map, paddr, psize);
2989 			}
2990 			return mr;
2991 		}
2992 	}
2993 
2994 	assert(psize == 0);
2995 	return MACH_MSG_SUCCESS;
2996 }
2997 
2998 /*
2999  *	Routine:	ipc_kmsg_get_and_inflate_from_user()
3000  *	Purpose:
3001  *		Copies in user message (and aux) to the allocated
3002  *		kernel message buffer, and expands header and descriptor
3003  *		into "kernel" format.
3004  *
3005  *	Conditions:
3006  *		msg up to sizeof(mach_msg_user_header_t) has been previously
3007  *		copied in, and number of descriptors has been made known.
3008  *
3009  *		if send_aux_size is not 0, mach_msg_validate_data_vectors()
3010  *		guarantees that aux_size must be larger than
3011  *		mach_msg_aux_header_t.
3012  */
3013 static mach_msg_return_t
ipc_kmsg_get_and_inflate_from_user(ipc_kmsg_t kmsg,mach_msg_send_uctx_t * send_uctx,mach_msg_header_t * khdr,vm_map_t map,mach_msg_option64_t options)3014 ipc_kmsg_get_and_inflate_from_user(
3015 	ipc_kmsg_t              kmsg,
3016 	mach_msg_send_uctx_t   *send_uctx,
3017 	mach_msg_header_t      *khdr,
3018 	vm_map_t                map,
3019 	mach_msg_option64_t     options)
3020 {
3021 	bool                    isU64 = (map->max_offset > VM_MAX_ADDRESS);
3022 	mach_msg_user_header_t *uhdr  = &send_uctx->send_header;
3023 	char                   *kdesc = (char *)khdr; /* where descriptors start */
3024 	char                   *kbody = NULL;         /* where the body starts   */
3025 	mach_msg_size_t         upos  = 0;            /* copyin cursor so far    */
3026 	mach_msg_size_t         usize = send_uctx->send_msg_size;
3027 	mach_msg_return_t       mr    = MACH_MSG_SUCCESS;
3028 
3029 	/*
3030 	 * Step 1: inflate the header in kernel representation
3031 	 *
3032 	 * Notable steps:
3033 	 * - the msgh_bits are normalized
3034 	 * - the msgh_size is incorrect until we measure descriptors
3035 	 */
3036 	*khdr = (mach_msg_header_t){
3037 		.msgh_bits         = uhdr->msgh_bits & MACH_MSGH_BITS_USER,
3038 		.msgh_size         = usize + USER_HEADER_SIZE_DELTA,
3039 		.msgh_remote_port  = CAST_MACH_NAME_TO_PORT(uhdr->msgh_remote_port),
3040 		.msgh_local_port   = CAST_MACH_NAME_TO_PORT(uhdr->msgh_local_port),
3041 		.msgh_voucher_port = uhdr->msgh_voucher_port,
3042 		.msgh_id           = uhdr->msgh_id,
3043 	};
3044 
3045 	if (uhdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3046 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(khdr);
3047 
3048 		kbase->msgb_dsc_count = send_uctx->send_dsc_count;
3049 		kdesc = (char *)(kbase + 1);
3050 		upos  = sizeof(mach_msg_user_base_t);
3051 	} else {
3052 		kdesc = (char *)(khdr + 1);
3053 		upos  = sizeof(mach_msg_user_header_t);
3054 	}
3055 	if (ikm_is_linear(kmsg)) {
3056 		kbody = (char *)kdesc +
3057 		    send_uctx->send_dsc_count * KERNEL_DESC_SIZE;
3058 	} else {
3059 		kbody = kmsg->ikm_udata;
3060 	}
3061 
3062 	/*
3063 	 * Step 2: inflate descriptors in kernel representation
3064 	 *
3065 	 * Notable steps:
3066 	 * - for linear messages we will copy the entire body too at once.
3067 	 * - the msgh_size will be updated for the inflated size of descriptors.
3068 	 */
3069 	if (send_uctx->send_dsc_count) {
3070 		mach_msg_size_t desc_count = send_uctx->send_dsc_count;
3071 		mach_msg_size_t desc_ksize = desc_count * KERNEL_DESC_SIZE;
3072 		mach_msg_size_t copyin_size;
3073 
3074 		/*
3075 		 * If kmsg is linear, copy in all data in the buffer.
3076 		 * Otherwise, first copyin until the end of descriptors
3077 		 * or the message, whichever comes first.
3078 		 */
3079 		if (ikm_is_linear(kmsg)) {
3080 			copyin_size = usize - upos;
3081 		} else {
3082 			copyin_size = MIN(desc_ksize, usize - upos);
3083 		}
3084 		assert((vm_offset_t)kdesc + copyin_size <= ikm_kdata_end(kmsg));
3085 
3086 		if (copyinmsg(send_uctx->send_msg_addr + upos, kdesc, copyin_size)) {
3087 			return MACH_SEND_INVALID_DATA;
3088 		}
3089 		upos += copyin_size;
3090 
3091 		/*
3092 		 * pre-validate and measure the descriptors user claims
3093 		 * to have by checking their size and type.
3094 		 */
3095 		mr = ipc_kmsg_measure_descriptors_from_user((vm_address_t)kdesc,
3096 		    copyin_size, send_uctx, options, isU64);
3097 		if (mr != MACH_MSG_SUCCESS) {
3098 			return mr;
3099 		}
3100 		khdr->msgh_size += desc_ksize - send_uctx->send_dsc_usize;
3101 
3102 		/*
3103 		 * If the descriptors user size is smaller than their
3104 		 * kernel size, we copied in some piece of body that we need to
3105 		 * relocate, and we need to inflate descriptors.
3106 		 */
3107 		if (send_uctx->send_dsc_usize != desc_ksize) {
3108 			memmove(kbody, kdesc + send_uctx->send_dsc_usize,
3109 			    copyin_size - send_uctx->send_dsc_usize);
3110 			kbody += copyin_size - send_uctx->send_dsc_usize;
3111 		}
3112 
3113 		mr = ipc_kmsg_inflate_descriptors(kdesc, send_uctx,
3114 		    map->max_offset > VM_MAX_ADDRESS);
3115 		if (mr != MACH_MSG_SUCCESS) {
3116 			return mr;
3117 		}
3118 	}
3119 
3120 	/*
3121 	 * Step 3: copy pure user data remaining.
3122 	 */
3123 	if (upos < usize &&
3124 	    copyinmsg(send_uctx->send_msg_addr + upos, kbody, usize - upos)) {
3125 		return MACH_SEND_INVALID_DATA;
3126 	}
3127 	kbody += usize - upos;
3128 
3129 	/*
3130 	 * Step 4: copy auxiliary data if any
3131 	 */
3132 	if (send_uctx->send_aux_size) {
3133 		mach_msg_aux_header_t *aux_hdr  = ikm_aux_header(kmsg);
3134 		mach_msg_size_t        aux_size = send_uctx->send_aux_size;
3135 
3136 		assert((vm_offset_t)kbody <= (vm_offset_t)aux_hdr);
3137 		assert(aux_size >= sizeof(aux_hdr[0]));
3138 
3139 		/* initialize aux data header */
3140 		aux_hdr->msgdh_size = send_uctx->send_aux_size;
3141 		aux_hdr->msgdh_reserved = 0;
3142 
3143 		/* copyin aux data after the header */
3144 		if (aux_size > sizeof(aux_hdr[0]) &&
3145 		    copyinmsg(send_uctx->send_aux_addr + sizeof(*aux_hdr),
3146 		    aux_hdr + 1, aux_size - sizeof(*aux_hdr))) {
3147 			return MACH_SEND_INVALID_DATA;
3148 		}
3149 	}
3150 
3151 	return MACH_MSG_SUCCESS;
3152 }
3153 
3154 /*
3155  *	Routine:	ipc_kmsg_copyin_from_user
3156  *	Purpose:
3157  *		"Copy-in" port rights and out-of-line memory
3158  *		in the message.
3159  *
3160  *		In all failure cases, the message is left holding
3161  *		no rights or memory.  However, the message buffer
3162  *		is not deallocated.  If successful, the message
3163  *		contains a valid destination port.
3164  *	Conditions:
3165  *		Nothing locked.
3166  *	Returns:
3167  *		MACH_MSG_SUCCESS	Successful copyin.
3168  *		MACH_SEND_INVALID_HEADER Illegal value in the message header bits.
3169  *		MACH_SEND_INVALID_DEST	Can't copyin destination port.
3170  *		MACH_SEND_INVALID_REPLY	Can't copyin reply port.
3171  *		MACH_SEND_INVALID_MEMORY	Can't grab out-of-line memory.
3172  *		MACH_SEND_INVALID_RIGHT	Can't copyin port right in body.
3173  *		MACH_SEND_INVALID_TYPE	Bad type specification.
3174  *		MACH_SEND_MSG_TOO_SMALL	Body is too small for types/data.
3175  */
3176 
3177 mach_msg_return_t
ipc_kmsg_copyin_from_user(ipc_kmsg_t kmsg,mach_msg_send_uctx_t * send_uctx,ipc_space_t space,vm_map_t map,mach_msg_priority_t priority,mach_msg_option64_t * option64p)3178 ipc_kmsg_copyin_from_user(
3179 	ipc_kmsg_t              kmsg,
3180 	mach_msg_send_uctx_t   *send_uctx,
3181 	ipc_space_t             space,
3182 	vm_map_t                map,
3183 	mach_msg_priority_t     priority,
3184 	mach_msg_option64_t    *option64p)
3185 {
3186 	mach_msg_option64_t options = *option64p;
3187 	mach_msg_header_t  *hdr = ikm_header(kmsg);
3188 	mach_msg_return_t   mr;
3189 
3190 	mr = ipc_validate_kmsg_header_schema_from_user(&send_uctx->send_header,
3191 	    send_uctx->send_dsc_count, options);
3192 	if (mr != MACH_MSG_SUCCESS) {
3193 		return mr;
3194 	}
3195 
3196 	mr = ipc_kmsg_get_and_inflate_from_user(kmsg, send_uctx,
3197 	    hdr, map, options);
3198 	if (mr != MACH_MSG_SUCCESS) {
3199 		return mr;
3200 	}
3201 
3202 	mr = ipc_validate_kmsg_schema_from_user(hdr, send_uctx, options);
3203 	if (mr != MACH_MSG_SUCCESS) {
3204 		return mr;
3205 	}
3206 
3207 	/* copyin_header may add MACH64_SEND_ALWAYS option */
3208 	mr = ipc_kmsg_copyin_header(kmsg, space, priority, option64p);
3209 	if (mr != MACH_MSG_SUCCESS) {
3210 		return mr;
3211 	}
3212 	options = *option64p;
3213 
3214 	mr = ipc_validate_kmsg_header_from_user(hdr, send_uctx, options);
3215 	if (mr != MACH_MSG_SUCCESS) {
3216 		/* no descriptors have been copied in yet */
3217 		ipc_kmsg_clean_header(kmsg);
3218 		return mr;
3219 	}
3220 
3221 	KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_SEND) | DBG_FUNC_NONE,
3222 	    VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3223 	    (uintptr_t)hdr->msgh_bits,
3224 	    (uintptr_t)hdr->msgh_id,
3225 	    VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(ipc_kmsg_get_voucher_port(kmsg))),
3226 	    0);
3227 
3228 	DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_copyin_from_user header:\n%.8x\n%.8x\n%p\n%p\n%p\n%.8x\n",
3229 	    hdr->msgh_size,
3230 	    hdr->msgh_bits,
3231 	    hdr->msgh_remote_port,
3232 	    hdr->msgh_local_port,
3233 	    ipc_kmsg_get_voucher_port(kmsg),
3234 	    hdr->msgh_id);
3235 
3236 	if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3237 		mr = ipc_kmsg_copyin_body(kmsg, send_uctx, space, map);
3238 	}
3239 
3240 	return mr;
3241 }
3242 
3243 /** @} */
3244 #pragma mark ipc_kmsg copyout and deflate (to user)
3245 /*!
3246  * @defgroup IPC kmsg copyout and deflate functions
3247  * @{
3248  *
3249  * IPC (right) copyout
3250  * ~~~~~~~~~~~~~~~~~~~
3251  *
3252  * This is the operation that turns kernel objects like IPC ports or
3253  * vm_map_copy_t and turns them into port names or userspace VM addresses.
3254  *
3255  * This is done on an IPC kmsg in "kernel representation" and just replace
3256  * kernel pointers with scalar values only meaningful to userspace in place.
3257  *
3258  * There are several copyout machineries that will drive this operation:
3259  * - @c ipc_kmsg_copyout() for the regular case,
3260  * - @c ipc_kmsg_copyout_pseudo() for pseud-receive,
3261  * - @c ipc_kmsg_copyout_dest_to_user() for receive error cases
3262  *   where the actual message is destroyed and a minimal message
3263  *   is received instead.
3264  *
3265  * Copied out messages do not hold any "right" in the "kdata" part of the
3266  * message anymore.
3267  *
3268  *
3269  * IPC kmsg deflate
3270  * ~~~~~~~~~~~~~~~~
3271  *
3272  * This is the operation that turns a message in kernel representation,
3273  * but with rights copied out, into user representation.
3274  *
3275  * This is driven by @c ipc_kmsg_deflate() which will:
3276  * - convert the message header into user layout (mach_msg_user_header_t),
3277  * - convert the descriptors into user layout,
3278  * - generate receive time parts of the trailer and convert it to user layout.
3279  *
3280  * This operation mangles the payload of the kmsg, making most of the kmsg
3281  * functions have undefined behavior. The only valid things to do with
3282  * a deflated message is to copy the bytes back to userspace and destroy
3283  * the message with @c ipc_kmsg_free().
3284  *
3285  *
3286  * Note that deflation will maintain the position of the pure data bodies
3287  * trailers and auxiliary data payloads. The deflation causes the header
3288  * desscriptors to contract by moving the start of the message rather
3289  * than by shortening it.
3290  *
3291  * As a result, it means that deflation works left-to-right (end toward start),
3292  * starting with the trailer, then descriptors and header last.
3293  * (@see @c ipc_kmsg_deflate() and @c ipc_kmsg_deflate_descriptors()).
3294  *
3295  *
3296  * IPC kmsg "put"
3297  * ~~~~~~~~~~~~~~
3298  *
3299  * This denotes the operation that copies the paylaod of an IPC kmsg into the
3300  * provided buffer, ending with the IPC kmsg being freed.
3301  *
3302  * There are two possible variants of this operation:
3303  *
3304  * - @c ipc_kmsg_put_to_kernel() which uses a kernel provided buffer,
3305  *   and performs no transformation. It is used for kernel upcall replies
3306  *   (see kernel_mach_msg_rpc()).
3307  *
3308  * - @c ipc_kmsg_put_to_user() which uses a user provided buffer.
3309  *   The message will undergo copyout and deflation before the put to user
3310  *   actually happens. This is used by the user mach_msg() receive paths.
3311  */
3312 
3313 /*!
3314  * @typedef ikm_deflate_context_t
3315  *
3316  * @brief
3317  * Data structure holding the various parameters during a deflate operation.
3318  *
3319  * @field dctx_uhdr             the pointer to the start of the user header
3320  * @field dctx_udata            the pointer to the pure data parts or NULL
3321  * @field dctx_trailer          the pointer to the trailer,
3322  *                              or NULL if doing a pseudo-receive.
3323  * @field dctx_aux_hdr          the pointer to the auxiliary data or NULL.
3324  *
3325  * @field dctx_uhdr_size        the number of bytes to copyout from dctx_uhdr.
3326  * @field dctx_udata_size       the number of bytes to copyout from dctx_udata,
3327  *                              or 0 if dctx_udata is NULL.
3328  * @field dctx_trailer_size     the size of the trailer,
3329  *                              or 0 if dctx_trailer is NULL.
3330  * @field dctx_aux_size         the size of the auxiliary data payload,
3331  *                              or 0 if dctx_aux_hdr is NULL.
3332  * @field dctx_isU64            whether the user process receiving the message
3333  *                              is 32 or 64bits.
3334  */
3335 typedef struct {
3336 	char                   *dctx_uhdr;
3337 	char                   *dctx_udata;
3338 	mach_msg_max_trailer_t *dctx_trailer;
3339 	mach_msg_aux_header_t  *dctx_aux_hdr;
3340 	mach_msg_size_t         dctx_uhdr_size;
3341 	mach_msg_size_t         dctx_udata_size;
3342 	mach_msg_size_t         dctx_trailer_size;
3343 	mach_msg_size_t         dctx_aux_size;
3344 	bool                    dctx_isU64;
3345 } ikm_deflate_context_t;
3346 
3347 #define ipc_kmsg_deflate_put(udesc_end, value) \
3348 	memcpy((udesc_end) - sizeof(*(value)), (value), sizeof(*(value)))
3349 
3350 /*
3351  *	Routine:	ipc_kmsg_copyout_header
3352  *	Purpose:
3353  *		"Copy-out" port rights in the header of a message.
3354  *		Operates atomically; if it doesn't succeed the
3355  *		message header and the space are left untouched.
3356  *		If it does succeed the remote/local port fields
3357  *		contain port names instead of object pointers,
3358  *		and the bits field is updated.
3359  *	Conditions:
3360  *		Nothing locked.
3361  *	Returns:
3362  *		MACH_MSG_SUCCESS	Copied out port rights.
3363  *		MACH_RCV_INVALID_NOTIFY
3364  *			Notify is non-null and doesn't name a receive right.
3365  *			(Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
3366  *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3367  *			The space is dead.
3368  *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3369  *			No room in space for another name.
3370  *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3371  *			Couldn't allocate memory for the reply port.
3372  *		MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3373  *			Couldn't allocate memory for the dead-name request.
3374  */
3375 static mach_msg_return_t
ipc_kmsg_copyout_header(ipc_kmsg_t kmsg,mach_msg_header_t * msg,ipc_space_t space,mach_msg_option64_t option)3376 ipc_kmsg_copyout_header(
3377 	ipc_kmsg_t              kmsg,
3378 	mach_msg_header_t      *msg,
3379 	ipc_space_t             space,
3380 	mach_msg_option64_t     option)
3381 {
3382 	mach_msg_bits_t mbits = msg->msgh_bits;
3383 	ipc_port_t dest = msg->msgh_remote_port;
3384 
3385 	mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3386 	mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3387 	mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3388 	ipc_port_t reply = msg->msgh_local_port;
3389 	ipc_port_t release_reply_port = IP_NULL;
3390 	mach_port_name_t dest_name, reply_name;
3391 
3392 	ipc_port_t voucher = ipc_kmsg_get_voucher_port(kmsg);
3393 	uintptr_t voucher_addr = 0;
3394 	ipc_port_t release_voucher_port = IP_NULL;
3395 	mach_port_name_t voucher_name;
3396 
3397 	uint32_t entries_held = 0;
3398 	boolean_t need_write_lock = FALSE;
3399 	ipc_object_copyout_flags_t reply_copyout_options = IPC_OBJECT_COPYOUT_FLAGS_NONE;
3400 	kern_return_t kr;
3401 
3402 	assert(IP_VALID(dest));
3403 
3404 	/*
3405 	 * While we still hold a reference on the received-from port,
3406 	 * process all send-possible notfications we received along with
3407 	 * the message.
3408 	 */
3409 	ipc_port_spnotify(dest);
3410 
3411 	/*
3412 	 * Reserve any potentially needed entries in the target space.
3413 	 * We'll free any unused before unlocking the space.
3414 	 */
3415 	if (IP_VALID(reply)) {
3416 		entries_held++;
3417 		need_write_lock = TRUE;
3418 	}
3419 	if (IP_VALID(voucher)) {
3420 		assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3421 
3422 		if ((option & MACH_RCV_VOUCHER) != 0) {
3423 			entries_held++;
3424 		}
3425 		need_write_lock = TRUE;
3426 		voucher_addr = unsafe_convert_port_to_voucher(voucher);
3427 	}
3428 
3429 	if (need_write_lock) {
3430 handle_reply_again:
3431 		is_write_lock(space);
3432 
3433 		while (entries_held) {
3434 			if (!is_active(space)) {
3435 				is_write_unlock(space);
3436 				return MACH_RCV_HEADER_ERROR |
3437 				       MACH_MSG_IPC_SPACE;
3438 			}
3439 
3440 			kr = ipc_entries_hold(space, entries_held);
3441 			if (KERN_SUCCESS == kr) {
3442 				break;
3443 			}
3444 
3445 			kr = ipc_entry_grow_table(space, ITS_SIZE_NONE);
3446 			if (KERN_SUCCESS != kr) {
3447 				return MACH_RCV_HEADER_ERROR |
3448 				       MACH_MSG_IPC_SPACE;
3449 			}
3450 			/* space was unlocked and relocked - retry */
3451 		}
3452 
3453 		/* Handle reply port. */
3454 		if (IP_VALID(reply)) {
3455 			ipc_port_t reply_subst = IP_NULL;
3456 			ipc_entry_t entry;
3457 
3458 			ip_mq_lock_check_aligned(reply);
3459 
3460 			/* Is the reply port still active and allowed to be copied out? */
3461 			if (!ip_active(reply) ||
3462 			    !ip_label_check(space, reply, reply_type,
3463 			    &reply_copyout_options, &reply_subst)) {
3464 				/* clear the context value */
3465 				reply->ip_reply_context = 0;
3466 				ip_mq_unlock(reply);
3467 
3468 				assert(reply_subst == IP_NULL);
3469 				release_reply_port = reply;
3470 				reply = IP_DEAD;
3471 				reply_name = MACH_PORT_DEAD;
3472 				goto done_with_reply;
3473 			}
3474 
3475 			/* is the kolabel requesting a substitution */
3476 			if (reply_subst != IP_NULL) {
3477 				/*
3478 				 * port is unlocked, its right consumed
3479 				 * space is unlocked
3480 				 */
3481 				assert(reply_type == MACH_MSG_TYPE_PORT_SEND);
3482 				msg->msgh_local_port = reply = reply_subst;
3483 				goto handle_reply_again;
3484 			}
3485 
3486 
3487 			/* Is there already an entry we can use? */
3488 			if ((reply_type != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
3489 			    ipc_right_reverse(space, reply, &reply_name, &entry)) {
3490 				assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE);
3491 			} else {
3492 				/* claim a held entry for the reply port */
3493 				assert(entries_held > 0);
3494 				entries_held--;
3495 				ipc_entry_claim(space, ip_to_object(reply),
3496 				    &reply_name, &entry);
3497 			}
3498 
3499 			/* space and reply port are locked and active */
3500 			ip_reference(reply);         /* hold onto the reply port */
3501 
3502 			/*
3503 			 * If the receiver would like to enforce strict reply
3504 			 * semantics, and the message looks like it expects a reply,
3505 			 * and contains a voucher, then link the context in the
3506 			 * voucher with the reply port so that the next message sent
3507 			 * to the reply port must come from a thread that has a
3508 			 * matching context (voucher).
3509 			 */
3510 			if (enforce_strict_reply && MACH_RCV_WITH_STRICT_REPLY(option) && IP_VALID(voucher)) {
3511 				if (ipc_kmsg_validate_reply_port_locked(reply, option) != KERN_SUCCESS) {
3512 					/* if the receiver isn't happy with the reply port: fail the receive. */
3513 					assert(!ip_is_pinned(reply));
3514 					ipc_entry_dealloc(space, ip_to_object(reply),
3515 					    reply_name, entry);
3516 					ip_mq_unlock(reply);
3517 					is_write_unlock(space);
3518 					ip_release(reply);
3519 					return MACH_RCV_INVALID_REPLY;
3520 				}
3521 				ipc_kmsg_link_reply_context_locked(reply, voucher);
3522 			} else {
3523 				/*
3524 				 * if the receive did not choose to participate
3525 				 * in the strict reply/RPC, then don't enforce
3526 				 * anything (as this could lead to booby-trapped
3527 				 * messages that kill the server).
3528 				 */
3529 				reply->ip_reply_context = 0;
3530 			}
3531 
3532 			kr = ipc_right_copyout(space, reply, reply_type,
3533 			    IPC_OBJECT_COPYOUT_FLAGS_NONE, reply_name, entry,
3534 			    NULL);
3535 			assert(kr == KERN_SUCCESS);
3536 			/* reply port is unlocked */
3537 		} else {
3538 			reply_name = CAST_MACH_PORT_TO_NAME(reply);
3539 		}
3540 
3541 done_with_reply:
3542 
3543 		/* Handle voucher port. */
3544 		if (voucher_type != MACH_MSGH_BITS_ZERO) {
3545 			assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3546 
3547 			if (!IP_VALID(voucher)) {
3548 				if ((option & MACH_RCV_VOUCHER) == 0) {
3549 					voucher_type = MACH_MSGH_BITS_ZERO;
3550 				}
3551 				voucher_name = MACH_PORT_NULL;
3552 				goto done_with_voucher;
3553 			}
3554 
3555 #if CONFIG_PREADOPT_TG
3556 			struct knote *kn = current_thread()->ith_knote;
3557 			if (kn == ITH_KNOTE_NULL || kn == ITH_KNOTE_PSEUDO) {
3558 				/*
3559 				 * We are not in this path of voucher copyout because of
3560 				 * kevent - we cannot expect a voucher preadopt happening on
3561 				 * this thread for this message later on
3562 				 */
3563 				KDBG_DEBUG(MACHDBG_CODE(DBG_MACH_THREAD_GROUP, MACH_THREAD_GROUP_PREADOPT_NA),
3564 				    thread_tid(current_thread()), 0, 0, 0);
3565 			}
3566 #endif
3567 
3568 			/* clear voucher from its hiding place back in the kmsg */
3569 			ipc_kmsg_clear_voucher_port(kmsg);
3570 
3571 			if ((option & MACH_RCV_VOUCHER) != 0) {
3572 				ipc_entry_t entry;
3573 
3574 				ip_mq_lock_check_aligned(voucher);
3575 
3576 				if (ipc_right_reverse(space, voucher,
3577 				    &voucher_name, &entry)) {
3578 					assert(entry->ie_bits & MACH_PORT_TYPE_SEND);
3579 				} else {
3580 					assert(entries_held > 0);
3581 					entries_held--;
3582 					ipc_entry_claim(space, ip_to_object(voucher), &voucher_name, &entry);
3583 				}
3584 				/* space is locked and active */
3585 
3586 				assert(ip_kotype(voucher) == IKOT_VOUCHER);
3587 				kr = ipc_right_copyout(space, voucher,
3588 				    MACH_MSG_TYPE_MOVE_SEND, IPC_OBJECT_COPYOUT_FLAGS_NONE,
3589 				    voucher_name, entry, NULL);
3590 				/* voucher port is unlocked */
3591 			} else {
3592 				voucher_type = MACH_MSGH_BITS_ZERO;
3593 				release_voucher_port = voucher;
3594 				voucher_name = MACH_PORT_NULL;
3595 			}
3596 		} else {
3597 			voucher_name = msg->msgh_voucher_port;
3598 		}
3599 
3600 done_with_voucher:
3601 
3602 		ip_mq_lock(dest);
3603 		is_write_unlock(space);
3604 	} else {
3605 		/*
3606 		 *	No reply or voucher port!  This is an easy case.
3607 		 *
3608 		 *	We only need to check that the space is still
3609 		 *	active once we locked the destination:
3610 		 *
3611 		 *	- if the space holds a receive right for `dest`,
3612 		 *	  then holding the port lock means we can't fail
3613 		 *	  to notice if the space went dead because
3614 		 *	  the is_write_unlock() will pair with
3615 		 *	  os_atomic_barrier_before_lock_acquire() + ip_mq_lock().
3616 		 *
3617 		 *	- if this space doesn't hold a receive right
3618 		 *	  for `dest`, then `dest->ip_receiver` points
3619 		 *	  elsewhere, and ipc_object_copyout_dest() will
3620 		 *	  handle this situation, and failing to notice
3621 		 *	  that the space was dead is accetable.
3622 		 */
3623 
3624 		os_atomic_barrier_before_lock_acquire();
3625 		ip_mq_lock(dest);
3626 		if (!is_active(space)) {
3627 			ip_mq_unlock(dest);
3628 			return MACH_RCV_HEADER_ERROR | MACH_MSG_IPC_SPACE;
3629 		}
3630 
3631 		reply_name = CAST_MACH_PORT_TO_NAME(reply);
3632 
3633 		if (voucher_type != MACH_MSGH_BITS_ZERO) {
3634 			assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3635 			if ((option & MACH_RCV_VOUCHER) == 0) {
3636 				voucher_type = MACH_MSGH_BITS_ZERO;
3637 			}
3638 			voucher_name = MACH_PORT_NULL;
3639 		} else {
3640 			voucher_name = msg->msgh_voucher_port;
3641 		}
3642 	}
3643 
3644 	/*
3645 	 *	At this point, the space is unlocked and the destination
3646 	 *	port is locked.
3647 	 *	reply_name is taken care of; we still need dest_name.
3648 	 *	We still hold a ref for reply (if it is valid).
3649 	 *
3650 	 *	If the space holds receive rights for the destination,
3651 	 *	we return its name for the right.  Otherwise the task
3652 	 *	managed to destroy or give away the receive right between
3653 	 *	receiving the message and this copyout.  If the destination
3654 	 *	is dead, return MACH_PORT_DEAD, and if the receive right
3655 	 *	exists somewhere else (another space, in transit)
3656 	 *	return MACH_PORT_NULL.
3657 	 *
3658 	 *	Making this copyout operation atomic with the previous
3659 	 *	copyout of the reply port is a bit tricky.  If there was
3660 	 *	no real reply port (it wasn't IP_VALID) then this isn't
3661 	 *	an issue.  If the reply port was dead at copyout time,
3662 	 *	then we are OK, because if dest is dead we serialize
3663 	 *	after the death of both ports and if dest is alive
3664 	 *	we serialize after reply died but before dest's (later) death.
3665 	 *	So assume reply was alive when we copied it out.  If dest
3666 	 *	is alive, then we are OK because we serialize before
3667 	 *	the ports' deaths.  So assume dest is dead when we look at it.
3668 	 *	If reply dies/died after dest, then we are OK because
3669 	 *	we serialize after dest died but before reply dies.
3670 	 *	So the hard case is when reply is alive at copyout,
3671 	 *	dest is dead at copyout, and reply died before dest died.
3672 	 *	In this case pretend that dest is still alive, so
3673 	 *	we serialize while both ports are alive.
3674 	 *
3675 	 *	Because the space lock is held across the copyout of reply
3676 	 *	and locking dest, the receive right for dest can't move
3677 	 *	in or out of the space while the copyouts happen, so
3678 	 *	that isn't an atomicity problem.  In the last hard case
3679 	 *	above, this implies that when dest is dead that the
3680 	 *	space couldn't have had receive rights for dest at
3681 	 *	the time reply was copied-out, so when we pretend
3682 	 *	that dest is still alive, we can return MACH_PORT_NULL.
3683 	 *
3684 	 *	If dest == reply, then we have to make it look like
3685 	 *	either both copyouts happened before the port died,
3686 	 *	or both happened after the port died.  This special
3687 	 *	case works naturally if the timestamp comparison
3688 	 *	is done correctly.
3689 	 */
3690 
3691 	if (ip_active(dest)) {
3692 		ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
3693 		/* dest is unlocked */
3694 	} else {
3695 		ipc_port_timestamp_t timestamp;
3696 
3697 		timestamp = ip_get_death_time(dest);
3698 		ip_mq_unlock(dest);
3699 		ip_release(dest);
3700 
3701 		if (IP_VALID(reply)) {
3702 			ip_mq_lock(reply);
3703 			if (ip_active(reply) ||
3704 			    IP_TIMESTAMP_ORDER(timestamp,
3705 			    ip_get_death_time(reply))) {
3706 				dest_name = MACH_PORT_DEAD;
3707 			} else {
3708 				dest_name = MACH_PORT_NULL;
3709 			}
3710 			ip_mq_unlock(reply);
3711 		} else {
3712 			dest_name = MACH_PORT_DEAD;
3713 		}
3714 	}
3715 
3716 	if (IP_VALID(reply)) {
3717 		ip_release(reply);
3718 	}
3719 
3720 	if (IP_VALID(release_reply_port)) {
3721 		if (reply_type == MACH_MSG_TYPE_PORT_SEND_ONCE) {
3722 			ipc_port_release_sonce(release_reply_port);
3723 		} else {
3724 			ipc_port_release_send(release_reply_port);
3725 		}
3726 	}
3727 
3728 	if ((option & MACH_RCV_VOUCHER) != 0) {
3729 		KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV) | DBG_FUNC_NONE,
3730 		    VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3731 		    (uintptr_t)msg->msgh_bits,
3732 		    (uintptr_t)msg->msgh_id,
3733 		    VM_KERNEL_ADDRPERM(voucher_addr), 0);
3734 	} else {
3735 		KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV_VOUCHER_REFUSED) | DBG_FUNC_NONE,
3736 		    VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3737 		    (uintptr_t)msg->msgh_bits,
3738 		    (uintptr_t)msg->msgh_id,
3739 		    VM_KERNEL_ADDRPERM(voucher_addr), 0);
3740 	}
3741 
3742 	if (IP_VALID(release_voucher_port)) {
3743 		ipc_port_release_send(release_voucher_port);
3744 	}
3745 
3746 	msg->msgh_bits = MACH_MSGH_BITS_SET(reply_type, dest_type,
3747 	    voucher_type, mbits);
3748 	msg->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
3749 	msg->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3750 	msg->msgh_voucher_port = voucher_name;
3751 
3752 	return MACH_MSG_SUCCESS;
3753 }
3754 
3755 /*
3756  *	Routine:	ipc_kmsg_copyout_port
3757  *	Purpose:
3758  *		Copy-out a port right.  Always returns a name,
3759  *		even for unsuccessful return codes.  Always
3760  *		consumes the supplied port.
3761  *	Conditions:
3762  *		Nothing locked.
3763  *	Returns:
3764  *		MACH_MSG_SUCCESS	The space acquired the right
3765  *			(name is valid) or the port is dead (MACH_PORT_DEAD).
3766  *		MACH_MSG_IPC_SPACE	No room in space for the right,
3767  *			or the space is dead.  (Name is MACH_PORT_NULL.)
3768  *		MACH_MSG_IPC_KERNEL	Kernel resource shortage.
3769  *			(Name is MACH_PORT_NULL.)
3770  */
3771 static mach_msg_return_t
ipc_kmsg_copyout_port(ipc_space_t space,ipc_port_t port,mach_msg_type_name_t msgt_name,mach_msg_guarded_port_descriptor_t * gdesc,mach_port_name_t * namep)3772 ipc_kmsg_copyout_port(
3773 	ipc_space_t             space,
3774 	ipc_port_t              port,
3775 	mach_msg_type_name_t    msgt_name,
3776 	mach_msg_guarded_port_descriptor_t *gdesc,
3777 	mach_port_name_t       *namep)
3778 {
3779 	kern_return_t kr;
3780 
3781 	if (!IP_VALID(port)) {
3782 		*namep = CAST_MACH_PORT_TO_NAME(port);
3783 		return MACH_MSG_SUCCESS;
3784 	}
3785 
3786 	kr = ipc_object_copyout(space, port, msgt_name,
3787 	    IPC_OBJECT_COPYOUT_FLAGS_NONE, gdesc, namep);
3788 	if (kr != KERN_SUCCESS) {
3789 		if (kr == KERN_INVALID_CAPABILITY) {
3790 			*namep = MACH_PORT_DEAD;
3791 		} else {
3792 			*namep = MACH_PORT_NULL;
3793 
3794 			if (kr == KERN_RESOURCE_SHORTAGE) {
3795 				return MACH_MSG_IPC_KERNEL;
3796 			} else {
3797 				return MACH_MSG_IPC_SPACE;
3798 			}
3799 		}
3800 	}
3801 
3802 	return MACH_MSG_SUCCESS;
3803 }
3804 
3805 /*
3806  *	Routine:	ipc_kmsg_copyout_reply_port
3807  *	Purpose:
3808  *      Kernel swallows the send-once right associated with reply port.
3809  *      Always returns a name, even for unsuccessful return codes.
3810  *      Returns
3811  *          MACH_MSG_SUCCESS Returns name of receive right for reply port.
3812  *              Name is valid if the space acquired the right and msgt_name would be changed from MOVE_SO to MAKE_SO.
3813  *              Name is MACH_PORT_DEAD if the port is dead.
3814  *              Name is MACH_PORT_NULL if its entry could not be found in task's ipc space.
3815  *          MACH_MSG_IPC_SPACE
3816  *              The space is dead.  (Name is MACH_PORT_NULL.)
3817  *	Conditions:
3818  *      Nothing locked.
3819  */
3820 static mach_msg_return_t
ipc_kmsg_copyout_reply_port(ipc_space_t space,ipc_port_t port,mach_msg_type_name_t * msgt_name,mach_port_name_t * namep)3821 ipc_kmsg_copyout_reply_port(
3822 	ipc_space_t             space,
3823 	ipc_port_t              port,
3824 	mach_msg_type_name_t   *msgt_name,
3825 	mach_port_name_t       *namep)
3826 {
3827 	ipc_entry_t entry;
3828 	kern_return_t kr;
3829 
3830 	if (!IP_VALID(port)) {
3831 		*namep = CAST_MACH_PORT_TO_NAME(port);
3832 		return MACH_MSG_SUCCESS;
3833 	}
3834 
3835 	assert(ip_is_reply_port(port));
3836 	assert(*msgt_name == MACH_MSG_TYPE_PORT_SEND_ONCE);
3837 
3838 	is_write_lock(space);
3839 
3840 	if (!is_active(space)) {
3841 		ipc_port_release_sonce(port);
3842 		is_write_unlock(space);
3843 		*namep = MACH_PORT_NULL;
3844 		return MACH_MSG_IPC_SPACE;
3845 	}
3846 
3847 	ip_mq_lock(port);
3848 
3849 	if (!ip_active(port)) {
3850 		*namep = MACH_PORT_DEAD;
3851 		kr = MACH_MSG_SUCCESS;
3852 		goto out;
3853 	}
3854 
3855 	/* space is locked and active. port is locked and active. */
3856 	if (!ipc_right_reverse(space, port, namep, &entry)) {
3857 		*namep = MACH_PORT_NULL;
3858 		kr = MACH_MSG_SUCCESS;
3859 		goto out;
3860 	}
3861 
3862 	assert(entry->ie_bits & MACH_PORT_TYPE_RECEIVE);
3863 
3864 	*msgt_name = MACH_MSG_TYPE_MAKE_SEND_ONCE;
3865 	ipc_port_release_sonce_and_unlock(port);
3866 	/* port is unlocked. */
3867 
3868 	is_write_unlock(space);
3869 
3870 	return MACH_MSG_SUCCESS;
3871 
3872 out:
3873 
3874 	/* space and object are locked. */
3875 	ipc_port_release_sonce_and_unlock(port);
3876 
3877 	is_write_unlock(space);
3878 
3879 	return kr;
3880 }
3881 
3882 
3883 static mach_msg_return_t
ipc_kmsg_copyout_port_descriptor(mach_msg_port_descriptor_t * dsc,ipc_space_t space)3884 ipc_kmsg_copyout_port_descriptor(
3885 	mach_msg_port_descriptor_t *dsc,
3886 	ipc_space_t             space)
3887 {
3888 	mach_port_name_t  name;
3889 	mach_msg_return_t mr;
3890 
3891 	/* Copyout port right carried in the message */
3892 	mr = ipc_kmsg_copyout_port(space, dsc->name, dsc->disposition,
3893 	    NULL, &name);
3894 	dsc->u_name = CAST_MACH_NAME_TO_PORT(name);
3895 	return mr;
3896 }
3897 
3898 static char *
ipc_kmsg_deflate_port_descriptor(char * udesc_end,const mach_msg_port_descriptor_t * kdesc)3899 ipc_kmsg_deflate_port_descriptor(
3900 	char                   *udesc_end,
3901 	const mach_msg_port_descriptor_t *kdesc)
3902 {
3903 	mach_msg_user_port_descriptor_t udesc = {
3904 		.name        = CAST_MACH_PORT_TO_NAME(kdesc->u_name),
3905 		.disposition = kdesc->disposition,
3906 		.type        = kdesc->type,
3907 	};
3908 
3909 	return ipc_kmsg_deflate_put(udesc_end, &udesc);
3910 }
3911 #if 0 /* done to avoid merge conflicts, will be cleaned up with RDAR_91262248 */
3912 }
3913 
3914 extern const char *proc_best_name(struct proc *proc);
3915 static mach_msg_descriptor_t *
3916 
3917 #endif
3918 static mach_msg_return_t
ipc_kmsg_copyout_ool_descriptor(mach_msg_ool_descriptor_t * dsc,vm_map_t map)3919 ipc_kmsg_copyout_ool_descriptor(
3920 	mach_msg_ool_descriptor_t  *dsc,
3921 	vm_map_t                    map)
3922 {
3923 	vm_map_copy_t               copy = dsc->address;
3924 	vm_map_size_t               size = dsc->size;
3925 	vm_map_address_t            rcv_addr;
3926 	boolean_t                   misaligned = FALSE;
3927 	mach_msg_return_t           mr  = MACH_MSG_SUCCESS;
3928 
3929 	if (copy != VM_MAP_COPY_NULL) {
3930 		kern_return_t kr;
3931 
3932 		rcv_addr = 0;
3933 		if (vm_map_copy_validate_size(map, copy, &size) == FALSE) {
3934 			panic("Inconsistent OOL/copyout size on %p: expected %d, got %lld @%p",
3935 			    dsc, dsc->size, (unsigned long long)copy->size, copy);
3936 		}
3937 
3938 		if ((copy->type == VM_MAP_COPY_ENTRY_LIST) &&
3939 		    (trunc_page(copy->offset) != copy->offset ||
3940 		    round_page(dsc->size) != dsc->size)) {
3941 			misaligned = TRUE;
3942 		}
3943 
3944 		if (misaligned) {
3945 			mach_vm_offset_t rounded_addr;
3946 			vm_map_size_t   rounded_size;
3947 			vm_map_offset_t effective_page_mask, effective_page_size;
3948 
3949 			effective_page_mask = VM_MAP_PAGE_MASK(map);
3950 			effective_page_size = effective_page_mask + 1;
3951 
3952 			rounded_size = vm_map_round_page(copy->offset + size, effective_page_mask) - vm_map_trunc_page(copy->offset, effective_page_mask);
3953 
3954 			kr = mach_vm_allocate_kernel(map, &rounded_addr, rounded_size,
3955 			    VM_MAP_KERNEL_FLAGS_ANYWHERE(.vm_tag = VM_MEMORY_MACH_MSG));
3956 
3957 			if (kr == KERN_SUCCESS) {
3958 				/*
3959 				 * vm_map_copy_overwrite does a full copy
3960 				 * if size is too small to optimize.
3961 				 * So we tried skipping the offset adjustment
3962 				 * if we fail the 'size' test.
3963 				 *
3964 				 * if (size >= VM_MAP_COPY_OVERWRITE_OPTIMIZATION_THRESHOLD_PAGES * effective_page_size)
3965 				 *
3966 				 * This resulted in leaked memory especially on the
3967 				 * older watches (16k user - 4k kernel) because we
3968 				 * would do a physical copy into the start of this
3969 				 * rounded range but could leak part of it
3970 				 * on deallocation if the 'size' being deallocated
3971 				 * does not cover the full range. So instead we do
3972 				 * the misalignment adjustment always so that on
3973 				 * deallocation we will remove the full range.
3974 				 */
3975 				if ((rounded_addr & effective_page_mask) !=
3976 				    (copy->offset & effective_page_mask)) {
3977 					/*
3978 					 * Need similar mis-alignment of source and destination...
3979 					 */
3980 					rounded_addr += (copy->offset & effective_page_mask);
3981 
3982 					assert((rounded_addr & effective_page_mask) == (copy->offset & effective_page_mask));
3983 				}
3984 				rcv_addr = rounded_addr;
3985 
3986 				kr = vm_map_copy_overwrite(map, rcv_addr, copy, size,
3987 				    FALSE);
3988 			}
3989 		} else {
3990 			kr = vm_map_copyout_size(map, &rcv_addr, copy, size);
3991 		}
3992 		if (kr != KERN_SUCCESS) {
3993 			if (kr == KERN_RESOURCE_SHORTAGE) {
3994 				mr = MACH_MSG_VM_KERNEL;
3995 			} else {
3996 				mr = MACH_MSG_VM_SPACE;
3997 			}
3998 			vm_map_copy_discard(copy);
3999 			rcv_addr = 0;
4000 			size = 0;
4001 		}
4002 	} else {
4003 		rcv_addr = 0;
4004 		size = 0;
4005 	}
4006 
4007 	dsc->u_address = rcv_addr;
4008 	dsc->size      = size;
4009 	return mr;
4010 }
4011 
4012 static char *
ipc_kmsg_deflate_memory_descriptor(char * udesc_end,const mach_msg_ool_descriptor_t * kdesc,bool isU64)4013 ipc_kmsg_deflate_memory_descriptor(
4014 	char                   *udesc_end,
4015 	const mach_msg_ool_descriptor_t *kdesc,
4016 	bool                    isU64)
4017 {
4018 	bool deallocate = (kdesc->copy == MACH_MSG_VIRTUAL_COPY);
4019 
4020 	if (isU64) {
4021 		mach_msg_ool_descriptor64_t udesc = {
4022 			.address     = kdesc->u_address,
4023 			.size        = kdesc->size,
4024 			.deallocate  = deallocate,
4025 			.copy        = kdesc->copy,
4026 			.type        = kdesc->type,
4027 		};
4028 
4029 		return ipc_kmsg_deflate_put(udesc_end, &udesc);
4030 	} else {
4031 		mach_msg_ool_descriptor32_t udesc = {
4032 			.address     = (uint32_t)kdesc->u_address,
4033 			.size        = kdesc->size,
4034 			.deallocate  = deallocate,
4035 			.copy        = kdesc->copy,
4036 			.type        = kdesc->type,
4037 		};
4038 
4039 		return ipc_kmsg_deflate_put(udesc_end, &udesc);
4040 	}
4041 }
4042 
4043 
4044 static mach_msg_return_t
ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_kdescriptor_t * kdesc,vm_map_t map,ipc_space_t space)4045 ipc_kmsg_copyout_ool_ports_descriptor(
4046 	mach_msg_kdescriptor_t *kdesc,
4047 	vm_map_t                map,
4048 	ipc_space_t             space)
4049 {
4050 	mach_msg_ool_ports_descriptor_t *dsc = &kdesc->kdesc_port_array;
4051 	mach_msg_type_name_t    disp  = dsc->disposition;
4052 	mach_msg_type_number_t  count = dsc->count;
4053 	mach_port_array_t       array = dsc->address;
4054 	mach_port_name_t       *names = dsc->address;
4055 
4056 	vm_size_t               names_length = count * sizeof(mach_port_name_t);
4057 	mach_vm_offset_t        rcv_addr = 0;
4058 	mach_msg_return_t       mr = MACH_MSG_SUCCESS;
4059 
4060 	if (count != 0 && array != NULL) {
4061 		kern_return_t kr;
4062 		vm_tag_t tag;
4063 
4064 		/*
4065 		 * Dynamically allocate the region
4066 		 */
4067 		if (vm_kernel_map_is_kernel(map)) {
4068 			tag = VM_KERN_MEMORY_IPC;
4069 		} else {
4070 			tag = VM_MEMORY_MACH_MSG;
4071 		}
4072 
4073 		kr = mach_vm_allocate_kernel(map, &rcv_addr, names_length,
4074 		    VM_MAP_KERNEL_FLAGS_ANYWHERE(.vm_tag = tag));
4075 
4076 		/*
4077 		 * Handle the port rights and copy out the names
4078 		 * for those rights out to user-space.
4079 		 */
4080 		if (kr == MACH_MSG_SUCCESS) {
4081 			for (mach_msg_size_t i = 0; i < count; i++) {
4082 				mr |= ipc_kmsg_copyout_port(space,
4083 				    array[i].port, disp, NULL, &names[i]);
4084 			}
4085 			if (copyoutmap(map, names, rcv_addr, names_length)) {
4086 				mr |= MACH_MSG_VM_SPACE;
4087 			}
4088 			mach_port_array_free(array, count);
4089 		} else {
4090 			ipc_kmsg_clean_descriptors(kdesc, 1);
4091 			if (kr == KERN_RESOURCE_SHORTAGE) {
4092 				mr = MACH_MSG_VM_KERNEL;
4093 			} else {
4094 				mr = MACH_MSG_VM_SPACE;
4095 			}
4096 			rcv_addr = 0;
4097 		}
4098 	}
4099 
4100 	dsc->u_address = rcv_addr;
4101 	return mr;
4102 }
4103 
4104 static char *
ipc_kmsg_deflate_port_array_descriptor(char * udesc_end,const mach_msg_ool_ports_descriptor_t * kdesc,bool isU64)4105 ipc_kmsg_deflate_port_array_descriptor(
4106 	char                   *udesc_end,
4107 	const mach_msg_ool_ports_descriptor_t *kdesc,
4108 	bool                    isU64)
4109 {
4110 	if (isU64) {
4111 		mach_msg_ool_ports_descriptor64_t udesc = {
4112 			.address     = kdesc->u_address,
4113 			.count       = kdesc->count,
4114 			.deallocate  = true,
4115 			.copy        = MACH_MSG_VIRTUAL_COPY,
4116 			.disposition = kdesc->disposition,
4117 			.type        = kdesc->type,
4118 		};
4119 
4120 		return ipc_kmsg_deflate_put(udesc_end, &udesc);
4121 	} else {
4122 		mach_msg_ool_ports_descriptor32_t udesc = {
4123 			.address     = (uint32_t)kdesc->u_address,
4124 			.count       = kdesc->count,
4125 			.deallocate  = true,
4126 			.copy        = MACH_MSG_VIRTUAL_COPY,
4127 			.disposition = kdesc->disposition,
4128 			.type        = kdesc->type,
4129 		};
4130 
4131 		return ipc_kmsg_deflate_put(udesc_end, &udesc);
4132 	}
4133 }
4134 
4135 
4136 static mach_msg_return_t
ipc_kmsg_copyout_guarded_port_descriptor(mach_msg_guarded_port_descriptor_t * dsc,ipc_space_t space,mach_msg_option64_t option)4137 ipc_kmsg_copyout_guarded_port_descriptor(
4138 	mach_msg_guarded_port_descriptor_t *dsc,
4139 	ipc_space_t             space,
4140 	mach_msg_option64_t     option)
4141 {
4142 	mach_port_t             port    = dsc->name;
4143 	mach_msg_type_name_t    disp    = dsc->disposition;
4144 	mach_msg_return_t       mr      = MACH_MSG_SUCCESS;
4145 
4146 	/* Currently kernel_task doesnt support receiving guarded port descriptors */
4147 	struct knote *kn = current_thread()->ith_knote;
4148 	if ((kn != ITH_KNOTE_PSEUDO) && ((option & MACH_RCV_GUARDED_DESC) == 0)) {
4149 #if DEVELOPMENT || DEBUG
4150 		/*
4151 		 * Simulated crash needed for debugging, notifies the receiver to opt into receiving
4152 		 * guarded descriptors.
4153 		 */
4154 		mach_port_guard_exception(current_thread()->ith_receiver_name,
4155 		    0, kGUARD_EXC_RCV_GUARDED_DESC);
4156 #endif
4157 		KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_DESTROY_GUARDED_DESC),
4158 		    current_thread()->ith_receiver_name,
4159 		    VM_KERNEL_ADDRPERM(port), disp, dsc->flags);
4160 
4161 		ipc_object_destroy(port, disp);
4162 		dsc->u_context = 0;
4163 		dsc->u_name    = MACH_PORT_NULL;
4164 	} else {
4165 		mr = ipc_kmsg_copyout_port(space, port, disp, dsc,
4166 		    &dsc->u_name);
4167 	}
4168 
4169 	return mr;
4170 }
4171 
4172 static char *
ipc_kmsg_deflate_guarded_port_descriptor(char * udesc_end,const mach_msg_guarded_port_descriptor_t * kdesc,bool isU64)4173 ipc_kmsg_deflate_guarded_port_descriptor(
4174 	char                   *udesc_end,
4175 	const mach_msg_guarded_port_descriptor_t *kdesc,
4176 	bool                    isU64)
4177 {
4178 	if (isU64) {
4179 		mach_msg_guarded_port_descriptor64_t udesc = {
4180 			.context     = kdesc->u_context,
4181 			.flags       = kdesc->flags,
4182 			.disposition = kdesc->disposition,
4183 			.type        = kdesc->type,
4184 			.name        = kdesc->u_name,
4185 		};
4186 
4187 		return ipc_kmsg_deflate_put(udesc_end, &udesc);
4188 	} else {
4189 		mach_msg_guarded_port_descriptor32_t udesc = {
4190 			.context     = (uint32_t)kdesc->u_context,
4191 			.flags       = kdesc->flags,
4192 			.disposition = kdesc->disposition,
4193 			.type        = kdesc->type,
4194 			.name        = kdesc->u_name,
4195 		};
4196 
4197 		return ipc_kmsg_deflate_put(udesc_end, &udesc);
4198 	}
4199 }
4200 
4201 
4202 /*
4203  *	Routine:	ipc_kmsg_copyout_descriptors
4204  *	Purpose:
4205  *		"Copy-out" port rights and out-of-line memory
4206  *		in the body of a message.
4207  *
4208  *		The error codes are a combination of special bits.
4209  *		The copyout proceeds despite errors.
4210  *	Conditions:
4211  *		Nothing locked.
4212  *	Returns:
4213  *		MACH_MSG_SUCCESS	Successful copyout.
4214  *		MACH_MSG_IPC_SPACE	No room for port right in name space.
4215  *		MACH_MSG_VM_SPACE	No room for memory in address space.
4216  *		MACH_MSG_IPC_KERNEL	Resource shortage handling port right.
4217  *		MACH_MSG_VM_KERNEL	Resource shortage handling memory.
4218  *		MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
4219  */
4220 
4221 static mach_msg_return_t
ipc_kmsg_copyout_descriptors(mach_msg_kdescriptor_t * kdesc,mach_msg_size_t dsc_count,ipc_space_t space,vm_map_t map,mach_msg_option64_t option)4222 ipc_kmsg_copyout_descriptors(
4223 	mach_msg_kdescriptor_t *kdesc,
4224 	mach_msg_size_t         dsc_count,
4225 	ipc_space_t             space,
4226 	vm_map_t                map,
4227 	mach_msg_option64_t     option)
4228 {
4229 	mach_msg_return_t mr = MACH_MSG_SUCCESS;
4230 
4231 	assert(current_task() != kernel_task);
4232 
4233 	for (mach_msg_size_t i = 0; i < dsc_count; i++, kdesc++) {
4234 		switch (mach_msg_kdescriptor_type(kdesc)) {
4235 		case MACH_MSG_PORT_DESCRIPTOR:
4236 			mr |= ipc_kmsg_copyout_port_descriptor(&kdesc->kdesc_port,
4237 			    space);
4238 			break;
4239 		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4240 		case MACH_MSG_OOL_DESCRIPTOR:
4241 			mr |= ipc_kmsg_copyout_ool_descriptor(&kdesc->kdesc_memory,
4242 			    map);
4243 			break;
4244 		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
4245 			mr |= ipc_kmsg_copyout_ool_ports_descriptor(kdesc,
4246 			    map, space);
4247 			break;
4248 		case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
4249 			mr |= ipc_kmsg_copyout_guarded_port_descriptor(&kdesc->kdesc_guarded_port,
4250 			    space, option);
4251 			break;
4252 		default:
4253 			__ipc_kmsg_descriptor_invalid_type_panic(kdesc);
4254 		}
4255 	}
4256 
4257 	if (mr != MACH_MSG_SUCCESS) {
4258 		mr |= MACH_RCV_BODY_ERROR;
4259 	}
4260 	return mr;
4261 }
4262 
4263 static void
ipc_kmsg_deflate_descriptors(ikm_deflate_context_t * dctx,mach_msg_kdescriptor_t * desc_array,mach_msg_size_t desc_count)4264 ipc_kmsg_deflate_descriptors(
4265 	ikm_deflate_context_t  *dctx,
4266 	mach_msg_kdescriptor_t *desc_array,
4267 	mach_msg_size_t         desc_count)
4268 {
4269 	char           *udesc = (char *)(desc_array + desc_count);
4270 	mach_msg_body_t body  = {
4271 		.msgh_descriptor_count = desc_count,
4272 	};
4273 
4274 	for (mach_msg_size_t i = desc_count; i-- > 0;) {
4275 		const mach_msg_kdescriptor_t *kdesc = &desc_array[i];
4276 
4277 		switch (mach_msg_kdescriptor_type(kdesc)) {
4278 		case MACH_MSG_PORT_DESCRIPTOR:
4279 			udesc = ipc_kmsg_deflate_port_descriptor(udesc,
4280 			    &kdesc->kdesc_port);
4281 			break;
4282 		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4283 		case MACH_MSG_OOL_DESCRIPTOR:
4284 			udesc = ipc_kmsg_deflate_memory_descriptor(udesc,
4285 			    &kdesc->kdesc_memory, dctx->dctx_isU64);
4286 			break;
4287 		case MACH_MSG_OOL_PORTS_DESCRIPTOR:
4288 			udesc = ipc_kmsg_deflate_port_array_descriptor(udesc,
4289 			    &kdesc->kdesc_port_array, dctx->dctx_isU64);
4290 			break;
4291 		case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
4292 			udesc = ipc_kmsg_deflate_guarded_port_descriptor(udesc,
4293 			    &kdesc->kdesc_guarded_port, dctx->dctx_isU64);
4294 			break;
4295 		default:
4296 			__ipc_kmsg_descriptor_invalid_type_panic(kdesc);
4297 		}
4298 	}
4299 
4300 	/* adjust the context with how much the descriptors contracted */
4301 	dctx->dctx_uhdr      += udesc - (char *)desc_array;
4302 	dctx->dctx_uhdr_size -= udesc - (char *)desc_array;
4303 
4304 	/* update the descriptor count right before the array */
4305 	udesc = ipc_kmsg_deflate_put(udesc, &body);
4306 }
4307 
4308 static mach_msg_size_t
ipc_kmsg_descriptors_copyout_size(mach_msg_kdescriptor_t * kdesc,mach_msg_size_t count,vm_map_t map)4309 ipc_kmsg_descriptors_copyout_size(
4310 	mach_msg_kdescriptor_t *kdesc,
4311 	mach_msg_size_t         count,
4312 	vm_map_t                map)
4313 {
4314 	bool isU64 = (map->max_offset > VM_MAX_ADDRESS);
4315 	mach_msg_size_t size = 0;
4316 
4317 	for (mach_msg_size_t i = 0; i < count; i++) {
4318 		size += ikm_user_desc_size(kdesc[i].kdesc_header.type, isU64);
4319 	}
4320 
4321 	return size;
4322 }
4323 
4324 /*
4325  *	Routine:	ipc_kmsg_copyout_size
4326  *	Purpose:
4327  *		Compute the size of the message as copied out to the given
4328  *		map. If the destination map's pointers are a different size
4329  *		than the kernel's, we have to allow for expansion/
4330  *		contraction of the descriptors as appropriate.
4331  *	Conditions:
4332  *		Nothing locked.
4333  *	Returns:
4334  *		size of the message as it would be received.
4335  */
4336 
4337 mach_msg_size_t
ipc_kmsg_copyout_size(ipc_kmsg_t kmsg,vm_map_t map)4338 ipc_kmsg_copyout_size(
4339 	ipc_kmsg_t              kmsg,
4340 	vm_map_t                map)
4341 {
4342 	mach_msg_header_t *hdr   = ikm_header(kmsg);
4343 	mach_msg_size_t    size  = hdr->msgh_size - USER_HEADER_SIZE_DELTA;
4344 
4345 	if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
4346 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
4347 
4348 		size -= KERNEL_DESC_SIZE * kbase->msgb_dsc_count;
4349 		size += ipc_kmsg_descriptors_copyout_size(kbase->msgb_dsc_array,
4350 		    kbase->msgb_dsc_count, map);
4351 	}
4352 
4353 	return size;
4354 }
4355 
4356 /*
4357  *	Routine:	ipc_kmsg_copyout
4358  *	Purpose:
4359  *		"Copy-out" port rights and out-of-line memory
4360  *		in the message.
4361  *	Conditions:
4362  *		Nothing locked.
4363  *	Returns:
4364  *		MACH_MSG_SUCCESS	Copied out all rights and memory.
4365  *		MACH_RCV_HEADER_ERROR + special bits
4366  *			Rights and memory in the message are intact.
4367  *		MACH_RCV_BODY_ERROR + special bits
4368  *			The message header was successfully copied out.
4369  *			As much of the body was handled as possible.
4370  */
4371 
4372 mach_msg_return_t
ipc_kmsg_copyout(ipc_kmsg_t kmsg,ipc_space_t space,vm_map_t map,mach_msg_option64_t option)4373 ipc_kmsg_copyout(
4374 	ipc_kmsg_t              kmsg,
4375 	ipc_space_t             space,
4376 	vm_map_t                map,
4377 	mach_msg_option64_t     option)
4378 {
4379 	mach_msg_header_t *hdr = ikm_header(kmsg);
4380 	mach_msg_size_t    dsc_count;
4381 	mach_msg_return_t  mr;
4382 
4383 	dsc_count = ipc_kmsg_validate_signature(kmsg);
4384 
4385 	mr = ipc_kmsg_copyout_header(kmsg, hdr, space, option);
4386 	if (mr != MACH_MSG_SUCCESS) {
4387 		return mr;
4388 	}
4389 
4390 	if (dsc_count) {
4391 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
4392 
4393 		mr = ipc_kmsg_copyout_descriptors(kbase->msgb_dsc_array,
4394 		    dsc_count, space, map, option);
4395 	}
4396 
4397 	return mr;
4398 }
4399 
4400 /*
4401  *	Routine:	ipc_kmsg_copyout_pseudo
4402  *	Purpose:
4403  *		Does a pseudo-copyout of the message.
4404  *		This is like a regular copyout, except
4405  *		that the ports in the header are handled
4406  *		as if they are in the body.  They aren't reversed.
4407  *
4408  *		The error codes are a combination of special bits.
4409  *		The copyout proceeds despite errors.
4410  *	Conditions:
4411  *		Nothing locked.
4412  *	Returns:
4413  *		MACH_MSG_SUCCESS	Successful copyout.
4414  *		MACH_MSG_IPC_SPACE	No room for port right in name space.
4415  *		MACH_MSG_VM_SPACE	No room for memory in address space.
4416  *		MACH_MSG_IPC_KERNEL	Resource shortage handling port right.
4417  *		MACH_MSG_VM_KERNEL	Resource shortage handling memory.
4418  */
4419 
4420 mach_msg_return_t
ipc_kmsg_copyout_pseudo(ipc_kmsg_t kmsg,ipc_space_t space,vm_map_t map)4421 ipc_kmsg_copyout_pseudo(
4422 	ipc_kmsg_t              kmsg,
4423 	ipc_space_t             space,
4424 	vm_map_t                map)
4425 {
4426 	mach_msg_header_t *hdr = ikm_header(kmsg);
4427 	mach_msg_bits_t mbits = hdr->msgh_bits;
4428 	ipc_port_t dest = hdr->msgh_remote_port;
4429 	ipc_port_t reply = hdr->msgh_local_port;
4430 	ipc_port_t voucher = ipc_kmsg_get_voucher_port(kmsg);
4431 	mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
4432 	mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
4433 	mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
4434 	mach_port_name_t voucher_name = hdr->msgh_voucher_port;
4435 	mach_port_name_t dest_name, reply_name;
4436 	mach_msg_return_t mr;
4437 	mach_msg_size_t dsc_count;
4438 
4439 	/* Set ith_knote to ITH_KNOTE_PSEUDO */
4440 	current_thread()->ith_knote = ITH_KNOTE_PSEUDO;
4441 
4442 	dsc_count = ipc_kmsg_validate_signature(kmsg);
4443 
4444 	assert(IP_VALID(dest));
4445 
4446 #if 0
4447 	/*
4448 	 * If we did this here, it looks like we wouldn't need the undo logic
4449 	 * at the end of ipc_kmsg_send() in the error cases.  Not sure which
4450 	 * would be more elegant to keep.
4451 	 */
4452 	ipc_importance_clean(kmsg);
4453 #else
4454 	/* just assert it is already clean */
4455 	ipc_importance_assert_clean(kmsg);
4456 #endif
4457 
4458 	mr = ipc_kmsg_copyout_port(space, dest, dest_type, NULL, &dest_name);
4459 
4460 	if (!IP_VALID(reply)) {
4461 		reply_name = CAST_MACH_PORT_TO_NAME(reply);
4462 	} else if (ip_is_reply_port(reply)) {
4463 		mach_msg_return_t reply_mr;
4464 		reply_mr = ipc_kmsg_copyout_reply_port(space, reply, &reply_type, &reply_name);
4465 		mr = mr | reply_mr;
4466 		if (reply_mr == MACH_MSG_SUCCESS) {
4467 			mbits = MACH_MSGH_BITS_SET(dest_type, reply_type, voucher_type, MACH_MSGH_BITS_OTHER(mbits));
4468 		}
4469 	} else {
4470 		mr = mr | ipc_kmsg_copyout_port(space, reply, reply_type, NULL, &reply_name);
4471 	}
4472 
4473 	hdr->msgh_bits = mbits & MACH_MSGH_BITS_USER;
4474 	hdr->msgh_remote_port = CAST_MACH_NAME_TO_PORT(dest_name);
4475 	hdr->msgh_local_port = CAST_MACH_NAME_TO_PORT(reply_name);
4476 
4477 	/* restore the voucher:
4478 	 * If it was copied in via move-send, have to put back a voucher send right.
4479 	 *
4480 	 * If it was copied in via copy-send, the header still contains the old voucher name.
4481 	 * Restore the type and discard the copied-in/pre-processed voucher.
4482 	 */
4483 	if (IP_VALID(voucher)) {
4484 		assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
4485 		if (kmsg->ikm_voucher_type == MACH_MSG_TYPE_MOVE_SEND) {
4486 			mr |= ipc_kmsg_copyout_port(space, voucher, voucher_type, NULL, &voucher_name);
4487 			hdr->msgh_voucher_port = voucher_name;
4488 		} else {
4489 			assert(kmsg->ikm_voucher_type == MACH_MSG_TYPE_COPY_SEND);
4490 			hdr->msgh_bits = MACH_MSGH_BITS_SET(dest_type, reply_type, MACH_MSG_TYPE_COPY_SEND,
4491 			    MACH_MSGH_BITS_OTHER(hdr->msgh_bits));
4492 			ipc_object_destroy(voucher, voucher_type);
4493 		}
4494 		ipc_kmsg_clear_voucher_port(kmsg);
4495 	}
4496 
4497 	if (dsc_count) {
4498 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
4499 
4500 		/* rdar://120614480 this MACH64_MSG_OPTION_NONE is wrong */
4501 		mr |= ipc_kmsg_copyout_descriptors(kbase->msgb_dsc_array,
4502 		    dsc_count, space, map, MACH64_MSG_OPTION_NONE);
4503 	}
4504 
4505 	current_thread()->ith_knote = ITH_KNOTE_NULL;
4506 
4507 	return mr;
4508 }
4509 
4510 /*
4511  *	Routine:	ipc_kmsg_copyout_dest_to_user
4512  *	Purpose:
4513  *		Copies out the destination port in the message.
4514  *		Destroys all other rights and memory in the message.
4515  *		Transforms the message into a bare header with trailer.
4516  *	Conditions:
4517  *		Nothing locked.
4518  */
4519 
4520 void
ipc_kmsg_copyout_dest_to_user(ipc_kmsg_t kmsg,ipc_space_t space)4521 ipc_kmsg_copyout_dest_to_user(
4522 	ipc_kmsg_t      kmsg,
4523 	ipc_space_t     space)
4524 {
4525 	mach_msg_bits_t mbits;
4526 	ipc_port_t dest;
4527 	ipc_port_t reply;
4528 	ipc_port_t voucher;
4529 	mach_msg_type_name_t dest_type;
4530 	mach_msg_type_name_t reply_type;
4531 	mach_msg_type_name_t voucher_type;
4532 	mach_port_name_t dest_name, reply_name, voucher_name;
4533 	mach_msg_header_t *hdr;
4534 	mach_msg_id_t msg_id;
4535 	mach_msg_size_t aux_size;
4536 	mach_msg_size_t dsc_count;
4537 
4538 	dsc_count = ipc_kmsg_validate_signature(kmsg);
4539 
4540 	hdr = ikm_header(kmsg);
4541 	mbits = hdr->msgh_bits;
4542 	dest = hdr->msgh_remote_port;
4543 	reply = hdr->msgh_local_port;
4544 	voucher = ipc_kmsg_get_voucher_port(kmsg);
4545 	voucher_name = hdr->msgh_voucher_port;
4546 	msg_id = hdr->msgh_id;
4547 	dest_type = MACH_MSGH_BITS_REMOTE(mbits);
4548 	reply_type = MACH_MSGH_BITS_LOCAL(mbits);
4549 	voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
4550 	aux_size = kmsg->ikm_aux_size;
4551 
4552 	assert(IP_VALID(dest));
4553 
4554 	ipc_importance_assert_clean(kmsg);
4555 
4556 	ip_mq_lock(dest);
4557 	if (ip_active(dest)) {
4558 		ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
4559 		/* dest is unlocked */
4560 	} else {
4561 		ip_mq_unlock(dest);
4562 		ip_release(dest);
4563 		dest_name = MACH_PORT_DEAD;
4564 	}
4565 
4566 	if (IP_VALID(reply)) {
4567 		ipc_object_destroy(reply, reply_type);
4568 		reply_name = MACH_PORT_NULL;
4569 	} else {
4570 		reply_name = CAST_MACH_PORT_TO_NAME(reply);
4571 	}
4572 
4573 	if (IP_VALID(voucher)) {
4574 		assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
4575 		ipc_object_destroy(voucher, voucher_type);
4576 		ipc_kmsg_clear_voucher_port(kmsg);
4577 		voucher_name = MACH_PORT_NULL;
4578 	}
4579 
4580 	if (mbits & MACH_MSGH_BITS_COMPLEX) {
4581 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
4582 
4583 		ipc_kmsg_clean_descriptors(kbase->msgb_dsc_array, dsc_count);
4584 	}
4585 
4586 	ipc_kmsg_free_allocations(kmsg);
4587 
4588 	/* and now reconstruct a message anew */
4589 
4590 	mbits = MACH_MSGH_BITS_SET(reply_type, dest_type, voucher_type, mbits);
4591 	*ikm_header(kmsg) = (mach_msg_header_t){
4592 		.msgh_bits         = mbits,
4593 		.msgh_size         = sizeof(mach_msg_header_t),
4594 		.msgh_local_port   = CAST_MACH_NAME_TO_PORT(dest_name),
4595 		.msgh_remote_port  = CAST_MACH_NAME_TO_PORT(reply_name),
4596 		.msgh_voucher_port = voucher_name,
4597 		.msgh_id           = msg_id,
4598 	};
4599 	ipc_kmsg_init_trailer_and_sign(kmsg, TASK_NULL);
4600 
4601 	/* put a minimal aux header if there was one */
4602 	if (aux_size) {
4603 		kmsg->ikm_aux_size = sizeof(mach_msg_aux_header_t);
4604 		*ikm_aux_header(kmsg) = (mach_msg_aux_header_t){
4605 			.msgdh_size = sizeof(mach_msg_aux_header_t),
4606 		};
4607 	}
4608 }
4609 
4610 /*
4611  *	Routine:	ipc_kmsg_copyout_dest_to_kernel
4612  *	Purpose:
4613  *		Copies out the destination and reply ports in the message.
4614  *		Leaves all other rights and memory in the message alone.
4615  *	Conditions:
4616  *		Nothing locked.
4617  *
4618  *	Derived from ipc_kmsg_copyout_dest_to_user.
4619  *	Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
4620  *	We really do want to save rights and memory.
4621  */
4622 
4623 void
ipc_kmsg_copyout_dest_to_kernel(ipc_kmsg_t kmsg,ipc_space_t space)4624 ipc_kmsg_copyout_dest_to_kernel(
4625 	ipc_kmsg_t      kmsg,
4626 	ipc_space_t     space)
4627 {
4628 	ipc_port_t dest;
4629 	mach_port_t reply;
4630 	mach_msg_type_name_t dest_type;
4631 	mach_msg_type_name_t reply_type;
4632 	mach_port_name_t dest_name;
4633 	mach_msg_header_t *hdr;
4634 
4635 	(void)ipc_kmsg_validate_signature(kmsg);
4636 
4637 	hdr = ikm_header(kmsg);
4638 	dest = hdr->msgh_remote_port;
4639 	reply = hdr->msgh_local_port;
4640 	dest_type = MACH_MSGH_BITS_REMOTE(hdr->msgh_bits);
4641 	reply_type = MACH_MSGH_BITS_LOCAL(hdr->msgh_bits);
4642 
4643 	assert(IP_VALID(dest));
4644 
4645 	ip_mq_lock(dest);
4646 	if (ip_active(dest)) {
4647 		ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
4648 		/* dest is unlocked */
4649 	} else {
4650 		ip_mq_unlock(dest);
4651 		ip_release(dest);
4652 		dest_name = MACH_PORT_DEAD;
4653 	}
4654 
4655 	/*
4656 	 * While MIG kernel users don't receive vouchers, the
4657 	 * msgh_voucher_port field is intended to be round-tripped through the
4658 	 * kernel if there is no voucher disposition set. Here we check for a
4659 	 * non-zero voucher disposition, and consume the voucher send right as
4660 	 * there is no possible way to specify MACH_RCV_VOUCHER semantics.
4661 	 */
4662 	mach_msg_type_name_t voucher_type;
4663 	voucher_type = MACH_MSGH_BITS_VOUCHER(hdr->msgh_bits);
4664 	if (voucher_type != MACH_MSGH_BITS_ZERO) {
4665 		ipc_port_t voucher = ipc_kmsg_get_voucher_port(kmsg);
4666 
4667 		assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
4668 		/*
4669 		 * someone managed to send this kernel routine a message with
4670 		 * a voucher in it. Cleanup the reference in
4671 		 * kmsg->ikm_voucher.
4672 		 */
4673 		if (IP_VALID(voucher)) {
4674 			ipc_port_release_send(voucher);
4675 		}
4676 		hdr->msgh_voucher_port = 0;
4677 		ipc_kmsg_clear_voucher_port(kmsg);
4678 	}
4679 
4680 	hdr->msgh_bits =
4681 	    (MACH_MSGH_BITS_OTHER(hdr->msgh_bits) |
4682 	    MACH_MSGH_BITS(reply_type, dest_type));
4683 	hdr->msgh_local_port =  CAST_MACH_NAME_TO_PORT(dest_name);
4684 	hdr->msgh_remote_port = reply;
4685 }
4686 
4687 static void
ipc_kmsg_deflate_header(ikm_deflate_context_t * dctx,mach_msg_header_t * hdr)4688 ipc_kmsg_deflate_header(
4689 	ikm_deflate_context_t  *dctx,
4690 	mach_msg_header_t      *hdr)
4691 {
4692 	mach_msg_user_header_t uhdr = {
4693 		.msgh_bits         = hdr->msgh_bits,
4694 		.msgh_size         = dctx->dctx_uhdr_size + dctx->dctx_udata_size,
4695 		.msgh_remote_port  = CAST_MACH_PORT_TO_NAME(hdr->msgh_remote_port),
4696 		.msgh_local_port   = CAST_MACH_PORT_TO_NAME(hdr->msgh_local_port),
4697 		.msgh_voucher_port = hdr->msgh_voucher_port,
4698 		.msgh_id           = hdr->msgh_id,
4699 	};
4700 
4701 	/* the header will contract, take it into account */
4702 	dctx->dctx_uhdr      += USER_HEADER_SIZE_DELTA;
4703 	dctx->dctx_uhdr_size -= USER_HEADER_SIZE_DELTA;
4704 	uhdr.msgh_size       -= USER_HEADER_SIZE_DELTA;
4705 	memcpy(dctx->dctx_uhdr, &uhdr, sizeof(uhdr));
4706 }
4707 
4708 static void
ipc_kmsg_deflate_trailer(ikm_deflate_context_t * dctx,mach_msg_recv_result_t * msgr)4709 ipc_kmsg_deflate_trailer(
4710 	ikm_deflate_context_t  *dctx,
4711 	mach_msg_recv_result_t *msgr)
4712 {
4713 	mach_msg_max_trailer_t   *trailer = dctx->dctx_trailer;
4714 #ifdef __arm64__
4715 	mach_msg_max_trailer32_t *out32  = (mach_msg_max_trailer32_t *)trailer;
4716 	mach_msg_max_trailer64_t *out64  = (mach_msg_max_trailer64_t *)trailer;
4717 #else
4718 	mach_msg_max_trailer_t   *out32  = trailer;
4719 	mach_msg_max_trailer_t   *out64  = trailer;
4720 #endif /* __arm64__ */
4721 
4722 #define trailer_assert_same_field(field) \
4723 	static_assert(offsetof(typeof(*out32), field) == \
4724 	    offsetof(typeof(*out64), field)); \
4725 	static_assert(sizeof(out32->field) == sizeof(out64->field))
4726 
4727 	/*
4728 	 * These fields have been set by ipc_kmsg_init_trailer_and_sign(),
4729 	 * but alias in both 32 and 64 bit forms and need no munging:
4730 	 *
4731 	 *   msgh_trailer_type, msgh_trailer_size, msgh_sender, msgh_audit
4732 	 *
4733 	 * Update the size with the user requested one,
4734 	 * and update the message seqno.
4735 	 *
4736 	 * These cover:
4737 	 * - mach_msg_trailer_t           (msgh_trailer_type + msgh_trailer_size)
4738 	 * - mach_msg_seqno_trailer_t     (the above + msgh_seqno)
4739 	 * - mach_msg_security_trailer_t  (the above + msgh_sender)
4740 	 * - mach_msg_audit_trailer_t     (the above + msgh_audit)
4741 	 */
4742 	trailer_assert_same_field(msgh_trailer_type);
4743 	trailer_assert_same_field(msgh_trailer_size);
4744 	trailer_assert_same_field(msgh_seqno);
4745 	trailer_assert_same_field(msgh_sender);
4746 	trailer_assert_same_field(msgh_audit);
4747 
4748 	trailer->msgh_trailer_size = dctx->dctx_trailer_size;
4749 	trailer->msgh_seqno        = msgr->msgr_seqno;
4750 
4751 	/*
4752 	 * Lastly update fields that are 32bit versus 64bit dependent,
4753 	 * which are all after msgh_context (including this field).
4754 	 *
4755 	 * These cover:
4756 	 * - mach_msg_context_trailer_t   (the above + msgh_context)
4757 	 * - mach_msg_mac_trailer_t       (the above + msg_ad + msgh_labels)
4758 	 */
4759 
4760 	bzero((char *)trailer + sizeof(mach_msg_audit_trailer_t),
4761 	    MAX_TRAILER_SIZE - sizeof(mach_msg_audit_trailer_t));
4762 
4763 	if (dctx->dctx_isU64) {
4764 		out64->msgh_context = msgr->msgr_context;
4765 	} else {
4766 		out32->msgh_context = (typeof(out32->msgh_context))msgr->msgr_context;
4767 	}
4768 #undef trailer_assert_same_field
4769 }
4770 
4771 static ikm_deflate_context_t
ipc_kmsg_deflate(ipc_kmsg_t kmsg,mach_msg_recv_result_t * msgr,mach_msg_option64_t options,vm_map_t map)4772 ipc_kmsg_deflate(
4773 	ipc_kmsg_t              kmsg,     /* scalar or vector */
4774 	mach_msg_recv_result_t *msgr,
4775 	mach_msg_option64_t     options,
4776 	vm_map_t                map)
4777 {
4778 	mach_msg_header_t      *hdr  = ikm_header(kmsg);
4779 	ikm_deflate_context_t   dctx = {
4780 		.dctx_uhdr       = (char *)hdr,
4781 		.dctx_uhdr_size  = hdr->msgh_size,
4782 
4783 		.dctx_aux_hdr    = ikm_aux_header(kmsg),
4784 		.dctx_aux_size   = kmsg->ikm_aux_size,
4785 
4786 		.dctx_isU64      = (map->max_offset > VM_MAX_ADDRESS),
4787 	};
4788 
4789 	/*
4790 	 * If we aren't pseudo-receiving, deflate the trailer
4791 	 * before where it is is mangled beyond recognition.
4792 	 */
4793 	if (msgr->msgr_recv_name != MSGR_PSEUDO_RECEIVE) {
4794 		dctx.dctx_trailer      = ipc_kmsg_get_trailer(kmsg);
4795 		dctx.dctx_trailer_size = ipc_kmsg_trailer_size(options, map);
4796 	}
4797 
4798 	/*
4799 	 * If the message isn't linear,
4800 	 * split into uhdr=header+descriptors and udata=body+trailer
4801 	 */
4802 	if (!ikm_is_linear(kmsg)) {
4803 		mach_msg_size_t kdata_size = ikm_kdata_size(hdr);
4804 
4805 		dctx.dctx_udata_size = dctx.dctx_uhdr_size - kdata_size;
4806 		if (dctx.dctx_udata_size || dctx.dctx_trailer_size) {
4807 			dctx.dctx_udata      = kmsg->ikm_udata;
4808 			dctx.dctx_uhdr_size  = kdata_size;
4809 		}
4810 	}
4811 
4812 	/*
4813 	 * /!\ past this point, very few ipc_kmsg methods are allowed /!\
4814 	 *
4815 	 * The kmsg layout will be mangled in order to copy the bytes out,
4816 	 * and once that is done, destroying the message is the only thing
4817 	 * allowed.
4818 	 */
4819 
4820 	if (msgr->msgr_recv_name != MSGR_PSEUDO_RECEIVE) {
4821 		ipc_kmsg_deflate_trailer(&dctx, msgr);
4822 	}
4823 
4824 	if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
4825 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
4826 
4827 		ipc_kmsg_deflate_descriptors(&dctx,
4828 		    kbase->msgb_dsc_array, kbase->msgb_dsc_count);
4829 	}
4830 
4831 	ipc_kmsg_deflate_header(&dctx, hdr);
4832 
4833 	return dctx;
4834 }
4835 
4836 
4837 /*
4838  *	Routine:	ipc_kmsg_put_to_user
4839  *	Purpose:
4840  *		Copies a scalar or vector message buffer to a user message.
4841  *		Frees the message buffer.
4842  *
4843  *		1. If user has allocated space for aux data,
4844  *		   mach_msg_validate_data_vectors() guarantees that
4845  *		   recv_aux_addr is non-zero, and recv_aux_size
4846  *		   is at least sizeof(mach_msg_aux_header_t).
4847  *
4848  *		   In case the kmsg is a scalar or a vector without auxiliary
4849  *		   data, copy out an empty aux header to recv_aux_addr
4850  *		   which serves as EOF.
4851  *
4852  *		2. If the user has not allocated space for aux data,
4853  *		   silently drop the aux payload on reception.
4854  *
4855  *		3. If MACH64_RCV_LINEAR_VECTOR is set, use recv_msg_addr as
4856  *		   the combined buffer for message proper and aux data.
4857  *		   recv_aux_addr and recv_aux_size must be passed as
4858  *		   zeros and are ignored.
4859  *
4860  *	Conditions:
4861  *		Nothing locked. kmsg is freed upon return.
4862  *
4863  *	Returns:
4864  *		MACH_RCV_INVALID_DATA    Couldn't copy to user message.
4865  *		the incoming "mr"        Copied data out of message buffer.
4866  */
4867 mach_msg_return_t
ipc_kmsg_put_to_user(ipc_kmsg_t kmsg,mach_msg_recv_bufs_t * recv_bufs,mach_msg_recv_result_t * msgr,mach_msg_option64_t options,vm_map_t map,mach_msg_return_t mr)4868 ipc_kmsg_put_to_user(
4869 	ipc_kmsg_t              kmsg,     /* scalar or vector */
4870 	mach_msg_recv_bufs_t   *recv_bufs,
4871 	mach_msg_recv_result_t *msgr,
4872 	mach_msg_option64_t     options,
4873 	vm_map_t                map,
4874 	mach_msg_return_t       mr)
4875 {
4876 	mach_msg_aux_header_t   eof_aux = { .msgdh_size = 0 };
4877 	mach_vm_address_t       msg_rcv_addr = recv_bufs->recv_msg_addr;
4878 	mach_vm_address_t       aux_rcv_addr = recv_bufs->recv_aux_addr;
4879 	mach_msg_size_t         usize = 0;
4880 	ikm_deflate_context_t   dctx;
4881 
4882 	/*
4883 	 * After this, the kmsg() is mangled beyond recognition,
4884 	 * and calling things like ikm_header() etc.. will have
4885 	 * undefined behavior.
4886 	 */
4887 	dctx = ipc_kmsg_deflate(kmsg, msgr, options, map);
4888 
4889 	msgr->msgr_msg_size     = dctx.dctx_uhdr_size + dctx.dctx_udata_size;
4890 	msgr->msgr_trailer_size = dctx.dctx_trailer_size;
4891 	msgr->msgr_aux_size     = dctx.dctx_aux_size;
4892 
4893 	usize = msgr->msgr_msg_size + msgr->msgr_trailer_size;
4894 
4895 	/*
4896 	 * Validate our parameters, and compute the actual copy out addresses
4897 	 */
4898 
4899 	if (options & MACH64_RCV_LINEAR_VECTOR) {
4900 		assert(options & MACH64_MSG_VECTOR);
4901 
4902 		if (usize + dctx.dctx_aux_size > recv_bufs->recv_msg_size) {
4903 			mr = MACH_RCV_INVALID_DATA;
4904 			goto out;
4905 		}
4906 		if (options & MACH64_RCV_STACK) {
4907 			msg_rcv_addr += recv_bufs->recv_msg_size -
4908 			    (usize + dctx.dctx_aux_size);
4909 		}
4910 		aux_rcv_addr = msg_rcv_addr + usize;
4911 	} else {
4912 		assert(!(options & MACH64_RCV_STACK));
4913 
4914 		if (msgr->msgr_msg_size > recv_bufs->recv_msg_size) {
4915 			mr = MACH_RCV_INVALID_DATA;
4916 			goto out;
4917 		}
4918 
4919 		/*
4920 		 * (81193887) some clients stomp their own stack due to mis-sized
4921 		 * combined send/receives where the receive buffer didn't account
4922 		 * for the trailer size.
4923 		 *
4924 		 * At the very least, avoid smashing their stack
4925 		 */
4926 		if (usize > recv_bufs->recv_msg_size) {
4927 			dctx.dctx_trailer_size -= recv_bufs->recv_msg_size - usize;
4928 			usize = recv_bufs->recv_msg_size;
4929 		}
4930 
4931 		/*
4932 		 * If user has a buffer for aux data, at least copy out
4933 		 * an empty header which serves as an EOF.
4934 		 *
4935 		 * We don't need to do so for linear vector because
4936 		 * it's used in kevent context and we will return
4937 		 * msgr_aux_size as 0 on ext[3] to signify empty aux data.
4938 		 *
4939 		 * See: filt_machportprocess().
4940 		 */
4941 		if (aux_rcv_addr && !dctx.dctx_aux_hdr) {
4942 			dctx.dctx_aux_hdr  = &eof_aux;
4943 			dctx.dctx_aux_size = sizeof(eof_aux);
4944 			msgr->msgr_aux_size  = sizeof(eof_aux);
4945 		}
4946 
4947 		/*
4948 		 * If a receiver tries to receive a message with an aux vector,
4949 		 * but didn't provide one, we silently drop it for backward
4950 		 * compatibility reasons.
4951 		 */
4952 		if (dctx.dctx_aux_size > recv_bufs->recv_aux_size) {
4953 			dctx.dctx_aux_hdr  = NULL;
4954 			dctx.dctx_aux_size = 0;
4955 			msgr->msgr_aux_size  = 0;
4956 			aux_rcv_addr         = 0;
4957 		}
4958 	}
4959 
4960 
4961 	/*
4962 	 * Now that we measured twice, time to copyout all pieces.
4963 	 */
4964 
4965 	if (dctx.dctx_udata) {
4966 		mach_msg_size_t uhdr_size = dctx.dctx_uhdr_size;
4967 
4968 		if (copyoutmsg(dctx.dctx_uhdr, msg_rcv_addr, uhdr_size) ||
4969 		    copyoutmsg(dctx.dctx_udata, msg_rcv_addr + uhdr_size,
4970 		    usize - uhdr_size)) {
4971 			mr = MACH_RCV_INVALID_DATA;
4972 			goto out;
4973 		}
4974 	} else {
4975 		if (copyoutmsg(dctx.dctx_uhdr, msg_rcv_addr, usize)) {
4976 			mr = MACH_RCV_INVALID_DATA;
4977 			goto out;
4978 		}
4979 	}
4980 
4981 	if (dctx.dctx_aux_size &&
4982 	    copyoutmsg(dctx.dctx_aux_hdr, aux_rcv_addr, dctx.dctx_aux_size)) {
4983 		mr = MACH_RCV_INVALID_DATA;
4984 		goto out;
4985 	}
4986 
4987 out:
4988 	if (mr == MACH_RCV_INVALID_DATA) {
4989 		msgr->msgr_msg_size     = 0;
4990 		msgr->msgr_trailer_size = 0;
4991 		msgr->msgr_aux_size     = 0;
4992 	}
4993 
4994 	KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_LINK) | DBG_FUNC_NONE,
4995 	    recv_bufs->recv_msg_addr, VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
4996 	    /* this is on the receive/copyout path */ 1, 0, 0);
4997 
4998 	ipc_kmsg_free(kmsg);
4999 
5000 	return mr;
5001 }
5002 
5003 /** @} */
5004 #pragma mark ipc_kmsg kernel interfaces (get/put, copyin_from_kernel, send)
5005 
5006 /*
5007  *	Routine:	ipc_kmsg_get_from_kernel
5008  *	Purpose:
5009  *		Allocates a new kernel message buffer.
5010  *		Copies a kernel message to the message buffer.
5011  *		Only resource errors are allowed.
5012  *	Conditions:
5013  *		Nothing locked.
5014  *		Ports in header are ipc_port_t.
5015  *	Returns:
5016  *		MACH_MSG_SUCCESS	Acquired a message buffer.
5017  *		MACH_SEND_NO_BUFFER	Couldn't allocate a message buffer.
5018  */
5019 
5020 mach_msg_return_t
ipc_kmsg_get_from_kernel(mach_msg_header_t * msg,mach_msg_size_t size,mach_msg_option64_t options,ipc_kmsg_t * kmsgp)5021 ipc_kmsg_get_from_kernel(
5022 	mach_msg_header_t      *msg,
5023 	mach_msg_size_t         size,
5024 	mach_msg_option64_t     options,
5025 	ipc_kmsg_t             *kmsgp)
5026 {
5027 	mach_msg_kbase_t  *src_base;
5028 	ipc_kmsg_t         kmsg;
5029 	mach_msg_header_t *hdr;
5030 	mach_msg_size_t    desc_count, kdata_sz;
5031 
5032 	assert(size >= sizeof(mach_msg_header_t));
5033 	assert((size & 3) == 0);
5034 
5035 	if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
5036 		src_base   = mach_msg_header_to_kbase(msg);
5037 		desc_count = src_base->msgb_dsc_count;
5038 		kdata_sz   = ikm_kdata_size(desc_count, true);
5039 	} else {
5040 		desc_count = 0;
5041 		kdata_sz   = ikm_kdata_size(desc_count, false);
5042 	}
5043 
5044 	assert(size >= kdata_sz);
5045 	if (size < kdata_sz) {
5046 		return MACH_SEND_TOO_LARGE;
5047 	}
5048 
5049 	kmsg = ipc_kmsg_alloc(size, 0, desc_count, IPC_KMSG_ALLOC_KERNEL);
5050 	/* kmsg can be non-linear */
5051 
5052 	if (kmsg == IKM_NULL) {
5053 		return MACH_SEND_NO_BUFFER;
5054 	}
5055 
5056 	hdr = ikm_header(kmsg);
5057 	if (ikm_is_linear(kmsg)) {
5058 		memcpy(hdr, msg, size);
5059 	} else {
5060 		memcpy(hdr, msg, kdata_sz);
5061 		memcpy(kmsg->ikm_udata, (char *)msg + kdata_sz, size - kdata_sz);
5062 	}
5063 	hdr->msgh_size = size;
5064 
5065 	if (desc_count) {
5066 		mach_msg_kbase_t *dst_base = mach_msg_header_to_kbase(hdr);
5067 
5068 		if (options & MACH64_POLICY_KERNEL_EXTENSION) {
5069 			ipc_kmsg_sign_descriptors(dst_base->msgb_dsc_array,
5070 			    desc_count);
5071 		} else {
5072 			ipc_kmsg_relocate_descriptors(dst_base->msgb_dsc_array,
5073 			    src_base->msgb_dsc_array, desc_count);
5074 		}
5075 	}
5076 
5077 	*kmsgp = kmsg;
5078 	return MACH_MSG_SUCCESS;
5079 }
5080 
5081 static void
ipc_kmsg_copyin_port_from_kernel(mach_msg_header_t * hdr,ipc_port_t port,ipc_port_t remote,mach_msg_type_name_t disp)5082 ipc_kmsg_copyin_port_from_kernel(
5083 	mach_msg_header_t      *hdr,
5084 	ipc_port_t              port,
5085 	ipc_port_t              remote,
5086 	mach_msg_type_name_t    disp)
5087 {
5088 	ipc_object_copyin_from_kernel(port, disp);
5089 	/*
5090 	 * avoid circularity when the destination is also
5091 	 * the kernel.  This check should be changed into an
5092 	 * assert when the new kobject model is in place since
5093 	 * ports will not be used in kernel to kernel chats
5094 	 */
5095 
5096 	/* do not lock remote port, use raw pointer comparison */
5097 	if (!ip_in_space_noauth(remote, ipc_space_kernel)) {
5098 		/* remote port could be dead, in-transit or in an ipc space */
5099 		if (disp == MACH_MSG_TYPE_MOVE_RECEIVE &&
5100 		    ipc_port_check_circularity(port, remote)) {
5101 			hdr->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
5102 		}
5103 	}
5104 }
5105 
5106 /*
5107  *	Routine:	ipc_kmsg_copyin_from_kernel
5108  *	Purpose:
5109  *		"Copy-in" port rights and out-of-line memory
5110  *		in a message sent from the kernel.
5111  *
5112  *		Because the message comes from the kernel,
5113  *		the implementation assumes there are no errors
5114  *		or peculiarities in the message.
5115  *	Conditions:
5116  *		Nothing locked.
5117  */
5118 
5119 mach_msg_return_t
ipc_kmsg_copyin_from_kernel(ipc_kmsg_t kmsg)5120 ipc_kmsg_copyin_from_kernel(
5121 	ipc_kmsg_t      kmsg)
5122 {
5123 	mach_msg_header_t   *hdr = ikm_header(kmsg);
5124 	mach_msg_bits_t      bits = hdr->msgh_bits;
5125 	mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
5126 	mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
5127 	mach_msg_type_name_t vname = MACH_MSGH_BITS_VOUCHER(bits);
5128 	ipc_port_t           remote = hdr->msgh_remote_port;
5129 	ipc_port_t           local = hdr->msgh_local_port;
5130 	ipc_port_t           voucher = ipc_kmsg_get_voucher_port(kmsg);
5131 
5132 	/* translate the destination and reply ports */
5133 	if (!IP_VALID(remote)) {
5134 		return MACH_SEND_INVALID_DEST;
5135 	}
5136 
5137 	ipc_object_copyin_from_kernel(remote, rname);
5138 	if (IP_VALID(local)) {
5139 		ipc_object_copyin_from_kernel(local, lname);
5140 	}
5141 
5142 	if (IP_VALID(voucher)) {
5143 		ipc_object_copyin_from_kernel(voucher, vname);
5144 	}
5145 
5146 	/*
5147 	 *	The common case is a complex message with no reply port,
5148 	 *	because that is what the memory_object interface uses.
5149 	 */
5150 
5151 	if (bits == (MACH_MSGH_BITS_COMPLEX |
5152 	    MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
5153 		bits = (MACH_MSGH_BITS_COMPLEX |
5154 		    MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
5155 
5156 		hdr->msgh_bits = bits;
5157 	} else {
5158 		bits = (MACH_MSGH_BITS_OTHER(bits) |
5159 		    MACH_MSGH_BITS_SET_PORTS(ipc_object_copyin_type(rname),
5160 		    ipc_object_copyin_type(lname), ipc_object_copyin_type(vname)));
5161 
5162 		hdr->msgh_bits = bits;
5163 	}
5164 
5165 	ipc_kmsg_set_qos_kernel(kmsg);
5166 
5167 	/* Add trailer and signature to the message */
5168 	ipc_kmsg_init_trailer_and_sign(kmsg, TASK_NULL);
5169 
5170 	if (bits & MACH_MSGH_BITS_COMPLEX) {
5171 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(hdr);
5172 		mach_msg_size_t   count = kbase->msgb_dsc_count;
5173 		mach_msg_kdescriptor_t *kdesc = kbase->msgb_dsc_array;
5174 
5175 		/*
5176 		 * Check if the remote port accepts ports in the body.
5177 		 */
5178 		if (remote->ip_no_grant) {
5179 			for (mach_msg_size_t i = 0; i < count; i++) {
5180 				switch (mach_msg_kdescriptor_type(&kdesc[i])) {
5181 				case MACH_MSG_PORT_DESCRIPTOR:
5182 				case MACH_MSG_OOL_PORTS_DESCRIPTOR:
5183 				case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
5184 					/* no descriptors have been copied in yet */
5185 					ipc_kmsg_clean_header(kmsg);
5186 					return MACH_SEND_NO_GRANT_DEST;
5187 				}
5188 			}
5189 		}
5190 
5191 		for (mach_msg_size_t i = 0; i < count; i++) {
5192 			switch (mach_msg_kdescriptor_type(&kdesc[i])) {
5193 			case MACH_MSG_PORT_DESCRIPTOR: {
5194 				mach_msg_port_descriptor_t *dsc = &kdesc[i].kdesc_port;
5195 				mach_msg_type_name_t disp = dsc->disposition;
5196 				ipc_port_t           port = dsc->name;
5197 
5198 				dsc->disposition = ipc_object_copyin_type(disp);
5199 				if (IP_VALID(port)) {
5200 					ipc_kmsg_copyin_port_from_kernel(hdr,
5201 					    port, remote, disp);
5202 				}
5203 				break;
5204 			}
5205 			case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
5206 			case MACH_MSG_OOL_DESCRIPTOR: {
5207 				/*
5208 				 * The sender should supply ready-made memory, i.e.
5209 				 * a vm_map_copy_t, so we don't need to do anything.
5210 				 */
5211 				break;
5212 			}
5213 			case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
5214 				mach_msg_ool_ports_descriptor_t *dsc = &kdesc[i].kdesc_port_array;
5215 				mach_msg_type_name_t disp  = dsc->disposition;
5216 				mach_port_array_t    array = dsc->address;
5217 
5218 				dsc->disposition = ipc_object_copyin_type(disp);
5219 
5220 				for (mach_msg_size_t j = 0; j < dsc->count; j++) {
5221 					ipc_port_t port = array[j].port;
5222 
5223 					if (IP_VALID(port)) {
5224 						ipc_kmsg_copyin_port_from_kernel(hdr,
5225 						    port, remote, disp);
5226 					}
5227 				}
5228 				break;
5229 			}
5230 			case MACH_MSG_GUARDED_PORT_DESCRIPTOR: {
5231 				mach_msg_guarded_port_descriptor_t *dsc = &kdesc[i].kdesc_guarded_port;
5232 				mach_msg_type_name_t disp = dsc->disposition;
5233 				ipc_port_t           port = dsc->name;
5234 
5235 				dsc->disposition = ipc_object_copyin_type(disp);
5236 				assert(dsc->flags == 0);
5237 
5238 				if (IP_VALID(port)) {
5239 					ipc_kmsg_copyin_port_from_kernel(hdr,
5240 					    port, remote, disp);
5241 				}
5242 				break;
5243 			}
5244 			default:
5245 				__ipc_kmsg_descriptor_invalid_type_panic(kdesc);
5246 			}
5247 		}
5248 	}
5249 
5250 	return MACH_MSG_SUCCESS;
5251 }
5252 
5253 /*
5254  *	Routine:	ipc_kmsg_send
5255  *	Purpose:
5256  *		Send a message.  The message holds a reference
5257  *		for the destination port in the msgh_remote_port field.
5258  *
5259  *		If unsuccessful, the caller still has possession of
5260  *		the message and must do something with it.  If successful,
5261  *		the message is queued, given to a receiver, destroyed,
5262  *		or handled directly by the kernel via mach_msg.
5263  *	Conditions:
5264  *		Nothing locked.
5265  *	Returns:
5266  *		MACH_MSG_SUCCESS	       The message was accepted.
5267  *		MACH_SEND_TIMED_OUT	       Caller still has message.
5268  *		MACH_SEND_INTERRUPTED	   Caller still has message.
5269  *		MACH_SEND_INVALID_DEST	   Caller still has message.
5270  *      MACH_SEND_INVALID_OPTIONS  Caller still has message.
5271  */
5272 mach_msg_return_t
ipc_kmsg_send(ipc_kmsg_t kmsg,mach_msg_option64_t options,mach_msg_timeout_t send_timeout)5273 ipc_kmsg_send(
5274 	ipc_kmsg_t              kmsg,
5275 	mach_msg_option64_t     options,
5276 	mach_msg_timeout_t      send_timeout)
5277 {
5278 	ipc_port_t port;
5279 	thread_t th = current_thread();
5280 	mach_msg_return_t error = MACH_MSG_SUCCESS;
5281 	boolean_t kernel_reply = FALSE;
5282 	mach_msg_header_t *hdr;
5283 
5284 	/* Check if honor qlimit flag is set on thread. */
5285 	if ((th->options & TH_OPT_HONOR_QLIMIT) == TH_OPT_HONOR_QLIMIT) {
5286 		/* Remove the MACH_SEND_ALWAYS flag to honor queue limit. */
5287 		options &= (~MACH64_SEND_ALWAYS);
5288 		/* Add the timeout flag since the message queue might be full. */
5289 		options |= MACH64_SEND_TIMEOUT;
5290 		th->options &= (~TH_OPT_HONOR_QLIMIT);
5291 	}
5292 
5293 #if IMPORTANCE_INHERITANCE
5294 	bool did_importance = false;
5295 #if IMPORTANCE_TRACE
5296 	mach_msg_id_t imp_msgh_id = -1;
5297 	int           sender_pid  = -1;
5298 #endif /* IMPORTANCE_TRACE */
5299 #endif /* IMPORTANCE_INHERITANCE */
5300 
5301 	hdr = ikm_header(kmsg);
5302 	/* don't allow the creation of a circular loop */
5303 	if (hdr->msgh_bits & MACH_MSGH_BITS_CIRCULAR) {
5304 		ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_ALL);
5305 		KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, MACH_MSGH_BITS_CIRCULAR);
5306 		return MACH_MSG_SUCCESS;
5307 	}
5308 
5309 	ipc_voucher_send_preprocessing(kmsg);
5310 
5311 	port = hdr->msgh_remote_port;
5312 	assert(IP_VALID(port));
5313 	ip_mq_lock(port);
5314 
5315 	/*
5316 	 * If the destination has been guarded with a reply context, and the
5317 	 * sender is consuming a send-once right, then assume this is a reply
5318 	 * to an RPC and we need to validate that this sender is currently in
5319 	 * the correct context.
5320 	 */
5321 	if (enforce_strict_reply && port->ip_reply_context != 0 &&
5322 	    ((options & MACH64_SEND_KERNEL) == 0) &&
5323 	    MACH_MSGH_BITS_REMOTE(hdr->msgh_bits) == MACH_MSG_TYPE_PORT_SEND_ONCE) {
5324 		error = ipc_kmsg_validate_reply_context_locked(options,
5325 		    port, th->ith_voucher, th->ith_voucher_name);
5326 		if (error != MACH_MSG_SUCCESS) {
5327 			ip_mq_unlock(port);
5328 			return error;
5329 		}
5330 	}
5331 
5332 #if IMPORTANCE_INHERITANCE
5333 retry:
5334 #endif /* IMPORTANCE_INHERITANCE */
5335 	/*
5336 	 *	Can't deliver to a dead port.
5337 	 *	However, we can pretend it got sent
5338 	 *	and was then immediately destroyed.
5339 	 */
5340 	if (!ip_active(port)) {
5341 		ip_mq_unlock(port);
5342 #if MACH_FLIPC
5343 		if (MACH_NODE_VALID(kmsg->ikm_node) && FPORT_VALID(port->ip_messages.imq_fport)) {
5344 			flipc_msg_ack(kmsg->ikm_node, &port->ip_messages, FALSE);
5345 		}
5346 #endif
5347 		if (did_importance) {
5348 			/*
5349 			 * We're going to pretend we delivered this message
5350 			 * successfully, and just eat the kmsg. However, the
5351 			 * kmsg is actually visible via the importance_task!
5352 			 * We need to cleanup this linkage before we destroy
5353 			 * the message, and more importantly before we set the
5354 			 * msgh_remote_port to NULL. See: 34302571
5355 			 */
5356 			ipc_importance_clean(kmsg);
5357 		}
5358 		ip_release(port);  /* JMM - Future: release right, not just ref */
5359 		ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_SKIP_REMOTE);
5360 		KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, MACH_SEND_INVALID_DEST);
5361 		return MACH_MSG_SUCCESS;
5362 	}
5363 
5364 	if (ip_in_space(port, ipc_space_kernel)) {
5365 		require_ip_active(port);
5366 		port->ip_messages.imq_seqno++;
5367 		ip_mq_unlock(port);
5368 
5369 		counter_inc(&current_task()->messages_sent);
5370 
5371 		/*
5372 		 * Call the server routine, and get the reply message to send.
5373 		 */
5374 		kmsg = ipc_kobject_server(port, kmsg, options);
5375 		if (kmsg == IKM_NULL) {
5376 			return MACH_MSG_SUCCESS;
5377 		}
5378 		/* reload hdr since kmsg changed */
5379 		hdr = ikm_header(kmsg);
5380 
5381 		ipc_kmsg_init_trailer_and_sign(kmsg, TASK_NULL);
5382 
5383 		/* restart the KMSG_INFO tracing for the reply message */
5384 		KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_START);
5385 		port = hdr->msgh_remote_port;
5386 		assert(IP_VALID(port));
5387 		ip_mq_lock(port);
5388 		/* fall thru with reply - same options */
5389 		kernel_reply = TRUE;
5390 		if (!ip_active(port)) {
5391 			error = MACH_SEND_INVALID_DEST;
5392 		}
5393 	}
5394 
5395 #if IMPORTANCE_INHERITANCE
5396 	/*
5397 	 * Need to see if this message needs importance donation and/or
5398 	 * propagation.  That routine can drop the port lock temporarily.
5399 	 * If it does we'll have to revalidate the destination.
5400 	 */
5401 	if (!did_importance) {
5402 		did_importance = true;
5403 		if (ipc_importance_send(kmsg, options)) {
5404 			goto retry;
5405 		}
5406 	}
5407 #endif /* IMPORTANCE_INHERITANCE */
5408 
5409 	if (error != MACH_MSG_SUCCESS) {
5410 		ip_mq_unlock(port);
5411 	} else {
5412 		/*
5413 		 * We have a valid message and a valid reference on the port.
5414 		 * call mqueue_send() on its message queue.
5415 		 */
5416 		ipc_special_reply_port_msg_sent(port);
5417 
5418 		error = ipc_mqueue_send_locked(&port->ip_messages, kmsg,
5419 		    options, send_timeout);
5420 		/* port unlocked */
5421 	}
5422 
5423 #if IMPORTANCE_INHERITANCE
5424 	if (did_importance) {
5425 		__unused int importance_cleared = 0;
5426 		switch (error) {
5427 		case MACH_SEND_TIMED_OUT:
5428 		case MACH_SEND_NO_BUFFER:
5429 		case MACH_SEND_INTERRUPTED:
5430 		case MACH_SEND_INVALID_DEST:
5431 			/*
5432 			 * We still have the kmsg and its
5433 			 * reference on the port.  But we
5434 			 * have to back out the importance
5435 			 * boost.
5436 			 *
5437 			 * The port could have changed hands,
5438 			 * be inflight to another destination,
5439 			 * etc...  But in those cases our
5440 			 * back-out will find the new owner
5441 			 * (and all the operations that
5442 			 * transferred the right should have
5443 			 * applied their own boost adjustments
5444 			 * to the old owner(s)).
5445 			 */
5446 			importance_cleared = 1;
5447 			ipc_importance_clean(kmsg);
5448 			break;
5449 
5450 		case MACH_MSG_SUCCESS:
5451 		default:
5452 			break;
5453 		}
5454 #if IMPORTANCE_TRACE
5455 		KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, (IMPORTANCE_CODE(IMP_MSG, IMP_MSG_SEND)) | DBG_FUNC_END,
5456 		    task_pid(current_task()), sender_pid, imp_msgh_id, importance_cleared, 0);
5457 #endif /* IMPORTANCE_TRACE */
5458 	}
5459 #endif /* IMPORTANCE_INHERITANCE */
5460 
5461 	/*
5462 	 * If the port has been destroyed while we wait, treat the message
5463 	 * as a successful delivery (like we do for an inactive port).
5464 	 */
5465 	if (error == MACH_SEND_INVALID_DEST) {
5466 #if MACH_FLIPC
5467 		if (MACH_NODE_VALID(kmsg->ikm_node) && FPORT_VALID(port->ip_messages.imq_fport)) {
5468 			flipc_msg_ack(kmsg->ikm_node, &port->ip_messages, FALSE);
5469 		}
5470 #endif
5471 		ip_release(port); /* JMM - Future: release right, not just ref */
5472 		ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_SKIP_REMOTE);
5473 		KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, MACH_SEND_INVALID_DEST);
5474 		return MACH_MSG_SUCCESS;
5475 	}
5476 
5477 	if (error != MACH_MSG_SUCCESS && kernel_reply) {
5478 		/*
5479 		 * Kernel reply messages that fail can't be allowed to
5480 		 * pseudo-receive on error conditions. We need to just treat
5481 		 * the message as a successful delivery.
5482 		 */
5483 #if MACH_FLIPC
5484 		if (MACH_NODE_VALID(kmsg->ikm_node) && FPORT_VALID(port->ip_messages.imq_fport)) {
5485 			flipc_msg_ack(kmsg->ikm_node, &port->ip_messages, FALSE);
5486 		}
5487 #endif
5488 		ip_release(port); /* JMM - Future: release right, not just ref */
5489 		ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_SKIP_REMOTE);
5490 		KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, error);
5491 		return MACH_MSG_SUCCESS;
5492 	}
5493 	return error;
5494 }
5495 
5496 /*
5497  *	Routine:	ipc_kmsg_put_to_kernel
5498  *	Purpose:
5499  *		Copies a message buffer to a kernel message.
5500  *		Frees the message buffer.
5501  *		No errors allowed.
5502  *	Conditions:
5503  *		Nothing locked.
5504  */
5505 void
ipc_kmsg_put_to_kernel(mach_msg_header_t * msg,mach_msg_option64_t options,ipc_kmsg_t kmsg,mach_msg_size_t rcv_size)5506 ipc_kmsg_put_to_kernel(
5507 	mach_msg_header_t      *msg,
5508 	mach_msg_option64_t     options,
5509 	ipc_kmsg_t              kmsg,
5510 	mach_msg_size_t         rcv_size) /* includes trailer size */
5511 {
5512 	mach_msg_header_t *hdr = ikm_header(kmsg);
5513 	mach_msg_kbase_t  *src_base;
5514 	mach_msg_size_t    desc_count, kdata_sz;
5515 
5516 	assert(kmsg->ikm_aux_size == 0);
5517 	assert(rcv_size >= hdr->msgh_size);
5518 
5519 	if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
5520 		src_base   = mach_msg_header_to_kbase(hdr);
5521 		desc_count = src_base->msgb_dsc_count;
5522 		kdata_sz   = ikm_kdata_size(desc_count, true);
5523 	} else {
5524 		desc_count = 0;
5525 		kdata_sz   = ikm_kdata_size(desc_count, false);
5526 	}
5527 
5528 	if (ikm_is_linear(kmsg)) {
5529 		memcpy(msg, hdr, rcv_size);
5530 	} else {
5531 		memcpy(msg, hdr, kdata_sz);
5532 		memcpy((char *)msg + kdata_sz,
5533 		    kmsg->ikm_udata, rcv_size - kdata_sz);
5534 	}
5535 
5536 	if (desc_count) {
5537 		mach_msg_kbase_t *dst_base = mach_msg_header_to_kbase(msg);
5538 
5539 		if (options & MACH64_POLICY_KERNEL_EXTENSION) {
5540 			ipc_kmsg_strip_descriptors(dst_base->msgb_dsc_array,
5541 			    src_base->msgb_dsc_array, desc_count);
5542 		} else {
5543 			ipc_kmsg_relocate_descriptors(dst_base->msgb_dsc_array,
5544 			    src_base->msgb_dsc_array, desc_count);
5545 		}
5546 	}
5547 
5548 	ipc_kmsg_free(kmsg);
5549 }
5550 
5551 /** @} */
5552 #pragma mark ipc_kmsg tracing
5553 
5554 #define KMSG_TRACE_FLAG_TRACED     0x000001
5555 #define KMSG_TRACE_FLAG_COMPLEX    0x000002
5556 #define KMSG_TRACE_FLAG_OOLMEM     0x000004
5557 #define KMSG_TRACE_FLAG_VCPY       0x000008
5558 #define KMSG_TRACE_FLAG_PCPY       0x000010
5559 #define KMSG_TRACE_FLAG_SND64      0x000020
5560 #define KMSG_TRACE_FLAG_RAISEIMP   0x000040
5561 #define KMSG_TRACE_FLAG_APP_SRC    0x000080
5562 #define KMSG_TRACE_FLAG_APP_DST    0x000100
5563 #define KMSG_TRACE_FLAG_DAEMON_SRC 0x000200
5564 #define KMSG_TRACE_FLAG_DAEMON_DST 0x000400
5565 #define KMSG_TRACE_FLAG_DST_NDFLTQ 0x000800
5566 #define KMSG_TRACE_FLAG_SRC_NDFLTQ 0x001000
5567 #define KMSG_TRACE_FLAG_DST_SONCE  0x002000
5568 #define KMSG_TRACE_FLAG_SRC_SONCE  0x004000
5569 #define KMSG_TRACE_FLAG_CHECKIN    0x008000
5570 #define KMSG_TRACE_FLAG_ONEWAY     0x010000
5571 #define KMSG_TRACE_FLAG_IOKIT      0x020000
5572 #define KMSG_TRACE_FLAG_SNDRCV     0x040000
5573 #define KMSG_TRACE_FLAG_DSTQFULL   0x080000
5574 #define KMSG_TRACE_FLAG_VOUCHER    0x100000
5575 #define KMSG_TRACE_FLAG_TIMER      0x200000
5576 #define KMSG_TRACE_FLAG_SEMA       0x400000
5577 #define KMSG_TRACE_FLAG_DTMPOWNER  0x800000
5578 #define KMSG_TRACE_FLAG_GUARDED_DESC 0x1000000
5579 
5580 #define KMSG_TRACE_FLAGS_MASK      0x1ffffff
5581 #define KMSG_TRACE_FLAGS_SHIFT     8
5582 
5583 #define KMSG_TRACE_ID_SHIFT        32
5584 
5585 #define KMSG_TRACE_PORTS_MASK      0xff
5586 #define KMSG_TRACE_PORTS_SHIFT     0
5587 
5588 #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD)
5589 
5590 void
ipc_kmsg_trace_send(ipc_kmsg_t kmsg,mach_msg_option64_t option)5591 ipc_kmsg_trace_send(ipc_kmsg_t kmsg, mach_msg_option64_t option)
5592 {
5593 	task_t send_task = TASK_NULL;
5594 	ipc_port_t dst_port, src_port;
5595 	boolean_t is_task_64bit;
5596 	mach_msg_header_t *msg;
5597 	mach_msg_trailer_t *trailer;
5598 
5599 	int kotype = 0;
5600 	uint32_t msg_size = 0;
5601 	uint64_t msg_flags = KMSG_TRACE_FLAG_TRACED;
5602 	uint32_t num_ports = 0;
5603 	uint32_t send_pid, dst_pid;
5604 
5605 	/*
5606 	 * check to see not only if ktracing is enabled, but if we will
5607 	 * _actually_ emit the KMSG_INFO tracepoint. This saves us a
5608 	 * significant amount of processing (and a port lock hold) in
5609 	 * the non-tracing case.
5610 	 */
5611 	if (__probable((kdebug_enable & KDEBUG_TRACE) == 0)) {
5612 		return;
5613 	}
5614 	if (!kdebug_debugid_enabled(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO))) {
5615 		return;
5616 	}
5617 
5618 	msg = ikm_header(kmsg);
5619 
5620 	dst_port = msg->msgh_remote_port;
5621 	if (!IPC_PORT_VALID(dst_port)) {
5622 		return;
5623 	}
5624 
5625 	/*
5626 	 * Message properties / options
5627 	 */
5628 	if ((option & (MACH_SEND_MSG | MACH_RCV_MSG)) == (MACH_SEND_MSG | MACH_RCV_MSG)) {
5629 		msg_flags |= KMSG_TRACE_FLAG_SNDRCV;
5630 	}
5631 
5632 	if (msg->msgh_id >= is_iokit_subsystem.start &&
5633 	    msg->msgh_id < is_iokit_subsystem.end + 100) {
5634 		msg_flags |= KMSG_TRACE_FLAG_IOKIT;
5635 	}
5636 	/* magic XPC checkin message id (XPC_MESSAGE_ID_CHECKIN) from libxpc */
5637 	else if (msg->msgh_id == 0x77303074u /* w00t */) {
5638 		msg_flags |= KMSG_TRACE_FLAG_CHECKIN;
5639 	}
5640 
5641 	if (msg->msgh_bits & MACH_MSGH_BITS_RAISEIMP) {
5642 		msg_flags |= KMSG_TRACE_FLAG_RAISEIMP;
5643 	}
5644 
5645 	if (unsafe_convert_port_to_voucher(ipc_kmsg_get_voucher_port(kmsg))) {
5646 		msg_flags |= KMSG_TRACE_FLAG_VOUCHER;
5647 	}
5648 
5649 	/*
5650 	 * Sending task / port
5651 	 */
5652 	send_task = current_task();
5653 	send_pid = task_pid(send_task);
5654 
5655 	if (send_pid != 0) {
5656 		if (task_is_daemon(send_task)) {
5657 			msg_flags |= KMSG_TRACE_FLAG_DAEMON_SRC;
5658 		} else if (task_is_app(send_task)) {
5659 			msg_flags |= KMSG_TRACE_FLAG_APP_SRC;
5660 		}
5661 	}
5662 
5663 	is_task_64bit = (send_task->map->max_offset > VM_MAX_ADDRESS);
5664 	if (is_task_64bit) {
5665 		msg_flags |= KMSG_TRACE_FLAG_SND64;
5666 	}
5667 
5668 	src_port = msg->msgh_local_port;
5669 	if (src_port) {
5670 		if (src_port->ip_messages.imq_qlimit != MACH_PORT_QLIMIT_DEFAULT) {
5671 			msg_flags |= KMSG_TRACE_FLAG_SRC_NDFLTQ;
5672 		}
5673 		switch (MACH_MSGH_BITS_LOCAL(msg->msgh_bits)) {
5674 		case MACH_MSG_TYPE_MOVE_SEND_ONCE:
5675 			msg_flags |= KMSG_TRACE_FLAG_SRC_SONCE;
5676 			break;
5677 		default:
5678 			break;
5679 		}
5680 	} else {
5681 		msg_flags |= KMSG_TRACE_FLAG_ONEWAY;
5682 	}
5683 
5684 
5685 	/*
5686 	 * Destination task / port
5687 	 */
5688 	ip_mq_lock(dst_port);
5689 	if (!ip_active(dst_port)) {
5690 		/* dst port is being torn down */
5691 		dst_pid = (uint32_t)0xfffffff0;
5692 	} else if (dst_port->ip_tempowner) {
5693 		msg_flags |= KMSG_TRACE_FLAG_DTMPOWNER;
5694 		if (IIT_NULL != ip_get_imp_task(dst_port)) {
5695 			dst_pid = task_pid(dst_port->ip_imp_task->iit_task);
5696 		} else {
5697 			dst_pid = (uint32_t)0xfffffff1;
5698 		}
5699 	} else if (!ip_in_a_space(dst_port)) {
5700 		/* dst_port is otherwise in-transit */
5701 		dst_pid = (uint32_t)0xfffffff2;
5702 	} else {
5703 		if (ip_in_space(dst_port, ipc_space_kernel)) {
5704 			dst_pid = 0;
5705 		} else {
5706 			ipc_space_t dst_space;
5707 			dst_space = ip_get_receiver(dst_port);
5708 			if (dst_space && is_active(dst_space)) {
5709 				dst_pid = task_pid(dst_space->is_task);
5710 				if (task_is_daemon(dst_space->is_task)) {
5711 					msg_flags |= KMSG_TRACE_FLAG_DAEMON_DST;
5712 				} else if (task_is_app(dst_space->is_task)) {
5713 					msg_flags |= KMSG_TRACE_FLAG_APP_DST;
5714 				}
5715 			} else {
5716 				/* receiving task is being torn down */
5717 				dst_pid = (uint32_t)0xfffffff3;
5718 			}
5719 		}
5720 	}
5721 
5722 	if (dst_port->ip_messages.imq_qlimit != MACH_PORT_QLIMIT_DEFAULT) {
5723 		msg_flags |= KMSG_TRACE_FLAG_DST_NDFLTQ;
5724 	}
5725 	if (imq_full(&dst_port->ip_messages)) {
5726 		msg_flags |= KMSG_TRACE_FLAG_DSTQFULL;
5727 	}
5728 
5729 	kotype = ip_kotype(dst_port);
5730 
5731 	ip_mq_unlock(dst_port);
5732 
5733 	switch (kotype) {
5734 	case IKOT_SEMAPHORE:
5735 		msg_flags |= KMSG_TRACE_FLAG_SEMA;
5736 		break;
5737 	case IKOT_TIMER:
5738 	case IKOT_CLOCK:
5739 		msg_flags |= KMSG_TRACE_FLAG_TIMER;
5740 		break;
5741 	case IKOT_MAIN_DEVICE:
5742 	case IKOT_IOKIT_CONNECT:
5743 	case IKOT_IOKIT_OBJECT:
5744 	case IKOT_IOKIT_IDENT:
5745 	case IKOT_UEXT_OBJECT:
5746 		msg_flags |= KMSG_TRACE_FLAG_IOKIT;
5747 		break;
5748 	default:
5749 		break;
5750 	}
5751 
5752 	switch (MACH_MSGH_BITS_REMOTE(msg->msgh_bits)) {
5753 	case MACH_MSG_TYPE_PORT_SEND_ONCE:
5754 		msg_flags |= KMSG_TRACE_FLAG_DST_SONCE;
5755 		break;
5756 	default:
5757 		break;
5758 	}
5759 
5760 
5761 	/*
5762 	 * Message size / content
5763 	 */
5764 	msg_size = msg->msgh_size - sizeof(mach_msg_header_t);
5765 
5766 	if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
5767 		mach_msg_kbase_t *kbase = mach_msg_header_to_kbase(msg);
5768 		mach_msg_kdescriptor_t *kdesc;
5769 		mach_msg_descriptor_type_t dtype;
5770 
5771 		msg_flags |= KMSG_TRACE_FLAG_COMPLEX;
5772 
5773 		for (mach_msg_size_t i = 0; i < kbase->msgb_dsc_count; i++) {
5774 			kdesc = &kbase->msgb_dsc_array[i];
5775 			dtype = mach_msg_kdescriptor_type(kdesc);
5776 
5777 			switch (dtype) {
5778 			case MACH_MSG_PORT_DESCRIPTOR:
5779 				num_ports++;
5780 				break;
5781 			case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
5782 			case MACH_MSG_OOL_DESCRIPTOR: {
5783 				mach_msg_ool_descriptor_t *dsc = &kdesc->kdesc_memory;
5784 
5785 				msg_flags |= KMSG_TRACE_FLAG_OOLMEM;
5786 				msg_size += dsc->size;
5787 				if (dsc->size > msg_ool_size_small &&
5788 				    (dsc->copy == MACH_MSG_PHYSICAL_COPY) &&
5789 				    !dsc->deallocate) {
5790 					msg_flags |= KMSG_TRACE_FLAG_PCPY;
5791 				} else if (dsc->size <= msg_ool_size_small) {
5792 					msg_flags |= KMSG_TRACE_FLAG_PCPY;
5793 				} else {
5794 					msg_flags |= KMSG_TRACE_FLAG_VCPY;
5795 				}
5796 			} break;
5797 			case MACH_MSG_OOL_PORTS_DESCRIPTOR:
5798 				num_ports += kdesc->kdesc_port_array.count;
5799 				break;
5800 			case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
5801 				num_ports++;
5802 				msg_flags |= KMSG_TRACE_FLAG_GUARDED_DESC;
5803 				break;
5804 			default:
5805 				break;
5806 			}
5807 			msg_size -= ikm_user_desc_size(dtype, is_task_64bit);
5808 		}
5809 	}
5810 
5811 	/*
5812 	 * Trailer contents
5813 	 */
5814 	trailer = (mach_msg_trailer_t *)ipc_kmsg_get_trailer(kmsg);
5815 	if (trailer->msgh_trailer_size <= sizeof(mach_msg_security_trailer_t)) {
5816 		mach_msg_security_trailer_t *strailer;
5817 		strailer = (mach_msg_security_trailer_t *)trailer;
5818 		/*
5819 		 * verify the sender PID: replies from the kernel often look
5820 		 * like self-talk because the sending port is not reset.
5821 		 */
5822 		if (memcmp(&strailer->msgh_sender,
5823 		    &KERNEL_SECURITY_TOKEN,
5824 		    sizeof(KERNEL_SECURITY_TOKEN)) == 0) {
5825 			send_pid = 0;
5826 			msg_flags &= ~(KMSG_TRACE_FLAG_APP_SRC | KMSG_TRACE_FLAG_DAEMON_SRC);
5827 		}
5828 	}
5829 
5830 	KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END,
5831 	    (uintptr_t)send_pid,
5832 	    (uintptr_t)dst_pid,
5833 	    (uintptr_t)(((uint64_t)msg->msgh_id << KMSG_TRACE_ID_SHIFT) | msg_size),
5834 	    (uintptr_t)(
5835 		    ((msg_flags & KMSG_TRACE_FLAGS_MASK) << KMSG_TRACE_FLAGS_SHIFT) |
5836 		    ((num_ports & KMSG_TRACE_PORTS_MASK) << KMSG_TRACE_PORTS_SHIFT)
5837 		    )
5838 	    );
5839 }
5840 
5841 #endif
5842