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