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