1 /*
2 * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * @OSF_COPYRIGHT@
30 */
31 /*
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34 * All Rights Reserved.
35 *
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
41 *
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 * Software Distribution Coordinator or [email protected]
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56 /*
57 * NOTICE: This file was modified by McAfee Research in 2004 to introduce
58 * support for mandatory and extensible security protections. This notice
59 * is included in support of clause 2.2 (b) of the Apple Public License,
60 * Version 2.0.
61 * Copyright (c) 2005 SPARTA, Inc.
62 */
63 /*
64 */
65 /*
66 * File: ipc/ipc_kmsg.c
67 * Author: Rich Draves
68 * Date: 1989
69 *
70 * Operations on kernel messages.
71 */
72
73
74 #include <mach/mach_types.h>
75 #include <mach/boolean.h>
76 #include <mach/kern_return.h>
77 #include <mach/message.h>
78 #include <mach/port.h>
79 #include <mach/vm_map.h>
80 #include <mach/mach_vm.h>
81 #include <mach/vm_statistics.h>
82
83 #include <kern/kern_types.h>
84 #include <kern/assert.h>
85 #include <kern/debug.h>
86 #include <kern/ipc_kobject.h>
87 #include <kern/kalloc.h>
88 #include <kern/zalloc.h>
89 #include <kern/processor.h>
90 #include <kern/thread.h>
91 #include <kern/thread_group.h>
92 #include <kern/sched_prim.h>
93 #include <kern/misc_protos.h>
94 #include <kern/cpu_data.h>
95 #include <kern/policy_internal.h>
96 #include <kern/mach_filter.h>
97
98 #include <pthread/priority_private.h>
99
100 #include <machine/limits.h>
101
102 #include <vm/vm_map.h>
103 #include <vm/vm_object.h>
104 #include <vm/vm_kern.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_port.h>
114 #include <ipc/ipc_right.h>
115 #include <ipc/ipc_hash.h>
116 #include <ipc/ipc_importance.h>
117 #include <ipc/ipc_service_port.h>
118 #include <libkern/coreanalytics/coreanalytics.h>
119
120 #if MACH_FLIPC
121 #include <kern/mach_node.h>
122 #include <ipc/flipc.h>
123 #endif
124
125 #include <os/overflow.h>
126
127 #include <security/mac_mach_internal.h>
128
129 #include <device/device_server.h>
130
131 #include <string.h>
132
133 #if DEBUG
134 #define DEBUG_MSGS_K64 1
135 #endif
136
137 #include <sys/kdebug.h>
138 #include <libkern/OSAtomic.h>
139
140 #include <libkern/crypto/sha2.h>
141
142 #include <ptrauth.h>
143 #if __has_feature(ptrauth_calls)
144 #include <libkern/ptrauth_utils.h>
145 #endif
146
147 #if CONFIG_CSR
148 #include <sys/csr.h>
149 #endif
150
151 /*
152 * In kernel, complex mach msg have a simpler representation than userspace:
153 *
154 * <header>
155 * <desc-count>
156 * <descriptors> * desc-count
157 * <body>
158 *
159 * And the descriptors are of a fake type `mach_msg_descriptor_t`,
160 * that is large enough to accommodate for any possible representation.
161 *
162 * The `type` field of any desciptor is always at the same offset,
163 * and the smallest possible descriptor is of size MACH_MSG_DESC_MIN_SIZE.
164 *
165 * Note:
166 * - KERN_DESC_SIZE is 16 on all kernels
167 * - MACH_MSG_DESC_MIN_SIZE is 12 on all kernels
168 */
169
170 #define KERNEL_DESC_SIZE sizeof(mach_msg_descriptor_t)
171 #define MACH_MSG_DESC_MIN_SIZE sizeof(mach_msg_type_descriptor_t)
172
173 #define USER_HEADER_SIZE_DELTA \
174 ((mach_msg_size_t)(sizeof(mach_msg_header_t) - sizeof(mach_msg_user_header_t)))
175
176 #define USER_DESC_MAX_DELTA \
177 (KERNEL_DESC_SIZE - MACH_MSG_DESC_MIN_SIZE)
178
179 #define mach_validate_desc_type(t) \
180 static_assert(MACH_MSG_DESC_MIN_SIZE <= sizeof(t) && \
181 sizeof(t) <= sizeof(mach_msg_descriptor_t))
182
183 mach_validate_desc_type(mach_msg_descriptor_t);
184 mach_validate_desc_type(mach_msg_port_descriptor_t);
185 mach_validate_desc_type(mach_msg_user_port_descriptor_t);
186 mach_validate_desc_type(mach_msg_type_descriptor_t);
187 mach_validate_desc_type(mach_msg_ool_descriptor32_t);
188 mach_validate_desc_type(mach_msg_ool_descriptor64_t);
189 mach_validate_desc_type(mach_msg_ool_ports_descriptor32_t);
190 mach_validate_desc_type(mach_msg_ool_ports_descriptor64_t);
191 mach_validate_desc_type(mach_msg_guarded_port_descriptor32_t);
192 mach_validate_desc_type(mach_msg_guarded_port_descriptor64_t);
193
194 extern char *proc_name_address(struct proc *p);
195 static mach_msg_return_t ipc_kmsg_option_check(ipc_port_t port, mach_msg_option64_t option64);
196
197 /*
198 * As CA framework replies on successfully allocating zalloc memory,
199 * we maintain a small buffer that gets flushed when full. This helps us avoid taking spinlocks when working with CA.
200 */
201 #define REPLY_PORT_SEMANTICS_VIOLATIONS_RB_SIZE 2
202
203 /*
204 * Stripped down version of service port's string name. This is to avoid overwhelming CA's dynamic memory allocation.
205 */
206 #define CA_MACH_SERVICE_PORT_NAME_LEN 86
207
208 struct reply_port_semantics_violations_rb_entry {
209 char proc_name[CA_PROCNAME_LEN];
210 char service_name[CA_MACH_SERVICE_PORT_NAME_LEN];
211 };
212 struct reply_port_semantics_violations_rb_entry reply_port_semantics_violations_rb[REPLY_PORT_SEMANTICS_VIOLATIONS_RB_SIZE];
213 static uint8_t reply_port_semantics_violations_rb_index = 0;
214
215 LCK_GRP_DECLARE(reply_port_telemetry_lock_grp, "reply_port_telemetry_lock_grp");
216 LCK_SPIN_DECLARE(reply_port_telemetry_lock, &reply_port_telemetry_lock_grp);
217
218 /* Telemetry: report back the process name violating reply port semantics */
219 CA_EVENT(reply_port_semantics_violations,
220 CA_STATIC_STRING(CA_PROCNAME_LEN), proc_name,
221 CA_STATIC_STRING(CA_MACH_SERVICE_PORT_NAME_LEN), service_name);
222
223 /* Routine: flush_reply_port_semantics_violations_telemetry
224 * Conditions:
225 * Assumes the reply_port_telemetry_lock is held.
226 * Unlocks it before returning.
227 */
228 static void
flush_reply_port_semantics_violations_telemetry()229 flush_reply_port_semantics_violations_telemetry()
230 {
231 struct reply_port_semantics_violations_rb_entry local_rb[REPLY_PORT_SEMANTICS_VIOLATIONS_RB_SIZE];
232 uint8_t local_rb_index = 0;
233
234 if (__improbable(reply_port_semantics_violations_rb_index > REPLY_PORT_SEMANTICS_VIOLATIONS_RB_SIZE)) {
235 panic("Invalid reply port semantics violations buffer index %d > %d",
236 reply_port_semantics_violations_rb_index, REPLY_PORT_SEMANTICS_VIOLATIONS_RB_SIZE);
237 }
238
239 /*
240 * We operate on local copy of telemetry buffer because CA framework relies on successfully
241 * allocating zalloc memory. It can not do that if we are accessing the shared buffer
242 * with spin locks held.
243 */
244 while (local_rb_index != reply_port_semantics_violations_rb_index) {
245 local_rb[local_rb_index] = reply_port_semantics_violations_rb[local_rb_index];
246 local_rb_index++;
247 }
248
249 lck_spin_unlock(&reply_port_telemetry_lock);
250
251 while (local_rb_index > 0) {
252 struct reply_port_semantics_violations_rb_entry *entry = &local_rb[--local_rb_index];
253
254 ca_event_t ca_event = CA_EVENT_ALLOCATE_FLAGS(reply_port_semantics_violations, Z_NOWAIT);
255 if (ca_event) {
256 CA_EVENT_TYPE(reply_port_semantics_violations) * event = ca_event->data;
257 strlcpy(event->proc_name, entry->proc_name, CA_PROCNAME_LEN);
258 strlcpy(event->service_name, entry->service_name, CA_MACH_SERVICE_PORT_NAME_LEN);
259 CA_EVENT_SEND(ca_event);
260 }
261 }
262
263 /*
264 * Finally call out the buffer as empty. This is also a sort of rate limiting mechanisms for the events.
265 * Events will get dropped until the buffer is not fully flushed.
266 */
267 lck_spin_lock(&reply_port_telemetry_lock);
268 reply_port_semantics_violations_rb_index = 0;
269 }
270
271 static void
stash_reply_port_semantics_violations_telemetry(mach_service_port_info_t sp_info)272 stash_reply_port_semantics_violations_telemetry(mach_service_port_info_t sp_info)
273 {
274 struct reply_port_semantics_violations_rb_entry *entry;
275
276 lck_spin_lock(&reply_port_telemetry_lock);
277
278 if (reply_port_semantics_violations_rb_index == REPLY_PORT_SEMANTICS_VIOLATIONS_RB_SIZE) {
279 /* Dropping the event since buffer is full. */
280 lck_spin_unlock(&reply_port_telemetry_lock);
281 return;
282 }
283
284 task_t task = current_task_early();
285 if (task) {
286 char *proc_name = (char *) "unknown";
287 #ifdef MACH_BSD
288 proc_name = proc_name_address(get_bsdtask_info(task));
289 #endif /* MACH_BSD */
290 entry = &reply_port_semantics_violations_rb[reply_port_semantics_violations_rb_index++];
291 strlcpy(entry->proc_name, proc_name, CA_PROCNAME_LEN);
292
293 char *service_name = (char *) "unknown";
294 if (sp_info) {
295 service_name = sp_info->mspi_string_name;
296 }
297 strlcpy(entry->service_name, service_name, CA_MACH_SERVICE_PORT_NAME_LEN);
298 }
299
300 if (reply_port_semantics_violations_rb_index == REPLY_PORT_SEMANTICS_VIOLATIONS_RB_SIZE) {
301 flush_reply_port_semantics_violations_telemetry();
302 }
303
304 lck_spin_unlock(&reply_port_telemetry_lock);
305 }
306
307 /* Update following two helpers if new descriptor type is added */
308 static_assert(MACH_MSG_DESCRIPTOR_MAX == MACH_MSG_GUARDED_PORT_DESCRIPTOR);
309
310 static inline mach_msg_size_t
ikm_user_desc_size(mach_msg_descriptor_type_t type,bool is_task_64bit)311 ikm_user_desc_size(
312 mach_msg_descriptor_type_t type,
313 bool is_task_64bit)
314 {
315 if (is_task_64bit) {
316 switch (type) {
317 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
318 case MACH_MSG_OOL_DESCRIPTOR:
319 return sizeof(mach_msg_ool_descriptor64_t);
320 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
321 return sizeof(mach_msg_ool_ports_descriptor64_t);
322 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
323 return sizeof(mach_msg_guarded_port_descriptor64_t);
324 default: /* MACH_MSG_PORT_DESCRIPTOR */
325 return sizeof(mach_msg_user_port_descriptor_t);
326 }
327 } else {
328 switch (type) {
329 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
330 case MACH_MSG_OOL_DESCRIPTOR:
331 return sizeof(mach_msg_ool_descriptor32_t);
332 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
333 return sizeof(mach_msg_ool_ports_descriptor32_t);
334 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
335 return sizeof(mach_msg_guarded_port_descriptor32_t);
336 default: /* MACH_MSG_PORT_DESCRIPTOR */
337 return sizeof(mach_msg_user_port_descriptor_t);
338 }
339 }
340 }
341
342 static inline bool
ikm_user_desc_type_valid(mach_msg_descriptor_type_t type)343 ikm_user_desc_type_valid(
344 mach_msg_descriptor_type_t type)
345 {
346 return type <= MACH_MSG_DESCRIPTOR_MAX;
347 }
348
349 /*
350 * Measure the total descriptor size in a kmsg.
351 *
352 * Condition:
353 * Descriptors must have valid type and message is well-formed.
354 * See ikm_check_descriptors().
355 */
356 static mach_msg_size_t
ikm_total_desc_size(ipc_kmsg_t kmsg,vm_map_t map,mach_msg_size_t body_adj,mach_msg_size_t header_adj,bool user_descs)357 ikm_total_desc_size(
358 ipc_kmsg_t kmsg,
359 vm_map_t map,
360 mach_msg_size_t body_adj, /* gap formed during copyout_body memmove */
361 mach_msg_size_t header_adj, /* gap formed during put_to_user */
362 bool user_descs) /* are descriptors user sized */
363 {
364 mach_msg_size_t total = 0;
365 bool is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
366 mach_msg_size_t hdr_size = sizeof(mach_msg_header_t) - header_adj;
367 /*
368 * hdr can be of type (mach_msg_user_header_t *) or (mach_msg_header_t *).
369 * following code relies on the fact that both structs share the same
370 * first two fields. (msgh_bits and msgh_size)
371 */
372 static_assert(offsetof(mach_msg_user_header_t, msgh_bits) ==
373 offsetof(mach_msg_header_t, msgh_bits));
374 static_assert(offsetof(mach_msg_user_header_t, msgh_size) ==
375 offsetof(mach_msg_header_t, msgh_size));
376
377 mach_msg_header_t *hdr = (mach_msg_header_t *)((vm_offset_t)ikm_header(kmsg) + header_adj);
378
379 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
380 mach_msg_body_t *body;
381 mach_msg_type_number_t dsc_count;
382 mach_msg_size_t dsize;
383 mach_msg_descriptor_t *daddr;
384
385 body = (mach_msg_body_t *)((vm_offset_t)hdr + hdr_size);
386 dsc_count = body->msgh_descriptor_count;
387
388 if (!user_descs) {
389 return dsc_count * KERNEL_DESC_SIZE;
390 }
391
392 daddr = (mach_msg_descriptor_t *)((vm_offset_t)(body + 1) + body_adj);
393 for (uint32_t i = 0; i < dsc_count; i++) {
394 dsize = ikm_user_desc_size(daddr->type.type, is_task_64bit);
395 daddr = (mach_msg_descriptor_t *)((vm_offset_t)daddr + dsize);
396 total += dsize;
397 }
398 }
399
400 return total;
401 }
402
403 /* Pre-validate descriptors and message size during copyin */
404 __result_use_check
405 static mach_msg_return_t
ikm_check_descriptors(ipc_kmsg_t kmsg,vm_map_t map,mach_msg_size_t copied_in)406 ikm_check_descriptors(
407 ipc_kmsg_t kmsg, /* a complex message */
408 vm_map_t map,
409 mach_msg_size_t copied_in)
410 {
411 mach_msg_body_t *body;
412 mach_msg_type_number_t dsc_count;
413 mach_msg_size_t dsize;
414 vm_offset_t end;
415 mach_msg_descriptor_t *daddr;
416
417 bool is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
418 mach_msg_size_t hdr_size = sizeof(mach_msg_header_t);
419 mach_msg_size_t base_size = sizeof(mach_msg_base_t);
420 mach_msg_header_t *hdr = ikm_header(kmsg);
421
422 assert(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX);
423
424 body = (mach_msg_body_t *)((vm_offset_t)hdr + hdr_size);
425 dsc_count = body->msgh_descriptor_count;
426 daddr = (mach_msg_descriptor_t *)(vm_offset_t)(body + 1);
427 /* Maximum possible descriptor end address */
428 end = (vm_offset_t)hdr + base_size + copied_in;
429
430 for (uint32_t i = 0; i < dsc_count; i++) {
431 if ((vm_offset_t)daddr + MACH_MSG_DESC_MIN_SIZE > end) {
432 return MACH_SEND_MSG_TOO_SMALL;
433 }
434 /* Now we can access daddr->type safely */
435 if (!ikm_user_desc_type_valid(daddr->type.type)) {
436 return MACH_SEND_INVALID_TYPE;
437 }
438 dsize = ikm_user_desc_size(daddr->type.type, is_task_64bit);
439
440 if ((vm_offset_t)daddr + dsize > end) {
441 return MACH_SEND_MSG_TOO_SMALL;
442 }
443 daddr = (mach_msg_descriptor_t *)((vm_offset_t)daddr + dsize);
444 }
445
446 return MACH_MSG_SUCCESS;
447 }
448
449 /* Measure the size of user data content carried in kmsg. */
450 static mach_msg_size_t
ikm_content_size(ipc_kmsg_t kmsg,vm_map_t map,mach_msg_size_t header_adj,bool user_descs)451 ikm_content_size(
452 ipc_kmsg_t kmsg,
453 vm_map_t map,
454 mach_msg_size_t header_adj, /* gap formed during put_to_user */
455 bool user_descs) /* are descriptors user sized */
456 {
457 mach_msg_size_t hdr_size = sizeof(mach_msg_header_t) - header_adj;
458 mach_msg_size_t base_size = hdr_size + sizeof(mach_msg_body_t);
459 /*
460 * hdr can be of type (mach_msg_user_header_t *) or (mach_msg_header_t *).
461 * following code relies on the fact that both structs share the same
462 * first two fields. (msgh_bits and msgh_size)
463 */
464 mach_msg_header_t *hdr = (mach_msg_header_t *)((vm_offset_t)ikm_header(kmsg) + header_adj);
465
466 assert(hdr->msgh_size >= hdr_size);
467 if (hdr->msgh_size <= hdr_size) {
468 return 0;
469 }
470
471 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
472 assert(hdr->msgh_size >= base_size +
473 ikm_total_desc_size(kmsg, map, 0, header_adj, user_descs));
474 return hdr->msgh_size - base_size -
475 ikm_total_desc_size(kmsg, map, 0, header_adj, user_descs);
476 } else {
477 assert(hdr->msgh_size > hdr_size);
478 return hdr->msgh_size - hdr_size;
479 }
480 }
481
482 /* Size of kmsg header (plus body and descriptors for complex messages) */
483 static mach_msg_size_t
ikm_kdata_size(ipc_kmsg_t kmsg,vm_map_t map,mach_msg_size_t header_adj,bool user_descs)484 ikm_kdata_size(
485 ipc_kmsg_t kmsg,
486 vm_map_t map,
487 mach_msg_size_t header_adj,
488 bool user_descs)
489 {
490 mach_msg_size_t content_size = ikm_content_size(kmsg, map, header_adj, user_descs);
491 /*
492 * hdr can be of type (mach_msg_user_header_t *) or (mach_msg_header_t *).
493 * following code relies on the fact that both structs share the same
494 * first two fields. (msgh_bits and msgh_size)
495 */
496 mach_msg_header_t *hdr = (mach_msg_header_t *)((vm_offset_t)ikm_header(kmsg) + header_adj);
497
498 assert(hdr->msgh_size > content_size);
499 return hdr->msgh_size - content_size;
500 }
501
502 #if __has_feature(ptrauth_calls)
503 typedef uintptr_t ikm_sig_scratch_t;
504
505 static void
ikm_init_sig(__unused ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)506 ikm_init_sig(
507 __unused ipc_kmsg_t kmsg,
508 ikm_sig_scratch_t *scratchp)
509 {
510 *scratchp = OS_PTRAUTH_DISCRIMINATOR("kmsg.ikm_signature");
511 }
512
513 static void
ikm_chunk_sig(ipc_kmsg_t kmsg,void * data,size_t len,ikm_sig_scratch_t * scratchp)514 ikm_chunk_sig(
515 ipc_kmsg_t kmsg,
516 void *data,
517 size_t len,
518 ikm_sig_scratch_t *scratchp)
519 {
520 int ptrauth_flags;
521 void *trailerp;
522
523 /*
524 * if we happen to be doing the trailer chunk,
525 * diversify with the ptrauth-ed trailer pointer -
526 * as that is unchanging for the kmsg
527 */
528 trailerp = (void *)ipc_kmsg_get_trailer(kmsg, false);
529
530 ptrauth_flags = (data == trailerp) ? PTRAUTH_ADDR_DIVERSIFY : 0;
531 *scratchp = ptrauth_utils_sign_blob_generic(data, len, *scratchp, ptrauth_flags);
532 }
533
534 static uintptr_t
ikm_finalize_sig(__unused ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)535 ikm_finalize_sig(
536 __unused ipc_kmsg_t kmsg,
537 ikm_sig_scratch_t *scratchp)
538 {
539 return *scratchp;
540 }
541
542 #elif defined(CRYPTO_SHA2) && !defined(__x86_64__)
543
544 typedef SHA256_CTX ikm_sig_scratch_t;
545
546 static void
ikm_init_sig(__unused ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)547 ikm_init_sig(
548 __unused ipc_kmsg_t kmsg,
549 ikm_sig_scratch_t *scratchp)
550 {
551 SHA256_Init(scratchp);
552 SHA256_Update(scratchp, &vm_kernel_addrhash_salt_ext, sizeof(uint64_t));
553 }
554
555 static void
ikm_chunk_sig(__unused ipc_kmsg_t kmsg,void * data,size_t len,ikm_sig_scratch_t * scratchp)556 ikm_chunk_sig(
557 __unused ipc_kmsg_t kmsg,
558 void *data,
559 size_t len,
560 ikm_sig_scratch_t *scratchp)
561 {
562 SHA256_Update(scratchp, data, len);
563 }
564
565 static uintptr_t
ikm_finalize_sig(__unused ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)566 ikm_finalize_sig(
567 __unused ipc_kmsg_t kmsg,
568 ikm_sig_scratch_t *scratchp)
569 {
570 uintptr_t sha_digest[SHA256_DIGEST_LENGTH / sizeof(uintptr_t)];
571
572 SHA256_Final((uint8_t *)sha_digest, scratchp);
573
574 /*
575 * Only use one uintptr_t sized part of result for space and compat reasons.
576 * Truncation is better than XOR'ing the chunks together in hopes of higher
577 * entropy - because of its lower risk of collisions.
578 */
579 return *sha_digest;
580 }
581
582 #else
583 /* Stubbed out implementation (for __x86_64__ for now) */
584
585 typedef uintptr_t ikm_sig_scratch_t;
586
587 static void
ikm_init_sig(__unused ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)588 ikm_init_sig(
589 __unused ipc_kmsg_t kmsg,
590 ikm_sig_scratch_t *scratchp)
591 {
592 *scratchp = 0;
593 }
594
595 static void
ikm_chunk_sig(__unused ipc_kmsg_t kmsg,__unused void * data,__unused size_t len,__unused ikm_sig_scratch_t * scratchp)596 ikm_chunk_sig(
597 __unused ipc_kmsg_t kmsg,
598 __unused void *data,
599 __unused size_t len,
600 __unused ikm_sig_scratch_t *scratchp)
601 {
602 return;
603 }
604
605 static uintptr_t
ikm_finalize_sig(__unused ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)606 ikm_finalize_sig(
607 __unused ipc_kmsg_t kmsg,
608 ikm_sig_scratch_t *scratchp)
609 {
610 return *scratchp;
611 }
612
613 #endif
614
615 static void
ikm_header_sig(ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)616 ikm_header_sig(
617 ipc_kmsg_t kmsg,
618 ikm_sig_scratch_t *scratchp)
619 {
620 mach_msg_size_t dsc_count;
621 mach_msg_base_t base;
622 boolean_t complex;
623
624 mach_msg_header_t *hdr = ikm_header(kmsg);
625 /* take a snapshot of the message header/body-count */
626 base.header = *hdr;
627 complex = ((base.header.msgh_bits & MACH_MSGH_BITS_COMPLEX) != 0);
628 if (complex) {
629 dsc_count = ((mach_msg_body_t *)(hdr + 1))->msgh_descriptor_count;
630 } else {
631 dsc_count = 0;
632 }
633 base.body.msgh_descriptor_count = dsc_count;
634
635 /* compute sig of a copy of the header with all varying bits masked off */
636 base.header.msgh_bits &= MACH_MSGH_BITS_USER;
637 base.header.msgh_bits &= ~MACH_MSGH_BITS_VOUCHER_MASK;
638 ikm_chunk_sig(kmsg, &base, sizeof(mach_msg_base_t), scratchp);
639 }
640
641 static void
ikm_trailer_sig(ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)642 ikm_trailer_sig(
643 ipc_kmsg_t kmsg,
644 ikm_sig_scratch_t *scratchp)
645 {
646 mach_msg_max_trailer_t *trailerp;
647
648 /* Add sig of the trailer contents */
649 trailerp = ipc_kmsg_get_trailer(kmsg, false);
650 ikm_chunk_sig(kmsg, trailerp, sizeof(*trailerp), scratchp);
651 }
652
653 /* Compute the signature for the body bits of a message */
654 static void
ikm_body_sig(ipc_kmsg_t kmsg,ikm_sig_scratch_t * scratchp)655 ikm_body_sig(
656 ipc_kmsg_t kmsg,
657 ikm_sig_scratch_t *scratchp)
658 {
659 mach_msg_descriptor_t *kern_dsc;
660 mach_msg_size_t dsc_count;
661 mach_msg_body_t *body;
662 mach_msg_size_t i;
663
664 mach_msg_header_t *hdr = ikm_header(kmsg);
665
666 if ((hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0) {
667 return;
668 }
669 body = (mach_msg_body_t *) (hdr + 1);
670 dsc_count = body->msgh_descriptor_count;
671
672 if (dsc_count == 0) {
673 return;
674 }
675
676 kern_dsc = (mach_msg_descriptor_t *) (body + 1);
677
678 /* Compute the signature for the whole descriptor array */
679 ikm_chunk_sig(kmsg, kern_dsc, sizeof(*kern_dsc) * dsc_count, scratchp);
680
681 /* look for descriptor contents that need a signature */
682 for (i = 0; i < dsc_count; i++) {
683 switch (kern_dsc[i].type.type) {
684 case MACH_MSG_PORT_DESCRIPTOR:
685 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
686 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
687 case MACH_MSG_OOL_DESCRIPTOR:
688 break;
689
690 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
691 mach_msg_ool_ports_descriptor_t *ports_dsc;
692
693 /* Compute sig for the port/object pointers */
694 ports_dsc = (mach_msg_ool_ports_descriptor_t *)&kern_dsc[i];
695 ikm_chunk_sig(kmsg, ports_dsc->address, ports_dsc->count * sizeof(ipc_object_t), scratchp);
696 break;
697 }
698 default: {
699 panic("ipc_kmsg_body_sig: invalid message descriptor");
700 }
701 }
702 }
703 }
704
705 static void
ikm_sign(ipc_kmsg_t kmsg)706 ikm_sign(ipc_kmsg_t kmsg)
707 {
708 ikm_sig_scratch_t scratch;
709 uintptr_t sig;
710
711 zone_require(ipc_kmsg_zone, kmsg);
712
713 ikm_init_sig(kmsg, &scratch);
714
715 /* First sign header and trailer and store a partial sig */
716 ikm_header_sig(kmsg, &scratch);
717 ikm_trailer_sig(kmsg, &scratch);
718
719 #if __has_feature(ptrauth_calls)
720 /*
721 * On PAC devices lower 32 bits of the signature generated by G Key are
722 * always zeros. Use that space to store header + trailer partial sig.
723 *
724 * See: ptrauth_utils_sign_blob_generic()
725 */
726 kmsg->ikm_sig_partial = (uint32_t)(ikm_finalize_sig(kmsg, &scratch) >> 32);
727 #endif
728
729 /* Then sign body, which may be large: ~ BigO(# descriptors) */
730 ikm_body_sig(kmsg, &scratch);
731
732 sig = ikm_finalize_sig(kmsg, &scratch);
733 #if __has_feature(ptrauth_calls)
734 kmsg->ikm_sig_full = (uint32_t)(sig >> 32);
735 #else
736 kmsg->ikm_signature = sig;
737 #endif
738 }
739
740 unsigned int ikm_signature_failures;
741 unsigned int ikm_signature_failure_id;
742 #if (DEVELOPMENT || DEBUG)
743 unsigned int ikm_signature_panic_disable;
744 unsigned int ikm_signature_header_failures;
745 unsigned int ikm_signature_trailer_failures;
746 #endif
747
748 /*
749 * Purpose:
750 * Validate kmsg signature.
751 * partial: Only validate header + trailer.
752 *
753 * Condition:
754 * On non-PAC devices, `partial` must be set to false.
755 */
756 static void
ikm_validate_sig_internal(ipc_kmsg_t kmsg,bool partial)757 ikm_validate_sig_internal(
758 ipc_kmsg_t kmsg,
759 bool partial)
760 {
761 ikm_sig_scratch_t scratch;
762 uintptr_t expected;
763 uintptr_t sig;
764 char *str;
765
766 zone_require(ipc_kmsg_zone, kmsg);
767
768 ikm_init_sig(kmsg, &scratch);
769
770 ikm_header_sig(kmsg, &scratch);
771
772 ikm_trailer_sig(kmsg, &scratch);
773
774 if (partial) {
775 #if __has_feature(ptrauth_calls)
776 /* Do partial evaluation of header + trailer signature */
777 sig = ikm_finalize_sig(kmsg, &scratch);
778 expected = (uintptr_t)kmsg->ikm_sig_partial << 32;
779 if (sig != expected) {
780 #if (DEVELOPMENT || DEBUG)
781 ikm_signature_trailer_failures++;
782 #endif
783 str = "header trailer";
784 goto failure;
785 }
786 return;
787 #else
788 panic("Partial kmsg signature validation only supported on PAC devices.");
789 #endif
790 }
791
792 ikm_body_sig(kmsg, &scratch);
793 sig = ikm_finalize_sig(kmsg, &scratch);
794
795 #if __has_feature(ptrauth_calls)
796 expected = (uintptr_t)kmsg->ikm_sig_full << 32;
797 #else
798 expected = kmsg->ikm_signature;
799 #endif
800
801 if (sig != expected) {
802 ikm_signature_failures++;
803 str = "full";
804
805 #if __has_feature(ptrauth_calls)
806 failure:
807 #endif
808 {
809 mach_msg_id_t id = ikm_header(kmsg)->msgh_id;
810
811 ikm_signature_failure_id = id;
812 #if (DEVELOPMENT || DEBUG)
813 if (ikm_signature_panic_disable) {
814 return;
815 }
816 #endif
817 panic("ikm_validate_sig: %s signature mismatch: kmsg=0x%p, id=%d, sig=0x%zx (expected 0x%zx)",
818 str, kmsg, id, sig, expected);
819 }
820 }
821 }
822
823 static void
ikm_validate_sig(ipc_kmsg_t kmsg)824 ikm_validate_sig(
825 ipc_kmsg_t kmsg)
826 {
827 ikm_validate_sig_internal(kmsg, false);
828 }
829
830 /*
831 * Purpose:
832 * Validate kmsg signature. [Exported in header]
833 * partial: Only validate header + trailer.
834 *
835 * Condition:
836 * On non-PAC devices, `partial` must be set to false.
837 */
838 void
ipc_kmsg_validate_sig(ipc_kmsg_t kmsg,bool partial)839 ipc_kmsg_validate_sig(
840 ipc_kmsg_t kmsg,
841 bool partial)
842 {
843 ikm_validate_sig_internal(kmsg, partial);
844 }
845
846 #if DEBUG_MSGS_K64
847 extern void ipc_pset_print64(
848 ipc_pset_t pset);
849
850 extern void ipc_kmsg_print64(
851 ipc_kmsg_t kmsg,
852 const char *str);
853
854 extern void ipc_msg_print64(
855 mach_msg_header_t *msgh);
856
857 extern ipc_port_t ipc_name_to_data64(
858 task_t task,
859 mach_port_name_t name);
860
861 /*
862 * Forward declarations
863 */
864 void ipc_msg_print_untyped64(
865 mach_msg_body_t *body);
866
867 const char * ipc_type_name64(
868 int type_name,
869 boolean_t received);
870
871 void ipc_print_type_name64(
872 int type_name);
873
874 const char *
875 msgh_bit_decode64(
876 mach_msg_bits_t bit);
877
878 const char *
879 mm_copy_options_string64(
880 mach_msg_copy_options_t option);
881
882 void db_print_msg_uid64(mach_msg_header_t *);
883
884 static void
ipc_msg_body_print64(void * body,int size)885 ipc_msg_body_print64(void *body, int size)
886 {
887 uint32_t *word = (uint32_t *) body;
888 uint32_t *end = (uint32_t *)(((uintptr_t) body) + size
889 - sizeof(mach_msg_header_t));
890 int i;
891
892 kprintf(" body(%p-%p):\n %p: ", body, end, word);
893 for (;;) {
894 for (i = 0; i < 8; i++, word++) {
895 if (word >= end) {
896 kprintf("\n");
897 return;
898 }
899 kprintf("%08x ", *word);
900 }
901 kprintf("\n %p: ", word);
902 }
903 }
904
905
906 const char *
ipc_type_name64(int type_name,boolean_t received)907 ipc_type_name64(
908 int type_name,
909 boolean_t received)
910 {
911 switch (type_name) {
912 case MACH_MSG_TYPE_PORT_NAME:
913 return "port_name";
914
915 case MACH_MSG_TYPE_MOVE_RECEIVE:
916 if (received) {
917 return "port_receive";
918 } else {
919 return "move_receive";
920 }
921
922 case MACH_MSG_TYPE_MOVE_SEND:
923 if (received) {
924 return "port_send";
925 } else {
926 return "move_send";
927 }
928
929 case MACH_MSG_TYPE_MOVE_SEND_ONCE:
930 if (received) {
931 return "port_send_once";
932 } else {
933 return "move_send_once";
934 }
935
936 case MACH_MSG_TYPE_COPY_SEND:
937 return "copy_send";
938
939 case MACH_MSG_TYPE_MAKE_SEND:
940 return "make_send";
941
942 case MACH_MSG_TYPE_MAKE_SEND_ONCE:
943 return "make_send_once";
944
945 default:
946 return (char *) 0;
947 }
948 }
949
950 void
ipc_print_type_name64(int type_name)951 ipc_print_type_name64(
952 int type_name)
953 {
954 const char *name = ipc_type_name64(type_name, TRUE);
955 if (name) {
956 kprintf("%s", name);
957 } else {
958 kprintf("type%d", type_name);
959 }
960 }
961
962 /*
963 * ipc_kmsg_print64 [ debug ]
964 */
965 void
ipc_kmsg_print64(ipc_kmsg_t kmsg,const char * str)966 ipc_kmsg_print64(
967 ipc_kmsg_t kmsg,
968 const char *str)
969 {
970 kprintf("%s kmsg=%p:\n", str, kmsg);
971 kprintf(" next=%p, prev=%p",
972 kmsg->ikm_link.next,
973 kmsg->ikm_link.prev);
974 kprintf("\n");
975 ipc_msg_print64(ikm_header(kmsg));
976 }
977
978 const char *
msgh_bit_decode64(mach_msg_bits_t bit)979 msgh_bit_decode64(
980 mach_msg_bits_t bit)
981 {
982 switch (bit) {
983 case MACH_MSGH_BITS_COMPLEX: return "complex";
984 case MACH_MSGH_BITS_CIRCULAR: return "circular";
985 default: return (char *) 0;
986 }
987 }
988
989 /*
990 * ipc_msg_print64 [ debug ]
991 */
992 void
ipc_msg_print64(mach_msg_header_t * msgh)993 ipc_msg_print64(
994 mach_msg_header_t *msgh)
995 {
996 mach_msg_bits_t mbits;
997 unsigned int bit, i;
998 const char *bit_name;
999 int needs_comma;
1000
1001 mbits = msgh->msgh_bits;
1002 kprintf(" msgh_bits=0x%x: l=0x%x,r=0x%x\n",
1003 mbits,
1004 MACH_MSGH_BITS_LOCAL(msgh->msgh_bits),
1005 MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
1006
1007 mbits = MACH_MSGH_BITS_OTHER(mbits) & MACH_MSGH_BITS_USED;
1008 kprintf(" decoded bits: ");
1009 needs_comma = 0;
1010 for (i = 0, bit = 1; i < sizeof(mbits) * 8; ++i, bit <<= 1) {
1011 if ((mbits & bit) == 0) {
1012 continue;
1013 }
1014 bit_name = msgh_bit_decode64((mach_msg_bits_t)bit);
1015 if (bit_name) {
1016 kprintf("%s%s", needs_comma ? "," : "", bit_name);
1017 } else {
1018 kprintf("%sunknown(0x%x),", needs_comma ? "," : "", bit);
1019 }
1020 ++needs_comma;
1021 }
1022 if (msgh->msgh_bits & ~MACH_MSGH_BITS_USED) {
1023 kprintf("%sunused=0x%x,", needs_comma ? "," : "",
1024 msgh->msgh_bits & ~MACH_MSGH_BITS_USED);
1025 }
1026 kprintf("\n");
1027
1028 needs_comma = 1;
1029 if (msgh->msgh_remote_port) {
1030 kprintf(" remote=%p(", msgh->msgh_remote_port);
1031 ipc_print_type_name64(MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
1032 kprintf(")");
1033 } else {
1034 kprintf(" remote=null");
1035 }
1036
1037 if (msgh->msgh_local_port) {
1038 kprintf("%slocal=%p(", needs_comma ? "," : "",
1039 msgh->msgh_local_port);
1040 ipc_print_type_name64(MACH_MSGH_BITS_LOCAL(msgh->msgh_bits));
1041 kprintf(")\n");
1042 } else {
1043 kprintf("local=null\n");
1044 }
1045
1046 kprintf(" msgh_id=%d, size=%d\n",
1047 msgh->msgh_id,
1048 msgh->msgh_size);
1049
1050 if (mbits & MACH_MSGH_BITS_COMPLEX) {
1051 ipc_msg_print_untyped64((mach_msg_body_t *) (msgh + 1));
1052 }
1053
1054 ipc_msg_body_print64((void *)(msgh + 1), msgh->msgh_size);
1055 }
1056
1057
1058 const char *
mm_copy_options_string64(mach_msg_copy_options_t option)1059 mm_copy_options_string64(
1060 mach_msg_copy_options_t option)
1061 {
1062 const char *name;
1063
1064 switch (option) {
1065 case MACH_MSG_PHYSICAL_COPY:
1066 name = "PHYSICAL";
1067 break;
1068 case MACH_MSG_VIRTUAL_COPY:
1069 name = "VIRTUAL";
1070 break;
1071 case MACH_MSG_OVERWRITE:
1072 name = "OVERWRITE(DEPRECATED)";
1073 break;
1074 case MACH_MSG_ALLOCATE:
1075 name = "ALLOCATE";
1076 break;
1077 case MACH_MSG_KALLOC_COPY_T:
1078 name = "KALLOC_COPY_T";
1079 break;
1080 default:
1081 name = "unknown";
1082 break;
1083 }
1084 return name;
1085 }
1086
1087 void
ipc_msg_print_untyped64(mach_msg_body_t * body)1088 ipc_msg_print_untyped64(
1089 mach_msg_body_t *body)
1090 {
1091 mach_msg_descriptor_t *saddr, *send;
1092 mach_msg_descriptor_type_t type;
1093
1094 kprintf(" %d descriptors: \n", body->msgh_descriptor_count);
1095
1096 saddr = (mach_msg_descriptor_t *) (body + 1);
1097 send = saddr + body->msgh_descriptor_count;
1098
1099 for (; saddr < send; saddr++) {
1100 type = saddr->type.type;
1101
1102 switch (type) {
1103 case MACH_MSG_PORT_DESCRIPTOR: {
1104 mach_msg_port_descriptor_t *dsc;
1105
1106 dsc = &saddr->port;
1107 kprintf(" PORT name = %p disp = ", dsc->name);
1108 ipc_print_type_name64(dsc->disposition);
1109 kprintf("\n");
1110 break;
1111 }
1112 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
1113 case MACH_MSG_OOL_DESCRIPTOR: {
1114 mach_msg_ool_descriptor_t *dsc;
1115
1116 dsc = (mach_msg_ool_descriptor_t *) &saddr->out_of_line;
1117 kprintf(" OOL%s addr = %p size = 0x%x copy = %s %s\n",
1118 type == MACH_MSG_OOL_DESCRIPTOR ? "" : " VOLATILE",
1119 dsc->address, dsc->size,
1120 mm_copy_options_string64(dsc->copy),
1121 dsc->deallocate ? "DEALLOC" : "");
1122 break;
1123 }
1124 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
1125 mach_msg_ool_ports_descriptor_t *dsc;
1126
1127 dsc = (mach_msg_ool_ports_descriptor_t *) &saddr->ool_ports;
1128
1129 kprintf(" OOL_PORTS addr = %p count = 0x%x ",
1130 dsc->address, dsc->count);
1131 kprintf("disp = ");
1132 ipc_print_type_name64(dsc->disposition);
1133 kprintf(" copy = %s %s\n",
1134 mm_copy_options_string64(dsc->copy),
1135 dsc->deallocate ? "DEALLOC" : "");
1136 break;
1137 }
1138 case MACH_MSG_GUARDED_PORT_DESCRIPTOR: {
1139 mach_msg_guarded_port_descriptor_t *dsc;
1140
1141 dsc = (mach_msg_guarded_port_descriptor_t *)&saddr->guarded_port;
1142 kprintf(" GUARDED_PORT name = %p flags = 0x%x disp = ", dsc->name, dsc->flags);
1143 ipc_print_type_name64(dsc->disposition);
1144 kprintf("\n");
1145 break;
1146 }
1147 default: {
1148 kprintf(" UNKNOWN DESCRIPTOR 0x%x\n", type);
1149 break;
1150 }
1151 }
1152 }
1153 }
1154
1155 #define DEBUG_IPC_KMSG_PRINT(kmsg, string) \
1156 __unreachable_ok_push \
1157 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \
1158 ipc_kmsg_print64(kmsg, string); \
1159 } \
1160 __unreachable_ok_pop
1161
1162 #define DEBUG_IPC_MSG_BODY_PRINT(body, size) \
1163 __unreachable_ok_push \
1164 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \
1165 ipc_msg_body_print64(body,size);\
1166 } \
1167 __unreachable_ok_pop
1168 #else /* !DEBUG_MSGS_K64 */
1169 #define DEBUG_IPC_KMSG_PRINT(kmsg, string)
1170 #define DEBUG_IPC_MSG_BODY_PRINT(body, size)
1171 #endif /* !DEBUG_MSGS_K64 */
1172
1173 extern vm_map_t ipc_kernel_copy_map;
1174 extern vm_size_t ipc_kmsg_max_space;
1175 extern const vm_size_t ipc_kmsg_max_vm_space;
1176 extern const vm_size_t msg_ool_size_small;
1177
1178 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
1179
1180 #define KMSG_TRACE_FLAG_TRACED 0x000001
1181 #define KMSG_TRACE_FLAG_COMPLEX 0x000002
1182 #define KMSG_TRACE_FLAG_OOLMEM 0x000004
1183 #define KMSG_TRACE_FLAG_VCPY 0x000008
1184 #define KMSG_TRACE_FLAG_PCPY 0x000010
1185 #define KMSG_TRACE_FLAG_SND64 0x000020
1186 #define KMSG_TRACE_FLAG_RAISEIMP 0x000040
1187 #define KMSG_TRACE_FLAG_APP_SRC 0x000080
1188 #define KMSG_TRACE_FLAG_APP_DST 0x000100
1189 #define KMSG_TRACE_FLAG_DAEMON_SRC 0x000200
1190 #define KMSG_TRACE_FLAG_DAEMON_DST 0x000400
1191 #define KMSG_TRACE_FLAG_DST_NDFLTQ 0x000800
1192 #define KMSG_TRACE_FLAG_SRC_NDFLTQ 0x001000
1193 #define KMSG_TRACE_FLAG_DST_SONCE 0x002000
1194 #define KMSG_TRACE_FLAG_SRC_SONCE 0x004000
1195 #define KMSG_TRACE_FLAG_CHECKIN 0x008000
1196 #define KMSG_TRACE_FLAG_ONEWAY 0x010000
1197 #define KMSG_TRACE_FLAG_IOKIT 0x020000
1198 #define KMSG_TRACE_FLAG_SNDRCV 0x040000
1199 #define KMSG_TRACE_FLAG_DSTQFULL 0x080000
1200 #define KMSG_TRACE_FLAG_VOUCHER 0x100000
1201 #define KMSG_TRACE_FLAG_TIMER 0x200000
1202 #define KMSG_TRACE_FLAG_SEMA 0x400000
1203 #define KMSG_TRACE_FLAG_DTMPOWNER 0x800000
1204 #define KMSG_TRACE_FLAG_GUARDED_DESC 0x1000000
1205
1206 #define KMSG_TRACE_FLAGS_MASK 0x1ffffff
1207 #define KMSG_TRACE_FLAGS_SHIFT 8
1208
1209 #define KMSG_TRACE_PORTS_MASK 0xff
1210 #define KMSG_TRACE_PORTS_SHIFT 0
1211
1212 #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD)
1213 #include <stdint.h>
1214
1215 void
ipc_kmsg_trace_send(ipc_kmsg_t kmsg,mach_msg_option_t option)1216 ipc_kmsg_trace_send(ipc_kmsg_t kmsg,
1217 mach_msg_option_t option)
1218 {
1219 task_t send_task = TASK_NULL;
1220 ipc_port_t dst_port, src_port;
1221 boolean_t is_task_64bit;
1222 mach_msg_header_t *msg;
1223 mach_msg_trailer_t *trailer;
1224
1225 int kotype = 0;
1226 uint32_t msg_size = 0;
1227 uint64_t msg_flags = KMSG_TRACE_FLAG_TRACED;
1228 uint32_t num_ports = 0;
1229 uint32_t send_pid, dst_pid;
1230
1231 /*
1232 * check to see not only if ktracing is enabled, but if we will
1233 * _actually_ emit the KMSG_INFO tracepoint. This saves us a
1234 * significant amount of processing (and a port lock hold) in
1235 * the non-tracing case.
1236 */
1237 if (__probable((kdebug_enable & KDEBUG_TRACE) == 0)) {
1238 return;
1239 }
1240 if (!kdebug_debugid_enabled(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO))) {
1241 return;
1242 }
1243
1244 msg = ikm_header(kmsg);
1245
1246 dst_port = msg->msgh_remote_port;
1247 if (!IPC_PORT_VALID(dst_port)) {
1248 return;
1249 }
1250
1251 /*
1252 * Message properties / options
1253 */
1254 if ((option & (MACH_SEND_MSG | MACH_RCV_MSG)) == (MACH_SEND_MSG | MACH_RCV_MSG)) {
1255 msg_flags |= KMSG_TRACE_FLAG_SNDRCV;
1256 }
1257
1258 if (msg->msgh_id >= is_iokit_subsystem.start &&
1259 msg->msgh_id < is_iokit_subsystem.end + 100) {
1260 msg_flags |= KMSG_TRACE_FLAG_IOKIT;
1261 }
1262 /* magic XPC checkin message id (XPC_MESSAGE_ID_CHECKIN) from libxpc */
1263 else if (msg->msgh_id == 0x77303074u /* w00t */) {
1264 msg_flags |= KMSG_TRACE_FLAG_CHECKIN;
1265 }
1266
1267 if (msg->msgh_bits & MACH_MSGH_BITS_RAISEIMP) {
1268 msg_flags |= KMSG_TRACE_FLAG_RAISEIMP;
1269 }
1270
1271 if (unsafe_convert_port_to_voucher(ipc_kmsg_get_voucher_port(kmsg))) {
1272 msg_flags |= KMSG_TRACE_FLAG_VOUCHER;
1273 }
1274
1275 /*
1276 * Sending task / port
1277 */
1278 send_task = current_task();
1279 send_pid = task_pid(send_task);
1280
1281 if (send_pid != 0) {
1282 if (task_is_daemon(send_task)) {
1283 msg_flags |= KMSG_TRACE_FLAG_DAEMON_SRC;
1284 } else if (task_is_app(send_task)) {
1285 msg_flags |= KMSG_TRACE_FLAG_APP_SRC;
1286 }
1287 }
1288
1289 is_task_64bit = (send_task->map->max_offset > VM_MAX_ADDRESS);
1290 if (is_task_64bit) {
1291 msg_flags |= KMSG_TRACE_FLAG_SND64;
1292 }
1293
1294 src_port = msg->msgh_local_port;
1295 if (src_port) {
1296 if (src_port->ip_messages.imq_qlimit != MACH_PORT_QLIMIT_DEFAULT) {
1297 msg_flags |= KMSG_TRACE_FLAG_SRC_NDFLTQ;
1298 }
1299 switch (MACH_MSGH_BITS_LOCAL(msg->msgh_bits)) {
1300 case MACH_MSG_TYPE_MOVE_SEND_ONCE:
1301 msg_flags |= KMSG_TRACE_FLAG_SRC_SONCE;
1302 break;
1303 default:
1304 break;
1305 }
1306 } else {
1307 msg_flags |= KMSG_TRACE_FLAG_ONEWAY;
1308 }
1309
1310
1311 /*
1312 * Destination task / port
1313 */
1314 ip_mq_lock(dst_port);
1315 if (!ip_active(dst_port)) {
1316 /* dst port is being torn down */
1317 dst_pid = (uint32_t)0xfffffff0;
1318 } else if (dst_port->ip_tempowner) {
1319 msg_flags |= KMSG_TRACE_FLAG_DTMPOWNER;
1320 if (IIT_NULL != ip_get_imp_task(dst_port)) {
1321 dst_pid = task_pid(dst_port->ip_imp_task->iit_task);
1322 } else {
1323 dst_pid = (uint32_t)0xfffffff1;
1324 }
1325 } else if (!ip_in_a_space(dst_port)) {
1326 /* dst_port is otherwise in-transit */
1327 dst_pid = (uint32_t)0xfffffff2;
1328 } else {
1329 if (ip_in_space(dst_port, ipc_space_kernel)) {
1330 dst_pid = 0;
1331 } else {
1332 ipc_space_t dst_space;
1333 dst_space = ip_get_receiver(dst_port);
1334 if (dst_space && is_active(dst_space)) {
1335 dst_pid = task_pid(dst_space->is_task);
1336 if (task_is_daemon(dst_space->is_task)) {
1337 msg_flags |= KMSG_TRACE_FLAG_DAEMON_DST;
1338 } else if (task_is_app(dst_space->is_task)) {
1339 msg_flags |= KMSG_TRACE_FLAG_APP_DST;
1340 }
1341 } else {
1342 /* receiving task is being torn down */
1343 dst_pid = (uint32_t)0xfffffff3;
1344 }
1345 }
1346 }
1347
1348 if (dst_port->ip_messages.imq_qlimit != MACH_PORT_QLIMIT_DEFAULT) {
1349 msg_flags |= KMSG_TRACE_FLAG_DST_NDFLTQ;
1350 }
1351 if (imq_full(&dst_port->ip_messages)) {
1352 msg_flags |= KMSG_TRACE_FLAG_DSTQFULL;
1353 }
1354
1355 kotype = ip_kotype(dst_port);
1356
1357 ip_mq_unlock(dst_port);
1358
1359 switch (kotype) {
1360 case IKOT_SEMAPHORE:
1361 msg_flags |= KMSG_TRACE_FLAG_SEMA;
1362 break;
1363 case IKOT_TIMER:
1364 case IKOT_CLOCK:
1365 msg_flags |= KMSG_TRACE_FLAG_TIMER;
1366 break;
1367 case IKOT_MAIN_DEVICE:
1368 case IKOT_IOKIT_CONNECT:
1369 case IKOT_IOKIT_OBJECT:
1370 case IKOT_IOKIT_IDENT:
1371 case IKOT_UEXT_OBJECT:
1372 msg_flags |= KMSG_TRACE_FLAG_IOKIT;
1373 break;
1374 default:
1375 break;
1376 }
1377
1378 switch (MACH_MSGH_BITS_REMOTE(msg->msgh_bits)) {
1379 case MACH_MSG_TYPE_PORT_SEND_ONCE:
1380 msg_flags |= KMSG_TRACE_FLAG_DST_SONCE;
1381 break;
1382 default:
1383 break;
1384 }
1385
1386
1387 /*
1388 * Message size / content
1389 */
1390 msg_size = msg->msgh_size - sizeof(mach_msg_header_t);
1391
1392 if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
1393 mach_msg_body_t *msg_body;
1394 mach_msg_descriptor_t *kern_dsc;
1395 mach_msg_size_t dsc_count;
1396
1397 msg_flags |= KMSG_TRACE_FLAG_COMPLEX;
1398
1399 msg_body = (mach_msg_body_t *)(msg + 1);
1400 dsc_count = msg_body->msgh_descriptor_count;
1401 kern_dsc = (mach_msg_descriptor_t *)(msg_body + 1);
1402
1403 for (mach_msg_size_t i = 0; i < dsc_count; i++) {
1404 switch (kern_dsc[i].type.type) {
1405 case MACH_MSG_PORT_DESCRIPTOR:
1406 num_ports++;
1407 break;
1408 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
1409 case MACH_MSG_OOL_DESCRIPTOR: {
1410 mach_msg_ool_descriptor_t *dsc;
1411 dsc = (mach_msg_ool_descriptor_t *)&kern_dsc[i];
1412 msg_flags |= KMSG_TRACE_FLAG_OOLMEM;
1413 msg_size += dsc->size;
1414 if (dsc->size > MSG_OOL_SIZE_SMALL &&
1415 (dsc->copy == MACH_MSG_PHYSICAL_COPY) &&
1416 !dsc->deallocate) {
1417 msg_flags |= KMSG_TRACE_FLAG_PCPY;
1418 } else if (dsc->size <= MSG_OOL_SIZE_SMALL) {
1419 msg_flags |= KMSG_TRACE_FLAG_PCPY;
1420 } else {
1421 msg_flags |= KMSG_TRACE_FLAG_VCPY;
1422 }
1423 } break;
1424 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
1425 mach_msg_ool_ports_descriptor_t *dsc;
1426 dsc = (mach_msg_ool_ports_descriptor_t *)&kern_dsc[i];
1427 num_ports += dsc->count;
1428 } break;
1429 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
1430 num_ports++;
1431 msg_flags |= KMSG_TRACE_FLAG_GUARDED_DESC;
1432 break;
1433 default:
1434 break;
1435 }
1436 msg_size -= ikm_user_desc_size(kern_dsc[i].type.type, is_task_64bit);
1437 }
1438 }
1439
1440 /*
1441 * Trailer contents
1442 */
1443 trailer = (mach_msg_trailer_t *)ipc_kmsg_get_trailer(kmsg, false);
1444 if (trailer->msgh_trailer_size <= sizeof(mach_msg_security_trailer_t)) {
1445 mach_msg_security_trailer_t *strailer;
1446 strailer = (mach_msg_security_trailer_t *)trailer;
1447 /*
1448 * verify the sender PID: replies from the kernel often look
1449 * like self-talk because the sending port is not reset.
1450 */
1451 if (memcmp(&strailer->msgh_sender,
1452 &KERNEL_SECURITY_TOKEN,
1453 sizeof(KERNEL_SECURITY_TOKEN)) == 0) {
1454 send_pid = 0;
1455 msg_flags &= ~(KMSG_TRACE_FLAG_APP_SRC | KMSG_TRACE_FLAG_DAEMON_SRC);
1456 }
1457 }
1458
1459 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END,
1460 (uintptr_t)send_pid,
1461 (uintptr_t)dst_pid,
1462 (uintptr_t)msg_size,
1463 (uintptr_t)(
1464 ((msg_flags & KMSG_TRACE_FLAGS_MASK) << KMSG_TRACE_FLAGS_SHIFT) |
1465 ((num_ports & KMSG_TRACE_PORTS_MASK) << KMSG_TRACE_PORTS_SHIFT)
1466 )
1467 );
1468 }
1469 #endif
1470
1471 /* zone for cached ipc_kmsg_t structures */
1472 ZONE_DEFINE(ipc_kmsg_zone, "ipc kmsgs", IKM_SAVED_KMSG_SIZE,
1473 ZC_CACHING | ZC_ZFREE_CLEARMEM);
1474 static TUNABLE(bool, enforce_strict_reply, "ipc_strict_reply", false);
1475
1476 /*
1477 * Forward declarations
1478 */
1479
1480 static void ipc_kmsg_clean(
1481 ipc_kmsg_t kmsg);
1482
1483 static void
1484 ipc_kmsg_link_reply_context_locked(
1485 ipc_port_t reply_port,
1486 ipc_port_t voucher_port);
1487
1488 static kern_return_t
1489 ipc_kmsg_validate_reply_port_locked(
1490 ipc_port_t reply_port,
1491 mach_msg_option_t options);
1492
1493 static mach_msg_return_t
1494 ipc_kmsg_validate_reply_context_locked(
1495 mach_msg_option_t option,
1496 ipc_port_t dest_port,
1497 ipc_voucher_t voucher,
1498 mach_port_name_t voucher_name);
1499
1500 /* we can't include the BSD <sys/persona.h> header here... */
1501 #ifndef PERSONA_ID_NONE
1502 #define PERSONA_ID_NONE ((uint32_t)-1)
1503 #endif
1504
1505 static inline void *
ikm_inline_data(ipc_kmsg_t kmsg)1506 ikm_inline_data(
1507 ipc_kmsg_t kmsg)
1508 {
1509 return (void *)(kmsg + 1);
1510 }
1511
1512 /* Whether header, body, content and trailer occupy contiguous memory space */
1513 static inline bool
ikm_is_linear(ipc_kmsg_t kmsg)1514 ikm_is_linear(ipc_kmsg_t kmsg)
1515 {
1516 return kmsg->ikm_type == IKM_TYPE_ALL_INLINED ||
1517 kmsg->ikm_type == IKM_TYPE_KDATA_OOL;
1518 }
1519
1520 static inline bool
ikm_header_inlined(ipc_kmsg_t kmsg)1521 ikm_header_inlined(ipc_kmsg_t kmsg)
1522 {
1523 /* ikm_type must not be reordered */
1524 static_assert(IKM_TYPE_UDATA_OOL == 1);
1525 static_assert(IKM_TYPE_ALL_INLINED == 0);
1526 return kmsg->ikm_type <= IKM_TYPE_UDATA_OOL;
1527 }
1528
1529 /*
1530 * Returns start address of user data for kmsg.
1531 *
1532 * Condition:
1533 * 1. kmsg descriptors must have been validated and expanded, or is a message
1534 * originated from kernel.
1535 * 2. ikm_header() content may or may not be populated
1536 */
1537 void *
ikm_udata(ipc_kmsg_t kmsg,mach_msg_size_t desc_count,bool complex)1538 ikm_udata(
1539 ipc_kmsg_t kmsg,
1540 mach_msg_size_t desc_count,
1541 bool complex)
1542 {
1543 if (!ikm_is_linear(kmsg)) {
1544 return kmsg->ikm_udata;
1545 } else if (complex) {
1546 return (void *)((vm_offset_t)ikm_header(kmsg) + sizeof(mach_msg_base_t) +
1547 desc_count * KERNEL_DESC_SIZE);
1548 } else {
1549 return (void *)((vm_offset_t)ikm_header(kmsg) + sizeof(mach_msg_header_t));
1550 }
1551 }
1552
1553 #if (DEVELOPMENT || DEBUG)
1554 /* Returns end of kdata buffer (may contain extra space) */
1555 static vm_offset_t
ikm_kdata_end(ipc_kmsg_t kmsg)1556 ikm_kdata_end(ipc_kmsg_t kmsg)
1557 {
1558 if (ikm_header_inlined(kmsg)) {
1559 /* round up to total kmsg buffer size */
1560 return (vm_offset_t)kmsg + IKM_SAVED_KMSG_SIZE;
1561 } else if (ikm_is_linear(kmsg)) {
1562 /* round up to total kmsg buffer size */
1563 ipc_kmsg_vector_t *vec = ikm_inline_data(kmsg);
1564 return (vm_offset_t)vec->kmsgv_data + vec->kmsgv_size;
1565 } else {
1566 assert(kmsg->ikm_type == IKM_TYPE_ALL_OOL);
1567 ipc_kmsg_vector_t *vec = ikm_inline_data(kmsg);
1568 return (vm_offset_t)vec->kmsgv_data + sizeof(mach_msg_base_t) +
1569 vec->kmsgv_size * KERNEL_DESC_SIZE;
1570 }
1571 }
1572
1573 /* Returns end of udata buffer (may contain extra space) */
1574 static vm_offset_t
ikm_udata_end(ipc_kmsg_t kmsg)1575 ikm_udata_end(ipc_kmsg_t kmsg)
1576 {
1577 assert(kmsg->ikm_type != IKM_TYPE_ALL_INLINED);
1578 assert(kmsg->ikm_udata != NULL);
1579
1580 return (vm_offset_t)kmsg->ikm_udata + kmsg->ikm_udata_size;
1581 }
1582 #endif
1583
1584 /*
1585 * Returns message header address.
1586 *
1587 * /!\ WARNING /!\
1588 * Need to shift the return value after call to ipc_kmsg_convert_header_to_user().
1589 */
1590 inline mach_msg_header_t *
ikm_header(ipc_kmsg_t kmsg)1591 ikm_header(
1592 ipc_kmsg_t kmsg)
1593 {
1594 return ikm_header_inlined(kmsg) ? (mach_msg_header_t *)ikm_inline_data(kmsg) :
1595 (mach_msg_header_t *)(((ipc_kmsg_vector_t *)ikm_inline_data(kmsg))->kmsgv_data);
1596 }
1597
1598 static inline mach_msg_aux_header_t *
ikm_aux_header(ipc_kmsg_t kmsg)1599 ikm_aux_header(
1600 ipc_kmsg_t kmsg)
1601 {
1602 if (!kmsg->ikm_aux_size) {
1603 return NULL;
1604 }
1605
1606 assert(kmsg->ikm_aux_size >= sizeof(mach_msg_aux_header_t));
1607
1608 if (kmsg->ikm_type == IKM_TYPE_ALL_INLINED) {
1609 return (mach_msg_aux_header_t *)((vm_offset_t)kmsg + IKM_SAVED_KMSG_SIZE -
1610 kmsg->ikm_aux_size);
1611 } else {
1612 assert(kmsg->ikm_type != IKM_TYPE_KDATA_OOL);
1613 return (mach_msg_aux_header_t *)((vm_offset_t)kmsg->ikm_udata +
1614 kmsg->ikm_udata_size - kmsg->ikm_aux_size);
1615 }
1616 }
1617
1618 /* Return real size of kmsg aux data */
1619 inline mach_msg_size_t
ipc_kmsg_aux_data_size(ipc_kmsg_t kmsg)1620 ipc_kmsg_aux_data_size(
1621 ipc_kmsg_t kmsg)
1622 {
1623 mach_msg_aux_header_t *aux;
1624
1625 aux = ikm_aux_header(kmsg);
1626 if (aux == NULL) {
1627 return 0;
1628 }
1629
1630 #if (DEVELOPMENT || DEBUG)
1631 if (kmsg->ikm_type == IKM_TYPE_ALL_INLINED) {
1632 assert((vm_offset_t)aux + aux->msgdh_size <= (vm_offset_t)kmsg + IKM_SAVED_KMSG_SIZE);
1633 } else {
1634 assert((vm_offset_t)aux + aux->msgdh_size <= ikm_udata_end(kmsg));
1635 }
1636
1637 assert3u(aux->msgdh_size, <=, kmsg->ikm_aux_size);
1638 assert3u(aux->msgdh_size, >=, sizeof(mach_msg_aux_header_t));
1639 #endif
1640
1641 return aux->msgdh_size;
1642 }
1643
1644 void
ipc_kmsg_set_aux_data_header(ipc_kmsg_t kmsg,mach_msg_aux_header_t * new_hdr)1645 ipc_kmsg_set_aux_data_header(
1646 ipc_kmsg_t kmsg,
1647 mach_msg_aux_header_t *new_hdr)
1648 {
1649 mach_msg_aux_header_t *cur_hdr;
1650
1651 assert3u(new_hdr->msgdh_size, >=, sizeof(mach_msg_aux_header_t));
1652
1653 cur_hdr = ikm_aux_header(kmsg);
1654 if (cur_hdr == NULL) {
1655 return;
1656 }
1657
1658 /*
1659 * New header size must not exceed the space allocated for aux.
1660 */
1661 assert3u(kmsg->ikm_aux_size, >=, new_hdr->msgdh_size);
1662 assert3u(kmsg->ikm_aux_size, >=, sizeof(mach_msg_aux_header_t));
1663
1664 *cur_hdr = *new_hdr;
1665 }
1666
1667 KALLOC_TYPE_VAR_DEFINE(KT_IPC_KMSG_KDATA_OOL,
1668 mach_msg_base_t, mach_msg_descriptor_t, KT_DEFAULT);
1669
1670 static inline void *
ikm_alloc_kdata_ool(size_t size,zalloc_flags_t flags)1671 ikm_alloc_kdata_ool(size_t size, zalloc_flags_t flags)
1672 {
1673 return kalloc_type_var_impl(KT_IPC_KMSG_KDATA_OOL,
1674 size, flags, NULL);
1675 }
1676
1677 static inline void
ikm_free_kdata_ool(void * ptr,size_t size)1678 ikm_free_kdata_ool(void *ptr, size_t size)
1679 {
1680 kfree_type_var_impl(KT_IPC_KMSG_KDATA_OOL, ptr, size);
1681 }
1682
1683
1684 /*
1685 * Routine: ipc_kmsg_alloc
1686 * Purpose:
1687 * Allocate a kernel message structure. If the
1688 * message is scalar and all the data resides inline, that is best.
1689 * Otherwise, allocate out of line buffers to fit the message and
1690 * the optional auxiliary data.
1691 *
1692 * Conditions:
1693 * Nothing locked.
1694 *
1695 * kmsg_size doesn't take the trailer or descriptor
1696 * inflation into account, but already accounts for the mach
1697 * message header expansion.
1698 */
1699 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)1700 ipc_kmsg_alloc(
1701 mach_msg_size_t kmsg_size,
1702 mach_msg_size_t aux_size,
1703 mach_msg_size_t desc_count,
1704 ipc_kmsg_alloc_flags_t flags)
1705 {
1706 mach_msg_size_t max_kmsg_size, max_delta, max_kdata_size,
1707 min_kdata_size, max_udata_size, max_kmsg_and_aux_size;
1708 ipc_kmsg_t kmsg;
1709
1710 void *msg_data = NULL, *user_data = NULL;
1711 zalloc_flags_t alloc_flags = Z_WAITOK;
1712 ipc_kmsg_type_t kmsg_type;
1713 ipc_kmsg_vector_t *vec;
1714
1715 /*
1716 * In kernel descriptors, are of the same size (KERNEL_DESC_SIZE),
1717 * but in userspace, depending on 64-bitness, descriptors might be
1718 * smaller.
1719 *
1720 * When handling a userspace message however, we know how many
1721 * descriptors have been declared, and we pad for the maximum expansion.
1722 *
1723 * During descriptor expansion, message header stays at the same place
1724 * while everything after it gets shifted to higher address.
1725 */
1726 if (flags & IPC_KMSG_ALLOC_KERNEL) {
1727 assert(aux_size == 0);
1728 max_delta = 0;
1729 } else if (os_mul_overflow(desc_count, USER_DESC_MAX_DELTA, &max_delta)) {
1730 return IKM_NULL;
1731 }
1732
1733 if (os_add3_overflow(kmsg_size, MAX_TRAILER_SIZE, max_delta, &max_kmsg_size)) {
1734 return IKM_NULL;
1735 }
1736 if (os_add_overflow(max_kmsg_size, aux_size, &max_kmsg_and_aux_size)) {
1737 return IKM_NULL;
1738 }
1739
1740 if (flags & IPC_KMSG_ALLOC_ZERO) {
1741 alloc_flags |= Z_ZERO;
1742 }
1743 if (flags & IPC_KMSG_ALLOC_NOFAIL) {
1744 alloc_flags |= Z_NOFAIL;
1745 }
1746
1747 /* First, determine the layout of the kmsg to allocate */
1748 if (max_kmsg_and_aux_size <= IKM_SAVED_MSG_SIZE) {
1749 kmsg_type = IKM_TYPE_ALL_INLINED;
1750 max_udata_size = 0;
1751 max_kdata_size = 0;
1752 } else if (flags & IPC_KMSG_ALLOC_SAVED) {
1753 panic("size too large for the fast kmsg zone (%d)", kmsg_size);
1754 } else if (flags & IPC_KMSG_ALLOC_LINEAR) {
1755 kmsg_type = IKM_TYPE_KDATA_OOL;
1756 /*
1757 * Caller sets MACH64_SEND_KOBJECT_CALL or MACH64_SEND_ANY, or that
1758 * the call originates from kernel, or it's a mach_msg() call.
1759 * In any case, message does not carry aux data.
1760 * We have validated mach_msg2() call options in mach_msg2_trap().
1761 */
1762 if (aux_size != 0) {
1763 panic("non-zero aux size for kmsg type IKM_TYPE_KDATA_OOL.");
1764 }
1765 max_udata_size = aux_size;
1766 max_kdata_size = max_kmsg_size;
1767 } else {
1768 /*
1769 * If message can be splitted from the middle, IOW does not need to
1770 * occupy contiguous memory space, sequester (header + descriptors)
1771 * from (content + trailer + aux) for memory security.
1772 */
1773 assert(max_kmsg_and_aux_size > IKM_SAVED_MSG_SIZE);
1774
1775 /*
1776 * max_kdata_size: Maximum combined size of header plus (optional) descriptors.
1777 * This is _base_ size + descriptor count * kernel descriptor size.
1778 */
1779 if (os_mul_and_add_overflow(desc_count, KERNEL_DESC_SIZE,
1780 sizeof(mach_msg_base_t), &max_kdata_size)) {
1781 return IKM_NULL;
1782 }
1783
1784 /*
1785 * min_kdata_size: Minimum combined size of header plus (optional) descriptors.
1786 * This is _header_ size + descriptor count * minimal descriptor size.
1787 */
1788 mach_msg_size_t min_size = (flags & IPC_KMSG_ALLOC_KERNEL) ?
1789 KERNEL_DESC_SIZE : MACH_MSG_DESC_MIN_SIZE;
1790 if (os_mul_and_add_overflow(desc_count, min_size,
1791 sizeof(mach_msg_header_t), &min_kdata_size)) {
1792 return IKM_NULL;
1793 }
1794
1795 /*
1796 * max_udata_size: Maximum combined size of message content, trailer and aux.
1797 * This is total kmsg and aux size (already accounts for max trailer size) minus
1798 * _minimum_ (header + descs) size.
1799 */
1800 if (os_sub_overflow(max_kmsg_and_aux_size, min_kdata_size, &max_udata_size)) {
1801 return IKM_NULL;
1802 }
1803
1804 if (max_kdata_size <= IKM_SAVED_MSG_SIZE) {
1805 max_kdata_size = 0; /* no need to allocate kdata */
1806 kmsg_type = IKM_TYPE_UDATA_OOL;
1807 } else {
1808 kmsg_type = IKM_TYPE_ALL_OOL;
1809 }
1810 }
1811
1812 /* Then, allocate memory for both udata and kdata if needed, as well as kmsg */
1813 if (max_udata_size > 0) {
1814 user_data = kalloc_data(max_udata_size, alloc_flags);
1815 if (user_data == NULL) {
1816 return IKM_NULL;
1817 }
1818 }
1819
1820 if (max_kdata_size > 0) {
1821 if (kmsg_type == IKM_TYPE_ALL_OOL) {
1822 msg_data = kalloc_type(mach_msg_base_t, mach_msg_descriptor_t,
1823 desc_count, alloc_flags | Z_SPRAYQTN);
1824 } else {
1825 assert(kmsg_type == IKM_TYPE_KDATA_OOL);
1826 msg_data = ikm_alloc_kdata_ool(max_kdata_size, alloc_flags);
1827 }
1828
1829 if (__improbable(msg_data == NULL)) {
1830 kfree_data(user_data, max_udata_size);
1831 return IKM_NULL;
1832 }
1833 }
1834
1835 kmsg = zalloc_flags(ipc_kmsg_zone, Z_WAITOK | Z_ZERO | Z_NOFAIL);
1836 kmsg->ikm_type = kmsg_type;
1837 kmsg->ikm_aux_size = aux_size;
1838
1839 /* Finally, set up pointers properly */
1840 if (user_data) {
1841 assert(kmsg_type != IKM_TYPE_ALL_INLINED);
1842 kmsg->ikm_udata = user_data;
1843 kmsg->ikm_udata_size = max_udata_size; /* buffer size */
1844 }
1845 if (msg_data) {
1846 assert(kmsg_type == IKM_TYPE_ALL_OOL || kmsg_type == IKM_TYPE_KDATA_OOL);
1847 vec = (ipc_kmsg_vector_t *)ikm_inline_data(kmsg);
1848 vec->kmsgv_data = msg_data;
1849 vec->kmsgv_size = (kmsg_type == IKM_TYPE_ALL_OOL) ?
1850 desc_count : /* save descriptor count on kmsgv_size */
1851 max_kdata_size; /* buffer size */
1852 }
1853
1854 /* inline kmsg space at least can fit a vector */
1855 static_assert(IKM_SAVED_MSG_SIZE > sizeof(ipc_kmsg_vector_t));
1856
1857 return kmsg;
1858 }
1859
1860 /* re-export for IOKit's c++ */
1861 extern ipc_kmsg_t ipc_kmsg_alloc_uext_reply(mach_msg_size_t);
1862
1863 ipc_kmsg_t
ipc_kmsg_alloc_uext_reply(mach_msg_size_t size)1864 ipc_kmsg_alloc_uext_reply(
1865 mach_msg_size_t size)
1866 {
1867 return ipc_kmsg_alloc(size, 0, 0, IPC_KMSG_ALLOC_KERNEL | IPC_KMSG_ALLOC_LINEAR |
1868 IPC_KMSG_ALLOC_ZERO | IPC_KMSG_ALLOC_NOFAIL);
1869 }
1870
1871
1872 /*
1873 * Routine: ipc_kmsg_free
1874 * Purpose:
1875 * Free a kernel message (and udata) buffer. If the kmg is preallocated
1876 * to a port, just "put it back (marked unused)." We have to
1877 * do this with the port locked. The port may have its hold
1878 * on our message released. In that case, we have to just
1879 * revert the message to a traditional one and free it normally.
1880 * Conditions:
1881 * Nothing locked.
1882 */
1883 void
ipc_kmsg_free(ipc_kmsg_t kmsg)1884 ipc_kmsg_free(
1885 ipc_kmsg_t kmsg)
1886 {
1887 mach_msg_size_t msg_buf_size = 0, udata_buf_size = 0, dsc_count = 0;
1888 void *msg_buf = NULL, *udata_buf = NULL;
1889 ipc_kmsg_vector_t *vec = NULL;
1890 ipc_port_t inuse_port = IP_NULL;
1891 mach_msg_header_t *hdr;
1892
1893 assert(!IP_VALID(ipc_kmsg_get_voucher_port(kmsg)));
1894
1895 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_FREE) | DBG_FUNC_NONE,
1896 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
1897 0, 0, 0, 0);
1898
1899 switch (kmsg->ikm_type) {
1900 case IKM_TYPE_ALL_INLINED:
1901 case IKM_TYPE_UDATA_OOL:
1902 msg_buf = ikm_inline_data(kmsg);
1903 msg_buf_size = IKM_SAVED_MSG_SIZE;
1904 break;
1905 case IKM_TYPE_KDATA_OOL:
1906 vec = ikm_inline_data(kmsg);
1907 msg_buf = vec->kmsgv_data;
1908 msg_buf_size = vec->kmsgv_size;
1909 break;
1910 case IKM_TYPE_ALL_OOL:
1911 vec = ikm_inline_data(kmsg);
1912 msg_buf = vec->kmsgv_data;
1913 dsc_count = vec->kmsgv_size;
1914 msg_buf_size = sizeof(mach_msg_base_t) + dsc_count * KERNEL_DESC_SIZE;
1915 break;
1916 default:
1917 panic("strange kmsg type");
1918 }
1919
1920 hdr = ikm_header(kmsg);
1921 if ((void *)hdr < msg_buf ||
1922 (void *)hdr >= (void *)((uintptr_t)msg_buf + msg_buf_size)) {
1923 panic("ipc_kmsg_free: invalid kmsg (%p) header", kmsg);
1924 }
1925
1926 if (kmsg->ikm_type != IKM_TYPE_ALL_INLINED) {
1927 udata_buf = kmsg->ikm_udata;
1928 udata_buf_size = kmsg->ikm_udata_size;
1929 }
1930
1931 switch (kmsg->ikm_type) {
1932 case IKM_TYPE_ALL_INLINED:
1933 /*
1934 * Check to see if the message is bound to the port.
1935 * If so, mark it not in use.
1936 */
1937 inuse_port = ikm_prealloc_inuse_port(kmsg);
1938 if (inuse_port != IP_NULL) {
1939 ip_mq_lock(inuse_port);
1940 ikm_prealloc_clear_inuse(kmsg);
1941 assert(inuse_port->ip_premsg == kmsg);
1942 assert(IP_PREALLOC(inuse_port));
1943 ip_mq_unlock(inuse_port);
1944 ip_release(inuse_port); /* May be last reference */
1945 return;
1946 }
1947 /* all data inlined, nothing to do */
1948 break;
1949 case IKM_TYPE_UDATA_OOL:
1950 assert(udata_buf != NULL);
1951 kfree_data(udata_buf, udata_buf_size);
1952 /* kdata is inlined, udata freed */
1953 break;
1954 case IKM_TYPE_KDATA_OOL:
1955 ikm_free_kdata_ool(msg_buf, msg_buf_size);
1956 assert(udata_buf == NULL);
1957 assert(udata_buf_size == 0);
1958 /* kdata freed, no udata */
1959 break;
1960 case IKM_TYPE_ALL_OOL:
1961 kfree_type(mach_msg_base_t, mach_msg_descriptor_t, dsc_count, msg_buf);
1962 /* kdata freed */
1963 assert(udata_buf != NULL);
1964 kfree_data(udata_buf, udata_buf_size);
1965 /* udata freed */
1966 break;
1967 default:
1968 panic("strange kmsg type");
1969 }
1970
1971 zfree(ipc_kmsg_zone, kmsg);
1972 /* kmsg struct freed */
1973 }
1974
1975
1976 /*
1977 * Routine: ipc_kmsg_enqueue_qos
1978 * Purpose:
1979 * Enqueue a kmsg, propagating qos
1980 * overrides towards the head of the queue.
1981 *
1982 * Returns:
1983 * whether the head of the queue had
1984 * it's override-qos adjusted because
1985 * of this insertion.
1986 */
1987
1988 bool
ipc_kmsg_enqueue_qos(ipc_kmsg_queue_t queue,ipc_kmsg_t kmsg)1989 ipc_kmsg_enqueue_qos(
1990 ipc_kmsg_queue_t queue,
1991 ipc_kmsg_t kmsg)
1992 {
1993 mach_msg_qos_t qos_ovr = kmsg->ikm_qos_override;
1994 ipc_kmsg_t prev;
1995
1996 if (ipc_kmsg_enqueue(queue, kmsg)) {
1997 return true;
1998 }
1999
2000 /* apply QoS overrides towards the head */
2001 prev = ipc_kmsg_queue_element(kmsg->ikm_link.prev);
2002 while (prev != kmsg) {
2003 if (qos_ovr <= prev->ikm_qos_override) {
2004 return false;
2005 }
2006 prev->ikm_qos_override = qos_ovr;
2007 prev = ipc_kmsg_queue_element(prev->ikm_link.prev);
2008 }
2009
2010 return true;
2011 }
2012
2013 /*
2014 * Routine: ipc_kmsg_override_qos
2015 * Purpose:
2016 * Update the override for a given kmsg already
2017 * enqueued, propagating qos override adjustments
2018 * towards the head of the queue.
2019 *
2020 * Returns:
2021 * whether the head of the queue had
2022 * it's override-qos adjusted because
2023 * of this insertion.
2024 */
2025
2026 bool
ipc_kmsg_override_qos(ipc_kmsg_queue_t queue,ipc_kmsg_t kmsg,mach_msg_qos_t qos_ovr)2027 ipc_kmsg_override_qos(
2028 ipc_kmsg_queue_t queue,
2029 ipc_kmsg_t kmsg,
2030 mach_msg_qos_t qos_ovr)
2031 {
2032 ipc_kmsg_t first = ipc_kmsg_queue_first(queue);
2033 ipc_kmsg_t cur = kmsg;
2034
2035 /* apply QoS overrides towards the head */
2036 while (qos_ovr > cur->ikm_qos_override) {
2037 cur->ikm_qos_override = qos_ovr;
2038 if (cur == first) {
2039 return true;
2040 }
2041 cur = ipc_kmsg_queue_element(cur->ikm_link.prev);
2042 }
2043
2044 return false;
2045 }
2046
2047 /*
2048 * Routine: ipc_kmsg_destroy
2049 * Purpose:
2050 * Destroys a kernel message. Releases all rights,
2051 * references, and memory held by the message.
2052 * Frees the message.
2053 * Conditions:
2054 * No locks held.
2055 */
2056
2057 void
ipc_kmsg_destroy(ipc_kmsg_t kmsg,ipc_kmsg_destroy_flags_t flags)2058 ipc_kmsg_destroy(
2059 ipc_kmsg_t kmsg,
2060 ipc_kmsg_destroy_flags_t flags)
2061 {
2062 /* sign the msg if it has not been signed */
2063 boolean_t sign_msg = (flags & IPC_KMSG_DESTROY_NOT_SIGNED);
2064 mach_msg_header_t *hdr = ikm_header(kmsg);
2065
2066 if (flags & IPC_KMSG_DESTROY_SKIP_REMOTE) {
2067 hdr->msgh_remote_port = MACH_PORT_NULL;
2068 /* re-sign the msg since content changed */
2069 sign_msg = true;
2070 }
2071
2072 if (flags & IPC_KMSG_DESTROY_SKIP_LOCAL) {
2073 hdr->msgh_local_port = MACH_PORT_NULL;
2074 /* re-sign the msg since content changed */
2075 sign_msg = true;
2076 }
2077
2078 if (sign_msg) {
2079 ikm_sign(kmsg);
2080 }
2081
2082 /*
2083 * Destroying a message can cause more messages to be destroyed.
2084 * Curtail recursion by putting messages on the deferred
2085 * destruction queue. If this was the first message on the
2086 * queue, this instance must process the full queue.
2087 */
2088 if (ipc_kmsg_delayed_destroy(kmsg)) {
2089 ipc_kmsg_reap_delayed();
2090 }
2091 }
2092
2093 /*
2094 * Routine: ipc_kmsg_delayed_destroy
2095 * Purpose:
2096 * Enqueues a kernel message for deferred destruction.
2097 * Returns:
2098 * Boolean indicator that the caller is responsible to reap
2099 * deferred messages.
2100 */
2101
2102 bool
ipc_kmsg_delayed_destroy(ipc_kmsg_t kmsg)2103 ipc_kmsg_delayed_destroy(
2104 ipc_kmsg_t kmsg)
2105 {
2106 return ipc_kmsg_enqueue(¤t_thread()->ith_messages, kmsg);
2107 }
2108
2109 /*
2110 * Routine: ipc_kmsg_delayed_destroy_queue
2111 * Purpose:
2112 * Enqueues a queue of kernel messages for deferred destruction.
2113 * Returns:
2114 * Boolean indicator that the caller is responsible to reap
2115 * deferred messages.
2116 */
2117
2118 bool
ipc_kmsg_delayed_destroy_queue(ipc_kmsg_queue_t queue)2119 ipc_kmsg_delayed_destroy_queue(
2120 ipc_kmsg_queue_t queue)
2121 {
2122 return circle_queue_concat_tail(¤t_thread()->ith_messages, queue);
2123 }
2124
2125 /*
2126 * Routine: ipc_kmsg_reap_delayed
2127 * Purpose:
2128 * Destroys messages from the per-thread
2129 * deferred reaping queue.
2130 * Conditions:
2131 * No locks held. kmsgs on queue must be signed.
2132 */
2133
2134 void
ipc_kmsg_reap_delayed(void)2135 ipc_kmsg_reap_delayed(void)
2136 {
2137 ipc_kmsg_queue_t queue = &(current_thread()->ith_messages);
2138 ipc_kmsg_t kmsg;
2139
2140 /*
2141 * must leave kmsg in queue while cleaning it to assure
2142 * no nested calls recurse into here.
2143 */
2144 while ((kmsg = ipc_kmsg_queue_first(queue)) != IKM_NULL) {
2145 /*
2146 * Kmsgs queued for delayed destruction either come from
2147 * ipc_kmsg_destroy() or ipc_kmsg_delayed_destroy_queue(),
2148 * where we handover all kmsgs enqueued on port to destruction
2149 * queue in O(1). In either case, all kmsgs must have been
2150 * signed.
2151 *
2152 * For each unreceived msg, validate its signature before freeing.
2153 */
2154 ikm_validate_sig(kmsg);
2155
2156 ipc_kmsg_clean(kmsg);
2157 ipc_kmsg_rmqueue(queue, kmsg);
2158 ipc_kmsg_free(kmsg);
2159 }
2160 }
2161
2162 /*
2163 * Routine: ipc_kmsg_clean_body
2164 * Purpose:
2165 * Cleans the body of a kernel message.
2166 * Releases all rights, references, and memory.
2167 *
2168 * Conditions:
2169 * No locks held.
2170 */
2171 static void
ipc_kmsg_clean_body(__unused ipc_kmsg_t kmsg,mach_msg_type_number_t number,mach_msg_descriptor_t * saddr)2172 ipc_kmsg_clean_body(
2173 __unused ipc_kmsg_t kmsg,
2174 mach_msg_type_number_t number,
2175 mach_msg_descriptor_t *saddr)
2176 {
2177 mach_msg_type_number_t i;
2178
2179 if (number == 0) {
2180 return;
2181 }
2182
2183 for (i = 0; i < number; i++, saddr++) {
2184 switch (saddr->type.type) {
2185 case MACH_MSG_PORT_DESCRIPTOR: {
2186 mach_msg_port_descriptor_t *dsc;
2187
2188 dsc = &saddr->port;
2189
2190 /*
2191 * Destroy port rights carried in the message
2192 */
2193 if (!IP_VALID(dsc->name)) {
2194 continue;
2195 }
2196 ipc_object_destroy(ip_to_object(dsc->name), dsc->disposition);
2197 break;
2198 }
2199 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2200 case MACH_MSG_OOL_DESCRIPTOR: {
2201 mach_msg_ool_descriptor_t *dsc;
2202
2203 dsc = (mach_msg_ool_descriptor_t *)&saddr->out_of_line;
2204
2205 /*
2206 * Destroy memory carried in the message
2207 */
2208 if (dsc->size == 0) {
2209 assert(dsc->address == (void *) 0);
2210 } else {
2211 vm_map_copy_discard((vm_map_copy_t) dsc->address);
2212 }
2213 break;
2214 }
2215 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
2216 ipc_object_t *objects;
2217 mach_msg_type_number_t j;
2218 mach_msg_ool_ports_descriptor_t *dsc;
2219
2220 dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports;
2221 objects = (ipc_object_t *) dsc->address;
2222
2223 if (dsc->count == 0) {
2224 break;
2225 }
2226
2227 assert(objects != (ipc_object_t *) 0);
2228
2229 /* destroy port rights carried in the message */
2230
2231 for (j = 0; j < dsc->count; j++) {
2232 ipc_object_t object = objects[j];
2233
2234 if (!IO_VALID(object)) {
2235 continue;
2236 }
2237
2238 ipc_object_destroy(object, dsc->disposition);
2239 }
2240
2241 /* destroy memory carried in the message */
2242
2243 assert(dsc->count != 0);
2244
2245 kfree_type(mach_port_t, dsc->count, dsc->address);
2246 break;
2247 }
2248 case MACH_MSG_GUARDED_PORT_DESCRIPTOR: {
2249 mach_msg_guarded_port_descriptor_t *dsc = (typeof(dsc)) & saddr->guarded_port;
2250
2251 /*
2252 * Destroy port rights carried in the message
2253 */
2254 if (!IP_VALID(dsc->name)) {
2255 continue;
2256 }
2257 ipc_object_destroy(ip_to_object(dsc->name), dsc->disposition);
2258 break;
2259 }
2260 default:
2261 panic("invalid descriptor type: (%p: %d)",
2262 saddr, saddr->type.type);
2263 }
2264 }
2265 }
2266
2267 /*
2268 * Routine: ipc_kmsg_clean_partial
2269 * Purpose:
2270 * Cleans a partially-acquired kernel message.
2271 * number is the index of the type descriptor
2272 * in the body of the message that contained the error.
2273 * If dolast, the memory and port rights in this last
2274 * type spec are also cleaned. In that case, number
2275 * specifies the number of port rights to clean.
2276 * Conditions:
2277 * Nothing locked.
2278 */
2279
2280 static void
ipc_kmsg_clean_partial(ipc_kmsg_t kmsg,mach_msg_type_number_t number,mach_msg_descriptor_t * desc,vm_offset_t paddr,vm_size_t length)2281 ipc_kmsg_clean_partial(
2282 ipc_kmsg_t kmsg,
2283 mach_msg_type_number_t number,
2284 mach_msg_descriptor_t *desc,
2285 vm_offset_t paddr,
2286 vm_size_t length)
2287 {
2288 ipc_object_t object;
2289 mach_msg_header_t *hdr = ikm_header(kmsg);
2290 mach_msg_bits_t mbits = hdr->msgh_bits;
2291
2292 /* deal with importance chain while we still have dest and voucher references */
2293 ipc_importance_clean(kmsg);
2294
2295 object = ip_to_object(hdr->msgh_remote_port);
2296 assert(IO_VALID(object));
2297 ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits));
2298
2299 object = ip_to_object(hdr->msgh_local_port);
2300 if (IO_VALID(object)) {
2301 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
2302 }
2303
2304 object = ip_to_object(ipc_kmsg_get_voucher_port(kmsg));
2305 if (IO_VALID(object)) {
2306 assert(MACH_MSGH_BITS_VOUCHER(mbits) == MACH_MSG_TYPE_MOVE_SEND);
2307 ipc_object_destroy(object, MACH_MSG_TYPE_PORT_SEND);
2308 ipc_kmsg_clear_voucher_port(kmsg);
2309 }
2310
2311 if (paddr) {
2312 kmem_free(ipc_kernel_copy_map, paddr, length);
2313 }
2314
2315 ipc_kmsg_clean_body(kmsg, number, desc);
2316 }
2317
2318 /*
2319 * Routine: ipc_kmsg_clean
2320 * Purpose:
2321 * Cleans a kernel message. Releases all rights,
2322 * references, and memory held by the message.
2323 * Conditions:
2324 * No locks held.
2325 */
2326
2327 static void
ipc_kmsg_clean(ipc_kmsg_t kmsg)2328 ipc_kmsg_clean(
2329 ipc_kmsg_t kmsg)
2330 {
2331 ipc_object_t object;
2332 mach_msg_bits_t mbits;
2333 mach_msg_header_t *hdr;
2334
2335 /* deal with importance chain while we still have dest and voucher references */
2336 ipc_importance_clean(kmsg);
2337
2338 hdr = ikm_header(kmsg);
2339 mbits = hdr->msgh_bits;
2340 object = ip_to_object(hdr->msgh_remote_port);
2341 if (IO_VALID(object)) {
2342 ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits));
2343 }
2344
2345 object = ip_to_object(hdr->msgh_local_port);
2346 if (IO_VALID(object)) {
2347 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
2348 }
2349
2350 object = ip_to_object(ipc_kmsg_get_voucher_port(kmsg));
2351 if (IO_VALID(object)) {
2352 assert(MACH_MSGH_BITS_VOUCHER(mbits) == MACH_MSG_TYPE_MOVE_SEND);
2353 ipc_object_destroy(object, MACH_MSG_TYPE_PORT_SEND);
2354 ipc_kmsg_clear_voucher_port(kmsg);
2355 }
2356
2357 if (mbits & MACH_MSGH_BITS_COMPLEX) {
2358 mach_msg_body_t *body;
2359
2360 body = (mach_msg_body_t *) (hdr + 1);
2361 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count,
2362 (mach_msg_descriptor_t *)(body + 1));
2363 }
2364 }
2365
2366 /*
2367 * Routine: ipc_kmsg_set_prealloc
2368 * Purpose:
2369 * Assign a kmsg as a preallocated message buffer to a port.
2370 * Conditions:
2371 * port locked.
2372 */
2373 void
ipc_kmsg_set_prealloc(ipc_kmsg_t kmsg,ipc_port_t port)2374 ipc_kmsg_set_prealloc(
2375 ipc_kmsg_t kmsg,
2376 ipc_port_t port)
2377 {
2378 assert(kmsg->ikm_prealloc == IP_NULL);
2379 assert(kmsg->ikm_type == IKM_TYPE_ALL_INLINED);
2380 kmsg->ikm_prealloc = IP_NULL;
2381
2382 IP_SET_PREALLOC(port, kmsg);
2383 }
2384
2385 /*
2386 * Routine: ipc_kmsg_too_large
2387 * Purpose:
2388 * Return true if kmsg is too large to be received:
2389 *
2390 * If MACH64_RCV_LINEAR_VECTOR:
2391 * - combined message buffer is not large enough
2392 * to fit both the message (plus trailer) and
2393 * auxiliary data.
2394 * Otherwise:
2395 * - message buffer is not large enough
2396 * - auxiliary buffer is not large enough:
2397 * (1) kmsg is a vector with aux, but user expects
2398 * a scalar kmsg (ith_max_asize is 0)
2399 * (2) kmsg is a vector with aux, but user aux
2400 * buffer is not large enough.
2401 */
2402 bool
ipc_kmsg_too_large(mach_msg_size_t msg_size,mach_msg_size_t aux_size,mach_msg_option64_t option64,mach_msg_size_t max_msg_size,mach_msg_size_t max_aux_size,thread_t receiver)2403 ipc_kmsg_too_large(
2404 mach_msg_size_t msg_size,
2405 mach_msg_size_t aux_size,
2406 mach_msg_option64_t option64,
2407 mach_msg_size_t max_msg_size,
2408 mach_msg_size_t max_aux_size,
2409 thread_t receiver)
2410 {
2411 mach_msg_size_t tsize = REQUESTED_TRAILER_SIZE(thread_is_64bit_addr(receiver),
2412 receiver->ith_option);
2413
2414 if (max_aux_size != 0) {
2415 assert(option64 & MACH64_MSG_VECTOR);
2416 }
2417
2418 if (option64 & MACH64_RCV_LINEAR_VECTOR) {
2419 assert(receiver->ith_max_asize == 0);
2420 assert(receiver->ith_aux_addr == 0);
2421 assert(option64 & MACH64_MSG_VECTOR);
2422
2423 if (max_msg_size < msg_size + tsize + aux_size) {
2424 return true;
2425 }
2426 } else {
2427 if (max_msg_size < msg_size + tsize) {
2428 return true;
2429 }
2430
2431 /*
2432 * only return too large if MACH64_MSG_VECTOR.
2433 *
2434 * silently drop aux data when receiver is not expecting it for compat
2435 * reasons.
2436 */
2437 if ((option64 & MACH64_MSG_VECTOR) && max_aux_size < aux_size) {
2438 return true;
2439 }
2440 }
2441
2442 return false;
2443 }
2444
2445 /*
2446 * Routine: ipc_kmsg_get_body_and_aux_from_user
2447 * Purpose:
2448 * Copies in user message (and aux) to allocated kernel message buffer.
2449 * Conditions:
2450 * msg_addr and msg_size must be valid. aux_addr and aux_size can
2451 * be NULL if kmsg is not vectorized, or vector kmsg does not carry
2452 * auxiliary data.
2453 *
2454 * msg up to sizeof(mach_msg_user_header_t) has been previously copied in,
2455 * and number of descriptors has been made known.
2456 *
2457 * kmsg_size already accounts for message header expansion.
2458 *
2459 * if aux_size is not 0, mach_msg_validate_data_vectors() guarantees that
2460 * aux_size must be larger than mach_msg_aux_header_t.
2461 */
2462 static mach_msg_return_t
ipc_kmsg_get_body_and_aux_from_user(ipc_kmsg_t kmsg,mach_vm_address_t msg_addr,mach_msg_size_t kmsg_size,mach_vm_address_t aux_addr,mach_msg_size_t aux_size,mach_msg_size_t desc_count,mach_msg_user_header_t user_header)2463 ipc_kmsg_get_body_and_aux_from_user(
2464 ipc_kmsg_t kmsg,
2465 mach_vm_address_t msg_addr,
2466 mach_msg_size_t kmsg_size,
2467 mach_vm_address_t aux_addr, /* Nullable */
2468 mach_msg_size_t aux_size, /* Nullable */
2469 mach_msg_size_t desc_count,
2470 mach_msg_user_header_t user_header)
2471 {
2472 mach_msg_header_t *hdr = ikm_header(kmsg);
2473 hdr->msgh_size = kmsg_size;
2474 hdr->msgh_bits = user_header.msgh_bits;
2475 hdr->msgh_remote_port = CAST_MACH_NAME_TO_PORT(user_header.msgh_remote_port);
2476 hdr->msgh_local_port = CAST_MACH_NAME_TO_PORT(user_header.msgh_local_port);
2477 hdr->msgh_voucher_port = user_header.msgh_voucher_port;
2478 hdr->msgh_id = user_header.msgh_id;
2479
2480 if (user_header.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
2481 mach_msg_base_t *kbase = (mach_msg_base_t *)hdr;
2482
2483 assert(kmsg_size >= sizeof(mach_msg_base_t));
2484 kbase->body.msgh_descriptor_count = desc_count;
2485
2486 /* copy in the rest of the message, after user_base */
2487 if (kmsg_size > sizeof(mach_msg_base_t)) {
2488 /*
2489 * if kmsg is linear, just copyin the remaining msg after base
2490 * and we are done. Otherwise, first copyin until the end of descriptors
2491 * or the message, whichever comes first.
2492 */
2493 mach_msg_size_t copyin_size = kmsg_size - sizeof(mach_msg_base_t);
2494 if (!ikm_is_linear(kmsg) && (desc_count * KERNEL_DESC_SIZE < copyin_size)) {
2495 copyin_size = desc_count * KERNEL_DESC_SIZE;
2496 }
2497
2498 assert((vm_offset_t)hdr + sizeof(mach_msg_base_t) +
2499 copyin_size <= ikm_kdata_end(kmsg));
2500
2501 if (copyinmsg(msg_addr + sizeof(mach_msg_user_base_t),
2502 (char *)hdr + sizeof(mach_msg_base_t),
2503 copyin_size)) {
2504 return MACH_SEND_INVALID_DATA;
2505 }
2506
2507 /*
2508 * next, pre-validate the descriptors user claims to have by checking
2509 * their size and type, instead of doing it at body copyin time.
2510 */
2511 mach_msg_return_t mr = ikm_check_descriptors(kmsg, current_map(), copyin_size);
2512 if (mr != MACH_MSG_SUCCESS) {
2513 return mr;
2514 }
2515
2516 /*
2517 * for non-linear kmsg, since we have copied in all data that can
2518 * possibly be a descriptor and pre-validated them, we can now measure
2519 * the actual descriptor size and copyin the remaining user data
2520 * following the descriptors, if there is any.
2521 */
2522 if (!ikm_is_linear(kmsg)) {
2523 mach_msg_size_t dsc_size = ikm_total_desc_size(kmsg, current_map(), 0, 0, true);
2524 assert(desc_count * KERNEL_DESC_SIZE >= dsc_size);
2525
2526 /* if there is user data after descriptors, copy it into data heap */
2527 if (kmsg_size > sizeof(mach_msg_base_t) + dsc_size) {
2528 copyin_size = kmsg_size - sizeof(mach_msg_base_t) - dsc_size;
2529
2530 assert(kmsg->ikm_udata != NULL);
2531 assert((vm_offset_t)kmsg->ikm_udata + copyin_size <= ikm_udata_end(kmsg));
2532 if (copyinmsg(msg_addr + sizeof(mach_msg_user_base_t) + dsc_size,
2533 (char *)kmsg->ikm_udata,
2534 copyin_size)) {
2535 return MACH_SEND_INVALID_DATA;
2536 }
2537 }
2538
2539 /* finally, nil out the extra user data we copied into kdata */
2540 if (desc_count * KERNEL_DESC_SIZE > dsc_size) {
2541 bzero((void *)((vm_offset_t)hdr + sizeof(mach_msg_base_t) + dsc_size),
2542 desc_count * KERNEL_DESC_SIZE - dsc_size);
2543 }
2544 }
2545 }
2546 } else {
2547 assert(desc_count == 0);
2548 /* copy in the rest of the message, after user_header */
2549 if (kmsg_size > sizeof(mach_msg_header_t)) {
2550 char *msg_content = ikm_is_linear(kmsg) ?
2551 (char *)hdr + sizeof(mach_msg_header_t) :
2552 (char *)kmsg->ikm_udata;
2553
2554 if (ikm_is_linear(kmsg)) {
2555 assert((vm_offset_t)hdr + kmsg_size <= ikm_kdata_end(kmsg));
2556 } else {
2557 assert((vm_offset_t)kmsg->ikm_udata + kmsg_size - sizeof(mach_msg_header_t) <= ikm_udata_end(kmsg));
2558 }
2559
2560 if (copyinmsg(msg_addr + sizeof(mach_msg_user_header_t), msg_content,
2561 kmsg_size - sizeof(mach_msg_header_t))) {
2562 return MACH_SEND_INVALID_DATA;
2563 }
2564 }
2565 }
2566
2567 if (aux_size > 0) {
2568 assert(aux_addr != 0);
2569 mach_msg_aux_header_t *aux_header = ikm_aux_header(kmsg);
2570
2571 assert(kmsg->ikm_aux_size == aux_size);
2572 assert(aux_header != NULL);
2573
2574 /* initialize aux data header */
2575 aux_header->msgdh_size = aux_size;
2576 aux_header->msgdh_reserved = 0;
2577
2578 /* copyin aux data after the header */
2579 assert(aux_size >= sizeof(mach_msg_aux_header_t));
2580 if (aux_size > sizeof(mach_msg_aux_header_t)) {
2581 if (kmsg->ikm_type != IKM_TYPE_ALL_INLINED) {
2582 assert((vm_offset_t)aux_header + aux_size <= ikm_udata_end(kmsg));
2583 } else {
2584 assert((vm_offset_t)aux_header + aux_size <= ikm_kdata_end(kmsg));
2585 }
2586 if (copyinmsg(aux_addr + sizeof(mach_msg_aux_header_t),
2587 (char *)aux_header + sizeof(mach_msg_aux_header_t),
2588 aux_size - sizeof(mach_msg_aux_header_t))) {
2589 return MACH_SEND_INVALID_DATA;
2590 }
2591 }
2592 }
2593
2594 return MACH_MSG_SUCCESS;
2595 }
2596
2597 /*
2598 * Routine: ipc_kmsg_get_from_user
2599 * Purpose:
2600 * Allocates a scalar or vector kernel message buffer.
2601 * Copies user message (and optional aux data) to the message buffer.
2602 * Conditions:
2603 * user_msg_size must have been bound checked. aux_{addr, size} are
2604 * 0 if not MACH64_MSG_VECTOR.
2605 * Returns:
2606 * Produces a kmsg reference on success.
2607 *
2608 * MACH_MSG_SUCCESS Acquired a message buffer.
2609 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
2610 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
2611 * MACH_SEND_TOO_LARGE Message too large to ever be sent.
2612 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
2613 * MACH_SEND_INVALID_DATA Couldn't copy message data.
2614 */
2615 mach_msg_return_t
ipc_kmsg_get_from_user(mach_vm_address_t msg_addr,mach_msg_size_t user_msg_size,mach_vm_address_t aux_addr,mach_msg_size_t aux_size,mach_msg_user_header_t user_header,mach_msg_size_t desc_count,mach_msg_option64_t option64,ipc_kmsg_t * kmsgp)2616 ipc_kmsg_get_from_user(
2617 mach_vm_address_t msg_addr,
2618 mach_msg_size_t user_msg_size,
2619 mach_vm_address_t aux_addr,
2620 mach_msg_size_t aux_size,
2621 mach_msg_user_header_t user_header,
2622 mach_msg_size_t desc_count,
2623 mach_msg_option64_t option64,
2624 ipc_kmsg_t *kmsgp)
2625 {
2626 mach_msg_size_t kmsg_size = 0;
2627 ipc_kmsg_alloc_flags_t flags = IPC_KMSG_ALLOC_USER;
2628 ipc_kmsg_t kmsg;
2629 kern_return_t kr;
2630
2631 kmsg_size = user_msg_size + USER_HEADER_SIZE_DELTA;
2632
2633 if (aux_size == 0) {
2634 assert(aux_addr == 0);
2635 } else {
2636 assert(aux_size >= sizeof(mach_msg_aux_header_t));
2637 }
2638
2639 if (!(option64 & MACH64_MSG_VECTOR)) {
2640 assert(aux_addr == 0);
2641 assert(aux_size == 0);
2642 }
2643
2644 /*
2645 * If not a mach_msg2() call to a message queue, allocate a linear kmsg.
2646 *
2647 * This is equivalent to making the following cases always linear:
2648 * - mach_msg_trap() calls.
2649 * - mach_msg2_trap() to kobject ports.
2650 * - mach_msg2_trap() from old simulators.
2651 */
2652 if (!(option64 & MACH64_SEND_MQ_CALL)) {
2653 flags |= IPC_KMSG_ALLOC_LINEAR;
2654 }
2655
2656 kmsg = ipc_kmsg_alloc(kmsg_size, aux_size, desc_count, flags);
2657 /* can fail if msg size is too large */
2658 if (kmsg == IKM_NULL) {
2659 return MACH_SEND_NO_BUFFER;
2660 }
2661
2662 kr = ipc_kmsg_get_body_and_aux_from_user(kmsg, msg_addr, kmsg_size,
2663 aux_addr, aux_size, desc_count, user_header);
2664 if (kr != MACH_MSG_SUCCESS) {
2665 ipc_kmsg_free(kmsg);
2666 return kr;
2667 }
2668
2669 *kmsgp = kmsg;
2670 return MACH_MSG_SUCCESS;
2671 }
2672
2673 /*
2674 * Routine: ipc_kmsg_get_from_kernel
2675 * Purpose:
2676 * First checks for a preallocated message
2677 * reserved for kernel clients. If not found or size is too large -
2678 * allocates a new kernel message buffer.
2679 * Copies a kernel message to the message buffer.
2680 * Only resource errors are allowed.
2681 * Conditions:
2682 * Nothing locked.
2683 * Ports in header are ipc_port_t.
2684 * Returns:
2685 * MACH_MSG_SUCCESS Acquired a message buffer.
2686 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
2687 */
2688
2689 mach_msg_return_t
ipc_kmsg_get_from_kernel(mach_msg_header_t * msg,mach_msg_size_t size,ipc_kmsg_t * kmsgp)2690 ipc_kmsg_get_from_kernel(
2691 mach_msg_header_t *msg,
2692 mach_msg_size_t size, /* can be larger than prealloc space */
2693 ipc_kmsg_t *kmsgp)
2694 {
2695 ipc_kmsg_t kmsg;
2696 mach_msg_header_t *hdr;
2697 void *udata;
2698
2699 ipc_port_t dest_port;
2700 bool complex;
2701 mach_msg_size_t desc_count, kdata_sz;
2702
2703 assert(size >= sizeof(mach_msg_header_t));
2704 assert((size & 3) == 0);
2705
2706 dest_port = msg->msgh_remote_port; /* Nullable */
2707 complex = (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX);
2708
2709 /*
2710 * See if the port has a pre-allocated kmsg for kernel
2711 * clients. These are set up for those kernel clients
2712 * which cannot afford to wait.
2713 */
2714 if (IP_VALID(dest_port) && IP_PREALLOC(dest_port)) {
2715 ip_mq_lock(dest_port);
2716
2717 if (!ip_active(dest_port)) {
2718 ip_mq_unlock(dest_port);
2719 return MACH_SEND_NO_BUFFER;
2720 }
2721
2722 assert(IP_PREALLOC(dest_port));
2723 kmsg = dest_port->ip_premsg;
2724
2725 if (ikm_prealloc_inuse(kmsg)) {
2726 ip_mq_unlock(dest_port);
2727 return MACH_SEND_NO_BUFFER;
2728 }
2729
2730 assert(kmsg->ikm_type == IKM_TYPE_ALL_INLINED);
2731 assert(kmsg->ikm_aux_size == 0);
2732
2733 if (size + MAX_TRAILER_SIZE > IKM_SAVED_MSG_SIZE) {
2734 ip_mq_unlock(dest_port);
2735 return MACH_SEND_TOO_LARGE;
2736 }
2737 ikm_prealloc_set_inuse(kmsg, dest_port);
2738
2739 ip_mq_unlock(dest_port);
2740 } else {
2741 desc_count = 0;
2742 kdata_sz = sizeof(mach_msg_header_t);
2743
2744 if (complex) {
2745 desc_count = ((mach_msg_base_t *)msg)->body.msgh_descriptor_count;
2746 kdata_sz = sizeof(mach_msg_base_t) + desc_count * KERNEL_DESC_SIZE;
2747 assert(size >= kdata_sz);
2748 }
2749
2750 kmsg = ipc_kmsg_alloc(size, 0, desc_count, IPC_KMSG_ALLOC_KERNEL);
2751 /* kmsg can be non-linear */
2752 }
2753
2754 if (kmsg == IKM_NULL) {
2755 return MACH_SEND_NO_BUFFER;
2756 }
2757
2758 hdr = ikm_header(kmsg);
2759 if (ikm_is_linear(kmsg)) {
2760 memcpy(hdr, msg, size);
2761 } else {
2762 /* copy kdata to kernel allocation chunk */
2763 memcpy(hdr, msg, kdata_sz);
2764 /* copy udata to user allocation chunk */
2765 udata = ikm_udata(kmsg, desc_count, complex);
2766 memcpy(udata, (char *)msg + kdata_sz, size - kdata_sz);
2767 }
2768 hdr->msgh_size = size;
2769
2770 *kmsgp = kmsg;
2771 return MACH_MSG_SUCCESS;
2772 }
2773
2774 /*
2775 * Routine: ipc_kmsg_option_check
2776 * Purpose:
2777 * Check the option passed by mach_msg2 that works with
2778 * the passed destination port.
2779 * Conditions:
2780 * Space locked.
2781 * Returns:
2782 * MACH_MSG_SUCCESS On Success.
2783 * MACH_SEND_INVALID_OPTIONS On Failure.
2784 */
2785 static mach_msg_return_t
ipc_kmsg_option_check(ipc_port_t port,mach_msg_option64_t option64)2786 ipc_kmsg_option_check(
2787 ipc_port_t port,
2788 mach_msg_option64_t option64)
2789 {
2790 if (option64 & MACH64_MACH_MSG2) {
2791 /*
2792 * This is a _user_ message via mach_msg2_trap()。
2793 *
2794 * To curb kobject port/message queue confusion and improve control flow
2795 * integrity, mach_msg2_trap() invocations mandate the use of either
2796 * MACH64_SEND_KOBJECT_CALL or MACH64_SEND_MQ_CALL and that the flag
2797 * matches the underlying port type. (unless the call is from a simulator,
2798 * since old simulators keep using mach_msg() in all cases indiscriminatingly.)
2799 *
2800 * Since:
2801 * (1) We make sure to always pass either MACH64_SEND_MQ_CALL or
2802 * MACH64_SEND_KOBJECT_CALL bit at all sites outside simulators
2803 * (checked by mach_msg2_trap());
2804 * (2) We checked in mach_msg2_trap() that _exactly_ one of the three bits is set.
2805 *
2806 * CFI check cannot be bypassed by simply setting MACH64_SEND_ANY.
2807 */
2808 #if XNU_TARGET_OS_OSX
2809 if (option64 & MACH64_SEND_ANY) {
2810 return MACH_MSG_SUCCESS;
2811 }
2812 #endif /* XNU_TARGET_OS_OSX */
2813
2814 if (ip_is_kobject(port)) {
2815 natural_t kotype = ip_kotype(port);
2816
2817 if (__improbable(kotype == IKOT_TIMER)) {
2818 /*
2819 * For bincompat, let's still allow user messages to timer port, but
2820 * force MACH64_SEND_MQ_CALL flag for memory segregation.
2821 */
2822 if (__improbable(!(option64 & MACH64_SEND_MQ_CALL))) {
2823 return MACH_SEND_INVALID_OPTIONS;
2824 }
2825 } else {
2826 /* Otherwise, caller must set MACH64_SEND_KOBJECT_CALL. */
2827 if (__improbable(!(option64 & MACH64_SEND_KOBJECT_CALL))) {
2828 return MACH_SEND_INVALID_OPTIONS;
2829 }
2830 }
2831 }
2832
2833 #if CONFIG_CSR
2834 if (csr_check(CSR_ALLOW_KERNEL_DEBUGGER) == 0) {
2835 /*
2836 * Allow MACH64_SEND_KOBJECT_CALL flag to message queues when SIP
2837 * is off (for Mach-on-Mach emulation). The other direction is still
2838 * not allowed (MIG KernelServer assumes a linear kmsg).
2839 */
2840 return MACH_MSG_SUCCESS;
2841 }
2842 #endif /* CONFIG_CSR */
2843
2844 /* If destination is a message queue, caller must set MACH64_SEND_MQ_CALL */
2845 if (__improbable((!ip_is_kobject(port) &&
2846 !(option64 & MACH64_SEND_MQ_CALL)))) {
2847 return MACH_SEND_INVALID_OPTIONS;
2848 }
2849 }
2850 return MACH_MSG_SUCCESS;
2851 }
2852
2853 /*
2854 * Routine: ipc_kmsg_send
2855 * Purpose:
2856 * Send a message. The message holds a reference
2857 * for the destination port in the msgh_remote_port field.
2858 *
2859 * If unsuccessful, the caller still has possession of
2860 * the message and must do something with it. If successful,
2861 * the message is queued, given to a receiver, destroyed,
2862 * or handled directly by the kernel via mach_msg.
2863 * Conditions:
2864 * Nothing locked.
2865 * Returns:
2866 * MACH_MSG_SUCCESS The message was accepted.
2867 * MACH_SEND_TIMED_OUT Caller still has message.
2868 * MACH_SEND_INTERRUPTED Caller still has message.
2869 * MACH_SEND_INVALID_DEST Caller still has message.
2870 * MACH_SEND_INVALID_OPTIONS Caller still has message.
2871 */
2872 mach_msg_return_t
ipc_kmsg_send(ipc_kmsg_t kmsg,mach_msg_option64_t option64,mach_msg_timeout_t send_timeout)2873 ipc_kmsg_send(
2874 ipc_kmsg_t kmsg,
2875 mach_msg_option64_t option64,
2876 mach_msg_timeout_t send_timeout)
2877 {
2878 ipc_port_t port;
2879 thread_t th = current_thread();
2880 mach_msg_return_t error = MACH_MSG_SUCCESS;
2881 boolean_t kernel_reply = FALSE;
2882 mach_msg_header_t *hdr;
2883
2884 /* Check if honor qlimit flag is set on thread. */
2885 if ((th->options & TH_OPT_HONOR_QLIMIT) == TH_OPT_HONOR_QLIMIT) {
2886 /* Remove the MACH_SEND_ALWAYS flag to honor queue limit. */
2887 option64 &= (~MACH64_SEND_ALWAYS);
2888 /* Add the timeout flag since the message queue might be full. */
2889 option64 |= MACH64_SEND_TIMEOUT;
2890 th->options &= (~TH_OPT_HONOR_QLIMIT);
2891 }
2892
2893 #if IMPORTANCE_INHERITANCE
2894 bool did_importance = false;
2895 #if IMPORTANCE_TRACE
2896 mach_msg_id_t imp_msgh_id = -1;
2897 int sender_pid = -1;
2898 #endif /* IMPORTANCE_TRACE */
2899 #endif /* IMPORTANCE_INHERITANCE */
2900
2901 hdr = ikm_header(kmsg);
2902 /* don't allow the creation of a circular loop */
2903 if (hdr->msgh_bits & MACH_MSGH_BITS_CIRCULAR) {
2904 ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_ALL);
2905 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, MACH_MSGH_BITS_CIRCULAR);
2906 return MACH_MSG_SUCCESS;
2907 }
2908
2909 ipc_voucher_send_preprocessing(kmsg);
2910
2911 port = hdr->msgh_remote_port;
2912 assert(IP_VALID(port));
2913 ip_mq_lock(port);
2914
2915 /*
2916 * If the destination has been guarded with a reply context, and the
2917 * sender is consuming a send-once right, then assume this is a reply
2918 * to an RPC and we need to validate that this sender is currently in
2919 * the correct context.
2920 */
2921 if (enforce_strict_reply && port->ip_reply_context != 0 &&
2922 ((option64 & MACH64_SEND_KERNEL) == 0) &&
2923 MACH_MSGH_BITS_REMOTE(hdr->msgh_bits) == MACH_MSG_TYPE_PORT_SEND_ONCE) {
2924 error = ipc_kmsg_validate_reply_context_locked((mach_msg_option_t)option64,
2925 port, th->ith_voucher, th->ith_voucher_name);
2926 if (error != MACH_MSG_SUCCESS) {
2927 ip_mq_unlock(port);
2928 return error;
2929 }
2930 }
2931
2932 #if IMPORTANCE_INHERITANCE
2933 retry:
2934 #endif /* IMPORTANCE_INHERITANCE */
2935 /*
2936 * Can't deliver to a dead port.
2937 * However, we can pretend it got sent
2938 * and was then immediately destroyed.
2939 */
2940 if (!ip_active(port)) {
2941 ip_mq_unlock(port);
2942 #if MACH_FLIPC
2943 if (MACH_NODE_VALID(kmsg->ikm_node) && FPORT_VALID(port->ip_messages.imq_fport)) {
2944 flipc_msg_ack(kmsg->ikm_node, &port->ip_messages, FALSE);
2945 }
2946 #endif
2947 if (did_importance) {
2948 /*
2949 * We're going to pretend we delivered this message
2950 * successfully, and just eat the kmsg. However, the
2951 * kmsg is actually visible via the importance_task!
2952 * We need to cleanup this linkage before we destroy
2953 * the message, and more importantly before we set the
2954 * msgh_remote_port to NULL. See: 34302571
2955 */
2956 ipc_importance_clean(kmsg);
2957 }
2958 ip_release(port); /* JMM - Future: release right, not just ref */
2959 ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_SKIP_REMOTE);
2960 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, MACH_SEND_INVALID_DEST);
2961 return MACH_MSG_SUCCESS;
2962 }
2963
2964 if (ip_in_space(port, ipc_space_kernel)) {
2965 require_ip_active(port);
2966 port->ip_messages.imq_seqno++;
2967 ip_mq_unlock(port);
2968
2969 counter_inc(¤t_task()->messages_sent);
2970
2971 /*
2972 * Call the server routine, and get the reply message to send.
2973 */
2974 kmsg = ipc_kobject_server(port, kmsg, (mach_msg_option_t)option64);
2975 if (kmsg == IKM_NULL) {
2976 return MACH_MSG_SUCCESS;
2977 }
2978 /* reload hdr since kmsg changed */
2979 hdr = ikm_header(kmsg);
2980
2981 /* sign the reply message */
2982 ipc_kmsg_init_trailer(kmsg, TASK_NULL);
2983 ikm_sign(kmsg);
2984
2985 /* restart the KMSG_INFO tracing for the reply message */
2986 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_START);
2987 port = hdr->msgh_remote_port;
2988 assert(IP_VALID(port));
2989 ip_mq_lock(port);
2990 /* fall thru with reply - same options */
2991 kernel_reply = TRUE;
2992 if (!ip_active(port)) {
2993 error = MACH_SEND_INVALID_DEST;
2994 }
2995 }
2996
2997 #if IMPORTANCE_INHERITANCE
2998 /*
2999 * Need to see if this message needs importance donation and/or
3000 * propagation. That routine can drop the port lock temporarily.
3001 * If it does we'll have to revalidate the destination.
3002 */
3003 if (!did_importance) {
3004 did_importance = true;
3005 if (ipc_importance_send(kmsg, (mach_msg_option_t)option64)) {
3006 goto retry;
3007 }
3008 }
3009 #endif /* IMPORTANCE_INHERITANCE */
3010
3011 if (error != MACH_MSG_SUCCESS) {
3012 ip_mq_unlock(port);
3013 } else {
3014 /*
3015 * We have a valid message and a valid reference on the port.
3016 * call mqueue_send() on its message queue.
3017 */
3018 ipc_special_reply_port_msg_sent(port);
3019
3020 error = ipc_mqueue_send_locked(&port->ip_messages, kmsg,
3021 (mach_msg_option_t)option64, send_timeout);
3022 /* port unlocked */
3023 }
3024
3025 #if IMPORTANCE_INHERITANCE
3026 if (did_importance) {
3027 __unused int importance_cleared = 0;
3028 switch (error) {
3029 case MACH_SEND_TIMED_OUT:
3030 case MACH_SEND_NO_BUFFER:
3031 case MACH_SEND_INTERRUPTED:
3032 case MACH_SEND_INVALID_DEST:
3033 /*
3034 * We still have the kmsg and its
3035 * reference on the port. But we
3036 * have to back out the importance
3037 * boost.
3038 *
3039 * The port could have changed hands,
3040 * be inflight to another destination,
3041 * etc... But in those cases our
3042 * back-out will find the new owner
3043 * (and all the operations that
3044 * transferred the right should have
3045 * applied their own boost adjustments
3046 * to the old owner(s)).
3047 */
3048 importance_cleared = 1;
3049 ipc_importance_clean(kmsg);
3050 break;
3051
3052 case MACH_MSG_SUCCESS:
3053 default:
3054 break;
3055 }
3056 #if IMPORTANCE_TRACE
3057 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, (IMPORTANCE_CODE(IMP_MSG, IMP_MSG_SEND)) | DBG_FUNC_END,
3058 task_pid(current_task()), sender_pid, imp_msgh_id, importance_cleared, 0);
3059 #endif /* IMPORTANCE_TRACE */
3060 }
3061 #endif /* IMPORTANCE_INHERITANCE */
3062
3063 /*
3064 * If the port has been destroyed while we wait, treat the message
3065 * as a successful delivery (like we do for an inactive port).
3066 */
3067 if (error == MACH_SEND_INVALID_DEST) {
3068 #if MACH_FLIPC
3069 if (MACH_NODE_VALID(kmsg->ikm_node) && FPORT_VALID(port->ip_messages.imq_fport)) {
3070 flipc_msg_ack(kmsg->ikm_node, &port->ip_messages, FALSE);
3071 }
3072 #endif
3073 ip_release(port); /* JMM - Future: release right, not just ref */
3074 ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_SKIP_REMOTE);
3075 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, MACH_SEND_INVALID_DEST);
3076 return MACH_MSG_SUCCESS;
3077 }
3078
3079 if (error != MACH_MSG_SUCCESS && kernel_reply) {
3080 /*
3081 * Kernel reply messages that fail can't be allowed to
3082 * pseudo-receive on error conditions. We need to just treat
3083 * the message as a successful delivery.
3084 */
3085 #if MACH_FLIPC
3086 if (MACH_NODE_VALID(kmsg->ikm_node) && FPORT_VALID(port->ip_messages.imq_fport)) {
3087 flipc_msg_ack(kmsg->ikm_node, &port->ip_messages, FALSE);
3088 }
3089 #endif
3090 ip_release(port); /* JMM - Future: release right, not just ref */
3091 ipc_kmsg_destroy(kmsg, IPC_KMSG_DESTROY_SKIP_REMOTE);
3092 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_INFO) | DBG_FUNC_END, error);
3093 return MACH_MSG_SUCCESS;
3094 }
3095 return error;
3096 }
3097
3098 /*
3099 * Routine: ipc_kmsg_convert_header_to_user
3100 * Purpose:
3101 * Convert a kmsg header back to user header.
3102 */
3103 static mach_msg_user_header_t *
ipc_kmsg_convert_header_to_user(ipc_kmsg_t kmsg)3104 ipc_kmsg_convert_header_to_user(
3105 ipc_kmsg_t kmsg)
3106 {
3107 assert(current_task() != kernel_task);
3108 mach_msg_header_t *hdr = ikm_header(kmsg);
3109
3110 /* user_header is kernel header shifted in place */
3111 mach_msg_user_header_t *user_header =
3112 (mach_msg_user_header_t *)((vm_offset_t)(hdr) + USER_HEADER_SIZE_DELTA);
3113
3114 mach_msg_bits_t bits = hdr->msgh_bits;
3115 mach_msg_size_t kmsg_size = hdr->msgh_size;
3116 mach_port_name_t remote_port = CAST_MACH_PORT_TO_NAME(hdr->msgh_remote_port);
3117 mach_port_name_t local_port = CAST_MACH_PORT_TO_NAME(hdr->msgh_local_port);
3118 mach_port_name_t voucher_port = hdr->msgh_voucher_port;
3119 mach_msg_id_t id = hdr->msgh_id;
3120
3121 user_header->msgh_id = id;
3122 user_header->msgh_local_port = local_port;
3123 user_header->msgh_remote_port = remote_port;
3124 user_header->msgh_voucher_port = voucher_port;
3125 user_header->msgh_size = kmsg_size - USER_HEADER_SIZE_DELTA;
3126 user_header->msgh_bits = bits;
3127
3128 return user_header;
3129 }
3130
3131 /*
3132 * Routine: ipc_kmsg_put_vector_to_user
3133 * Purpose:
3134 * Copies a scalar or vector message buffer to a user message.
3135 * Frees the message buffer.
3136 * Conditions:
3137 * Nothing locked. kmsg is freed upon return.
3138 *
3139 * 1. If user has allocated space for aux data, mach_msg_validate_data_vectors
3140 * guarantees that rcv_aux_addr is non-zero, and max_aux_size must be at least
3141 * sizeof(mach_msg_aux_header_t). In case the kmsg is a scalar or a vector
3142 * without auxiliary data, copy out an empty aux header to rcv_aux_addr which
3143 * serves as EOF.
3144 *
3145 * 2. If kmsg is a vector without aux, copy out the message as if it's scalar
3146 *
3147 * 3. If an aux buffer is provided by user, max_aux_size must be large enough
3148 * to at least fit the minimum aux header built by msg_receive_error().
3149 *
3150 * 4. If MACH64_RCV_LINEAR_VECTOR is set, use rcv_msg_addr as the combined
3151 * buffer for message proper and aux data. rcv_aux_addr and max_aux_size
3152 * must be passed as zeros and are ignored.
3153 *
3154 * Returns:
3155 * MACH_MSG_SUCCESS Copied data out of message buffer.
3156 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
3157 */
3158 static mach_msg_return_t
ipc_kmsg_put_vector_to_user(ipc_kmsg_t kmsg,mach_msg_option64_t option64,mach_vm_address_t rcv_msg_addr,mach_msg_size_t max_msg_size,mach_vm_address_t rcv_aux_addr,mach_msg_size_t max_aux_size,mach_msg_size_t trailer_size,mach_msg_size_t * msg_sizep,mach_msg_size_t * aux_sizep)3159 ipc_kmsg_put_vector_to_user(
3160 ipc_kmsg_t kmsg, /* scalar or vector */
3161 mach_msg_option64_t option64,
3162 mach_vm_address_t rcv_msg_addr,
3163 mach_msg_size_t max_msg_size,
3164 mach_vm_address_t rcv_aux_addr, /* Nullable */
3165 mach_msg_size_t max_aux_size, /* Nullable */
3166 mach_msg_size_t trailer_size,
3167 mach_msg_size_t *msg_sizep, /* size of msg copied out */
3168 mach_msg_size_t *aux_sizep) /* size of aux copied out */
3169 {
3170 mach_msg_size_t cpout_msg_size, cpout_aux_size;
3171 mach_msg_user_header_t *user_hdr;
3172 mach_msg_return_t mr = MACH_MSG_SUCCESS;
3173
3174 DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_put_vector_to_user()");
3175
3176 assert(option64 & MACH64_MSG_VECTOR);
3177 user_hdr = ipc_kmsg_convert_header_to_user(kmsg);
3178 /* ikm_header->msgh_size is now user msg size */
3179
3180 /* msg and aux size might be updated by msg_receive_error() */
3181 cpout_msg_size = user_hdr->msgh_size + trailer_size;
3182 cpout_aux_size = ipc_kmsg_aux_data_size(kmsg);
3183
3184 /*
3185 * For ipc_kmsg_put_scalar_to_user() we try to receive up to
3186 * msg buffer size for backward-compatibility. (See below).
3187 *
3188 * For mach_msg2(), we just error out here.
3189 */
3190 if (option64 & MACH64_RCV_LINEAR_VECTOR) {
3191 if (cpout_msg_size + cpout_aux_size > max_msg_size) {
3192 mr = MACH_RCV_INVALID_DATA;
3193 cpout_msg_size = 0;
3194 cpout_aux_size = 0;
3195 goto failed;
3196 }
3197 assert(rcv_aux_addr == 0);
3198 assert(max_aux_size == 0);
3199
3200 if (option64 & MACH64_RCV_STACK) {
3201 rcv_msg_addr += max_msg_size - cpout_msg_size - cpout_aux_size;
3202 }
3203 rcv_aux_addr = rcv_msg_addr + cpout_msg_size;
3204 max_aux_size = cpout_aux_size;
3205 } else {
3206 /*
3207 * (81193887) some clients stomp their own stack due to mis-sized
3208 * combined send/receives where the receive buffer didn't account
3209 * for the trailer size.
3210 *
3211 * At the very least, avoid smashing their stack.
3212 */
3213 if (cpout_msg_size > max_msg_size) {
3214 cpout_msg_size = max_msg_size;
3215
3216 /* just copy out the partial message for compatibility */
3217 cpout_aux_size = 0;
3218 goto copyout_msg;
3219 }
3220
3221 if (cpout_aux_size > max_aux_size) {
3222 /*
3223 * mach_msg_validate_data_vectors() guarantees
3224 * that max_aux_size is at least what msg_receive_error() builds
3225 * during MACH_RCV_TOO_LARGE, if an aux buffer is provided.
3226 *
3227 * So this can only happen if caller is trying to receive a vector
3228 * kmsg with aux, but did not provide aux buffer. And we must be
3229 * coming from msg_receive_error().
3230 */
3231 assert(rcv_aux_addr == 0);
3232
3233 /* just copy out the minimal message header and trailer */
3234 cpout_aux_size = 0;
3235 goto copyout_msg;
3236 }
3237 }
3238
3239 /*
3240 * at this point, we are certain that receiver has enough space for both msg
3241 * proper and aux data.
3242 */
3243 assert(max_aux_size >= cpout_aux_size);
3244 if (option64 & MACH64_RCV_LINEAR_VECTOR) {
3245 assert(max_msg_size >= cpout_msg_size + cpout_aux_size);
3246 } else {
3247 assert(max_msg_size >= cpout_msg_size);
3248 }
3249
3250 /* receive the aux data to user space */
3251 if (cpout_aux_size) {
3252 mach_msg_aux_header_t *aux_header;
3253
3254 if ((aux_header = ikm_aux_header(kmsg)) != NULL) {
3255 /* user expecting aux data, and kmsg has it */
3256 assert(rcv_aux_addr != 0);
3257 if (copyoutmsg((const char *)aux_header, rcv_aux_addr, cpout_aux_size)) {
3258 mr = MACH_RCV_INVALID_DATA;
3259 cpout_aux_size = 0;
3260 cpout_msg_size = 0;
3261 goto failed;
3262 }
3263 /* success, copy out the msg next */
3264 goto copyout_msg;
3265 }
3266 }
3267
3268 /* we only reach here if have not copied out any aux data */
3269 if (!(option64 & MACH64_RCV_LINEAR_VECTOR) && rcv_aux_addr != 0) {
3270 /*
3271 * If user has a buffer for aux data, at least copy out an empty header
3272 * which serves as an EOF. We don't need to do so for linear vector
3273 * because it's used in kevent context and we will return cpout_aux_size
3274 * as 0 on ext[3] to signify empty aux data.
3275 *
3276 * See: filt_machportprocess().
3277 */
3278 mach_msg_aux_header_t header = {.msgdh_size = 0};
3279 cpout_aux_size = sizeof(header);
3280 assert(max_aux_size >= cpout_aux_size);
3281 if (copyoutmsg((const char *)&header, rcv_aux_addr, cpout_aux_size)) {
3282 mr = MACH_RCV_INVALID_DATA;
3283 cpout_aux_size = 0;
3284 cpout_msg_size = 0;
3285 goto failed;
3286 }
3287 }
3288
3289 copyout_msg:
3290 /* receive the message proper to user space */
3291 if (ikm_is_linear(kmsg)) {
3292 if (copyoutmsg((const char *)user_hdr, rcv_msg_addr, cpout_msg_size)) {
3293 mr = MACH_RCV_INVALID_DATA;
3294 cpout_msg_size = 0;
3295 goto failed;
3296 }
3297 } else {
3298 mach_msg_size_t kdata_size = ikm_kdata_size(kmsg, current_map(),
3299 USER_HEADER_SIZE_DELTA, true);
3300 mach_msg_size_t udata_size = ikm_content_size(kmsg, current_map(),
3301 USER_HEADER_SIZE_DELTA, true) + trailer_size;
3302
3303 mach_msg_size_t kdata_copyout_size = MIN(kdata_size, cpout_msg_size);
3304 mach_msg_size_t udata_copyout_size = MIN(udata_size, cpout_msg_size - kdata_copyout_size);
3305
3306 /* First copy out kdata */
3307 if (copyoutmsg((const char *)user_hdr, rcv_msg_addr, kdata_copyout_size)) {
3308 mr = MACH_RCV_INVALID_DATA;
3309 cpout_msg_size = 0;
3310 goto failed;
3311 }
3312
3313 /* Then copy out udata */
3314 if (copyoutmsg((const char *)kmsg->ikm_udata, rcv_msg_addr + kdata_copyout_size,
3315 udata_copyout_size)) {
3316 mr = MACH_RCV_INVALID_DATA;
3317 cpout_msg_size = 0;
3318 goto failed;
3319 }
3320 }
3321
3322 /* at this point, we have copied out the message proper */
3323 assert(cpout_msg_size > 0);
3324
3325 failed:
3326
3327 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_LINK) | DBG_FUNC_NONE,
3328 (rcv_msg_addr >= VM_MIN_KERNEL_AND_KEXT_ADDRESS ||
3329 rcv_msg_addr + cpout_msg_size >= VM_MIN_KERNEL_AND_KEXT_ADDRESS) ? (uintptr_t)0 : (uintptr_t)rcv_msg_addr,
3330 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3331 1, /* this is on the receive/copyout path */
3332 0, 0);
3333
3334 ipc_kmsg_free(kmsg);
3335
3336 if (msg_sizep) {
3337 *msg_sizep = cpout_msg_size;
3338 }
3339
3340 if (aux_sizep) {
3341 *aux_sizep = cpout_aux_size;
3342 }
3343
3344 return mr;
3345 }
3346
3347 /*
3348 * Routine: ipc_kmsg_put_scalar_to_user
3349 * Purpose:
3350 * Copies a scalar message buffer to a user message.
3351 * Frees the message buffer.
3352 * Conditions:
3353 * Nothing locked. kmsg is freed upon return.
3354 *
3355 * Returns:
3356 * MACH_MSG_SUCCESS Copied data out of message buffer.
3357 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
3358 */
3359 static mach_msg_return_t
ipc_kmsg_put_scalar_to_user(ipc_kmsg_t kmsg,__unused mach_msg_option64_t option64,mach_vm_address_t rcv_addr,mach_msg_size_t rcv_size,mach_msg_size_t trailer_size,mach_msg_size_t * sizep)3360 ipc_kmsg_put_scalar_to_user(
3361 ipc_kmsg_t kmsg,
3362 __unused mach_msg_option64_t option64,
3363 mach_vm_address_t rcv_addr,
3364 mach_msg_size_t rcv_size,
3365 mach_msg_size_t trailer_size,
3366 mach_msg_size_t *sizep) /* size of msg copied out */
3367 {
3368 mach_msg_size_t copyout_size;
3369 mach_msg_user_header_t *user_hdr;
3370 mach_msg_return_t mr = MACH_MSG_SUCCESS;
3371
3372 DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_put_scalar_to_user()");
3373
3374 assert(!(option64 & MACH64_MSG_VECTOR));
3375 /* stack-based receive must be vectorized */
3376 assert(!(option64 & MACH64_RCV_STACK));
3377 /*
3378 * We will reach here in one of the following cases, kmsg size
3379 * may have been updated by msg_receive_error();
3380 *
3381 * 1. kmsg is scalar: OK to copy out as scalar
3382 * 2. kmsg is vector without aux: OK to copy out as scalar
3383 * 3. kmsg is vector with aux: silently dropping aux data
3384 */
3385 user_hdr = ipc_kmsg_convert_header_to_user(kmsg);
3386 /* ikm_header->msgh_size is now user msg size */
3387
3388 copyout_size = user_hdr->msgh_size + trailer_size;
3389
3390 /*
3391 * (81193887) some clients stomp their own stack due to mis-sized
3392 * combined send/receives where the receive buffer didn't account
3393 * for the trailer size.
3394 *
3395 * At the very least, avoid smashing their stack.
3396 */
3397 if (copyout_size > rcv_size) {
3398 copyout_size = rcv_size;
3399 }
3400
3401 if (ikm_is_linear(kmsg)) {
3402 if (copyoutmsg((const char *)user_hdr, rcv_addr, copyout_size)) {
3403 mr = MACH_RCV_INVALID_DATA;
3404 copyout_size = 0;
3405 }
3406 } else {
3407 mach_msg_size_t kdata_size = ikm_kdata_size(kmsg, current_map(),
3408 USER_HEADER_SIZE_DELTA, true);
3409 mach_msg_size_t udata_size = ikm_content_size(kmsg, current_map(),
3410 USER_HEADER_SIZE_DELTA, true) + trailer_size;
3411
3412 mach_msg_size_t kdata_copyout_size = MIN(kdata_size, copyout_size);
3413 mach_msg_size_t udata_copyout_size = MIN(udata_size, copyout_size - kdata_copyout_size);
3414
3415 /* First copy out kdata */
3416 if (copyoutmsg((const char *)user_hdr, rcv_addr, kdata_copyout_size)) {
3417 mr = MACH_RCV_INVALID_DATA;
3418 copyout_size = 0;
3419 }
3420
3421 /* Then copy out udata */
3422 if (copyoutmsg((const char *)kmsg->ikm_udata, rcv_addr + kdata_copyout_size,
3423 udata_copyout_size)) {
3424 mr = MACH_RCV_INVALID_DATA;
3425 copyout_size = 0;
3426 }
3427 }
3428
3429 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_KMSG_LINK) | DBG_FUNC_NONE,
3430 (rcv_addr >= VM_MIN_KERNEL_AND_KEXT_ADDRESS ||
3431 rcv_addr + copyout_size >= VM_MIN_KERNEL_AND_KEXT_ADDRESS) ? (uintptr_t)0 : (uintptr_t)rcv_addr,
3432 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3433 1, /* this is on the receive/copyout path */
3434 0, 0);
3435
3436 ipc_kmsg_free(kmsg);
3437
3438 if (sizep) {
3439 *sizep = copyout_size;
3440 }
3441 return mr;
3442 }
3443
3444 /*
3445 * Routine: ipc_kmsg_put_to_user
3446 * Purpose:
3447 * Copies a scalar or vector message buffer to a user message.
3448 * Frees the message buffer.
3449 * See comments above ipc_kmsg_put_{scalar, vector}_to_user().
3450 * Conditions:
3451 * Nothing locked. kmsg is freed upon return.
3452 *
3453 * Returns:
3454 * MACH_MSG_SUCCESS Copied data out of message buffer.
3455 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
3456 */
3457 mach_msg_return_t
ipc_kmsg_put_to_user(ipc_kmsg_t kmsg,mach_msg_option64_t option64,mach_vm_address_t rcv_msg_addr,mach_msg_size_t max_msg_size,mach_vm_address_t rcv_aux_addr,mach_msg_size_t max_aux_size,mach_msg_size_t trailer_size,mach_msg_size_t * msg_sizep,mach_msg_size_t * aux_sizep)3458 ipc_kmsg_put_to_user(
3459 ipc_kmsg_t kmsg, /* scalar or vector */
3460 mach_msg_option64_t option64,
3461 mach_vm_address_t rcv_msg_addr,
3462 mach_msg_size_t max_msg_size,
3463 mach_vm_address_t rcv_aux_addr, /* Nullable */
3464 mach_msg_size_t max_aux_size, /* Nullable */
3465 mach_msg_size_t trailer_size,
3466 mach_msg_size_t *msg_sizep, /* size of msg copied out */
3467 mach_msg_size_t *aux_sizep) /* size of aux copied out */
3468 {
3469 mach_msg_return_t mr;
3470
3471 if (option64 & MACH64_MSG_VECTOR) {
3472 mr = ipc_kmsg_put_vector_to_user(kmsg, option64, rcv_msg_addr,
3473 max_msg_size, rcv_aux_addr, max_aux_size, trailer_size,
3474 msg_sizep, aux_sizep);
3475 } else {
3476 mr = ipc_kmsg_put_scalar_to_user(kmsg, option64, rcv_msg_addr,
3477 max_msg_size, trailer_size, msg_sizep);
3478 if (mr == MACH_MSG_SUCCESS && aux_sizep != NULL) {
3479 *aux_sizep = 0;
3480 }
3481 }
3482
3483 /*
3484 * During message copyout, MACH_RCV_INVALID_DATA takes precedence
3485 * over all other errors. Other error code will be treated as
3486 * MACH_MSG_SUCCESS by mach_msg_receive_results().
3487 *
3488 * See: msg_receive_error().
3489 */
3490 assert(mr == MACH_RCV_INVALID_DATA || mr == MACH_MSG_SUCCESS);
3491 return mr;
3492 }
3493
3494 /*
3495 * Routine: ipc_kmsg_put_to_kernel
3496 * Purpose:
3497 * Copies a message buffer to a kernel message.
3498 * Frees the message buffer.
3499 * No errors allowed.
3500 * Conditions:
3501 * Nothing locked.
3502 */
3503
3504 void
ipc_kmsg_put_to_kernel(mach_msg_header_t * msg,ipc_kmsg_t kmsg,mach_msg_size_t rcv_size)3505 ipc_kmsg_put_to_kernel(
3506 mach_msg_header_t *msg,
3507 ipc_kmsg_t kmsg,
3508 mach_msg_size_t rcv_size) /* includes trailer size */
3509 {
3510 mach_msg_header_t *hdr = ikm_header(kmsg);
3511
3512 assert(kmsg->ikm_aux_size == 0);
3513 assert(rcv_size >= hdr->msgh_size);
3514
3515 if (ikm_is_linear(kmsg)) {
3516 (void)memcpy((void *)msg, (const void *)hdr, rcv_size);
3517 } else {
3518 mach_msg_size_t kdata_size = ikm_kdata_size(kmsg, current_map(), 0, false);
3519
3520 /* First memcpy kdata */
3521 assert(rcv_size >= kdata_size);
3522 (void)memcpy((void *)msg, (const void *)hdr, kdata_size);
3523
3524 /* Fill the remaining space with udata */
3525 (void)memcpy((void *)((vm_offset_t)msg + kdata_size),
3526 (const void *)kmsg->ikm_udata, rcv_size - kdata_size);
3527 }
3528
3529 ipc_kmsg_free(kmsg);
3530 }
3531
3532 static pthread_priority_compact_t
ipc_get_current_thread_priority(void)3533 ipc_get_current_thread_priority(void)
3534 {
3535 thread_t thread = current_thread();
3536 thread_qos_t qos;
3537 int relpri;
3538
3539 qos = thread_get_requested_qos(thread, &relpri);
3540 if (!qos) {
3541 qos = thread_user_promotion_qos_for_pri(thread->base_pri);
3542 relpri = 0;
3543 }
3544 return _pthread_priority_make_from_thread_qos(qos, relpri, 0);
3545 }
3546
3547 static kern_return_t
ipc_kmsg_set_qos(ipc_kmsg_t kmsg,mach_msg_option_t options,mach_msg_priority_t priority)3548 ipc_kmsg_set_qos(
3549 ipc_kmsg_t kmsg,
3550 mach_msg_option_t options,
3551 mach_msg_priority_t priority)
3552 {
3553 kern_return_t kr;
3554 mach_msg_header_t *hdr = ikm_header(kmsg);
3555 ipc_port_t special_reply_port = hdr->msgh_local_port;
3556 ipc_port_t dest_port = hdr->msgh_remote_port;
3557
3558 if ((options & MACH_SEND_OVERRIDE) &&
3559 !mach_msg_priority_is_pthread_priority(priority)) {
3560 mach_msg_qos_t qos = mach_msg_priority_qos(priority);
3561 int relpri = mach_msg_priority_relpri(priority);
3562 mach_msg_qos_t ovr = mach_msg_priority_overide_qos(priority);
3563
3564 kmsg->ikm_ppriority = _pthread_priority_make_from_thread_qos(qos, relpri, 0);
3565 kmsg->ikm_qos_override = MAX(qos, ovr);
3566 } else {
3567 #if CONFIG_VOUCHER_DEPRECATED
3568 kr = ipc_get_pthpriority_from_kmsg_voucher(kmsg, &kmsg->ikm_ppriority);
3569 #else
3570 kr = KERN_FAILURE;
3571 #endif /* CONFIG_VOUCHER_DEPRECATED */
3572 if (kr != KERN_SUCCESS) {
3573 if (options & MACH_SEND_PROPAGATE_QOS) {
3574 kmsg->ikm_ppriority = ipc_get_current_thread_priority();
3575 } else {
3576 kmsg->ikm_ppriority = MACH_MSG_PRIORITY_UNSPECIFIED;
3577 }
3578 }
3579
3580 if (options & MACH_SEND_OVERRIDE) {
3581 mach_msg_qos_t qos = _pthread_priority_thread_qos(kmsg->ikm_ppriority);
3582 mach_msg_qos_t ovr = _pthread_priority_thread_qos(priority);
3583 kmsg->ikm_qos_override = MAX(qos, ovr);
3584 } else {
3585 kmsg->ikm_qos_override = _pthread_priority_thread_qos(kmsg->ikm_ppriority);
3586 }
3587 }
3588
3589 kr = KERN_SUCCESS;
3590
3591 if (IP_VALID(special_reply_port) &&
3592 special_reply_port->ip_specialreply &&
3593 !ip_is_kobject(dest_port) &&
3594 MACH_MSGH_BITS_LOCAL(hdr->msgh_bits) == MACH_MSG_TYPE_PORT_SEND_ONCE) {
3595 boolean_t sync_bootstrap_checkin = !!(options & MACH_SEND_SYNC_BOOTSTRAP_CHECKIN);
3596 /*
3597 * Link the destination port to special reply port and make sure that
3598 * dest port has a send turnstile, else allocate one.
3599 */
3600 ipc_port_link_special_reply_port(special_reply_port, dest_port, sync_bootstrap_checkin);
3601 }
3602 return kr;
3603 }
3604
3605 static kern_return_t
ipc_kmsg_set_qos_kernel(ipc_kmsg_t kmsg)3606 ipc_kmsg_set_qos_kernel(
3607 ipc_kmsg_t kmsg)
3608 {
3609 ipc_port_t dest_port = ikm_header(kmsg)->msgh_remote_port;
3610 kmsg->ikm_qos_override = dest_port->ip_kernel_qos_override;
3611 kmsg->ikm_ppriority = _pthread_priority_make_from_thread_qos(kmsg->ikm_qos_override, 0, 0);
3612 return KERN_SUCCESS;
3613 }
3614
3615 /*
3616 * Routine: ipc_kmsg_link_reply_context_locked
3617 * Purpose:
3618 * Link any required context from the sending voucher
3619 * to the reply port. The ipc_kmsg_copyin_from_user function will
3620 * enforce that the sender calls mach_msg in this context.
3621 * Conditions:
3622 * reply port is locked
3623 */
3624 static void
ipc_kmsg_link_reply_context_locked(ipc_port_t reply_port,ipc_port_t voucher_port)3625 ipc_kmsg_link_reply_context_locked(
3626 ipc_port_t reply_port,
3627 ipc_port_t voucher_port)
3628 {
3629 kern_return_t __assert_only kr;
3630 uint32_t persona_id = 0;
3631 ipc_voucher_t voucher;
3632
3633 ip_mq_lock_held(reply_port);
3634
3635 if (!ip_active(reply_port)) {
3636 return;
3637 }
3638
3639 voucher = convert_port_to_voucher(voucher_port);
3640
3641 kr = bank_get_bank_ledger_thread_group_and_persona(voucher, NULL, NULL, &persona_id);
3642 assert(kr == KERN_SUCCESS);
3643 ipc_voucher_release(voucher);
3644
3645 if (persona_id == 0 || persona_id == PERSONA_ID_NONE) {
3646 /* there was no persona context to record */
3647 return;
3648 }
3649
3650 /*
3651 * Set the persona_id as the context on the reply port.
3652 * This will force the thread that replies to have adopted a voucher
3653 * with a matching persona.
3654 */
3655 reply_port->ip_reply_context = persona_id;
3656
3657 return;
3658 }
3659
3660 static kern_return_t
ipc_kmsg_validate_reply_port_locked(ipc_port_t reply_port,mach_msg_option_t options)3661 ipc_kmsg_validate_reply_port_locked(ipc_port_t reply_port, mach_msg_option_t options)
3662 {
3663 ip_mq_lock_held(reply_port);
3664
3665 if (!ip_active(reply_port)) {
3666 /*
3667 * Ideally, we would enforce that the reply receive right is
3668 * active, but asynchronous XPC cancellation destroys the
3669 * receive right, so we just have to return success here.
3670 */
3671 return KERN_SUCCESS;
3672 }
3673
3674 if (options & MACH_SEND_MSG) {
3675 /*
3676 * If the rely port is active, then it should not be
3677 * in-transit, and the receive right should be in the caller's
3678 * IPC space.
3679 */
3680 if (!ip_in_space(reply_port, current_task()->itk_space)) {
3681 return KERN_INVALID_CAPABILITY;
3682 }
3683
3684 /*
3685 * A port used as a reply port in an RPC should have exactly 1
3686 * extant send-once right which we either just made or are
3687 * moving as part of the IPC.
3688 */
3689 if (reply_port->ip_sorights != 1) {
3690 return KERN_INVALID_CAPABILITY;
3691 }
3692 /*
3693 * XPC uses an extra send-right to keep the name of the reply
3694 * right around through cancellation. That makes it harder to
3695 * enforce a particular semantic kere, so for now, we say that
3696 * you can have a maximum of 1 send right (in addition to your
3697 * send once right). In the future, it would be great to lock
3698 * this down even further.
3699 */
3700 if (reply_port->ip_srights > 1) {
3701 return KERN_INVALID_CAPABILITY;
3702 }
3703
3704 /*
3705 * The sender can also specify that the receive right should
3706 * be immovable. Note that this check only applies to
3707 * send-only operations. Combined send/receive or rcv-only
3708 * operations can specify an immovable receive right by
3709 * opt-ing into guarded descriptors (MACH_RCV_GUARDED_DESC)
3710 * and using the MACH_MSG_STRICT_REPLY options flag.
3711 */
3712 if (MACH_SEND_REPLY_IS_IMMOVABLE(options)) {
3713 if (!reply_port->ip_immovable_receive) {
3714 return KERN_INVALID_CAPABILITY;
3715 }
3716 }
3717 }
3718
3719 /*
3720 * don't enforce this yet: need a better way of indicating the
3721 * receiver wants this...
3722 */
3723 #if 0
3724 if (MACH_RCV_WITH_IMMOVABLE_REPLY(options)) {
3725 if (!reply_port->ip_immovable_receive) {
3726 return KERN_INVALID_CAPABILITY;
3727 }
3728 }
3729 #endif /* 0 */
3730
3731 return KERN_SUCCESS;
3732 }
3733
3734 /*
3735 * Routine: ipc_kmsg_validate_reply_context_locked
3736 * Purpose:
3737 * Validate that the current thread is running in the context
3738 * required by the destination port.
3739 * Conditions:
3740 * dest_port is locked
3741 * Returns:
3742 * MACH_MSG_SUCCESS on success.
3743 * On error, an EXC_GUARD exception is also raised.
3744 * This function *always* resets the port reply context.
3745 */
3746 static mach_msg_return_t
ipc_kmsg_validate_reply_context_locked(mach_msg_option_t option,ipc_port_t dest_port,ipc_voucher_t voucher,mach_port_name_t voucher_name)3747 ipc_kmsg_validate_reply_context_locked(
3748 mach_msg_option_t option,
3749 ipc_port_t dest_port,
3750 ipc_voucher_t voucher,
3751 mach_port_name_t voucher_name)
3752 {
3753 uint32_t dest_ctx = dest_port->ip_reply_context;
3754 dest_port->ip_reply_context = 0;
3755
3756 if (!ip_active(dest_port)) {
3757 return MACH_MSG_SUCCESS;
3758 }
3759
3760 if (voucher == IPC_VOUCHER_NULL || !MACH_PORT_VALID(voucher_name)) {
3761 if ((option & MACH_SEND_KERNEL) == 0) {
3762 mach_port_guard_exception(voucher_name, 0,
3763 (MPG_FLAGS_STRICT_REPLY_INVALID_VOUCHER | dest_ctx),
3764 kGUARD_EXC_STRICT_REPLY);
3765 }
3766 return MACH_SEND_INVALID_CONTEXT;
3767 }
3768
3769 kern_return_t __assert_only kr;
3770 uint32_t persona_id = 0;
3771 kr = bank_get_bank_ledger_thread_group_and_persona(voucher, NULL, NULL, &persona_id);
3772 assert(kr == KERN_SUCCESS);
3773
3774 if (dest_ctx != persona_id) {
3775 if ((option & MACH_SEND_KERNEL) == 0) {
3776 mach_port_guard_exception(voucher_name, 0,
3777 (MPG_FLAGS_STRICT_REPLY_MISMATCHED_PERSONA | ((((uint64_t)persona_id << 32) & MPG_FLAGS_STRICT_REPLY_MASK) | dest_ctx)),
3778 kGUARD_EXC_STRICT_REPLY);
3779 }
3780 return MACH_SEND_INVALID_CONTEXT;
3781 }
3782
3783 return MACH_MSG_SUCCESS;
3784 }
3785
3786 /*
3787 * Routine: ipc_kmsg_copyin_header
3788 * Purpose:
3789 * "Copy-in" port rights in the header of a message.
3790 * Operates atomically; if it doesn't succeed the
3791 * message header and the space are left untouched.
3792 * If it does succeed the remote/local port fields
3793 * contain object pointers instead of port names,
3794 * and the bits field is updated. The destination port
3795 * will be a valid port pointer.
3796 *
3797 * Conditions:
3798 * Nothing locked. May add MACH64_SEND_ALWAYS option.
3799 * Returns:
3800 * MACH_MSG_SUCCESS Successful copyin.
3801 * MACH_SEND_INVALID_HEADER
3802 * Illegal value in the message header bits.
3803 * MACH_SEND_INVALID_DEST The space is dead.
3804 * MACH_SEND_INVALID_DEST Can't copyin destination port.
3805 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
3806 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
3807 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
3808 */
3809
3810 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)3811 ipc_kmsg_copyin_header(
3812 ipc_kmsg_t kmsg,
3813 ipc_space_t space,
3814 mach_msg_priority_t priority,
3815 mach_msg_option64_t *option64p)
3816 {
3817 mach_msg_header_t *msg = ikm_header(kmsg);
3818 mach_msg_bits_t mbits = msg->msgh_bits & MACH_MSGH_BITS_USER;
3819 mach_port_name_t dest_name = CAST_MACH_PORT_TO_NAME(msg->msgh_remote_port);
3820 mach_port_name_t reply_name = CAST_MACH_PORT_TO_NAME(msg->msgh_local_port);
3821 mach_port_name_t voucher_name = MACH_PORT_NULL;
3822 kern_return_t kr;
3823
3824 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3825 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3826 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3827 ipc_object_t dest_port = IO_NULL;
3828 ipc_object_t reply_port = IO_NULL;
3829 ipc_port_t dest_soright = IP_NULL;
3830 ipc_port_t dport = IP_NULL;
3831 ipc_port_t reply_soright = IP_NULL;
3832 ipc_port_t voucher_soright = IP_NULL;
3833 ipc_port_t release_port = IP_NULL;
3834 ipc_port_t voucher_port = IP_NULL;
3835 ipc_port_t voucher_release_port = IP_NULL;
3836 ipc_entry_t dest_entry = IE_NULL;
3837 ipc_entry_t reply_entry = IE_NULL;
3838 ipc_entry_t voucher_entry = IE_NULL;
3839 ipc_object_copyin_flags_t dest_flags = IPC_OBJECT_COPYIN_FLAGS_ALLOW_REPLY_MAKE_SEND_ONCE | IPC_OBJECT_COPYIN_FLAGS_ALLOW_REPLY_MOVE_SEND_ONCE;
3840 ipc_object_copyin_flags_t reply_flags = IPC_OBJECT_COPYIN_FLAGS_ALLOW_REPLY_MAKE_SEND_ONCE;
3841 boolean_t reply_port_semantics_violation = FALSE;
3842
3843 int assertcnt = 0;
3844 mach_msg_option_t option32 = (mach_msg_option_t)*option64p;
3845 #if IMPORTANCE_INHERITANCE
3846 boolean_t needboost = FALSE;
3847 #endif /* IMPORTANCE_INHERITANCE */
3848
3849 if ((mbits != msg->msgh_bits) ||
3850 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type)) ||
3851 ((reply_type == 0) ?
3852 (reply_name != MACH_PORT_NULL) :
3853 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type))) {
3854 return MACH_SEND_INVALID_HEADER;
3855 }
3856
3857 if (!MACH_PORT_VALID(dest_name)) {
3858 return MACH_SEND_INVALID_DEST;
3859 }
3860
3861 is_write_lock(space);
3862 if (!is_active(space)) {
3863 is_write_unlock(space);
3864 return MACH_SEND_INVALID_DEST;
3865 }
3866 /* space locked and active */
3867
3868 /*
3869 * If there is a voucher specified, make sure the disposition is
3870 * valid and the entry actually refers to a voucher port. Don't
3871 * actually copy in until we validate destination and reply.
3872 */
3873 if (voucher_type != MACH_MSGH_BITS_ZERO) {
3874 voucher_name = msg->msgh_voucher_port;
3875
3876 if (voucher_name == MACH_PORT_DEAD ||
3877 (voucher_type != MACH_MSG_TYPE_MOVE_SEND &&
3878 voucher_type != MACH_MSG_TYPE_COPY_SEND)) {
3879 is_write_unlock(space);
3880 if ((option32 & MACH_SEND_KERNEL) == 0) {
3881 mach_port_guard_exception(voucher_name, 0, 0, kGUARD_EXC_SEND_INVALID_VOUCHER);
3882 }
3883 return MACH_SEND_INVALID_VOUCHER;
3884 }
3885
3886 if (voucher_name != MACH_PORT_NULL) {
3887 voucher_entry = ipc_entry_lookup(space, voucher_name);
3888 if (voucher_entry == IE_NULL ||
3889 (voucher_entry->ie_bits & MACH_PORT_TYPE_SEND) == 0 ||
3890 io_kotype(voucher_entry->ie_object) != IKOT_VOUCHER) {
3891 is_write_unlock(space);
3892 if ((option32 & MACH_SEND_KERNEL) == 0) {
3893 mach_port_guard_exception(voucher_name, 0, 0, kGUARD_EXC_SEND_INVALID_VOUCHER);
3894 }
3895 return MACH_SEND_INVALID_VOUCHER;
3896 }
3897 } else {
3898 voucher_type = MACH_MSG_TYPE_MOVE_SEND;
3899 }
3900 }
3901
3902 if (enforce_strict_reply && MACH_SEND_WITH_STRICT_REPLY(option32) &&
3903 (!MACH_PORT_VALID(reply_name) ||
3904 ((reply_type != MACH_MSG_TYPE_MAKE_SEND_ONCE) && (reply_type != MACH_MSG_TYPE_MOVE_SEND_ONCE))
3905 )) {
3906 /*
3907 * The caller cannot enforce a reply context with an invalid
3908 * reply port name, or a non-send_once reply disposition.
3909 */
3910 is_write_unlock(space);
3911 if ((option32 & MACH_SEND_KERNEL) == 0) {
3912 mach_port_guard_exception(reply_name, 0,
3913 (MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_DISP | reply_type),
3914 kGUARD_EXC_STRICT_REPLY);
3915 }
3916 return MACH_SEND_INVALID_REPLY;
3917 }
3918
3919 /*
3920 * Handle combinations of validating destination and reply; along
3921 * with copying in destination, reply, and voucher in an atomic way.
3922 */
3923
3924 if (dest_name == voucher_name) {
3925 /*
3926 * If the destination name is the same as the voucher name,
3927 * the voucher_entry must already be known. Either that or
3928 * the destination name is MACH_PORT_NULL (i.e. invalid).
3929 */
3930 dest_entry = voucher_entry;
3931 if (dest_entry == IE_NULL) {
3932 goto invalid_dest;
3933 }
3934
3935 /*
3936 * Make sure a future copyin of the reply port will succeed.
3937 * Once we start copying in the dest/voucher pair, we can't
3938 * back out.
3939 */
3940 if (MACH_PORT_VALID(reply_name)) {
3941 assert(reply_type != 0); /* because reply_name not null */
3942
3943 /* It is just WRONG if dest, voucher, and reply are all the same. */
3944 if (voucher_name == reply_name) {
3945 goto invalid_reply;
3946 }
3947 reply_entry = ipc_entry_lookup(space, reply_name);
3948 if (reply_entry == IE_NULL) {
3949 goto invalid_reply;
3950 }
3951 assert(dest_entry != reply_entry); /* names are not equal */
3952 if (!ipc_right_copyin_check_reply(space, reply_name, reply_entry, reply_type, dest_entry, &reply_port_semantics_violation)) {
3953 goto invalid_reply;
3954 }
3955 }
3956
3957 /*
3958 * Do the joint copyin of the dest disposition and
3959 * voucher disposition from the one entry/port. We
3960 * already validated that the voucher copyin would
3961 * succeed (above). So, any failure in combining
3962 * the copyins can be blamed on the destination.
3963 */
3964 kr = ipc_right_copyin_two(space, dest_name, dest_entry,
3965 dest_type, voucher_type, IPC_OBJECT_COPYIN_FLAGS_NONE, IPC_OBJECT_COPYIN_FLAGS_NONE,
3966 &dest_port, &dest_soright, &release_port);
3967 if (kr != KERN_SUCCESS) {
3968 assert(kr != KERN_INVALID_CAPABILITY);
3969 goto invalid_dest;
3970 }
3971 voucher_port = ip_object_to_port(dest_port);
3972
3973 /*
3974 * could not have been one of these dispositions,
3975 * validated the port was a true kernel voucher port above,
3976 * AND was successfully able to copyin both dest and voucher.
3977 */
3978 assert(dest_type != MACH_MSG_TYPE_MAKE_SEND);
3979 assert(dest_type != MACH_MSG_TYPE_MAKE_SEND_ONCE);
3980 assert(dest_type != MACH_MSG_TYPE_MOVE_SEND_ONCE);
3981
3982 /*
3983 * Perform the delayed reply right copyin (guaranteed success).
3984 */
3985 if (reply_entry != IE_NULL) {
3986 kr = ipc_right_copyin(space, reply_name, reply_entry,
3987 reply_type, IPC_OBJECT_COPYIN_FLAGS_DEADOK | reply_flags,
3988 &reply_port, &reply_soright,
3989 &release_port, &assertcnt, 0, NULL);
3990 assert(assertcnt == 0);
3991 assert(kr == KERN_SUCCESS);
3992 }
3993 } else {
3994 if (dest_name == reply_name) {
3995 /*
3996 * Destination and reply ports are the same!
3997 * This is very similar to the case where the
3998 * destination and voucher ports were the same
3999 * (except the reply port disposition is not
4000 * previously validated).
4001 */
4002 dest_entry = ipc_entry_lookup(space, dest_name);
4003 if (dest_entry == IE_NULL) {
4004 goto invalid_dest;
4005 }
4006
4007 reply_entry = dest_entry;
4008 assert(reply_type != 0); /* because name not null */
4009
4010 /*
4011 * Pre-validate that the reply right can be copied in by itself.
4012 * Fail if reply port is marked as immovable send.
4013 */
4014 if (!ipc_right_copyin_check_reply(space, reply_name, reply_entry, reply_type, dest_entry, &reply_port_semantics_violation)) {
4015 goto invalid_reply;
4016 }
4017
4018 /*
4019 * Do the joint copyin of the dest disposition and
4020 * reply disposition from the one entry/port.
4021 */
4022 kr = ipc_right_copyin_two(space, dest_name, dest_entry, dest_type, reply_type,
4023 dest_flags, reply_flags, &dest_port, &dest_soright, &release_port);
4024 if (kr == KERN_INVALID_CAPABILITY) {
4025 goto invalid_reply;
4026 } else if (kr != KERN_SUCCESS) {
4027 goto invalid_dest;
4028 }
4029 reply_port = dest_port;
4030 } else {
4031 /*
4032 * Handle destination and reply independently, as
4033 * they are independent entries (even if the entries
4034 * refer to the same port).
4035 *
4036 * This can be the tough case to make atomic.
4037 *
4038 * The difficult problem is serializing with port death.
4039 * The bad case is when dest_port dies after its copyin,
4040 * reply_port dies before its copyin, and dest_port dies before
4041 * reply_port. Then the copyins operated as if dest_port was
4042 * alive and reply_port was dead, which shouldn't have happened
4043 * because they died in the other order.
4044 *
4045 * Note that it is easy for a user task to tell if
4046 * a copyin happened before or after a port died.
4047 * If a port dies before copyin, a dead-name notification
4048 * is generated and the dead name's urefs are incremented,
4049 * and if the copyin happens first, a port-deleted
4050 * notification is generated.
4051 *
4052 * Even so, avoiding that potentially detectable race is too
4053 * expensive - and no known code cares about it. So, we just
4054 * do the expedient thing and copy them in one after the other.
4055 */
4056
4057 dest_entry = ipc_entry_lookup(space, dest_name);
4058 if (dest_entry == IE_NULL) {
4059 goto invalid_dest;
4060 }
4061 assert(dest_entry != voucher_entry);
4062
4063 /*
4064 * Make sure reply port entry is valid before dest copyin.
4065 */
4066 if (MACH_PORT_VALID(reply_name)) {
4067 if (reply_name == voucher_name) {
4068 goto invalid_reply;
4069 }
4070 reply_entry = ipc_entry_lookup(space, reply_name);
4071 if (reply_entry == IE_NULL) {
4072 goto invalid_reply;
4073 }
4074 assert(dest_entry != reply_entry); /* names are not equal */
4075 assert(reply_type != 0); /* because reply_name not null */
4076
4077 if (!ipc_right_copyin_check_reply(space, reply_name, reply_entry, reply_type, dest_entry, &reply_port_semantics_violation)) {
4078 goto invalid_reply;
4079 }
4080 }
4081
4082 /*
4083 * copyin the destination.
4084 */
4085 kr = ipc_right_copyin(space, dest_name, dest_entry, dest_type,
4086 (IPC_OBJECT_COPYIN_FLAGS_ALLOW_IMMOVABLE_SEND | IPC_OBJECT_COPYIN_FLAGS_ALLOW_DEAD_SEND_ONCE | dest_flags),
4087 &dest_port, &dest_soright,
4088 &release_port, &assertcnt, 0, NULL);
4089 assert(assertcnt == 0);
4090 if (kr != KERN_SUCCESS) {
4091 goto invalid_dest;
4092 }
4093 assert(IO_VALID(dest_port));
4094 assert(!IP_VALID(release_port));
4095
4096 /*
4097 * Copyin the pre-validated reply right.
4098 * It's OK if the reply right has gone dead in the meantime.
4099 */
4100 if (MACH_PORT_VALID(reply_name)) {
4101 kr = ipc_right_copyin(space, reply_name, reply_entry,
4102 reply_type, IPC_OBJECT_COPYIN_FLAGS_DEADOK | reply_flags,
4103 &reply_port, &reply_soright,
4104 &release_port, &assertcnt, 0, NULL);
4105 assert(assertcnt == 0);
4106 assert(kr == KERN_SUCCESS);
4107 } else {
4108 /* convert invalid name to equivalent ipc_object type */
4109 reply_port = ip_to_object(CAST_MACH_NAME_TO_PORT(reply_name));
4110 }
4111 }
4112
4113 /*
4114 * Finally can copyin the voucher right now that dest and reply
4115 * are fully copied in (guaranteed success).
4116 */
4117 if (IE_NULL != voucher_entry) {
4118 kr = ipc_right_copyin(space, voucher_name, voucher_entry,
4119 voucher_type, IPC_OBJECT_COPYIN_FLAGS_NONE,
4120 (ipc_object_t *)&voucher_port,
4121 &voucher_soright,
4122 &voucher_release_port,
4123 &assertcnt, 0, NULL);
4124 assert(assertcnt == 0);
4125 assert(KERN_SUCCESS == kr);
4126 assert(IP_VALID(voucher_port));
4127 require_ip_active(voucher_port);
4128 }
4129 }
4130
4131 dest_type = ipc_object_copyin_type(dest_type);
4132 reply_type = ipc_object_copyin_type(reply_type);
4133
4134 dport = ip_object_to_port(dest_port);
4135 /*
4136 * If the dest port died, or is a kobject AND its receive right belongs to kernel,
4137 * allow copyin of immovable send rights in the message body (port descriptor) to
4138 * succeed since those send rights are simply "moved" or "copied" into kernel.
4139 *
4140 * See: ipc_object_copyin().
4141 */
4142
4143 ip_mq_lock(dport);
4144
4145 #if CONFIG_SERVICE_PORT_INFO
4146 /*
4147 * Service name is later used in CA telemetry in case of reply port security semantics violations.
4148 */
4149 mach_service_port_info_t sp_info = NULL;
4150 struct mach_service_port_info sp_info_filled = {};
4151 if (ip_active(dport) && (dport->ip_service_port) && (dport->ip_splabel)) {
4152 ipc_service_port_label_get_info((ipc_service_port_label_t)dport->ip_splabel, &sp_info_filled);
4153 sp_info = &sp_info_filled;
4154 }
4155 #endif /* CONFIG_SERVICE_PORT_INFO */
4156
4157 if (!ip_active(dport) || (ip_is_kobject(dport) &&
4158 ip_in_space(dport, ipc_space_kernel))) {
4159 assert(ip_kotype(dport) != IKOT_TIMER);
4160 kmsg->ikm_flags |= IPC_OBJECT_COPYIN_FLAGS_ALLOW_IMMOVABLE_SEND;
4161 }
4162
4163 /*
4164 * JMM - Without rdar://problem/6275821, this is the last place we can
4165 * re-arm the send-possible notifications. It may trigger unexpectedly
4166 * early (send may NOT have failed), but better than missing. We assure
4167 * we won't miss by forcing MACH_SEND_ALWAYS if we got past arming.
4168 */
4169 if (((option32 & MACH_SEND_NOTIFY) != 0) &&
4170 dest_type != MACH_MSG_TYPE_PORT_SEND_ONCE &&
4171 dest_entry != IE_NULL && dest_entry->ie_request != IE_REQ_NONE) {
4172 /* dport still locked from above */
4173 if (ip_active(dport) && !ip_in_space(dport, ipc_space_kernel)) {
4174 /* dport could be in-transit, or in an ipc space */
4175 if (ip_full(dport)) {
4176 #if IMPORTANCE_INHERITANCE
4177 needboost = ipc_port_request_sparm(dport, dest_name,
4178 dest_entry->ie_request,
4179 option32,
4180 priority);
4181 if (needboost == FALSE) {
4182 ip_mq_unlock(dport);
4183 }
4184 #else
4185 ipc_port_request_sparm(dport, dest_name,
4186 dest_entry->ie_request,
4187 option32,
4188 priority);
4189 ip_mq_unlock(dport);
4190 #endif /* IMPORTANCE_INHERITANCE */
4191 } else {
4192 *option64p |= MACH64_SEND_ALWAYS;
4193 ip_mq_unlock(dport);
4194 }
4195 } else {
4196 ip_mq_unlock(dport);
4197 }
4198 } else {
4199 ip_mq_unlock(dport);
4200 }
4201 /* dport is unlocked, unless needboost == TRUE */
4202
4203 is_write_unlock(space);
4204
4205 #if IMPORTANCE_INHERITANCE
4206 /*
4207 * If our request is the first boosting send-possible
4208 * notification this cycle, push the boost down the
4209 * destination port.
4210 */
4211 if (needboost == TRUE) {
4212 /* dport still locked from above */
4213 if (ipc_port_importance_delta(dport, IPID_OPTION_SENDPOSSIBLE, 1) == FALSE) {
4214 ip_mq_unlock(dport);
4215 }
4216 }
4217 #endif /* IMPORTANCE_INHERITANCE */
4218
4219 /* dport is unlocked */
4220
4221 if (dest_soright != IP_NULL) {
4222 ipc_notify_port_deleted(dest_soright, dest_name);
4223 }
4224 if (reply_soright != IP_NULL) {
4225 ipc_notify_port_deleted(reply_soright, reply_name);
4226 }
4227 if (voucher_soright != IP_NULL) {
4228 ipc_notify_port_deleted(voucher_soright, voucher_name);
4229 }
4230
4231 /*
4232 * No room to store voucher port in in-kernel msg header,
4233 * so we store it back in the kmsg itself. Store original voucher
4234 * type there as well, but set the bits to the post-copyin type.
4235 */
4236 if (IP_VALID(voucher_port)) {
4237 ipc_kmsg_set_voucher_port(kmsg, voucher_port, voucher_type);
4238 voucher_type = MACH_MSG_TYPE_MOVE_SEND;
4239 }
4240
4241 msg->msgh_bits = MACH_MSGH_BITS_SET(dest_type, reply_type, voucher_type, mbits);
4242 msg->msgh_remote_port = ip_object_to_port(dest_port);
4243 msg->msgh_local_port = ip_object_to_port(reply_port);
4244
4245 /*
4246 * capture the qos value(s) for the kmsg qos,
4247 * and apply any override before we enqueue the kmsg.
4248 */
4249 ipc_kmsg_set_qos(kmsg, option32, priority);
4250
4251 if (release_port != IP_NULL) {
4252 ip_release(release_port);
4253 }
4254
4255 if (voucher_release_port != IP_NULL) {
4256 ip_release(voucher_release_port);
4257 }
4258
4259 if (ipc_kmsg_option_check(ip_object_to_port(dest_port), *option64p) !=
4260 MACH_MSG_SUCCESS) {
4261 /*
4262 * no descriptors have been copied in yet, but the
4263 * full header has been copied in: clean it up
4264 */
4265 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
4266 mach_port_guard_exception(0, 0, 0, kGUARD_EXC_INVALID_OPTIONS);
4267 return MACH_SEND_INVALID_OPTIONS;
4268 }
4269
4270 if (enforce_strict_reply && MACH_SEND_WITH_STRICT_REPLY(option32) &&
4271 IP_VALID(msg->msgh_local_port)) {
4272 /*
4273 * We've already validated that the reply disposition is a
4274 * [make/move] send-once. Ideally, we should enforce that the
4275 * reply port is also not dead, but XPC asynchronous
4276 * cancellation can make the reply port dead before we
4277 * actually make it to the mach_msg send.
4278 *
4279 * Here, we ensure that if we have a non-dead reply port, then
4280 * the reply port's receive right should not be in-transit,
4281 * and should live in the caller's IPC space.
4282 */
4283 ipc_port_t rport = msg->msgh_local_port;
4284 ip_mq_lock(rport);
4285 kr = ipc_kmsg_validate_reply_port_locked(rport, option32);
4286 ip_mq_unlock(rport);
4287 if (kr != KERN_SUCCESS) {
4288 /*
4289 * no descriptors have been copied in yet, but the
4290 * full header has been copied in: clean it up
4291 */
4292 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
4293 if ((option32 & MACH_SEND_KERNEL) == 0) {
4294 mach_port_guard_exception(reply_name, 0,
4295 (MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_PORT | kr),
4296 kGUARD_EXC_STRICT_REPLY);
4297 }
4298 return MACH_SEND_INVALID_REPLY;
4299 }
4300 }
4301
4302 if (reply_port_semantics_violation) {
4303 /* Currently rate limiting it to sucess paths only. */
4304 task_t task = current_task_early();
4305 if (task) {
4306 task_lock(task);
4307 if (!task_has_reply_port_telemetry(task)) {
4308 /* Crash report rate limited to once per task per host. */
4309 mach_port_guard_exception(reply_name, 0, 0, kGUARD_EXC_REQUIRE_REPLY_PORT_SEMANTICS);
4310 task_set_reply_port_telemetry(task);
4311 }
4312 task_unlock(task);
4313 }
4314 #if CONFIG_SERVICE_PORT_INFO
4315 stash_reply_port_semantics_violations_telemetry(sp_info);
4316 #else
4317 stash_reply_port_semantics_violations_telemetry(NULL);
4318 #endif
4319 }
4320 return MACH_MSG_SUCCESS;
4321
4322 invalid_reply:
4323 is_write_unlock(space);
4324
4325 if (release_port != IP_NULL) {
4326 ip_release(release_port);
4327 }
4328
4329 assert(voucher_port == IP_NULL);
4330 assert(voucher_soright == IP_NULL);
4331
4332 if ((option32 & MACH_SEND_KERNEL) == 0) {
4333 mach_port_guard_exception(reply_name, 0, 0, kGUARD_EXC_SEND_INVALID_REPLY);
4334 }
4335 return MACH_SEND_INVALID_REPLY;
4336
4337 invalid_dest:
4338 is_write_unlock(space);
4339
4340 if (release_port != IP_NULL) {
4341 ip_release(release_port);
4342 }
4343
4344 if (reply_soright != IP_NULL) {
4345 ipc_notify_port_deleted(reply_soright, reply_name);
4346 }
4347
4348 assert(voucher_port == IP_NULL);
4349 assert(voucher_soright == IP_NULL);
4350
4351 return MACH_SEND_INVALID_DEST;
4352 }
4353
4354 static mach_msg_descriptor_t *
ipc_kmsg_copyin_port_descriptor(mach_msg_port_descriptor_t * dsc,mach_msg_user_port_descriptor_t * user_dsc_in,ipc_space_t space,ipc_object_t dest,ipc_kmsg_t kmsg,mach_msg_option_t options,mach_msg_return_t * mr)4355 ipc_kmsg_copyin_port_descriptor(
4356 mach_msg_port_descriptor_t *dsc,
4357 mach_msg_user_port_descriptor_t *user_dsc_in,
4358 ipc_space_t space,
4359 ipc_object_t dest,
4360 ipc_kmsg_t kmsg,
4361 mach_msg_option_t options,
4362 mach_msg_return_t *mr)
4363 {
4364 mach_msg_user_port_descriptor_t user_dsc = *user_dsc_in;
4365 mach_msg_type_name_t user_disp;
4366 mach_msg_type_name_t result_disp;
4367 mach_port_name_t name;
4368 ipc_object_t object;
4369
4370 user_disp = user_dsc.disposition;
4371 result_disp = ipc_object_copyin_type(user_disp);
4372
4373 name = (mach_port_name_t)user_dsc.name;
4374 if (MACH_PORT_VALID(name)) {
4375 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object, 0, NULL, kmsg->ikm_flags);
4376 if (kr != KERN_SUCCESS) {
4377 if (((options & MACH_SEND_KERNEL) == 0) && (kr == KERN_INVALID_RIGHT)) {
4378 mach_port_guard_exception(name, 0, 0, kGUARD_EXC_SEND_INVALID_RIGHT);
4379 }
4380 *mr = MACH_SEND_INVALID_RIGHT;
4381 return NULL;
4382 }
4383
4384 if ((result_disp == MACH_MSG_TYPE_PORT_RECEIVE) &&
4385 ipc_port_check_circularity(ip_object_to_port(object),
4386 ip_object_to_port(dest))) {
4387 ikm_header(kmsg)->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
4388 }
4389 dsc->name = ip_object_to_port(object);
4390 } else {
4391 dsc->name = CAST_MACH_NAME_TO_PORT(name);
4392 }
4393 dsc->disposition = result_disp;
4394 dsc->type = MACH_MSG_PORT_DESCRIPTOR;
4395
4396 dsc->pad_end = 0; // debug, unnecessary
4397
4398 return (mach_msg_descriptor_t *)(user_dsc_in + 1);
4399 }
4400
4401 static mach_msg_descriptor_t *
ipc_kmsg_copyin_ool_descriptor(mach_msg_ool_descriptor_t * dsc,mach_msg_descriptor_t * user_dsc,int is_64bit,mach_vm_address_t * paddr,vm_map_copy_t * copy,vm_size_t * space_needed,vm_map_t map,mach_msg_return_t * mr)4402 ipc_kmsg_copyin_ool_descriptor(
4403 mach_msg_ool_descriptor_t *dsc,
4404 mach_msg_descriptor_t *user_dsc,
4405 int is_64bit,
4406 mach_vm_address_t *paddr,
4407 vm_map_copy_t *copy,
4408 vm_size_t *space_needed,
4409 vm_map_t map,
4410 mach_msg_return_t *mr)
4411 {
4412 vm_size_t length;
4413 boolean_t dealloc;
4414 mach_msg_copy_options_t copy_options;
4415 mach_vm_offset_t addr;
4416 mach_msg_descriptor_type_t dsc_type;
4417
4418 if (is_64bit) {
4419 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
4420
4421 addr = (mach_vm_offset_t) user_ool_dsc->address;
4422 length = user_ool_dsc->size;
4423 dealloc = user_ool_dsc->deallocate;
4424 copy_options = user_ool_dsc->copy;
4425 dsc_type = user_ool_dsc->type;
4426
4427 user_dsc = (typeof(user_dsc))(user_ool_dsc + 1);
4428 } else {
4429 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
4430
4431 addr = CAST_USER_ADDR_T(user_ool_dsc->address);
4432 dealloc = user_ool_dsc->deallocate;
4433 copy_options = user_ool_dsc->copy;
4434 dsc_type = user_ool_dsc->type;
4435 length = user_ool_dsc->size;
4436
4437 user_dsc = (typeof(user_dsc))(user_ool_dsc + 1);
4438 }
4439
4440 dsc->size = (mach_msg_size_t)length;
4441 dsc->deallocate = dealloc;
4442 dsc->copy = copy_options;
4443 dsc->type = dsc_type;
4444
4445 if (length == 0) {
4446 dsc->address = NULL;
4447 } else if (length > MSG_OOL_SIZE_SMALL &&
4448 (copy_options == MACH_MSG_PHYSICAL_COPY) && !dealloc) {
4449 /*
4450 * If the request is a physical copy and the source
4451 * is not being deallocated, then allocate space
4452 * in the kernel's pageable ipc copy map and copy
4453 * the data in. The semantics guarantee that the
4454 * data will have been physically copied before
4455 * the send operation terminates. Thus if the data
4456 * is not being deallocated, we must be prepared
4457 * to page if the region is sufficiently large.
4458 */
4459 if (copyin(addr, (char *)*paddr, length)) {
4460 *mr = MACH_SEND_INVALID_MEMORY;
4461 return NULL;
4462 }
4463
4464 /*
4465 * The kernel ipc copy map is marked no_zero_fill.
4466 * If the transfer is not a page multiple, we need
4467 * to zero fill the balance.
4468 */
4469 if (!page_aligned(length)) {
4470 (void) memset((void *) (*paddr + length), 0,
4471 round_page(length) - length);
4472 }
4473 if (vm_map_copyin(ipc_kernel_copy_map, (vm_map_address_t)*paddr,
4474 (vm_map_size_t)length, TRUE, copy) != KERN_SUCCESS) {
4475 *mr = MACH_MSG_VM_KERNEL;
4476 return NULL;
4477 }
4478 dsc->address = (void *)*copy;
4479 *paddr += round_page(length);
4480 *space_needed -= round_page(length);
4481 } else {
4482 /*
4483 * Make a vm_map_copy_t of the of the data. If the
4484 * data is small, this will do an optimized physical
4485 * copy. Otherwise, it will do a virtual copy.
4486 *
4487 * NOTE: A virtual copy is OK if the original is being
4488 * deallocted, even if a physical copy was requested.
4489 */
4490 kern_return_t kr = vm_map_copyin(map, addr,
4491 (vm_map_size_t)length, dealloc, copy);
4492 if (kr != KERN_SUCCESS) {
4493 *mr = (kr == KERN_RESOURCE_SHORTAGE) ?
4494 MACH_MSG_VM_KERNEL :
4495 MACH_SEND_INVALID_MEMORY;
4496 return NULL;
4497 }
4498 dsc->address = (void *)*copy;
4499 }
4500
4501 return user_dsc;
4502 }
4503
4504 static mach_msg_descriptor_t *
ipc_kmsg_copyin_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t * dsc,mach_msg_descriptor_t * user_dsc,int is_64bit,vm_map_t map,ipc_space_t space,ipc_object_t dest,ipc_kmsg_t kmsg,mach_msg_option_t options,mach_msg_return_t * mr)4505 ipc_kmsg_copyin_ool_ports_descriptor(
4506 mach_msg_ool_ports_descriptor_t *dsc,
4507 mach_msg_descriptor_t *user_dsc,
4508 int is_64bit,
4509 vm_map_t map,
4510 ipc_space_t space,
4511 ipc_object_t dest,
4512 ipc_kmsg_t kmsg,
4513 mach_msg_option_t options,
4514 mach_msg_return_t *mr)
4515 {
4516 void *data;
4517 ipc_object_t *objects;
4518 unsigned int i;
4519 mach_vm_offset_t addr;
4520 mach_msg_type_name_t user_disp;
4521 mach_msg_type_name_t result_disp;
4522 mach_msg_type_number_t count;
4523 mach_msg_copy_options_t copy_option;
4524 boolean_t deallocate;
4525 mach_msg_descriptor_type_t type;
4526 vm_size_t ports_length, names_length;
4527
4528 if (is_64bit) {
4529 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
4530
4531 addr = (mach_vm_offset_t)user_ool_dsc->address;
4532 count = user_ool_dsc->count;
4533 deallocate = user_ool_dsc->deallocate;
4534 copy_option = user_ool_dsc->copy;
4535 user_disp = user_ool_dsc->disposition;
4536 type = user_ool_dsc->type;
4537
4538 user_dsc = (typeof(user_dsc))(user_ool_dsc + 1);
4539 } else {
4540 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
4541
4542 addr = CAST_USER_ADDR_T(user_ool_dsc->address);
4543 count = user_ool_dsc->count;
4544 deallocate = user_ool_dsc->deallocate;
4545 copy_option = user_ool_dsc->copy;
4546 user_disp = user_ool_dsc->disposition;
4547 type = user_ool_dsc->type;
4548
4549 user_dsc = (typeof(user_dsc))(user_ool_dsc + 1);
4550 }
4551
4552 dsc->deallocate = deallocate;
4553 dsc->copy = copy_option;
4554 dsc->type = type;
4555 dsc->count = count;
4556 dsc->address = NULL; /* for now */
4557
4558 result_disp = ipc_object_copyin_type(user_disp);
4559 dsc->disposition = result_disp;
4560
4561 /* We always do a 'physical copy', but you have to specify something valid */
4562 if (copy_option != MACH_MSG_PHYSICAL_COPY &&
4563 copy_option != MACH_MSG_VIRTUAL_COPY) {
4564 *mr = MACH_SEND_INVALID_TYPE;
4565 return NULL;
4566 }
4567
4568 /* calculate length of data in bytes, rounding up */
4569
4570 if (os_mul_overflow(count, sizeof(mach_port_t), &ports_length)) {
4571 *mr = MACH_SEND_TOO_LARGE;
4572 return NULL;
4573 }
4574
4575 if (os_mul_overflow(count, sizeof(mach_port_name_t), &names_length)) {
4576 *mr = MACH_SEND_TOO_LARGE;
4577 return NULL;
4578 }
4579
4580 if (ports_length == 0) {
4581 return user_dsc;
4582 }
4583
4584 data = kalloc_type(mach_port_t, count, Z_WAITOK | Z_SPRAYQTN);
4585
4586 if (data == NULL) {
4587 *mr = MACH_SEND_NO_BUFFER;
4588 return NULL;
4589 }
4590
4591 #ifdef __LP64__
4592 mach_port_name_t *names = &((mach_port_name_t *)data)[count];
4593 #else
4594 mach_port_name_t *names = ((mach_port_name_t *)data);
4595 #endif
4596
4597 if (copyinmap(map, addr, names, names_length) != KERN_SUCCESS) {
4598 kfree_type(mach_port_t, count, data);
4599 *mr = MACH_SEND_INVALID_MEMORY;
4600 return NULL;
4601 }
4602
4603 if (deallocate) {
4604 (void) mach_vm_deallocate(map, addr, (mach_vm_size_t)names_length);
4605 }
4606
4607 objects = (ipc_object_t *) data;
4608 dsc->address = data;
4609
4610 for (i = 0; i < count; i++) {
4611 mach_port_name_t name = names[i];
4612 ipc_object_t object;
4613
4614 if (!MACH_PORT_VALID(name)) {
4615 objects[i] = ip_to_object(CAST_MACH_NAME_TO_PORT(name));
4616 continue;
4617 }
4618
4619 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object, 0, NULL, kmsg->ikm_flags);
4620
4621 if (kr != KERN_SUCCESS) {
4622 unsigned int j;
4623
4624 for (j = 0; j < i; j++) {
4625 object = objects[j];
4626 if (IPC_OBJECT_VALID(object)) {
4627 ipc_object_destroy(object, result_disp);
4628 }
4629 }
4630 kfree_type(mach_port_t, count, data);
4631 dsc->address = NULL;
4632 if (((options & MACH_SEND_KERNEL) == 0) && (kr == KERN_INVALID_RIGHT)) {
4633 mach_port_guard_exception(name, 0, 0, kGUARD_EXC_SEND_INVALID_RIGHT);
4634 }
4635 *mr = MACH_SEND_INVALID_RIGHT;
4636 return NULL;
4637 }
4638
4639 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
4640 ipc_port_check_circularity(ip_object_to_port(object),
4641 ip_object_to_port(dest))) {
4642 ikm_header(kmsg)->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
4643 }
4644
4645 objects[i] = object;
4646 }
4647
4648 return user_dsc;
4649 }
4650
4651 static mach_msg_descriptor_t *
ipc_kmsg_copyin_guarded_port_descriptor(mach_msg_guarded_port_descriptor_t * dsc,mach_msg_descriptor_t * user_addr,int is_64bit,ipc_space_t space,ipc_object_t dest,ipc_kmsg_t kmsg,mach_msg_option_t options,mach_msg_return_t * mr)4652 ipc_kmsg_copyin_guarded_port_descriptor(
4653 mach_msg_guarded_port_descriptor_t *dsc,
4654 mach_msg_descriptor_t *user_addr,
4655 int is_64bit,
4656 ipc_space_t space,
4657 ipc_object_t dest,
4658 ipc_kmsg_t kmsg,
4659 mach_msg_option_t options,
4660 mach_msg_return_t *mr)
4661 {
4662 mach_msg_descriptor_t *user_dsc;
4663 mach_msg_type_name_t disp;
4664 mach_msg_type_name_t result_disp;
4665 mach_port_name_t name;
4666 mach_msg_guard_flags_t guard_flags;
4667 ipc_object_t object;
4668 mach_port_context_t context;
4669
4670 if (!is_64bit) {
4671 mach_msg_guarded_port_descriptor32_t *user_gp_dsc = (typeof(user_gp_dsc))user_addr;
4672 name = user_gp_dsc->name;
4673 guard_flags = user_gp_dsc->flags;
4674 disp = user_gp_dsc->disposition;
4675 context = user_gp_dsc->context;
4676 user_dsc = (mach_msg_descriptor_t *)(user_gp_dsc + 1);
4677 } else {
4678 mach_msg_guarded_port_descriptor64_t *user_gp_dsc = (typeof(user_gp_dsc))user_addr;
4679 name = user_gp_dsc->name;
4680 guard_flags = user_gp_dsc->flags;
4681 disp = user_gp_dsc->disposition;
4682 context = user_gp_dsc->context;
4683 user_dsc = (mach_msg_descriptor_t *)(user_gp_dsc + 1);
4684 }
4685
4686 guard_flags &= MACH_MSG_GUARD_FLAGS_MASK;
4687 result_disp = ipc_object_copyin_type(disp);
4688
4689 if (MACH_PORT_VALID(name)) {
4690 kern_return_t kr = ipc_object_copyin(space, name, disp, &object, context, &guard_flags, kmsg->ikm_flags);
4691 if (kr != KERN_SUCCESS) {
4692 if (((options & MACH_SEND_KERNEL) == 0) && (kr == KERN_INVALID_RIGHT)) {
4693 mach_port_guard_exception(name, 0, 0, kGUARD_EXC_SEND_INVALID_RIGHT);
4694 }
4695 *mr = MACH_SEND_INVALID_RIGHT;
4696 return NULL;
4697 }
4698
4699 if ((result_disp == MACH_MSG_TYPE_PORT_RECEIVE) &&
4700 ipc_port_check_circularity(ip_object_to_port(object),
4701 ip_object_to_port(dest))) {
4702 ikm_header(kmsg)->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
4703 }
4704 dsc->name = ip_object_to_port(object);
4705 } else {
4706 dsc->name = CAST_MACH_NAME_TO_PORT(name);
4707 }
4708 dsc->flags = guard_flags;
4709 dsc->disposition = result_disp;
4710 dsc->type = MACH_MSG_GUARDED_PORT_DESCRIPTOR;
4711
4712 #if __LP64__
4713 dsc->pad_end = 0; // debug, unnecessary
4714 #endif
4715
4716 return user_dsc;
4717 }
4718
4719
4720 /*
4721 * Routine: ipc_kmsg_copyin_body
4722 * Purpose:
4723 * "Copy-in" port rights and out-of-line memory
4724 * in the message body.
4725 *
4726 * In all failure cases, the message is left holding
4727 * no rights or memory. However, the message buffer
4728 * is not deallocated. If successful, the message
4729 * contains a valid destination port.
4730 * Conditions:
4731 * Nothing locked.
4732 * Returns:
4733 * MACH_MSG_SUCCESS Successful copyin.
4734 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
4735 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
4736 * MACH_SEND_INVALID_TYPE Bad type specification.
4737 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
4738 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
4739 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
4740 * MACH_SEND_NO_GRANT_DEST Dest port doesn't accept ports in body
4741 */
4742
4743 static mach_msg_return_t
ipc_kmsg_copyin_body(ipc_kmsg_t kmsg,ipc_space_t space,vm_map_t map,mach_msg_option_t options)4744 ipc_kmsg_copyin_body(
4745 ipc_kmsg_t kmsg,
4746 ipc_space_t space,
4747 vm_map_t map,
4748 mach_msg_option_t options)
4749 {
4750 ipc_object_t dest;
4751 mach_msg_body_t *body;
4752 mach_msg_descriptor_t *daddr;
4753 mach_msg_descriptor_t *user_addr, *kern_addr;
4754 mach_msg_type_number_t dsc_count;
4755 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
4756 boolean_t contains_port_desc = FALSE;
4757 vm_size_t space_needed = 0;
4758 mach_vm_address_t paddr = 0;
4759 __assert_only vm_offset_t end;
4760 vm_map_copy_t copy = VM_MAP_COPY_NULL;
4761 mach_msg_return_t mr = MACH_MSG_SUCCESS;
4762 mach_msg_header_t *hdr = ikm_header(kmsg);
4763
4764 ipc_port_t remote_port = hdr->msgh_remote_port;
4765
4766 vm_size_t descriptor_size = 0;
4767
4768 mach_msg_type_number_t total_ool_port_count = 0;
4769 mach_msg_guard_flags_t guard_flags = 0;
4770 mach_port_context_t context;
4771 mach_msg_type_name_t disp;
4772
4773 /*
4774 * Determine if the target is a kernel port.
4775 */
4776 dest = ip_to_object(remote_port);
4777 body = (mach_msg_body_t *) (hdr + 1);
4778 daddr = (mach_msg_descriptor_t *) (body + 1);
4779
4780 dsc_count = body->msgh_descriptor_count;
4781 if (dsc_count == 0) {
4782 return MACH_MSG_SUCCESS;
4783 }
4784
4785 assert(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX);
4786 end = (vm_offset_t)hdr + sizeof(mach_msg_base_t) +
4787 dsc_count * KERNEL_DESC_SIZE;
4788
4789 /*
4790 * Make an initial pass to determine kernal VM space requirements for
4791 * physical copies and possible contraction of the descriptors from
4792 * processes with pointers larger than the kernel's.
4793 */
4794 for (mach_msg_type_number_t i = 0; i < dsc_count; i++) {
4795 mach_msg_size_t dsize;
4796 mach_msg_size_t size;
4797 mach_msg_type_number_t ool_port_count = 0;
4798
4799 dsize = ikm_user_desc_size(daddr->type.type, is_task_64bit);
4800 /* descriptor size check has been hoisted to ikm_check_descriptors() */
4801 assert((vm_offset_t)daddr + dsize <= end);
4802
4803 switch (daddr->type.type) {
4804 case MACH_MSG_OOL_DESCRIPTOR:
4805 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4806 size = (is_task_64bit) ?
4807 ((mach_msg_ool_descriptor64_t *)daddr)->size :
4808 daddr->out_of_line.size;
4809
4810 if (daddr->out_of_line.copy != MACH_MSG_PHYSICAL_COPY &&
4811 daddr->out_of_line.copy != MACH_MSG_VIRTUAL_COPY) {
4812 /*
4813 * Invalid copy option
4814 */
4815 mr = MACH_SEND_INVALID_TYPE;
4816 goto clean_message;
4817 }
4818
4819 if (size > MSG_OOL_SIZE_SMALL &&
4820 (daddr->out_of_line.copy == MACH_MSG_PHYSICAL_COPY) &&
4821 !(daddr->out_of_line.deallocate)) {
4822 /*
4823 * Out-of-line memory descriptor, accumulate kernel
4824 * memory requirements
4825 */
4826 if (space_needed + round_page(size) <= space_needed) {
4827 /* Overflow dectected */
4828 mr = MACH_MSG_VM_KERNEL;
4829 goto clean_message;
4830 }
4831
4832 space_needed += round_page(size);
4833 if (space_needed > ipc_kmsg_max_vm_space) {
4834 /* Per message kernel memory limit exceeded */
4835 mr = MACH_MSG_VM_KERNEL;
4836 goto clean_message;
4837 }
4838 }
4839 break;
4840 case MACH_MSG_PORT_DESCRIPTOR:
4841 if (os_add_overflow(total_ool_port_count, 1, &total_ool_port_count)) {
4842 /* Overflow detected */
4843 mr = MACH_SEND_TOO_LARGE;
4844 goto clean_message;
4845 }
4846 contains_port_desc = TRUE;
4847 break;
4848 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
4849 ool_port_count = (is_task_64bit) ?
4850 ((mach_msg_ool_ports_descriptor64_t *)daddr)->count :
4851 daddr->ool_ports.count;
4852
4853 if (os_add_overflow(total_ool_port_count, ool_port_count, &total_ool_port_count)) {
4854 /* Overflow detected */
4855 mr = MACH_SEND_TOO_LARGE;
4856 goto clean_message;
4857 }
4858
4859 if (ool_port_count > (ipc_kmsg_max_vm_space / sizeof(mach_port_t))) {
4860 /* Per message kernel memory limit exceeded */
4861 mr = MACH_SEND_TOO_LARGE;
4862 goto clean_message;
4863 }
4864 contains_port_desc = TRUE;
4865 break;
4866 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
4867 guard_flags = (is_task_64bit) ?
4868 ((mach_msg_guarded_port_descriptor64_t *)daddr)->flags :
4869 ((mach_msg_guarded_port_descriptor32_t *)daddr)->flags;
4870 context = (is_task_64bit) ?
4871 ((mach_msg_guarded_port_descriptor64_t *)daddr)->context :
4872 ((mach_msg_guarded_port_descriptor32_t *)daddr)->context;
4873 disp = (is_task_64bit) ?
4874 ((mach_msg_guarded_port_descriptor64_t *)daddr)->disposition :
4875 ((mach_msg_guarded_port_descriptor32_t *)daddr)->disposition;
4876
4877 /* Only MACH_MSG_TYPE_MOVE_RECEIVE is supported for now */
4878 if (!guard_flags || ((guard_flags & ~MACH_MSG_GUARD_FLAGS_MASK) != 0) ||
4879 ((guard_flags & MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND) && (context != 0)) ||
4880 (disp != MACH_MSG_TYPE_MOVE_RECEIVE)) {
4881 /*
4882 * Invalid guard flags, context or disposition
4883 */
4884 mr = MACH_SEND_INVALID_TYPE;
4885 goto clean_message;
4886 }
4887 if (os_add_overflow(total_ool_port_count, 1, &total_ool_port_count)) {
4888 /* Overflow detected */
4889 mr = MACH_SEND_TOO_LARGE;
4890 goto clean_message;
4891 }
4892 contains_port_desc = TRUE;
4893 break;
4894 default:
4895 /* descriptor type check has been hoisted to ikm_check_descriptors() */
4896 panic("invalid descriptor type");
4897 }
4898
4899 descriptor_size += dsize;
4900 daddr = (typeof(daddr))((vm_offset_t)daddr + dsize);
4901 }
4902
4903 /* Sending more than 16383 rights in one message seems crazy */
4904 if (total_ool_port_count >= (MACH_PORT_UREFS_MAX / 4)) {
4905 mr = MACH_SEND_TOO_LARGE;
4906 goto clean_message;
4907 }
4908
4909 /*
4910 * Check if dest is a no-grant port; Since this bit is set only on
4911 * port construction and cannot be unset later, we can peek at the
4912 * bit without paying the cost of locking the port.
4913 */
4914 if (contains_port_desc && remote_port->ip_no_grant) {
4915 mr = MACH_SEND_NO_GRANT_DEST;
4916 goto clean_message;
4917 }
4918
4919 /*
4920 * Allocate space in the pageable kernel ipc copy map for all the
4921 * ool data that is to be physically copied. Map is marked wait for
4922 * space.
4923 */
4924 if (space_needed) {
4925 if (mach_vm_allocate_kernel(ipc_kernel_copy_map, &paddr, space_needed,
4926 VM_FLAGS_ANYWHERE, VM_KERN_MEMORY_IPC) != KERN_SUCCESS) {
4927 mr = MACH_MSG_VM_KERNEL;
4928 goto clean_message;
4929 }
4930 }
4931
4932 /* kern_addr = just after base as it was copied in */
4933 kern_addr = (mach_msg_descriptor_t *)((vm_offset_t)hdr +
4934 sizeof(mach_msg_base_t));
4935
4936 /*
4937 * Shift memory after mach_msg_base_t to make room for dsc_count * 16bytes
4938 * of descriptors on 64 bit kernels
4939 */
4940 vm_offset_t dsc_adjust = KERNEL_DESC_SIZE * dsc_count - descriptor_size;
4941
4942 if (descriptor_size != KERNEL_DESC_SIZE * dsc_count) {
4943 if (ikm_is_linear(kmsg)) {
4944 memmove((char *)(((vm_offset_t)hdr) + sizeof(mach_msg_base_t) + dsc_adjust),
4945 (void *)((vm_offset_t)hdr + sizeof(mach_msg_base_t)),
4946 hdr->msgh_size - sizeof(mach_msg_base_t));
4947 } else {
4948 /* just memmove the descriptors following the header */
4949 memmove((char *)(((vm_offset_t)hdr) + sizeof(mach_msg_base_t) + dsc_adjust),
4950 (void *)((vm_offset_t)hdr + sizeof(mach_msg_base_t)),
4951 ikm_total_desc_size(kmsg, current_map(), 0, 0, true));
4952 }
4953
4954 /* Update the message size for the larger in-kernel representation */
4955 hdr->msgh_size += (mach_msg_size_t)dsc_adjust;
4956 }
4957
4958
4959 /* user_addr = just after base after it has been (conditionally) moved */
4960 user_addr = (mach_msg_descriptor_t *)((vm_offset_t)hdr +
4961 sizeof(mach_msg_base_t) + dsc_adjust);
4962
4963 /*
4964 * Receive right of a libxpc connection port is moved as a part of kmsg's body
4965 * 1. from a client to a service during connection etsablishment.
4966 * 2. back to the client on service's death or port deallocation.
4967 *
4968 * Any other attempt to move this receive right is not allowed.
4969 */
4970 kmsg->ikm_flags |= IPC_OBJECT_COPYIN_FLAGS_ALLOW_CONN_IMMOVABLE_RECEIVE;
4971
4972 /* handle the OOL regions and port descriptors. */
4973 for (mach_msg_type_number_t copied_in_dscs = 0;
4974 copied_in_dscs < dsc_count; copied_in_dscs++) {
4975 switch (user_addr->type.type) {
4976 case MACH_MSG_PORT_DESCRIPTOR:
4977 user_addr = ipc_kmsg_copyin_port_descriptor((mach_msg_port_descriptor_t *)kern_addr,
4978 (mach_msg_user_port_descriptor_t *)user_addr, space, dest, kmsg, options, &mr);
4979 kern_addr++;
4980 break;
4981 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4982 case MACH_MSG_OOL_DESCRIPTOR:
4983 user_addr = ipc_kmsg_copyin_ool_descriptor((mach_msg_ool_descriptor_t *)kern_addr,
4984 user_addr, is_task_64bit, &paddr, ©, &space_needed, map, &mr);
4985 kern_addr++;
4986 break;
4987 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
4988 user_addr = ipc_kmsg_copyin_ool_ports_descriptor((mach_msg_ool_ports_descriptor_t *)kern_addr,
4989 user_addr, is_task_64bit, map, space, dest, kmsg, options, &mr);
4990 kern_addr++;
4991 break;
4992 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
4993 user_addr = ipc_kmsg_copyin_guarded_port_descriptor((mach_msg_guarded_port_descriptor_t *)kern_addr,
4994 user_addr, is_task_64bit, space, dest, kmsg, options, &mr);
4995 kern_addr++;
4996 break;
4997 default:
4998 panic("invalid descriptor type %d", user_addr->type.type);
4999 }
5000
5001 if (MACH_MSG_SUCCESS != mr) {
5002 /* clean from start of message descriptors to copied_in_dscs */
5003 ipc_kmsg_clean_partial(kmsg, copied_in_dscs,
5004 (mach_msg_descriptor_t *)((mach_msg_base_t *)hdr + 1),
5005 paddr, space_needed);
5006 goto out;
5007 }
5008 } /* End of loop */
5009
5010 out:
5011 return mr;
5012
5013 clean_message:
5014 /* no descriptors have been copied in yet */
5015 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
5016 return mr;
5017 }
5018
5019 #define MACH_BOOTSTRAP_PORT_MSG_ID_MASK ((1ul << 24) - 1)
5020
5021 /*
5022 * Routine: ipc_kmsg_copyin_from_user
5023 * Purpose:
5024 * "Copy-in" port rights and out-of-line memory
5025 * in the message.
5026 *
5027 * In all failure cases, the message is left holding
5028 * no rights or memory. However, the message buffer
5029 * is not deallocated. If successful, the message
5030 * contains a valid destination port.
5031 * Conditions:
5032 * Nothing locked.
5033 * Returns:
5034 * MACH_MSG_SUCCESS Successful copyin.
5035 * MACH_SEND_INVALID_HEADER Illegal value in the message header bits.
5036 * MACH_SEND_INVALID_DEST Can't copyin destination port.
5037 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
5038 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
5039 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
5040 * MACH_SEND_INVALID_TYPE Bad type specification.
5041 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
5042 */
5043
5044 mach_msg_return_t
ipc_kmsg_copyin_from_user(ipc_kmsg_t kmsg,ipc_space_t space,vm_map_t map,mach_msg_priority_t priority,mach_msg_option64_t * option64p,bool filter_nonfatal)5045 ipc_kmsg_copyin_from_user(
5046 ipc_kmsg_t kmsg,
5047 ipc_space_t space,
5048 vm_map_t map,
5049 mach_msg_priority_t priority,
5050 mach_msg_option64_t *option64p,
5051 bool filter_nonfatal)
5052 {
5053 mach_msg_return_t mr;
5054 mach_msg_header_t *hdr = ikm_header(kmsg);
5055 mach_port_name_t dest_name = CAST_MACH_PORT_TO_NAME(hdr->msgh_remote_port);
5056
5057 hdr->msgh_bits &= MACH_MSGH_BITS_USER;
5058
5059 mr = ipc_kmsg_copyin_header(kmsg, space, priority, option64p);
5060 /* copyin_header may add MACH64_SEND_ALWAYS option */
5061
5062 if (mr != MACH_MSG_SUCCESS) {
5063 return mr;
5064 }
5065
5066 /* Get the message filter policy if the task and port support filtering */
5067 mach_msg_filter_id fid = 0;
5068 mach_port_t remote_port = hdr->msgh_remote_port;
5069 mach_msg_id_t msg_id = hdr->msgh_id;
5070 void * sblabel = NULL;
5071
5072 if (mach_msg_filter_at_least(MACH_MSG_FILTER_CALLBACKS_VERSION_1) &&
5073 task_get_filter_msg_flag(current_task()) &&
5074 ip_enforce_msg_filtering(remote_port)) {
5075 ip_mq_lock(remote_port);
5076 if (ip_active(remote_port)) {
5077 if (remote_port->ip_service_port) {
5078 ipc_service_port_label_t label = remote_port->ip_splabel;
5079 sblabel = label->ispl_sblabel;
5080 if (label && ipc_service_port_label_is_bootstrap_port(label)) {
5081 /*
5082 * Mask the top byte for messages sent to launchd's bootstrap port.
5083 * Filter any messages with domain 0 (as they correspond to MIG
5084 * based messages)
5085 */
5086 unsigned msg_protocol = msg_id & ~MACH_BOOTSTRAP_PORT_MSG_ID_MASK;
5087 if (!msg_protocol) {
5088 ip_mq_unlock(remote_port);
5089 goto filtered_msg;
5090 }
5091 msg_id = msg_id & MACH_BOOTSTRAP_PORT_MSG_ID_MASK;
5092 }
5093 } else {
5094 assert(!ip_is_kolabeled(remote_port));
5095 /* Connection ports can also have send-side message filters */
5096 sblabel = remote_port->ip_splabel;
5097 }
5098 if (sblabel) {
5099 mach_msg_filter_retain_sblabel_callback(sblabel);
5100 }
5101 }
5102 ip_mq_unlock(remote_port);
5103
5104 if (sblabel && !mach_msg_fetch_filter_policy(sblabel, msg_id, &fid)) {
5105 goto filtered_msg;
5106 }
5107 }
5108
5109 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_SEND) | DBG_FUNC_NONE,
5110 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
5111 (uintptr_t)hdr->msgh_bits,
5112 (uintptr_t)hdr->msgh_id,
5113 VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(ipc_kmsg_get_voucher_port(kmsg))),
5114 0);
5115
5116 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_copyin_from_user header:\n%.8x\n%.8x\n%p\n%p\n%p\n%.8x\n",
5117 hdr->msgh_size,
5118 hdr->msgh_bits,
5119 hdr->msgh_remote_port,
5120 hdr->msgh_local_port,
5121 ipc_kmsg_get_voucher_port(kmsg),
5122 hdr->msgh_id);
5123
5124 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
5125 mr = ipc_kmsg_copyin_body(kmsg, space, map, (mach_msg_option_t)*option64p);
5126 }
5127
5128 /* Sign the message contents */
5129 if (mr == MACH_MSG_SUCCESS) {
5130 ipc_kmsg_init_trailer(kmsg, current_task());
5131 ikm_sign(kmsg);
5132 }
5133
5134 return mr;
5135
5136 filtered_msg:
5137 if (!filter_nonfatal) {
5138 mach_port_guard_exception(dest_name, 0, 0, kGUARD_EXC_MSG_FILTERED);
5139 }
5140 /* no descriptors have been copied in yet */
5141 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
5142 return MACH_SEND_MSG_FILTERED;
5143 }
5144
5145 /*
5146 * Routine: ipc_kmsg_copyin_from_kernel
5147 * Purpose:
5148 * "Copy-in" port rights and out-of-line memory
5149 * in a message sent from the kernel.
5150 *
5151 * Because the message comes from the kernel,
5152 * the implementation assumes there are no errors
5153 * or peculiarities in the message.
5154 * Conditions:
5155 * Nothing locked.
5156 */
5157
5158 mach_msg_return_t
ipc_kmsg_copyin_from_kernel(ipc_kmsg_t kmsg)5159 ipc_kmsg_copyin_from_kernel(
5160 ipc_kmsg_t kmsg)
5161 {
5162 mach_msg_header_t *hdr = ikm_header(kmsg);
5163 mach_msg_bits_t bits = hdr->msgh_bits;
5164 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
5165 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
5166 mach_msg_type_name_t vname = MACH_MSGH_BITS_VOUCHER(bits);
5167 ipc_object_t remote = ip_to_object(hdr->msgh_remote_port);
5168 ipc_object_t local = ip_to_object(hdr->msgh_local_port);
5169 ipc_object_t voucher = ip_to_object(ipc_kmsg_get_voucher_port(kmsg));
5170 ipc_port_t dest = hdr->msgh_remote_port;
5171
5172 /* translate the destination and reply ports */
5173 if (!IO_VALID(remote)) {
5174 return MACH_SEND_INVALID_DEST;
5175 }
5176
5177 ipc_object_copyin_from_kernel(remote, rname);
5178 if (IO_VALID(local)) {
5179 ipc_object_copyin_from_kernel(local, lname);
5180 }
5181
5182 if (IO_VALID(voucher)) {
5183 ipc_object_copyin_from_kernel(voucher, vname);
5184 }
5185
5186 /*
5187 * The common case is a complex message with no reply port,
5188 * because that is what the memory_object interface uses.
5189 */
5190
5191 if (bits == (MACH_MSGH_BITS_COMPLEX |
5192 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
5193 bits = (MACH_MSGH_BITS_COMPLEX |
5194 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
5195
5196 hdr->msgh_bits = bits;
5197 } else {
5198 bits = (MACH_MSGH_BITS_OTHER(bits) |
5199 MACH_MSGH_BITS_SET_PORTS(ipc_object_copyin_type(rname),
5200 ipc_object_copyin_type(lname), ipc_object_copyin_type(vname)));
5201
5202 hdr->msgh_bits = bits;
5203 }
5204
5205 ipc_kmsg_set_qos_kernel(kmsg);
5206
5207 if (bits & MACH_MSGH_BITS_COMPLEX) {
5208 /*
5209 * Check if the remote port accepts ports in the body.
5210 */
5211 if (dest->ip_no_grant) {
5212 mach_msg_descriptor_t *saddr;
5213 mach_msg_body_t *body;
5214 mach_msg_type_number_t i, count;
5215
5216 body = (mach_msg_body_t *) (hdr + 1);
5217 saddr = (mach_msg_descriptor_t *) (body + 1);
5218 count = body->msgh_descriptor_count;
5219
5220 for (i = 0; i < count; i++, saddr++) {
5221 switch (saddr->type.type) {
5222 case MACH_MSG_PORT_DESCRIPTOR:
5223 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
5224 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
5225 /* no descriptors have been copied in yet */
5226 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
5227 return MACH_SEND_NO_GRANT_DEST;
5228 }
5229 }
5230 }
5231
5232 mach_msg_descriptor_t *saddr;
5233 mach_msg_body_t *body;
5234 mach_msg_type_number_t i, count;
5235
5236 body = (mach_msg_body_t *) (hdr + 1);
5237 saddr = (mach_msg_descriptor_t *) (body + 1);
5238 count = body->msgh_descriptor_count;
5239
5240 for (i = 0; i < count; i++, saddr++) {
5241 switch (saddr->type.type) {
5242 case MACH_MSG_PORT_DESCRIPTOR: {
5243 mach_msg_type_name_t name;
5244 ipc_object_t object;
5245 mach_msg_port_descriptor_t *dsc;
5246
5247 dsc = &saddr->port;
5248
5249 /* this is really the type SEND, SEND_ONCE, etc. */
5250 name = dsc->disposition;
5251 object = ip_to_object(dsc->name);
5252 dsc->disposition = ipc_object_copyin_type(name);
5253
5254 if (!IO_VALID(object)) {
5255 break;
5256 }
5257
5258 ipc_object_copyin_from_kernel(object, name);
5259
5260 /* CDY avoid circularity when the destination is also */
5261 /* the kernel. This check should be changed into an */
5262 /* assert when the new kobject model is in place since*/
5263 /* ports will not be used in kernel to kernel chats */
5264
5265 /* do not lock remote port, use raw pointer comparison */
5266 if (!ip_in_space_noauth(ip_object_to_port(remote), ipc_space_kernel)) {
5267 /* remote port could be dead, in-transit or in an ipc space */
5268 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
5269 ipc_port_check_circularity(ip_object_to_port(object),
5270 ip_object_to_port(remote))) {
5271 hdr->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
5272 }
5273 }
5274 break;
5275 }
5276 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
5277 case MACH_MSG_OOL_DESCRIPTOR: {
5278 /*
5279 * The sender should supply ready-made memory, i.e.
5280 * a vm_map_copy_t, so we don't need to do anything.
5281 */
5282 break;
5283 }
5284 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
5285 ipc_object_t *objects;
5286 unsigned int j;
5287 mach_msg_type_name_t name;
5288 mach_msg_ool_ports_descriptor_t *dsc;
5289
5290 dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports;
5291
5292 /* this is really the type SEND, SEND_ONCE, etc. */
5293 name = dsc->disposition;
5294 dsc->disposition = ipc_object_copyin_type(name);
5295
5296 objects = (ipc_object_t *) dsc->address;
5297
5298 for (j = 0; j < dsc->count; j++) {
5299 ipc_object_t object = objects[j];
5300
5301 if (!IO_VALID(object)) {
5302 continue;
5303 }
5304
5305 ipc_object_copyin_from_kernel(object, name);
5306
5307 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
5308 ipc_port_check_circularity(ip_object_to_port(object),
5309 ip_object_to_port(remote))) {
5310 hdr->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
5311 }
5312 }
5313 break;
5314 }
5315 case MACH_MSG_GUARDED_PORT_DESCRIPTOR: {
5316 mach_msg_guarded_port_descriptor_t *dsc = (typeof(dsc)) & saddr->guarded_port;
5317 mach_msg_type_name_t disp = dsc->disposition;
5318 ipc_object_t object = ip_to_object(dsc->name);
5319 dsc->disposition = ipc_object_copyin_type(disp);
5320 assert(dsc->flags == 0);
5321
5322 if (!IO_VALID(object)) {
5323 break;
5324 }
5325
5326 ipc_object_copyin_from_kernel(object, disp);
5327 /*
5328 * avoid circularity when the destination is also
5329 * the kernel. This check should be changed into an
5330 * assert when the new kobject model is in place since
5331 * ports will not be used in kernel to kernel chats
5332 */
5333
5334 /* do not lock remote port, use raw pointer comparison */
5335 if (!ip_in_space_noauth(ip_object_to_port(remote), ipc_space_kernel)) {
5336 /* remote port could be dead, in-transit or in an ipc space */
5337 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
5338 ipc_port_check_circularity(ip_object_to_port(object),
5339 ip_object_to_port(remote))) {
5340 hdr->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
5341 }
5342 }
5343 break;
5344 }
5345 default: {
5346 #if MACH_ASSERT
5347 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
5348 #endif /* MACH_ASSERT */
5349 }
5350 }
5351 }
5352 }
5353
5354 /* Add trailer and signature to the message */
5355 ipc_kmsg_init_trailer(kmsg, TASK_NULL);
5356 ikm_sign(kmsg);
5357
5358 return MACH_MSG_SUCCESS;
5359 }
5360
5361 /*
5362 * Routine: ipc_kmsg_copyout_header
5363 * Purpose:
5364 * "Copy-out" port rights in the header of a message.
5365 * Operates atomically; if it doesn't succeed the
5366 * message header and the space are left untouched.
5367 * If it does succeed the remote/local port fields
5368 * contain port names instead of object pointers,
5369 * and the bits field is updated.
5370 * Conditions:
5371 * Nothing locked.
5372 * Returns:
5373 * MACH_MSG_SUCCESS Copied out port rights.
5374 * MACH_RCV_INVALID_NOTIFY
5375 * Notify is non-null and doesn't name a receive right.
5376 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
5377 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
5378 * The space is dead.
5379 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
5380 * No room in space for another name.
5381 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
5382 * Couldn't allocate memory for the reply port.
5383 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
5384 * Couldn't allocate memory for the dead-name request.
5385 */
5386
5387 static mach_msg_return_t
ipc_kmsg_copyout_header(ipc_kmsg_t kmsg,ipc_space_t space,mach_msg_option_t option)5388 ipc_kmsg_copyout_header(
5389 ipc_kmsg_t kmsg,
5390 ipc_space_t space,
5391 mach_msg_option_t option)
5392 {
5393 mach_msg_header_t *msg = ikm_header(kmsg);
5394 mach_msg_bits_t mbits = msg->msgh_bits;
5395 ipc_port_t dest = msg->msgh_remote_port;
5396
5397 assert(IP_VALID(dest));
5398
5399 /*
5400 * While we still hold a reference on the received-from port,
5401 * process all send-possible notfications we received along with
5402 * the message.
5403 */
5404 ipc_port_spnotify(dest);
5405
5406 {
5407 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
5408 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
5409 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
5410 ipc_port_t reply = msg->msgh_local_port;
5411 ipc_port_t release_reply_port = IP_NULL;
5412 mach_port_name_t dest_name, reply_name;
5413
5414 ipc_port_t voucher = ipc_kmsg_get_voucher_port(kmsg);
5415 uintptr_t voucher_addr = 0;
5416 ipc_port_t release_voucher_port = IP_NULL;
5417 mach_port_name_t voucher_name;
5418
5419 uint32_t entries_held = 0;
5420 boolean_t need_write_lock = FALSE;
5421 ipc_object_copyout_flags_t reply_copyout_options = IPC_OBJECT_COPYOUT_FLAGS_NONE;
5422 kern_return_t kr;
5423
5424 /*
5425 * Reserve any potentially needed entries in the target space.
5426 * We'll free any unused before unlocking the space.
5427 */
5428 if (IP_VALID(reply)) {
5429 entries_held++;
5430 need_write_lock = TRUE;
5431 }
5432 if (IP_VALID(voucher)) {
5433 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
5434
5435 if ((option & MACH_RCV_VOUCHER) != 0) {
5436 entries_held++;
5437 }
5438 need_write_lock = TRUE;
5439 voucher_addr = unsafe_convert_port_to_voucher(voucher);
5440 }
5441
5442 if (need_write_lock) {
5443 handle_reply_again:
5444 is_write_lock(space);
5445
5446 while (entries_held) {
5447 if (!is_active(space)) {
5448 is_write_unlock(space);
5449 return MACH_RCV_HEADER_ERROR |
5450 MACH_MSG_IPC_SPACE;
5451 }
5452
5453 kr = ipc_entries_hold(space, entries_held);
5454 if (KERN_SUCCESS == kr) {
5455 break;
5456 }
5457
5458 kr = ipc_entry_grow_table(space, ITS_SIZE_NONE);
5459 if (KERN_SUCCESS != kr) {
5460 return MACH_RCV_HEADER_ERROR |
5461 MACH_MSG_IPC_SPACE;
5462 }
5463 /* space was unlocked and relocked - retry */
5464 }
5465
5466 /* Handle reply port. */
5467 if (IP_VALID(reply)) {
5468 ipc_port_t reply_subst = IP_NULL;
5469 ipc_entry_t entry;
5470
5471 ip_mq_lock(reply);
5472
5473 /* Is the reply port still active and allowed to be copied out? */
5474 if (!ip_active(reply) ||
5475 !ip_label_check(space, reply, reply_type,
5476 &reply_copyout_options, &reply_subst)) {
5477 /* clear the context value */
5478 reply->ip_reply_context = 0;
5479 ip_mq_unlock(reply);
5480
5481 assert(reply_subst == IP_NULL);
5482 release_reply_port = reply;
5483 reply = IP_DEAD;
5484 reply_name = MACH_PORT_DEAD;
5485 goto done_with_reply;
5486 }
5487
5488 /* is the kolabel requesting a substitution */
5489 if (reply_subst != IP_NULL) {
5490 /*
5491 * port is unlocked, its right consumed
5492 * space is unlocked
5493 */
5494 assert(reply_type == MACH_MSG_TYPE_PORT_SEND);
5495 msg->msgh_local_port = reply = reply_subst;
5496 goto handle_reply_again;
5497 }
5498
5499
5500 /* Is there already an entry we can use? */
5501 if ((reply_type != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
5502 ipc_right_reverse(space, ip_to_object(reply), &reply_name, &entry)) {
5503 assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE);
5504 } else {
5505 /* claim a held entry for the reply port */
5506 assert(entries_held > 0);
5507 entries_held--;
5508 ipc_entry_claim(space, ip_to_object(reply),
5509 &reply_name, &entry);
5510 }
5511
5512 /* space and reply port are locked and active */
5513 ip_reference(reply); /* hold onto the reply port */
5514
5515 /*
5516 * If the receiver would like to enforce strict reply
5517 * semantics, and the message looks like it expects a reply,
5518 * and contains a voucher, then link the context in the
5519 * voucher with the reply port so that the next message sent
5520 * to the reply port must come from a thread that has a
5521 * matching context (voucher).
5522 */
5523 if (enforce_strict_reply && MACH_RCV_WITH_STRICT_REPLY(option) && IP_VALID(voucher)) {
5524 if (ipc_kmsg_validate_reply_port_locked(reply, option) != KERN_SUCCESS) {
5525 /* if the receiver isn't happy with the reply port: fail the receive. */
5526 assert(!ip_is_pinned(reply));
5527 ipc_entry_dealloc(space, ip_to_object(reply),
5528 reply_name, entry);
5529 ip_mq_unlock(reply);
5530 is_write_unlock(space);
5531 ip_release(reply);
5532 return MACH_RCV_INVALID_REPLY;
5533 }
5534 ipc_kmsg_link_reply_context_locked(reply, voucher);
5535 } else {
5536 /*
5537 * if the receive did not choose to participate
5538 * in the strict reply/RPC, then don't enforce
5539 * anything (as this could lead to booby-trapped
5540 * messages that kill the server).
5541 */
5542 reply->ip_reply_context = 0;
5543 }
5544
5545 kr = ipc_right_copyout(space, reply_name, entry,
5546 reply_type, IPC_OBJECT_COPYOUT_FLAGS_NONE, NULL, NULL,
5547 ip_to_object(reply));
5548 assert(kr == KERN_SUCCESS);
5549 /* reply port is unlocked */
5550 } else {
5551 reply_name = CAST_MACH_PORT_TO_NAME(reply);
5552 }
5553
5554 done_with_reply:
5555
5556 /* Handle voucher port. */
5557 if (voucher_type != MACH_MSGH_BITS_ZERO) {
5558 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
5559
5560 if (!IP_VALID(voucher)) {
5561 if ((option & MACH_RCV_VOUCHER) == 0) {
5562 voucher_type = MACH_MSGH_BITS_ZERO;
5563 }
5564 voucher_name = MACH_PORT_NULL;
5565 goto done_with_voucher;
5566 }
5567
5568 #if CONFIG_PREADOPT_TG
5569 struct knote *kn = current_thread()->ith_knote;
5570 if (kn == ITH_KNOTE_NULL || kn == ITH_KNOTE_PSEUDO) {
5571 /*
5572 * We are not in this path of voucher copyout because of
5573 * kevent - we cannot expect a voucher preadopt happening on
5574 * this thread for this message later on
5575 */
5576 KDBG_DEBUG(MACHDBG_CODE(DBG_MACH_THREAD_GROUP, MACH_THREAD_GROUP_PREADOPT_NA),
5577 thread_tid(current_thread()), 0, 0, 0);
5578 }
5579 #endif
5580
5581 /* clear voucher from its hiding place back in the kmsg */
5582 ipc_kmsg_clear_voucher_port(kmsg);
5583
5584 if ((option & MACH_RCV_VOUCHER) != 0) {
5585 ipc_entry_t entry;
5586
5587 ip_mq_lock(voucher);
5588
5589 if (ipc_right_reverse(space, ip_to_object(voucher),
5590 &voucher_name, &entry)) {
5591 assert(entry->ie_bits & MACH_PORT_TYPE_SEND);
5592 } else {
5593 assert(entries_held > 0);
5594 entries_held--;
5595 ipc_entry_claim(space, ip_to_object(voucher), &voucher_name, &entry);
5596 }
5597 /* space is locked and active */
5598
5599 assert(ip_kotype(voucher) == IKOT_VOUCHER);
5600 kr = ipc_right_copyout(space, voucher_name, entry,
5601 MACH_MSG_TYPE_MOVE_SEND, IPC_OBJECT_COPYOUT_FLAGS_NONE,
5602 NULL, NULL, ip_to_object(voucher));
5603 /* voucher port is unlocked */
5604 } else {
5605 voucher_type = MACH_MSGH_BITS_ZERO;
5606 release_voucher_port = voucher;
5607 voucher_name = MACH_PORT_NULL;
5608 }
5609 } else {
5610 voucher_name = msg->msgh_voucher_port;
5611 }
5612
5613 done_with_voucher:
5614
5615 ip_mq_lock(dest);
5616 is_write_unlock(space);
5617 } else {
5618 /*
5619 * No reply or voucher port! This is an easy case.
5620 *
5621 * We only need to check that the space is still
5622 * active once we locked the destination:
5623 *
5624 * - if the space holds a receive right for `dest`,
5625 * then holding the port lock means we can't fail
5626 * to notice if the space went dead because
5627 * the is_write_unlock() will pair with
5628 * os_atomic_barrier_before_lock_acquire() + ip_mq_lock().
5629 *
5630 * - if this space doesn't hold a receive right
5631 * for `dest`, then `dest->ip_receiver` points
5632 * elsewhere, and ipc_object_copyout_dest() will
5633 * handle this situation, and failing to notice
5634 * that the space was dead is accetable.
5635 */
5636
5637 os_atomic_barrier_before_lock_acquire();
5638 ip_mq_lock(dest);
5639 if (!is_active(space)) {
5640 ip_mq_unlock(dest);
5641 return MACH_RCV_HEADER_ERROR | MACH_MSG_IPC_SPACE;
5642 }
5643
5644 reply_name = CAST_MACH_PORT_TO_NAME(reply);
5645
5646 if (voucher_type != MACH_MSGH_BITS_ZERO) {
5647 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
5648 if ((option & MACH_RCV_VOUCHER) == 0) {
5649 voucher_type = MACH_MSGH_BITS_ZERO;
5650 }
5651 voucher_name = MACH_PORT_NULL;
5652 } else {
5653 voucher_name = msg->msgh_voucher_port;
5654 }
5655 }
5656
5657 /*
5658 * At this point, the space is unlocked and the destination
5659 * port is locked.
5660 * reply_name is taken care of; we still need dest_name.
5661 * We still hold a ref for reply (if it is valid).
5662 *
5663 * If the space holds receive rights for the destination,
5664 * we return its name for the right. Otherwise the task
5665 * managed to destroy or give away the receive right between
5666 * receiving the message and this copyout. If the destination
5667 * is dead, return MACH_PORT_DEAD, and if the receive right
5668 * exists somewhere else (another space, in transit)
5669 * return MACH_PORT_NULL.
5670 *
5671 * Making this copyout operation atomic with the previous
5672 * copyout of the reply port is a bit tricky. If there was
5673 * no real reply port (it wasn't IP_VALID) then this isn't
5674 * an issue. If the reply port was dead at copyout time,
5675 * then we are OK, because if dest is dead we serialize
5676 * after the death of both ports and if dest is alive
5677 * we serialize after reply died but before dest's (later) death.
5678 * So assume reply was alive when we copied it out. If dest
5679 * is alive, then we are OK because we serialize before
5680 * the ports' deaths. So assume dest is dead when we look at it.
5681 * If reply dies/died after dest, then we are OK because
5682 * we serialize after dest died but before reply dies.
5683 * So the hard case is when reply is alive at copyout,
5684 * dest is dead at copyout, and reply died before dest died.
5685 * In this case pretend that dest is still alive, so
5686 * we serialize while both ports are alive.
5687 *
5688 * Because the space lock is held across the copyout of reply
5689 * and locking dest, the receive right for dest can't move
5690 * in or out of the space while the copyouts happen, so
5691 * that isn't an atomicity problem. In the last hard case
5692 * above, this implies that when dest is dead that the
5693 * space couldn't have had receive rights for dest at
5694 * the time reply was copied-out, so when we pretend
5695 * that dest is still alive, we can return MACH_PORT_NULL.
5696 *
5697 * If dest == reply, then we have to make it look like
5698 * either both copyouts happened before the port died,
5699 * or both happened after the port died. This special
5700 * case works naturally if the timestamp comparison
5701 * is done correctly.
5702 */
5703
5704 if (ip_active(dest)) {
5705 ipc_object_copyout_dest(space, ip_to_object(dest),
5706 dest_type, &dest_name);
5707 /* dest is unlocked */
5708 } else {
5709 ipc_port_timestamp_t timestamp;
5710
5711 timestamp = ip_get_death_time(dest);
5712 ip_mq_unlock(dest);
5713 ip_release(dest);
5714
5715 if (IP_VALID(reply)) {
5716 ip_mq_lock(reply);
5717 if (ip_active(reply) ||
5718 IP_TIMESTAMP_ORDER(timestamp,
5719 ip_get_death_time(reply))) {
5720 dest_name = MACH_PORT_DEAD;
5721 } else {
5722 dest_name = MACH_PORT_NULL;
5723 }
5724 ip_mq_unlock(reply);
5725 } else {
5726 dest_name = MACH_PORT_DEAD;
5727 }
5728 }
5729
5730 if (IP_VALID(reply)) {
5731 ip_release(reply);
5732 }
5733
5734 if (IP_VALID(release_reply_port)) {
5735 if (reply_type == MACH_MSG_TYPE_PORT_SEND_ONCE) {
5736 ipc_port_release_sonce(release_reply_port);
5737 } else {
5738 ipc_port_release_send(release_reply_port);
5739 }
5740 }
5741
5742 if ((option & MACH_RCV_VOUCHER) != 0) {
5743 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV) | DBG_FUNC_NONE,
5744 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
5745 (uintptr_t)msg->msgh_bits,
5746 (uintptr_t)msg->msgh_id,
5747 VM_KERNEL_ADDRPERM(voucher_addr), 0);
5748 } else {
5749 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV_VOUCHER_REFUSED) | DBG_FUNC_NONE,
5750 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
5751 (uintptr_t)msg->msgh_bits,
5752 (uintptr_t)msg->msgh_id,
5753 VM_KERNEL_ADDRPERM(voucher_addr), 0);
5754 }
5755
5756 if (IP_VALID(release_voucher_port)) {
5757 ipc_port_release_send(release_voucher_port);
5758 }
5759
5760 msg->msgh_bits = MACH_MSGH_BITS_SET(reply_type, dest_type,
5761 voucher_type, mbits);
5762 msg->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
5763 msg->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
5764 msg->msgh_voucher_port = voucher_name;
5765 }
5766
5767 return MACH_MSG_SUCCESS;
5768 }
5769
5770 /*
5771 * Routine: ipc_kmsg_copyout_object
5772 * Purpose:
5773 * Copy-out a port right. Always returns a name,
5774 * even for unsuccessful return codes. Always
5775 * consumes the supplied object.
5776 * Conditions:
5777 * Nothing locked.
5778 * Returns:
5779 * MACH_MSG_SUCCESS The space acquired the right
5780 * (name is valid) or the object is dead (MACH_PORT_DEAD).
5781 * MACH_MSG_IPC_SPACE No room in space for the right,
5782 * or the space is dead. (Name is MACH_PORT_NULL.)
5783 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
5784 * (Name is MACH_PORT_NULL.)
5785 */
5786 static mach_msg_return_t
ipc_kmsg_copyout_object(ipc_space_t space,ipc_object_t object,mach_msg_type_name_t msgt_name,mach_port_context_t * context,mach_msg_guard_flags_t * guard_flags,mach_port_name_t * namep)5787 ipc_kmsg_copyout_object(
5788 ipc_space_t space,
5789 ipc_object_t object,
5790 mach_msg_type_name_t msgt_name,
5791 mach_port_context_t *context,
5792 mach_msg_guard_flags_t *guard_flags,
5793 mach_port_name_t *namep)
5794 {
5795 kern_return_t kr;
5796
5797 if (!IO_VALID(object)) {
5798 *namep = CAST_MACH_PORT_TO_NAME(object);
5799 return MACH_MSG_SUCCESS;
5800 }
5801
5802 kr = ipc_object_copyout(space, object, msgt_name, IPC_OBJECT_COPYOUT_FLAGS_NONE,
5803 context, guard_flags, namep);
5804 if (kr != KERN_SUCCESS) {
5805 if (kr == KERN_INVALID_CAPABILITY) {
5806 *namep = MACH_PORT_DEAD;
5807 } else {
5808 *namep = MACH_PORT_NULL;
5809
5810 if (kr == KERN_RESOURCE_SHORTAGE) {
5811 return MACH_MSG_IPC_KERNEL;
5812 } else {
5813 return MACH_MSG_IPC_SPACE;
5814 }
5815 }
5816 }
5817
5818 return MACH_MSG_SUCCESS;
5819 }
5820
5821 /*
5822 * Routine: ipc_kmsg_copyout_reply_object
5823 * Purpose:
5824 * Kernel swallows the send-once right associated with reply port.
5825 * Always returns a name, even for unsuccessful return codes.
5826 * Returns
5827 * MACH_MSG_SUCCESS Returns name of receive right for reply port.
5828 * Name is valid if the space acquired the right and msgt_name would be changed from MOVE_SO to MAKE_SO.
5829 * Name is MACH_PORT_DEAD if the object is dead.
5830 * Name is MACH_PORT_NULL if its entry could not be found in task's ipc space.
5831 * MACH_MSG_IPC_SPACE
5832 * The space is dead. (Name is MACH_PORT_NULL.)
5833 * Conditions:
5834 * Nothing locked.
5835 */
5836 static mach_msg_return_t
ipc_kmsg_copyout_reply_object(ipc_space_t space,ipc_object_t object,mach_msg_type_name_t * msgt_name,mach_port_name_t * namep)5837 ipc_kmsg_copyout_reply_object(
5838 ipc_space_t space,
5839 ipc_object_t object,
5840 mach_msg_type_name_t *msgt_name,
5841 mach_port_name_t *namep)
5842 {
5843 ipc_port_t port;
5844 ipc_entry_t entry;
5845 kern_return_t kr;
5846
5847 if (!IO_VALID(object)) {
5848 *namep = CAST_MACH_PORT_TO_NAME(object);
5849 return MACH_MSG_SUCCESS;
5850 }
5851
5852 port = ip_object_to_port(object);
5853
5854 assert(ip_is_reply_port(port));
5855 assert(*msgt_name == MACH_MSG_TYPE_PORT_SEND_ONCE);
5856
5857 is_write_lock(space);
5858
5859 if (!is_active(space)) {
5860 ipc_port_release_sonce(port);
5861 is_write_unlock(space);
5862 *namep = MACH_PORT_NULL;
5863 return MACH_MSG_IPC_SPACE;
5864 }
5865
5866 io_lock(object);
5867
5868 if (!io_active(object)) {
5869 *namep = MACH_PORT_DEAD;
5870 kr = MACH_MSG_SUCCESS;
5871 goto out;
5872 }
5873
5874 /* space is locked and active. object is locked and active. */
5875 if (!ipc_right_reverse(space, object, namep, &entry)) {
5876 *namep = MACH_PORT_NULL;
5877 kr = MACH_MSG_SUCCESS;
5878 goto out;
5879 }
5880
5881 assert(entry->ie_bits & MACH_PORT_TYPE_RECEIVE);
5882
5883 *msgt_name = MACH_MSG_TYPE_MAKE_SEND_ONCE;
5884 ipc_port_release_sonce_and_unlock(port);
5885 /* object is unlocked. */
5886
5887 is_write_unlock(space);
5888
5889 return MACH_MSG_SUCCESS;
5890
5891 out:
5892
5893 /* space and object are locked. */
5894 ipc_port_release_sonce_and_unlock(port);
5895
5896 is_write_unlock(space);
5897
5898 return kr;
5899 }
5900
5901 static mach_msg_descriptor_t *
ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t * dsc,mach_msg_descriptor_t * dest_dsc,ipc_space_t space,kern_return_t * mr)5902 ipc_kmsg_copyout_port_descriptor(
5903 mach_msg_descriptor_t *dsc,
5904 mach_msg_descriptor_t *dest_dsc,
5905 ipc_space_t space,
5906 kern_return_t *mr)
5907 {
5908 mach_msg_user_port_descriptor_t *user_dsc;
5909 mach_port_t port;
5910 mach_port_name_t name;
5911 mach_msg_type_name_t disp;
5912
5913 /* Copyout port right carried in the message */
5914 port = dsc->port.name;
5915 disp = dsc->port.disposition;
5916 *mr |= ipc_kmsg_copyout_object(space,
5917 ip_to_object(port), disp, NULL, NULL, &name);
5918
5919 // point to the start of this port descriptor
5920 user_dsc = ((mach_msg_user_port_descriptor_t *)dest_dsc - 1);
5921 bzero((void *)user_dsc, sizeof(*user_dsc));
5922 user_dsc->name = CAST_MACH_PORT_TO_NAME(name);
5923 user_dsc->disposition = disp;
5924 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
5925
5926 return (mach_msg_descriptor_t *)user_dsc;
5927 }
5928
5929 static mach_msg_descriptor_t *
ipc_kmsg_copyout_ool_descriptor(mach_msg_ool_descriptor_t * dsc,mach_msg_descriptor_t * user_dsc,int is_64bit,vm_map_t map,mach_msg_return_t * mr)5930 ipc_kmsg_copyout_ool_descriptor(
5931 mach_msg_ool_descriptor_t *dsc,
5932 mach_msg_descriptor_t *user_dsc,
5933 int is_64bit,
5934 vm_map_t map,
5935 mach_msg_return_t *mr)
5936 {
5937 vm_map_copy_t copy;
5938 vm_map_address_t rcv_addr;
5939 mach_msg_copy_options_t copy_options;
5940 vm_map_size_t size;
5941 mach_msg_descriptor_type_t dsc_type;
5942 boolean_t misaligned = FALSE;
5943
5944 copy = (vm_map_copy_t)dsc->address;
5945 size = (vm_map_size_t)dsc->size;
5946 copy_options = dsc->copy;
5947 assert(copy_options != MACH_MSG_KALLOC_COPY_T);
5948 dsc_type = dsc->type;
5949
5950 if (copy != VM_MAP_COPY_NULL) {
5951 kern_return_t kr;
5952
5953 rcv_addr = 0;
5954 if (vm_map_copy_validate_size(map, copy, &size) == FALSE) {
5955 panic("Inconsistent OOL/copyout size on %p: expected %d, got %lld @%p",
5956 dsc, dsc->size, (unsigned long long)copy->size, copy);
5957 }
5958
5959 if ((copy->type == VM_MAP_COPY_ENTRY_LIST) &&
5960 (trunc_page(copy->offset) != copy->offset ||
5961 round_page(dsc->size) != dsc->size)) {
5962 misaligned = TRUE;
5963 }
5964
5965 if (misaligned) {
5966 mach_vm_offset_t rounded_addr;
5967 vm_map_size_t rounded_size;
5968 vm_map_offset_t effective_page_mask, effective_page_size;
5969
5970 effective_page_mask = VM_MAP_PAGE_MASK(map);
5971 effective_page_size = effective_page_mask + 1;
5972
5973 rounded_size = vm_map_round_page(copy->offset + size, effective_page_mask) - vm_map_trunc_page(copy->offset, effective_page_mask);
5974
5975 kr = mach_vm_allocate_kernel(map, &rounded_addr,
5976 rounded_size, VM_FLAGS_ANYWHERE, VM_KERN_MEMORY_IPC);
5977
5978 if (kr == KERN_SUCCESS) {
5979 /*
5980 * vm_map_copy_overwrite does a full copy
5981 * if size is too small to optimize.
5982 * So we tried skipping the offset adjustment
5983 * if we fail the 'size' test.
5984 *
5985 * if (size >= VM_MAP_COPY_OVERWRITE_OPTIMIZATION_THRESHOLD_PAGES * effective_page_size) {
5986 *
5987 * This resulted in leaked memory especially on the
5988 * older watches (16k user - 4k kernel) because we
5989 * would do a physical copy into the start of this
5990 * rounded range but could leak part of it
5991 * on deallocation if the 'size' being deallocated
5992 * does not cover the full range. So instead we do
5993 * the misalignment adjustment always so that on
5994 * deallocation we will remove the full range.
5995 */
5996 if ((rounded_addr & effective_page_mask) !=
5997 (copy->offset & effective_page_mask)) {
5998 /*
5999 * Need similar mis-alignment of source and destination...
6000 */
6001 rounded_addr += (copy->offset & effective_page_mask);
6002
6003 assert((rounded_addr & effective_page_mask) == (copy->offset & effective_page_mask));
6004 }
6005 rcv_addr = rounded_addr;
6006
6007 kr = vm_map_copy_overwrite(map, rcv_addr, copy, size, FALSE);
6008 }
6009 } else {
6010 kr = vm_map_copyout_size(map, &rcv_addr, copy, size);
6011 }
6012 if (kr != KERN_SUCCESS) {
6013 if (kr == KERN_RESOURCE_SHORTAGE) {
6014 *mr |= MACH_MSG_VM_KERNEL;
6015 } else {
6016 *mr |= MACH_MSG_VM_SPACE;
6017 }
6018 vm_map_copy_discard(copy);
6019 rcv_addr = 0;
6020 size = 0;
6021 }
6022 } else {
6023 rcv_addr = 0;
6024 size = 0;
6025 }
6026
6027 /*
6028 * Now update the descriptor as the user would see it.
6029 * This may require expanding the descriptor to the user
6030 * visible size. There is already space allocated for
6031 * this in what naddr points to.
6032 */
6033 if (is_64bit) {
6034 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
6035 user_ool_dsc--;
6036 bzero((void *)user_ool_dsc, sizeof(*user_ool_dsc));
6037
6038 user_ool_dsc->address = rcv_addr;
6039 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
6040 TRUE : FALSE;
6041 user_ool_dsc->copy = copy_options;
6042 user_ool_dsc->type = dsc_type;
6043 user_ool_dsc->size = (mach_msg_size_t)size;
6044
6045 user_dsc = (typeof(user_dsc))user_ool_dsc;
6046 } else {
6047 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
6048 user_ool_dsc--;
6049 bzero((void *)user_ool_dsc, sizeof(*user_ool_dsc));
6050
6051 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
6052 user_ool_dsc->size = (mach_msg_size_t)size;
6053 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
6054 TRUE : FALSE;
6055 user_ool_dsc->copy = copy_options;
6056 user_ool_dsc->type = dsc_type;
6057
6058 user_dsc = (typeof(user_dsc))user_ool_dsc;
6059 }
6060 return user_dsc;
6061 }
6062
6063 static mach_msg_descriptor_t *
ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t * dsc,mach_msg_descriptor_t * user_dsc,int is_64bit,vm_map_t map,ipc_space_t space,ipc_kmsg_t kmsg,mach_msg_return_t * mr)6064 ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc,
6065 mach_msg_descriptor_t *user_dsc,
6066 int is_64bit,
6067 vm_map_t map,
6068 ipc_space_t space,
6069 ipc_kmsg_t kmsg,
6070 mach_msg_return_t *mr)
6071 {
6072 mach_vm_offset_t rcv_addr = 0;
6073 mach_msg_type_name_t disp;
6074 mach_msg_type_number_t count, i;
6075 vm_size_t ports_length, names_length;
6076 mach_msg_copy_options_t copy_options = MACH_MSG_VIRTUAL_COPY;
6077
6078 count = dsc->count;
6079 disp = dsc->disposition;
6080 ports_length = count * sizeof(mach_port_t);
6081 names_length = count * sizeof(mach_port_name_t);
6082
6083 if (ports_length != 0 && dsc->address != 0) {
6084 if (copy_options == MACH_MSG_VIRTUAL_COPY) {
6085 /*
6086 * Dynamically allocate the region
6087 */
6088 vm_tag_t tag;
6089 if (vm_kernel_map_is_kernel(map)) {
6090 tag = VM_KERN_MEMORY_IPC;
6091 } else {
6092 tag = VM_MEMORY_MACH_MSG;
6093 }
6094
6095 kern_return_t kr;
6096 if ((kr = mach_vm_allocate_kernel(map, &rcv_addr,
6097 (mach_vm_size_t)names_length,
6098 VM_FLAGS_ANYWHERE, tag)) != KERN_SUCCESS) {
6099 ipc_kmsg_clean_body(kmsg, 1, (mach_msg_descriptor_t *)dsc);
6100 rcv_addr = 0;
6101
6102 if (kr == KERN_RESOURCE_SHORTAGE) {
6103 *mr |= MACH_MSG_VM_KERNEL;
6104 } else {
6105 *mr |= MACH_MSG_VM_SPACE;
6106 }
6107 }
6108 }
6109
6110 /*
6111 * Handle the port rights and copy out the names
6112 * for those rights out to user-space.
6113 */
6114 if (rcv_addr != 0) {
6115 ipc_object_t *objects = (ipc_object_t *) dsc->address;
6116 mach_port_name_t *names = (mach_port_name_t *) dsc->address;
6117
6118 /* copyout port rights carried in the message */
6119
6120 for (i = 0; i < count; i++) {
6121 ipc_object_t object = objects[i];
6122
6123 *mr |= ipc_kmsg_copyout_object(space, object,
6124 disp, NULL, NULL, &names[i]);
6125 }
6126
6127 /* copyout to memory allocated above */
6128 void *data = dsc->address;
6129 if (copyoutmap(map, data, rcv_addr, names_length) != KERN_SUCCESS) {
6130 *mr |= MACH_MSG_VM_SPACE;
6131 }
6132 kfree_type(mach_port_t, count, data);
6133 }
6134 } else {
6135 rcv_addr = 0;
6136 }
6137
6138 /*
6139 * Now update the descriptor based on the information
6140 * calculated above.
6141 */
6142 if (is_64bit) {
6143 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
6144 user_ool_dsc--;
6145 bzero((void *)user_ool_dsc, sizeof(*user_ool_dsc));
6146
6147 user_ool_dsc->address = rcv_addr;
6148 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
6149 TRUE : FALSE;
6150 user_ool_dsc->copy = copy_options;
6151 user_ool_dsc->disposition = disp;
6152 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
6153 user_ool_dsc->count = count;
6154
6155 user_dsc = (typeof(user_dsc))user_ool_dsc;
6156 } else {
6157 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
6158 user_ool_dsc--;
6159 bzero((void *)user_ool_dsc, sizeof(*user_ool_dsc));
6160
6161 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
6162 user_ool_dsc->count = count;
6163 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
6164 TRUE : FALSE;
6165 user_ool_dsc->copy = copy_options;
6166 user_ool_dsc->disposition = disp;
6167 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
6168
6169 user_dsc = (typeof(user_dsc))user_ool_dsc;
6170 }
6171 return user_dsc;
6172 }
6173
6174 static mach_msg_descriptor_t *
ipc_kmsg_copyout_guarded_port_descriptor(mach_msg_guarded_port_descriptor_t * dsc,mach_msg_descriptor_t * dest_dsc,int is_64bit,__unused ipc_kmsg_t kmsg,ipc_space_t space,mach_msg_option_t option,kern_return_t * mr)6175 ipc_kmsg_copyout_guarded_port_descriptor(
6176 mach_msg_guarded_port_descriptor_t *dsc,
6177 mach_msg_descriptor_t *dest_dsc,
6178 int is_64bit,
6179 __unused ipc_kmsg_t kmsg,
6180 ipc_space_t space,
6181 mach_msg_option_t option,
6182 kern_return_t *mr)
6183 {
6184 mach_port_t port;
6185 mach_port_name_t name = MACH_PORT_NULL;
6186 mach_msg_type_name_t disp;
6187 mach_msg_guard_flags_t guard_flags;
6188 mach_port_context_t context;
6189
6190 /* Copyout port right carried in the message */
6191 port = dsc->name;
6192 disp = dsc->disposition;
6193 guard_flags = dsc->flags;
6194 context = 0;
6195
6196 /* Currently kernel_task doesnt support receiving guarded port descriptors */
6197 struct knote *kn = current_thread()->ith_knote;
6198 if ((kn != ITH_KNOTE_PSEUDO) && ((option & MACH_RCV_GUARDED_DESC) == 0)) {
6199 #if DEVELOPMENT || DEBUG
6200 /*
6201 * Simulated crash needed for debugging, notifies the receiver to opt into receiving
6202 * guarded descriptors.
6203 */
6204 mach_port_guard_exception(current_thread()->ith_receiver_name,
6205 0, 0, kGUARD_EXC_RCV_GUARDED_DESC);
6206 #endif
6207 KDBG(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_DESTROY_GUARDED_DESC), current_thread()->ith_receiver_name,
6208 VM_KERNEL_ADDRPERM(port), disp, guard_flags);
6209 ipc_object_destroy(ip_to_object(port), disp);
6210 mach_msg_user_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc;
6211 user_dsc--; // point to the start of this port descriptor
6212 bzero((void *)user_dsc, sizeof(*user_dsc));
6213 user_dsc->name = name;
6214 user_dsc->disposition = disp;
6215 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
6216 dest_dsc = (typeof(dest_dsc))user_dsc;
6217 } else {
6218 *mr |= ipc_kmsg_copyout_object(space,
6219 ip_to_object(port), disp, &context, &guard_flags, &name);
6220
6221 if (!is_64bit) {
6222 mach_msg_guarded_port_descriptor32_t *user_dsc = (typeof(user_dsc))dest_dsc;
6223 user_dsc--; // point to the start of this port descriptor
6224 bzero((void *)user_dsc, sizeof(*user_dsc));
6225 user_dsc->name = name;
6226 user_dsc->flags = guard_flags;
6227 user_dsc->disposition = disp;
6228 user_dsc->type = MACH_MSG_GUARDED_PORT_DESCRIPTOR;
6229 user_dsc->context = CAST_DOWN_EXPLICIT(uint32_t, context);
6230 dest_dsc = (typeof(dest_dsc))user_dsc;
6231 } else {
6232 mach_msg_guarded_port_descriptor64_t *user_dsc = (typeof(user_dsc))dest_dsc;
6233 user_dsc--; // point to the start of this port descriptor
6234 bzero((void *)user_dsc, sizeof(*user_dsc));
6235 user_dsc->name = name;
6236 user_dsc->flags = guard_flags;
6237 user_dsc->disposition = disp;
6238 user_dsc->type = MACH_MSG_GUARDED_PORT_DESCRIPTOR;
6239 user_dsc->context = context;
6240 dest_dsc = (typeof(dest_dsc))user_dsc;
6241 }
6242 }
6243
6244 return (mach_msg_descriptor_t *)dest_dsc;
6245 }
6246
6247
6248 /*
6249 * Routine: ipc_kmsg_copyout_body
6250 * Purpose:
6251 * "Copy-out" port rights and out-of-line memory
6252 * in the body of a message.
6253 *
6254 * The error codes are a combination of special bits.
6255 * The copyout proceeds despite errors.
6256 * Conditions:
6257 * Nothing locked.
6258 * Returns:
6259 * MACH_MSG_SUCCESS Successful copyout.
6260 * MACH_MSG_IPC_SPACE No room for port right in name space.
6261 * MACH_MSG_VM_SPACE No room for memory in address space.
6262 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
6263 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
6264 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
6265 */
6266
6267 static mach_msg_return_t
ipc_kmsg_copyout_body(ipc_kmsg_t kmsg,ipc_space_t space,vm_map_t map,mach_msg_option_t option)6268 ipc_kmsg_copyout_body(
6269 ipc_kmsg_t kmsg,
6270 ipc_space_t space,
6271 vm_map_t map,
6272 mach_msg_option_t option)
6273 {
6274 mach_msg_body_t *body;
6275 mach_msg_descriptor_t *kern_dsc, *user_dsc;
6276 mach_msg_type_number_t dsc_count;
6277 mach_msg_return_t mr = MACH_MSG_SUCCESS;
6278 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
6279 mach_msg_header_t *hdr = ikm_header(kmsg);
6280
6281 body = (mach_msg_body_t *) (hdr + 1);
6282 dsc_count = body->msgh_descriptor_count;
6283 kern_dsc = (mach_msg_descriptor_t *) (body + 1);
6284 /* Point user_dsc just after the end of all the descriptors */
6285 user_dsc = &kern_dsc[dsc_count];
6286
6287 assert(current_task() != kernel_task);
6288
6289 /* Now process the descriptors - in reverse order */
6290 for (mach_msg_type_number_t i = dsc_count; i-- > 0;) {
6291 switch (kern_dsc[i].type.type) {
6292 case MACH_MSG_PORT_DESCRIPTOR:
6293 user_dsc = ipc_kmsg_copyout_port_descriptor(&kern_dsc[i],
6294 user_dsc, space, &mr);
6295 break;
6296 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
6297 case MACH_MSG_OOL_DESCRIPTOR:
6298 user_dsc = ipc_kmsg_copyout_ool_descriptor(
6299 (mach_msg_ool_descriptor_t *)&kern_dsc[i],
6300 user_dsc, is_task_64bit, map, &mr);
6301 break;
6302 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
6303 user_dsc = ipc_kmsg_copyout_ool_ports_descriptor(
6304 (mach_msg_ool_ports_descriptor_t *)&kern_dsc[i],
6305 user_dsc, is_task_64bit, map, space, kmsg, &mr);
6306 break;
6307 case MACH_MSG_GUARDED_PORT_DESCRIPTOR:
6308 user_dsc = ipc_kmsg_copyout_guarded_port_descriptor(
6309 (mach_msg_guarded_port_descriptor_t *)&kern_dsc[i],
6310 user_dsc, is_task_64bit, kmsg, space, option, &mr);
6311 break;
6312 default:
6313 panic("untyped IPC copyout body: invalid message descriptor");
6314 }
6315 }
6316
6317 assert((vm_offset_t)kern_dsc == (vm_offset_t)hdr + sizeof(mach_msg_base_t));
6318
6319 if (user_dsc != kern_dsc) {
6320 vm_offset_t dsc_adjust = (vm_offset_t)user_dsc - (vm_offset_t)kern_dsc;
6321 /* update the message size for the smaller user representation */
6322 hdr->msgh_size -= (mach_msg_size_t)dsc_adjust;
6323
6324 if (ikm_is_linear(kmsg)) {
6325 /* trailer has been initialized during send - memmove it too. */
6326 memmove((char *)kern_dsc,
6327 user_dsc, hdr->msgh_size - sizeof(mach_msg_base_t) + MAX_TRAILER_SIZE);
6328 } else {
6329 /* just memmove the descriptors following the header */
6330 memmove((char *)kern_dsc,
6331 user_dsc, ikm_total_desc_size(kmsg, current_map(), dsc_adjust, 0, true));
6332 }
6333 }
6334
6335 return mr;
6336 }
6337
6338 /*
6339 * Routine: ipc_kmsg_copyout_size
6340 * Purpose:
6341 * Compute the size of the message as copied out to the given
6342 * map. If the destination map's pointers are a different size
6343 * than the kernel's, we have to allow for expansion/
6344 * contraction of the descriptors as appropriate.
6345 * Conditions:
6346 * Nothing locked.
6347 * Returns:
6348 * size of the message as it would be received.
6349 */
6350
6351 mach_msg_size_t
ipc_kmsg_copyout_size(ipc_kmsg_t kmsg,vm_map_t map)6352 ipc_kmsg_copyout_size(
6353 ipc_kmsg_t kmsg,
6354 vm_map_t map)
6355 {
6356 mach_msg_size_t send_size;
6357 mach_msg_header_t *hdr;
6358
6359 hdr = ikm_header(kmsg);
6360 send_size = hdr->msgh_size - USER_HEADER_SIZE_DELTA;
6361
6362 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
6363
6364 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
6365 mach_msg_body_t *body;
6366 mach_msg_descriptor_t *saddr, *eaddr;
6367
6368 body = (mach_msg_body_t *) (hdr + 1);
6369 saddr = (mach_msg_descriptor_t *) (body + 1);
6370 eaddr = saddr + body->msgh_descriptor_count;
6371
6372 send_size -= KERNEL_DESC_SIZE * body->msgh_descriptor_count;
6373 for (; saddr < eaddr; saddr++) {
6374 send_size += ikm_user_desc_size(saddr->type.type, is_task_64bit);
6375 }
6376 }
6377 return send_size;
6378 }
6379
6380 /*
6381 * Routine: ipc_kmsg_copyout
6382 * Purpose:
6383 * "Copy-out" port rights and out-of-line memory
6384 * in the message.
6385 * Conditions:
6386 * Nothing locked.
6387 * Returns:
6388 * MACH_MSG_SUCCESS Copied out all rights and memory.
6389 * MACH_RCV_HEADER_ERROR + special bits
6390 * Rights and memory in the message are intact.
6391 * MACH_RCV_BODY_ERROR + special bits
6392 * The message header was successfully copied out.
6393 * As much of the body was handled as possible.
6394 */
6395
6396 mach_msg_return_t
ipc_kmsg_copyout(ipc_kmsg_t kmsg,ipc_space_t space,vm_map_t map,mach_msg_option_t option)6397 ipc_kmsg_copyout(
6398 ipc_kmsg_t kmsg,
6399 ipc_space_t space,
6400 vm_map_t map,
6401 mach_msg_option_t option)
6402 {
6403 mach_msg_return_t mr;
6404
6405 ikm_validate_sig(kmsg);
6406
6407 mr = ipc_kmsg_copyout_header(kmsg, space, option);
6408 if (mr != MACH_MSG_SUCCESS) {
6409 return mr;
6410 }
6411
6412 if (ikm_header(kmsg)->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
6413 mr = ipc_kmsg_copyout_body(kmsg, space, map, option);
6414
6415 if (mr != MACH_MSG_SUCCESS) {
6416 mr |= MACH_RCV_BODY_ERROR;
6417 }
6418 }
6419
6420 return mr;
6421 }
6422
6423 /*
6424 * Routine: ipc_kmsg_copyout_pseudo
6425 * Purpose:
6426 * Does a pseudo-copyout of the message.
6427 * This is like a regular copyout, except
6428 * that the ports in the header are handled
6429 * as if they are in the body. They aren't reversed.
6430 *
6431 * The error codes are a combination of special bits.
6432 * The copyout proceeds despite errors.
6433 * Conditions:
6434 * Nothing locked.
6435 * Returns:
6436 * MACH_MSG_SUCCESS Successful copyout.
6437 * MACH_MSG_IPC_SPACE No room for port right in name space.
6438 * MACH_MSG_VM_SPACE No room for memory in address space.
6439 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
6440 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
6441 */
6442
6443 mach_msg_return_t
ipc_kmsg_copyout_pseudo(ipc_kmsg_t kmsg,ipc_space_t space,vm_map_t map)6444 ipc_kmsg_copyout_pseudo(
6445 ipc_kmsg_t kmsg,
6446 ipc_space_t space,
6447 vm_map_t map)
6448 {
6449 mach_msg_header_t *hdr = ikm_header(kmsg);
6450 mach_msg_bits_t mbits = hdr->msgh_bits;
6451 ipc_object_t dest = ip_to_object(hdr->msgh_remote_port);
6452 ipc_object_t reply = ip_to_object(hdr->msgh_local_port);
6453 ipc_object_t voucher = ip_to_object(ipc_kmsg_get_voucher_port(kmsg));
6454 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
6455 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
6456 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
6457 mach_port_name_t voucher_name = hdr->msgh_voucher_port;
6458 mach_port_name_t dest_name, reply_name;
6459 mach_msg_return_t mr;
6460
6461 /* Set ith_knote to ITH_KNOTE_PSEUDO */
6462 current_thread()->ith_knote = ITH_KNOTE_PSEUDO;
6463
6464 ikm_validate_sig(kmsg);
6465
6466 assert(IO_VALID(dest));
6467
6468 #if 0
6469 /*
6470 * If we did this here, it looks like we wouldn't need the undo logic
6471 * at the end of ipc_kmsg_send() in the error cases. Not sure which
6472 * would be more elegant to keep.
6473 */
6474 ipc_importance_clean(kmsg);
6475 #else
6476 /* just assert it is already clean */
6477 ipc_importance_assert_clean(kmsg);
6478 #endif
6479
6480 mr = ipc_kmsg_copyout_object(space, dest, dest_type, NULL, NULL, &dest_name);
6481
6482 if (!IO_VALID(reply)) {
6483 reply_name = CAST_MACH_PORT_TO_NAME(reply);
6484 } else if (ip_is_reply_port(ip_object_to_port(reply))) {
6485 mach_msg_return_t reply_mr;
6486 reply_mr = ipc_kmsg_copyout_reply_object(space, reply, &reply_type, &reply_name);
6487 mr = mr | reply_mr;
6488 if (reply_mr == MACH_MSG_SUCCESS) {
6489 mbits = MACH_MSGH_BITS_SET(dest_type, reply_type, voucher_type, MACH_MSGH_BITS_OTHER(mbits));
6490 }
6491 } else {
6492 mr = mr | ipc_kmsg_copyout_object(space, reply, reply_type, NULL, NULL, &reply_name);
6493 }
6494
6495 hdr->msgh_bits = mbits & MACH_MSGH_BITS_USER;
6496 hdr->msgh_remote_port = CAST_MACH_NAME_TO_PORT(dest_name);
6497 hdr->msgh_local_port = CAST_MACH_NAME_TO_PORT(reply_name);
6498
6499 /* restore the voucher:
6500 * If it was copied in via move-send, have to put back a voucher send right.
6501 *
6502 * If it was copied in via copy-send, the header still contains the old voucher name.
6503 * Restore the type and discard the copied-in/pre-processed voucher.
6504 */
6505 if (IO_VALID(voucher)) {
6506 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
6507 if (kmsg->ikm_voucher_type == MACH_MSG_TYPE_MOVE_SEND) {
6508 mr |= ipc_kmsg_copyout_object(space, voucher, voucher_type, NULL, NULL, &voucher_name);
6509 hdr->msgh_voucher_port = voucher_name;
6510 } else {
6511 assert(kmsg->ikm_voucher_type == MACH_MSG_TYPE_COPY_SEND);
6512 hdr->msgh_bits = MACH_MSGH_BITS_SET(dest_type, reply_type, MACH_MSG_TYPE_COPY_SEND,
6513 MACH_MSGH_BITS_OTHER(hdr->msgh_bits));
6514 ipc_object_destroy(voucher, voucher_type);
6515 }
6516 ipc_kmsg_clear_voucher_port(kmsg);
6517 }
6518
6519 if (mbits & MACH_MSGH_BITS_COMPLEX) {
6520 mr |= ipc_kmsg_copyout_body(kmsg, space, map, 0);
6521 }
6522
6523 current_thread()->ith_knote = ITH_KNOTE_NULL;
6524
6525 return mr;
6526 }
6527
6528 /*
6529 * Routine: ipc_kmsg_copyout_dest_to_user
6530 * Purpose:
6531 * Copies out the destination port in the message.
6532 * Destroys all other rights and memory in the message.
6533 * Conditions:
6534 * Nothing locked.
6535 */
6536
6537 void
ipc_kmsg_copyout_dest_to_user(ipc_kmsg_t kmsg,ipc_space_t space)6538 ipc_kmsg_copyout_dest_to_user(
6539 ipc_kmsg_t kmsg,
6540 ipc_space_t space)
6541 {
6542 mach_msg_bits_t mbits;
6543 ipc_object_t dest;
6544 ipc_object_t reply;
6545 ipc_object_t voucher;
6546 mach_msg_type_name_t dest_type;
6547 mach_msg_type_name_t reply_type;
6548 mach_msg_type_name_t voucher_type;
6549 mach_port_name_t dest_name, reply_name, voucher_name;
6550 mach_msg_header_t *hdr;
6551
6552 ikm_validate_sig(kmsg);
6553
6554 hdr = ikm_header(kmsg);
6555 mbits = hdr->msgh_bits;
6556 dest = ip_to_object(hdr->msgh_remote_port);
6557 reply = ip_to_object(hdr->msgh_local_port);
6558 voucher = ip_to_object(ipc_kmsg_get_voucher_port(kmsg));
6559 voucher_name = hdr->msgh_voucher_port;
6560 dest_type = MACH_MSGH_BITS_REMOTE(mbits);
6561 reply_type = MACH_MSGH_BITS_LOCAL(mbits);
6562 voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
6563
6564 assert(IO_VALID(dest));
6565
6566 ipc_importance_assert_clean(kmsg);
6567
6568 io_lock(dest);
6569 if (io_active(dest)) {
6570 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
6571 /* dest is unlocked */
6572 } else {
6573 io_unlock(dest);
6574 io_release(dest);
6575 dest_name = MACH_PORT_DEAD;
6576 }
6577
6578 if (IO_VALID(reply)) {
6579 ipc_object_destroy(reply, reply_type);
6580 reply_name = MACH_PORT_NULL;
6581 } else {
6582 reply_name = CAST_MACH_PORT_TO_NAME(reply);
6583 }
6584
6585 if (IO_VALID(voucher)) {
6586 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
6587 ipc_object_destroy(voucher, voucher_type);
6588 ipc_kmsg_clear_voucher_port(kmsg);
6589 voucher_name = MACH_PORT_NULL;
6590 }
6591
6592 hdr->msgh_bits = MACH_MSGH_BITS_SET(reply_type, dest_type,
6593 voucher_type, mbits);
6594 hdr->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
6595 hdr->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
6596 hdr->msgh_voucher_port = voucher_name;
6597
6598 if (mbits & MACH_MSGH_BITS_COMPLEX) {
6599 mach_msg_body_t *body;
6600
6601 body = (mach_msg_body_t *) (hdr + 1);
6602 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count,
6603 (mach_msg_descriptor_t *)(body + 1));
6604 }
6605 }
6606
6607 /*
6608 * Routine: ipc_kmsg_copyout_dest_to_kernel
6609 * Purpose:
6610 * Copies out the destination and reply ports in the message.
6611 * Leaves all other rights and memory in the message alone.
6612 * Conditions:
6613 * Nothing locked.
6614 *
6615 * Derived from ipc_kmsg_copyout_dest_to_user.
6616 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
6617 * We really do want to save rights and memory.
6618 */
6619
6620 void
ipc_kmsg_copyout_dest_to_kernel(ipc_kmsg_t kmsg,ipc_space_t space)6621 ipc_kmsg_copyout_dest_to_kernel(
6622 ipc_kmsg_t kmsg,
6623 ipc_space_t space)
6624 {
6625 ipc_object_t dest;
6626 mach_port_t reply;
6627 mach_msg_type_name_t dest_type;
6628 mach_msg_type_name_t reply_type;
6629 mach_port_name_t dest_name;
6630 mach_msg_header_t *hdr;
6631
6632 ikm_validate_sig(kmsg);
6633
6634 hdr = ikm_header(kmsg);
6635 dest = ip_to_object(hdr->msgh_remote_port);
6636 reply = hdr->msgh_local_port;
6637 dest_type = MACH_MSGH_BITS_REMOTE(hdr->msgh_bits);
6638 reply_type = MACH_MSGH_BITS_LOCAL(hdr->msgh_bits);
6639
6640 assert(IO_VALID(dest));
6641
6642 io_lock(dest);
6643 if (io_active(dest)) {
6644 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
6645 /* dest is unlocked */
6646 } else {
6647 io_unlock(dest);
6648 io_release(dest);
6649 dest_name = MACH_PORT_DEAD;
6650 }
6651
6652 /*
6653 * While MIG kernel users don't receive vouchers, the
6654 * msgh_voucher_port field is intended to be round-tripped through the
6655 * kernel if there is no voucher disposition set. Here we check for a
6656 * non-zero voucher disposition, and consume the voucher send right as
6657 * there is no possible way to specify MACH_RCV_VOUCHER semantics.
6658 */
6659 mach_msg_type_name_t voucher_type;
6660 voucher_type = MACH_MSGH_BITS_VOUCHER(hdr->msgh_bits);
6661 if (voucher_type != MACH_MSGH_BITS_ZERO) {
6662 ipc_port_t voucher = ipc_kmsg_get_voucher_port(kmsg);
6663
6664 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
6665 /*
6666 * someone managed to send this kernel routine a message with
6667 * a voucher in it. Cleanup the reference in
6668 * kmsg->ikm_voucher.
6669 */
6670 if (IP_VALID(voucher)) {
6671 ipc_port_release_send(voucher);
6672 }
6673 hdr->msgh_voucher_port = 0;
6674 ipc_kmsg_clear_voucher_port(kmsg);
6675 }
6676
6677 hdr->msgh_bits =
6678 (MACH_MSGH_BITS_OTHER(hdr->msgh_bits) |
6679 MACH_MSGH_BITS(reply_type, dest_type));
6680 hdr->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
6681 hdr->msgh_remote_port = reply;
6682 }
6683
6684 /*
6685 * Caller has a reference to the kmsg and the mqueue lock held.
6686 *
6687 * As such, we can safely return a pointer to the thread group in the kmsg and
6688 * not an additional reference. It is up to the caller to decide to take an
6689 * additional reference on the thread group while still holding the mqueue lock,
6690 * if needed.
6691 */
6692 #if CONFIG_PREADOPT_TG
6693 struct thread_group *
ipc_kmsg_get_thread_group(ipc_kmsg_t kmsg)6694 ipc_kmsg_get_thread_group(ipc_kmsg_t kmsg)
6695 {
6696 struct thread_group *tg = NULL;
6697 kern_return_t __assert_only kr;
6698
6699 ipc_voucher_t voucher = convert_port_to_voucher(ipc_kmsg_get_voucher_port(kmsg));
6700 kr = bank_get_preadopt_thread_group(voucher, &tg);
6701 ipc_voucher_release(voucher);
6702
6703 return tg;
6704 }
6705 #endif
6706
6707 #ifdef __arm64__
6708 /*
6709 * Just sets those parts of the trailer that aren't set up at allocation time.
6710 */
6711 static void
ipc_kmsg_munge_trailer(mach_msg_max_trailer_t * in,void * _out,boolean_t is64bit)6712 ipc_kmsg_munge_trailer(mach_msg_max_trailer_t *in, void *_out, boolean_t is64bit)
6713 {
6714 if (is64bit) {
6715 mach_msg_max_trailer64_t *out = (mach_msg_max_trailer64_t*)_out;
6716 out->msgh_seqno = in->msgh_seqno;
6717 out->msgh_context = in->msgh_context;
6718 out->msgh_trailer_size = in->msgh_trailer_size;
6719 out->msgh_ad = in->msgh_ad;
6720 } else {
6721 mach_msg_max_trailer32_t *out = (mach_msg_max_trailer32_t*)_out;
6722 out->msgh_seqno = in->msgh_seqno;
6723 out->msgh_context = (mach_port_context32_t)in->msgh_context;
6724 out->msgh_trailer_size = in->msgh_trailer_size;
6725 out->msgh_ad = in->msgh_ad;
6726 }
6727 }
6728 #endif /* __arm64__ */
6729
6730 mach_msg_trailer_size_t
ipc_kmsg_trailer_size(mach_msg_option_t option,__unused thread_t thread)6731 ipc_kmsg_trailer_size(
6732 mach_msg_option_t option,
6733 __unused thread_t thread)
6734 {
6735 if (!(option & MACH_RCV_TRAILER_MASK)) {
6736 return MACH_MSG_TRAILER_MINIMUM_SIZE;
6737 } else {
6738 return REQUESTED_TRAILER_SIZE(thread_is_64bit_addr(thread), option);
6739 }
6740 }
6741
6742 /*
6743 * Routine: ipc_kmsg_init_trailer
6744 * Purpose:
6745 * Initiailizes a trailer in a message safely.
6746 */
6747 void
ipc_kmsg_init_trailer(ipc_kmsg_t kmsg,task_t sender)6748 ipc_kmsg_init_trailer(
6749 ipc_kmsg_t kmsg,
6750 task_t sender)
6751 {
6752 static const mach_msg_max_trailer_t KERNEL_TRAILER_TEMPLATE = {
6753 .msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0,
6754 .msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE,
6755 .msgh_sender = KERNEL_SECURITY_TOKEN_VALUE,
6756 .msgh_audit = KERNEL_AUDIT_TOKEN_VALUE
6757 };
6758
6759 mach_msg_max_trailer_t *trailer;
6760
6761 /*
6762 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
6763 * However, the internal size field of the trailer (msgh_trailer_size)
6764 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
6765 * the cases where no implicit data is requested.
6766 */
6767 trailer = ipc_kmsg_get_trailer(kmsg, false);
6768 if (sender == TASK_NULL) {
6769 memcpy(trailer, &KERNEL_TRAILER_TEMPLATE, sizeof(*trailer));
6770 } else {
6771 bzero(trailer, sizeof(*trailer));
6772 trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
6773 trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
6774 trailer->msgh_sender = *task_get_sec_token(sender);
6775 trailer->msgh_audit = *task_get_audit_token(sender);
6776 }
6777 }
6778
6779
6780 void
ipc_kmsg_add_trailer(ipc_kmsg_t kmsg,ipc_space_t space __unused,mach_msg_option_t option,__unused thread_t thread,mach_port_seqno_t seqno,boolean_t minimal_trailer,mach_vm_offset_t context)6781 ipc_kmsg_add_trailer(ipc_kmsg_t kmsg, ipc_space_t space __unused,
6782 mach_msg_option_t option, __unused thread_t thread,
6783 mach_port_seqno_t seqno, boolean_t minimal_trailer,
6784 mach_vm_offset_t context)
6785 {
6786 mach_msg_max_trailer_t *trailer;
6787
6788 #ifdef __arm64__
6789 mach_msg_max_trailer_t tmp_trailer; /* This accommodates U64, and we'll munge */
6790
6791 /*
6792 * If we are building a minimal_trailer, that means we have not attempted to
6793 * copy out message body (which converts descriptors to user sizes) because
6794 * we are coming from msg_receive_error().
6795 *
6796 * Adjust trailer calculation accordingly.
6797 */
6798 void *real_trailer_out = (void*)ipc_kmsg_get_trailer(kmsg, !minimal_trailer);
6799
6800 /*
6801 * Populate scratch with initial values set up at message allocation time.
6802 * After, we reinterpret the space in the message as the right type
6803 * of trailer for the address space in question.
6804 */
6805 bcopy(real_trailer_out, &tmp_trailer, MAX_TRAILER_SIZE);
6806 trailer = &tmp_trailer;
6807 #else /* __arm64__ */
6808 (void)thread;
6809 trailer = ipc_kmsg_get_trailer(kmsg, !minimal_trailer);
6810 #endif /* __arm64__ */
6811
6812 if (!(option & MACH_RCV_TRAILER_MASK)) {
6813 return;
6814 }
6815
6816 trailer->msgh_seqno = seqno;
6817 trailer->msgh_context = context;
6818 trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit_addr(thread), option);
6819
6820 if (minimal_trailer) {
6821 goto done;
6822 }
6823
6824 if (GET_RCV_ELEMENTS(option) >= MACH_RCV_TRAILER_AV) {
6825 trailer->msgh_ad = 0;
6826 }
6827
6828 /*
6829 * The ipc_kmsg_t holds a reference to the label of a label
6830 * handle, not the port. We must get a reference to the port
6831 * and a send right to copyout to the receiver.
6832 */
6833
6834 if (option & MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_LABELS)) {
6835 trailer->msgh_labels.sender = 0;
6836 }
6837
6838 done:
6839 #ifdef __arm64__
6840 ipc_kmsg_munge_trailer(trailer, real_trailer_out, thread_is_64bit_addr(thread));
6841 #endif /* __arm64__ */
6842 return;
6843 }
6844
6845 /*
6846 * Get the trailer address of kmsg.
6847 *
6848 * - body_copied_out: Whether ipc_kmsg_copyout_body() has been called.
6849 * If true, descriptors in kmsg has been converted to user size.
6850 *
6851 * /!\ WARNING /!\
6852 * Should not be used after ipc_kmsg_convert_header_to_user() is called.
6853 */
6854 mach_msg_max_trailer_t *
ipc_kmsg_get_trailer(ipc_kmsg_t kmsg,bool body_copied_out)6855 ipc_kmsg_get_trailer(
6856 ipc_kmsg_t kmsg,
6857 bool body_copied_out) /* is kmsg body copyout attempted */
6858 {
6859 mach_msg_header_t *hdr = ikm_header(kmsg);
6860
6861 if (ikm_is_linear(kmsg)) {
6862 return (mach_msg_max_trailer_t *)((vm_offset_t)hdr +
6863 mach_round_msg(hdr->msgh_size));
6864 } else {
6865 assert(kmsg->ikm_udata != NULL);
6866 return (mach_msg_max_trailer_t *)((vm_offset_t)kmsg->ikm_udata +
6867 ikm_content_size(kmsg, current_map(), 0, body_copied_out));
6868 }
6869 }
6870
6871 void
ipc_kmsg_set_voucher_port(ipc_kmsg_t kmsg,ipc_port_t voucher_port,mach_msg_type_name_t type)6872 ipc_kmsg_set_voucher_port(
6873 ipc_kmsg_t kmsg,
6874 ipc_port_t voucher_port,
6875 mach_msg_type_name_t type)
6876 {
6877 if (IP_VALID(voucher_port)) {
6878 assert(ip_kotype(voucher_port) == IKOT_VOUCHER);
6879 }
6880 kmsg->ikm_voucher_port = voucher_port;
6881 kmsg->ikm_voucher_type = type;
6882 }
6883
6884 ipc_port_t
ipc_kmsg_get_voucher_port(ipc_kmsg_t kmsg)6885 ipc_kmsg_get_voucher_port(ipc_kmsg_t kmsg)
6886 {
6887 return kmsg->ikm_voucher_port;
6888 }
6889
6890 void
ipc_kmsg_clear_voucher_port(ipc_kmsg_t kmsg)6891 ipc_kmsg_clear_voucher_port(ipc_kmsg_t kmsg)
6892 {
6893 kmsg->ikm_voucher_port = IP_NULL;
6894 kmsg->ikm_voucher_type = MACH_MSGH_BITS_ZERO;
6895 }
6896