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