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