]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ipc/ipc_kmsg.c
xnu-3248.20.55.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_kmsg.c
1 /*
2 * Copyright (c) 2000-2007 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 Software.Distribution@CS.CMU.EDU
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/sched_prim.h>
92 #include <kern/spl.h>
93 #include <kern/misc_protos.h>
94 #include <kern/counters.h>
95 #include <kern/cpu_data.h>
96
97 #include <machine/machlimits.h>
98
99 #include <vm/vm_map.h>
100 #include <vm/vm_object.h>
101 #include <vm/vm_kern.h>
102
103 #include <ipc/port.h>
104 #include <ipc/ipc_types.h>
105 #include <ipc/ipc_entry.h>
106 #include <ipc/ipc_kmsg.h>
107 #include <ipc/ipc_notify.h>
108 #include <ipc/ipc_object.h>
109 #include <ipc/ipc_space.h>
110 #include <ipc/ipc_port.h>
111 #include <ipc/ipc_right.h>
112 #include <ipc/ipc_hash.h>
113 #include <ipc/ipc_table.h>
114 #include <ipc/ipc_importance.h>
115
116 #include <security/mac_mach_internal.h>
117
118 #include <string.h>
119
120 #ifdef ppc
121 #include <ppc/Firmware.h>
122 #include <ppc/low_trace.h>
123 #endif
124
125 #if DEBUG
126 #define DEBUG_MSGS_K64 1
127 #endif
128
129 #include <sys/kdebug.h>
130 #include <libkern/OSAtomic.h>
131
132 #pragma pack(4)
133
134 typedef struct
135 {
136 mach_msg_bits_t msgh_bits;
137 mach_msg_size_t msgh_size;
138 mach_port_name_t msgh_remote_port;
139 mach_port_name_t msgh_local_port;
140 mach_port_name_t msgh_voucher_port;
141 mach_msg_id_t msgh_id;
142 } mach_msg_legacy_header_t;
143
144 typedef struct
145 {
146 mach_msg_legacy_header_t header;
147 mach_msg_body_t body;
148 } mach_msg_legacy_base_t;
149
150 typedef struct
151 {
152 mach_port_name_t name;
153 mach_msg_size_t pad1;
154 uint32_t pad2 : 16;
155 mach_msg_type_name_t disposition : 8;
156 mach_msg_descriptor_type_t type : 8;
157 } mach_msg_legacy_port_descriptor_t;
158
159
160 typedef union
161 {
162 mach_msg_legacy_port_descriptor_t port;
163 mach_msg_ool_descriptor32_t out_of_line32;
164 mach_msg_ool_ports_descriptor32_t ool_ports32;
165 mach_msg_type_descriptor_t type;
166 } mach_msg_legacy_descriptor_t;
167
168 #pragma pack()
169
170 #define LEGACY_HEADER_SIZE_DELTA ((mach_msg_size_t)(sizeof(mach_msg_header_t) - sizeof(mach_msg_legacy_header_t)))
171
172 // END LP64 fixes
173
174
175 #if DEBUG_MSGS_K64
176 extern void ipc_pset_print64(
177 ipc_pset_t pset);
178
179 extern void ipc_kmsg_print64(
180 ipc_kmsg_t kmsg,
181 const char *str);
182
183 extern void ipc_msg_print64(
184 mach_msg_header_t *msgh);
185
186 extern ipc_port_t ipc_name_to_data64(
187 task_t task,
188 mach_port_name_t name);
189
190 /*
191 * Forward declarations
192 */
193 void ipc_msg_print_untyped64(
194 mach_msg_body_t *body);
195
196 const char * ipc_type_name64(
197 int type_name,
198 boolean_t received);
199
200 void ipc_print_type_name64(
201 int type_name);
202
203 const char *
204 msgh_bit_decode64(
205 mach_msg_bits_t bit);
206
207 const char *
208 mm_copy_options_string64(
209 mach_msg_copy_options_t option);
210
211 void db_print_msg_uid64(mach_msg_header_t *);
212
213 static void
214 ipc_msg_body_print64(void *body, int size)
215 {
216 uint32_t *word = (uint32_t *) body;
217 uint32_t *end = (uint32_t *)(((uintptr_t) body) + size
218 - sizeof(mach_msg_header_t));
219 int i;
220
221 kprintf(" body(%p-%p):\n %p: ", body, end, word);
222 for (;;) {
223 for (i = 0; i < 8; i++, word++) {
224 if (word >= end) {
225 kprintf("\n");
226 return;
227 }
228 kprintf("%08x ", *word);
229 }
230 kprintf("\n %p: ", word);
231 }
232 }
233
234
235 const char *
236 ipc_type_name64(
237 int type_name,
238 boolean_t received)
239 {
240 switch (type_name) {
241 case MACH_MSG_TYPE_PORT_NAME:
242 return "port_name";
243
244 case MACH_MSG_TYPE_MOVE_RECEIVE:
245 if (received) {
246 return "port_receive";
247 } else {
248 return "move_receive";
249 }
250
251 case MACH_MSG_TYPE_MOVE_SEND:
252 if (received) {
253 return "port_send";
254 } else {
255 return "move_send";
256 }
257
258 case MACH_MSG_TYPE_MOVE_SEND_ONCE:
259 if (received) {
260 return "port_send_once";
261 } else {
262 return "move_send_once";
263 }
264
265 case MACH_MSG_TYPE_COPY_SEND:
266 return "copy_send";
267
268 case MACH_MSG_TYPE_MAKE_SEND:
269 return "make_send";
270
271 case MACH_MSG_TYPE_MAKE_SEND_ONCE:
272 return "make_send_once";
273
274 default:
275 return (char *) 0;
276 }
277 }
278
279 void
280 ipc_print_type_name64(
281 int type_name)
282 {
283 const char *name = ipc_type_name64(type_name, TRUE);
284 if (name) {
285 kprintf("%s", name);
286 } else {
287 kprintf("type%d", type_name);
288 }
289 }
290
291 /*
292 * ipc_kmsg_print64 [ debug ]
293 */
294 void
295 ipc_kmsg_print64(
296 ipc_kmsg_t kmsg,
297 const char *str)
298 {
299 kprintf("%s kmsg=%p:\n", str, kmsg);
300 kprintf(" next=%p, prev=%p, size=%d",
301 kmsg->ikm_next,
302 kmsg->ikm_prev,
303 kmsg->ikm_size);
304 kprintf("\n");
305 ipc_msg_print64(kmsg->ikm_header);
306 }
307
308 const char *
309 msgh_bit_decode64(
310 mach_msg_bits_t bit)
311 {
312 switch (bit) {
313 case MACH_MSGH_BITS_COMPLEX: return "complex";
314 case MACH_MSGH_BITS_CIRCULAR: return "circular";
315 default: return (char *) 0;
316 }
317 }
318
319 /*
320 * ipc_msg_print64 [ debug ]
321 */
322 void
323 ipc_msg_print64(
324 mach_msg_header_t *msgh)
325 {
326 mach_msg_bits_t mbits;
327 unsigned int bit, i;
328 const char *bit_name;
329 int needs_comma;
330
331 mbits = msgh->msgh_bits;
332 kprintf(" msgh_bits=0x%x: l=0x%x,r=0x%x\n",
333 mbits,
334 MACH_MSGH_BITS_LOCAL(msgh->msgh_bits),
335 MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
336
337 mbits = MACH_MSGH_BITS_OTHER(mbits) & MACH_MSGH_BITS_USED;
338 kprintf(" decoded bits: ");
339 needs_comma = 0;
340 for (i = 0, bit = 1; i < sizeof(mbits) * 8; ++i, bit <<= 1) {
341 if ((mbits & bit) == 0)
342 continue;
343 bit_name = msgh_bit_decode64((mach_msg_bits_t)bit);
344 if (bit_name)
345 kprintf("%s%s", needs_comma ? "," : "", bit_name);
346 else
347 kprintf("%sunknown(0x%x),", needs_comma ? "," : "", bit);
348 ++needs_comma;
349 }
350 if (msgh->msgh_bits & ~MACH_MSGH_BITS_USED) {
351 kprintf("%sunused=0x%x,", needs_comma ? "," : "",
352 msgh->msgh_bits & ~MACH_MSGH_BITS_USED);
353 }
354 kprintf("\n");
355
356 needs_comma = 1;
357 if (msgh->msgh_remote_port) {
358 kprintf(" remote=%p(", msgh->msgh_remote_port);
359 ipc_print_type_name64(MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
360 kprintf(")");
361 } else {
362 kprintf(" remote=null");
363 }
364
365 if (msgh->msgh_local_port) {
366 kprintf("%slocal=%p(", needs_comma ? "," : "",
367 msgh->msgh_local_port);
368 ipc_print_type_name64(MACH_MSGH_BITS_LOCAL(msgh->msgh_bits));
369 kprintf(")\n");
370 } else {
371 kprintf("local=null\n");
372 }
373
374 kprintf(" msgh_id=%d, size=%d\n",
375 msgh->msgh_id,
376 msgh->msgh_size);
377
378 if (mbits & MACH_MSGH_BITS_COMPLEX) {
379 ipc_msg_print_untyped64((mach_msg_body_t *) (msgh + 1));
380 }
381
382 ipc_msg_body_print64((void *)(msgh + 1), msgh->msgh_size);
383 }
384
385
386 const char *
387 mm_copy_options_string64(
388 mach_msg_copy_options_t option)
389 {
390 const char *name;
391
392 switch (option) {
393 case MACH_MSG_PHYSICAL_COPY:
394 name = "PHYSICAL";
395 break;
396 case MACH_MSG_VIRTUAL_COPY:
397 name = "VIRTUAL";
398 break;
399 case MACH_MSG_OVERWRITE:
400 name = "OVERWRITE(DEPRECATED)";
401 break;
402 case MACH_MSG_ALLOCATE:
403 name = "ALLOCATE";
404 break;
405 case MACH_MSG_KALLOC_COPY_T:
406 name = "KALLOC_COPY_T";
407 break;
408 default:
409 name = "unknown";
410 break;
411 }
412 return name;
413 }
414
415 void
416 ipc_msg_print_untyped64(
417 mach_msg_body_t *body)
418 {
419 mach_msg_descriptor_t *saddr, *send;
420 mach_msg_descriptor_type_t type;
421
422 kprintf(" %d descriptors: \n", body->msgh_descriptor_count);
423
424 saddr = (mach_msg_descriptor_t *) (body + 1);
425 send = saddr + body->msgh_descriptor_count;
426
427 for ( ; saddr < send; saddr++ ) {
428
429 type = saddr->type.type;
430
431 switch (type) {
432
433 case MACH_MSG_PORT_DESCRIPTOR: {
434 mach_msg_port_descriptor_t *dsc;
435
436 dsc = &saddr->port;
437 kprintf(" PORT name = %p disp = ", dsc->name);
438 ipc_print_type_name64(dsc->disposition);
439 kprintf("\n");
440 break;
441 }
442 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
443 case MACH_MSG_OOL_DESCRIPTOR: {
444 mach_msg_ool_descriptor_t *dsc;
445
446 dsc = (mach_msg_ool_descriptor_t *) &saddr->out_of_line;
447 kprintf(" OOL%s addr = %p size = 0x%x copy = %s %s\n",
448 type == MACH_MSG_OOL_DESCRIPTOR ? "" : " VOLATILE",
449 dsc->address, dsc->size,
450 mm_copy_options_string64(dsc->copy),
451 dsc->deallocate ? "DEALLOC" : "");
452 break;
453 }
454 case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
455 mach_msg_ool_ports_descriptor_t *dsc;
456
457 dsc = (mach_msg_ool_ports_descriptor_t *) &saddr->ool_ports;
458
459 kprintf(" OOL_PORTS addr = %p count = 0x%x ",
460 dsc->address, dsc->count);
461 kprintf("disp = ");
462 ipc_print_type_name64(dsc->disposition);
463 kprintf(" copy = %s %s\n",
464 mm_copy_options_string64(dsc->copy),
465 dsc->deallocate ? "DEALLOC" : "");
466 break;
467 }
468
469 default: {
470 kprintf(" UNKNOWN DESCRIPTOR 0x%x\n", type);
471 break;
472 }
473 }
474 }
475 }
476
477 #define DEBUG_IPC_KMSG_PRINT(kmsg,string) \
478 __unreachable_ok_push \
479 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \
480 ipc_kmsg_print64(kmsg, string); \
481 } \
482 __unreachable_ok_pop
483
484 #define DEBUG_IPC_MSG_BODY_PRINT(body,size) \
485 __unreachable_ok_push \
486 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \
487 ipc_msg_body_print64(body,size);\
488 } \
489 __unreachable_ok_pop
490 #else /* !DEBUG_MSGS_K64 */
491 #define DEBUG_IPC_KMSG_PRINT(kmsg,string)
492 #define DEBUG_IPC_MSG_BODY_PRINT(body,size)
493 #endif /* !DEBUG_MSGS_K64 */
494
495 extern vm_map_t ipc_kernel_copy_map;
496 extern vm_size_t ipc_kmsg_max_space;
497 extern vm_size_t ipc_kmsg_max_vm_space;
498 extern vm_size_t ipc_kmsg_max_body_space;
499 extern vm_size_t msg_ool_size_small;
500
501 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
502
503 #if defined(__LP64__)
504 #define MAP_SIZE_DIFFERS(map) (map->max_offset < MACH_VM_MAX_ADDRESS)
505 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor32_t
506 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor32_t
507 #else
508 #define MAP_SIZE_DIFFERS(map) (map->max_offset > VM_MAX_ADDRESS)
509 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor64_t
510 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor64_t
511 #endif
512
513 #define DESC_SIZE_ADJUSTMENT ((mach_msg_size_t)(sizeof(mach_msg_ool_descriptor64_t) - \
514 sizeof(mach_msg_ool_descriptor32_t)))
515
516 /* scatter list macros */
517
518 #define SKIP_PORT_DESCRIPTORS(s, c) \
519 MACRO_BEGIN \
520 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
521 while ((c) > 0) { \
522 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \
523 break; \
524 (s)++; (c)--; \
525 } \
526 if (c == 0) \
527 (s) = MACH_MSG_DESCRIPTOR_NULL; \
528 } \
529 MACRO_END
530
531 #define INCREMENT_SCATTER(s, c, d) \
532 MACRO_BEGIN \
533 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
534 s = (d) ? (mach_msg_descriptor_t *) \
535 ((OTHER_OOL_DESCRIPTOR *)(s) + 1) : \
536 (s + 1); \
537 (c)--; \
538 } \
539 MACRO_END
540
541 /* zone for cached ipc_kmsg_t structures */
542 zone_t ipc_kmsg_zone;
543
544 /*
545 * Forward declarations
546 */
547
548 void ipc_kmsg_clean(
549 ipc_kmsg_t kmsg);
550
551 void ipc_kmsg_clean_body(
552 ipc_kmsg_t kmsg,
553 mach_msg_type_number_t number,
554 mach_msg_descriptor_t *desc);
555
556 void ipc_kmsg_clean_partial(
557 ipc_kmsg_t kmsg,
558 mach_msg_type_number_t number,
559 mach_msg_descriptor_t *desc,
560 vm_offset_t paddr,
561 vm_size_t length);
562
563 mach_msg_return_t ipc_kmsg_copyin_body(
564 ipc_kmsg_t kmsg,
565 ipc_space_t space,
566 vm_map_t map);
567
568 /*
569 * We keep a per-processor cache of kernel message buffers.
570 * The cache saves the overhead/locking of using kalloc/kfree.
571 * The per-processor cache seems to miss less than a per-thread cache,
572 * and it also uses less memory. Access to the cache doesn't
573 * require locking.
574 */
575
576 /*
577 * Routine: ipc_kmsg_alloc
578 * Purpose:
579 * Allocate a kernel message structure. If we can get one from
580 * the cache, that is best. Otherwise, allocate a new one.
581 * Conditions:
582 * Nothing locked.
583 */
584 ipc_kmsg_t
585 ipc_kmsg_alloc(
586 mach_msg_size_t msg_and_trailer_size)
587 {
588 mach_msg_size_t max_expanded_size;
589 ipc_kmsg_t kmsg;
590
591 /*
592 * LP64support -
593 * Pad the allocation in case we need to expand the
594 * message descrptors for user spaces with pointers larger than
595 * the kernel's own, or vice versa. We don't know how many descriptors
596 * there are yet, so just assume the whole body could be
597 * descriptors (if there could be any at all).
598 *
599 * The expansion space is left in front of the header,
600 * because it is easier to pull the header and descriptors
601 * forward as we process them than it is to push all the
602 * data backwards.
603 */
604 mach_msg_size_t size = msg_and_trailer_size - MAX_TRAILER_SIZE;
605
606 /* compare against implementation upper limit for the body */
607 if (size > ipc_kmsg_max_body_space)
608 return IKM_NULL;
609
610 if (size > sizeof(mach_msg_base_t)) {
611 mach_msg_size_t max_desc = (mach_msg_size_t)(((size - sizeof(mach_msg_base_t)) /
612 sizeof(mach_msg_ool_descriptor32_t)) *
613 DESC_SIZE_ADJUSTMENT);
614
615 /* make sure expansion won't cause wrap */
616 if (msg_and_trailer_size > MACH_MSG_SIZE_MAX - max_desc)
617 return IKM_NULL;
618
619 max_expanded_size = msg_and_trailer_size + max_desc;
620 } else
621 max_expanded_size = msg_and_trailer_size;
622
623 if (max_expanded_size < IKM_SAVED_MSG_SIZE)
624 max_expanded_size = IKM_SAVED_MSG_SIZE; /* round up for ikm_cache */
625
626 if (max_expanded_size == IKM_SAVED_MSG_SIZE) {
627 struct ikm_cache *cache;
628 unsigned int i;
629
630 disable_preemption();
631 cache = &PROCESSOR_DATA(current_processor(), ikm_cache);
632 if ((i = cache->avail) > 0) {
633 assert(i <= IKM_STASH);
634 kmsg = cache->entries[--i];
635 cache->avail = i;
636 enable_preemption();
637 ikm_check_init(kmsg, max_expanded_size);
638 ikm_set_header(kmsg, msg_and_trailer_size);
639 return (kmsg);
640 }
641 enable_preemption();
642 kmsg = (ipc_kmsg_t)zalloc(ipc_kmsg_zone);
643 } else {
644 kmsg = (ipc_kmsg_t)kalloc(ikm_plus_overhead(max_expanded_size));
645 }
646
647 if (kmsg != IKM_NULL) {
648 ikm_init(kmsg, max_expanded_size);
649 ikm_set_header(kmsg, msg_and_trailer_size);
650 }
651
652 return(kmsg);
653 }
654
655 /*
656 * Routine: ipc_kmsg_free
657 * Purpose:
658 * Free a kernel message buffer. If the kms is preallocated
659 * to a port, just "put it back (marked unused)." We have to
660 * do this with the port locked. The port may have its hold
661 * on our message released. In that case, we have to just
662 * revert the message to a traditional one and free it normally.
663 * Conditions:
664 * Nothing locked.
665 */
666
667 void
668 ipc_kmsg_free(
669 ipc_kmsg_t kmsg)
670 {
671 mach_msg_size_t size = kmsg->ikm_size;
672 ipc_port_t port;
673
674 assert(!IP_VALID(kmsg->ikm_voucher));
675
676 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC,MACH_IPC_KMSG_FREE) | DBG_FUNC_NONE,
677 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
678 0, 0, 0, 0);
679
680 /*
681 * Check to see if the message is bound to the port. If so,
682 * mark it not in use. If the port isn't already dead, then
683 * leave the message associated with it. Otherwise, free it.
684 */
685 port = ikm_prealloc_inuse_port(kmsg);
686 if (port != IP_NULL) {
687 ip_lock(port);
688 ikm_prealloc_clear_inuse(kmsg, port);
689 if (ip_active(port) && (port->ip_premsg == kmsg)) {
690 assert(IP_PREALLOC(port));
691 ip_unlock(port);
692 ip_release(port);
693 return;
694 }
695 ip_unlock(port);
696 ip_release(port); /* May be last reference */
697 }
698
699 /*
700 * Peek and see if it has to go back in the cache.
701 */
702 if (kmsg->ikm_size == IKM_SAVED_MSG_SIZE) {
703 struct ikm_cache *cache;
704 unsigned int i;
705
706 disable_preemption();
707 cache = &PROCESSOR_DATA(current_processor(), ikm_cache);
708 if ((i = cache->avail) < IKM_STASH) {
709 cache->entries[i] = kmsg;
710 cache->avail = i + 1;
711 enable_preemption();
712 return;
713 }
714 enable_preemption();
715 zfree(ipc_kmsg_zone, kmsg);
716 return;
717 }
718 kfree(kmsg, ikm_plus_overhead(size));
719 }
720
721
722 /*
723 * Routine: ipc_kmsg_enqueue
724 * Purpose:
725 * Enqueue a kmsg.
726 */
727
728 void
729 ipc_kmsg_enqueue(
730 ipc_kmsg_queue_t queue,
731 ipc_kmsg_t kmsg)
732 {
733 ipc_kmsg_enqueue_macro(queue, kmsg);
734 }
735
736 /*
737 * Routine: ipc_kmsg_dequeue
738 * Purpose:
739 * Dequeue and return a kmsg.
740 */
741
742 ipc_kmsg_t
743 ipc_kmsg_dequeue(
744 ipc_kmsg_queue_t queue)
745 {
746 ipc_kmsg_t first;
747
748 first = ipc_kmsg_queue_first(queue);
749
750 if (first != IKM_NULL)
751 ipc_kmsg_rmqueue_first_macro(queue, first);
752
753 return first;
754 }
755
756 /*
757 * Routine: ipc_kmsg_rmqueue
758 * Purpose:
759 * Pull a kmsg out of a queue.
760 */
761
762 void
763 ipc_kmsg_rmqueue(
764 ipc_kmsg_queue_t queue,
765 ipc_kmsg_t kmsg)
766 {
767 ipc_kmsg_t next, prev;
768
769 assert(queue->ikmq_base != IKM_NULL);
770
771 next = kmsg->ikm_next;
772 prev = kmsg->ikm_prev;
773
774 if (next == kmsg) {
775 assert(prev == kmsg);
776 assert(queue->ikmq_base == kmsg);
777
778 queue->ikmq_base = IKM_NULL;
779 } else {
780 if (queue->ikmq_base == kmsg)
781 queue->ikmq_base = next;
782
783 next->ikm_prev = prev;
784 prev->ikm_next = next;
785 }
786 /* XXX Temporary debug logic */
787 assert((kmsg->ikm_next = IKM_BOGUS) == IKM_BOGUS);
788 assert((kmsg->ikm_prev = IKM_BOGUS) == IKM_BOGUS);
789 }
790
791 /*
792 * Routine: ipc_kmsg_queue_next
793 * Purpose:
794 * Return the kmsg following the given kmsg.
795 * (Or IKM_NULL if it is the last one in the queue.)
796 */
797
798 ipc_kmsg_t
799 ipc_kmsg_queue_next(
800 ipc_kmsg_queue_t queue,
801 ipc_kmsg_t kmsg)
802 {
803 ipc_kmsg_t next;
804
805 assert(queue->ikmq_base != IKM_NULL);
806
807 next = kmsg->ikm_next;
808 if (queue->ikmq_base == next)
809 next = IKM_NULL;
810
811 return next;
812 }
813
814 /*
815 * Routine: ipc_kmsg_destroy
816 * Purpose:
817 * Destroys a kernel message. Releases all rights,
818 * references, and memory held by the message.
819 * Frees the message.
820 * Conditions:
821 * No locks held.
822 */
823
824 void
825 ipc_kmsg_destroy(
826 ipc_kmsg_t kmsg)
827 {
828 /*
829 * Destroying a message can cause more messages to be destroyed.
830 * Curtail recursion by putting messages on the deferred
831 * destruction queue. If this was the first message on the
832 * queue, this instance must process the full queue.
833 */
834 if (ipc_kmsg_delayed_destroy(kmsg))
835 ipc_kmsg_reap_delayed();
836 }
837
838 /*
839 * Routine: ipc_kmsg_delayed_destroy
840 * Purpose:
841 * Enqueues a kernel message for deferred destruction.
842 * Returns:
843 * Boolean indicator that the caller is responsible to reap
844 * deferred messages.
845 */
846
847 boolean_t ipc_kmsg_delayed_destroy(
848 ipc_kmsg_t kmsg)
849 {
850 ipc_kmsg_queue_t queue = &(current_thread()->ith_messages);
851 boolean_t first = ipc_kmsg_queue_empty(queue);
852
853 ipc_kmsg_enqueue(queue, kmsg);
854 return first;
855 }
856
857 /*
858 * Routine: ipc_kmsg_destroy_queue
859 * Purpose:
860 * Destroys messages from the per-thread
861 * deferred reaping queue.
862 * Conditions:
863 * No locks held.
864 */
865
866 void
867 ipc_kmsg_reap_delayed(void)
868 {
869 ipc_kmsg_queue_t queue = &(current_thread()->ith_messages);
870 ipc_kmsg_t kmsg;
871
872 /*
873 * must leave kmsg in queue while cleaning it to assure
874 * no nested calls recurse into here.
875 */
876 while ((kmsg = ipc_kmsg_queue_first(queue)) != IKM_NULL) {
877 ipc_kmsg_clean(kmsg);
878 ipc_kmsg_rmqueue(queue, kmsg);
879 ipc_kmsg_free(kmsg);
880 }
881 }
882
883 /*
884 * Routine: ipc_kmsg_clean_body
885 * Purpose:
886 * Cleans the body of a kernel message.
887 * Releases all rights, references, and memory.
888 *
889 * Conditions:
890 * No locks held.
891 */
892 static unsigned int _ipc_kmsg_clean_invalid_desc = 0;
893 void
894 ipc_kmsg_clean_body(
895 __unused ipc_kmsg_t kmsg,
896 mach_msg_type_number_t number,
897 mach_msg_descriptor_t *saddr)
898 {
899 mach_msg_type_number_t i;
900
901 if ( number == 0 )
902 return;
903
904 for (i = 0 ; i < number; i++, saddr++ ) {
905
906 switch (saddr->type.type) {
907
908 case MACH_MSG_PORT_DESCRIPTOR: {
909 mach_msg_port_descriptor_t *dsc;
910
911 dsc = &saddr->port;
912
913 /*
914 * Destroy port rights carried in the message
915 */
916 if (!IO_VALID((ipc_object_t) dsc->name))
917 continue;
918 ipc_object_destroy((ipc_object_t) dsc->name, dsc->disposition);
919 break;
920 }
921 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
922 case MACH_MSG_OOL_DESCRIPTOR : {
923 mach_msg_ool_descriptor_t *dsc;
924
925 dsc = (mach_msg_ool_descriptor_t *)&saddr->out_of_line;
926
927 /*
928 * Destroy memory carried in the message
929 */
930 if (dsc->size == 0) {
931 assert(dsc->address == (void *) 0);
932 } else {
933 vm_map_copy_discard((vm_map_copy_t) dsc->address);
934 }
935 break;
936 }
937 case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
938 ipc_object_t *objects;
939 mach_msg_type_number_t j;
940 mach_msg_ool_ports_descriptor_t *dsc;
941
942 dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports;
943 objects = (ipc_object_t *) dsc->address;
944
945 if (dsc->count == 0) {
946 break;
947 }
948
949 assert(objects != (ipc_object_t *) 0);
950
951 /* destroy port rights carried in the message */
952
953 for (j = 0; j < dsc->count; j++) {
954 ipc_object_t object = objects[j];
955
956 if (!IO_VALID(object))
957 continue;
958
959 ipc_object_destroy(object, dsc->disposition);
960 }
961
962 /* destroy memory carried in the message */
963
964 assert(dsc->count != 0);
965
966 kfree(dsc->address,
967 (vm_size_t) dsc->count * sizeof(mach_port_t));
968 break;
969 }
970 default : {
971 _ipc_kmsg_clean_invalid_desc++; /* don't understand this type of descriptor */
972 }
973 }
974 }
975 }
976
977 /*
978 * Routine: ipc_kmsg_clean_partial
979 * Purpose:
980 * Cleans a partially-acquired kernel message.
981 * number is the index of the type descriptor
982 * in the body of the message that contained the error.
983 * If dolast, the memory and port rights in this last
984 * type spec are also cleaned. In that case, number
985 * specifies the number of port rights to clean.
986 * Conditions:
987 * Nothing locked.
988 */
989
990 void
991 ipc_kmsg_clean_partial(
992 ipc_kmsg_t kmsg,
993 mach_msg_type_number_t number,
994 mach_msg_descriptor_t *desc,
995 vm_offset_t paddr,
996 vm_size_t length)
997 {
998 ipc_object_t object;
999 mach_msg_bits_t mbits = kmsg->ikm_header->msgh_bits;
1000
1001 /* deal with importance chain while we still have dest and voucher references */
1002 ipc_importance_clean(kmsg);
1003
1004 object = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
1005 assert(IO_VALID(object));
1006 ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits));
1007
1008 object = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
1009 if (IO_VALID(object))
1010 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
1011
1012 object = (ipc_object_t) kmsg->ikm_voucher;
1013 if (IO_VALID(object)) {
1014 assert(MACH_MSGH_BITS_VOUCHER(mbits) == MACH_MSG_TYPE_MOVE_SEND);
1015 ipc_object_destroy(object, MACH_MSG_TYPE_PORT_SEND);
1016 kmsg->ikm_voucher = IP_NULL;
1017 }
1018
1019 if (paddr) {
1020 (void) vm_deallocate(ipc_kernel_copy_map, paddr, length);
1021 }
1022
1023 ipc_kmsg_clean_body(kmsg, number, desc);
1024 }
1025
1026 /*
1027 * Routine: ipc_kmsg_clean
1028 * Purpose:
1029 * Cleans a kernel message. Releases all rights,
1030 * references, and memory held by the message.
1031 * Conditions:
1032 * No locks held.
1033 */
1034
1035 void
1036 ipc_kmsg_clean(
1037 ipc_kmsg_t kmsg)
1038 {
1039 ipc_object_t object;
1040 mach_msg_bits_t mbits;
1041
1042 /* deal with importance chain while we still have dest and voucher references */
1043 ipc_importance_clean(kmsg);
1044
1045 mbits = kmsg->ikm_header->msgh_bits;
1046 object = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
1047 if (IO_VALID(object))
1048 ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits));
1049
1050 object = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
1051 if (IO_VALID(object))
1052 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
1053
1054 object = (ipc_object_t) kmsg->ikm_voucher;
1055 if (IO_VALID(object)) {
1056 assert(MACH_MSGH_BITS_VOUCHER(mbits) == MACH_MSG_TYPE_MOVE_SEND);
1057 ipc_object_destroy(object, MACH_MSG_TYPE_PORT_SEND);
1058 kmsg->ikm_voucher = IP_NULL;
1059 }
1060
1061 if (mbits & MACH_MSGH_BITS_COMPLEX) {
1062 mach_msg_body_t *body;
1063
1064 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
1065 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count,
1066 (mach_msg_descriptor_t *)(body + 1));
1067 }
1068 }
1069
1070 /*
1071 * Routine: ipc_kmsg_set_prealloc
1072 * Purpose:
1073 * Assign a kmsg as a preallocated message buffer to a port.
1074 * Conditions:
1075 * port locked.
1076 */
1077
1078 void
1079 ipc_kmsg_set_prealloc(
1080 ipc_kmsg_t kmsg,
1081 ipc_port_t port)
1082 {
1083 assert(kmsg->ikm_prealloc == IP_NULL);
1084
1085 kmsg->ikm_prealloc = IP_NULL;
1086 IP_SET_PREALLOC(port, kmsg);
1087 }
1088
1089 /*
1090 * Routine: ipc_kmsg_clear_prealloc
1091 * Purpose:
1092 * Release the Assignment of a preallocated message buffer from a port.
1093 * Conditions:
1094 * port locked.
1095 */
1096 void
1097 ipc_kmsg_clear_prealloc(
1098 ipc_kmsg_t kmsg,
1099 ipc_port_t port)
1100 {
1101 assert(kmsg->ikm_prealloc == port);
1102
1103 kmsg->ikm_prealloc = IP_NULL;
1104 IP_CLEAR_PREALLOC(port, kmsg);
1105 }
1106
1107 /*
1108 * Routine: ipc_kmsg_prealloc
1109 * Purpose:
1110 * Wraper to ipc_kmsg_alloc() to account for
1111 * header expansion requirements.
1112 */
1113 ipc_kmsg_t
1114 ipc_kmsg_prealloc(mach_msg_size_t size)
1115 {
1116 #if defined(__LP64__)
1117 if (size > MACH_MSG_SIZE_MAX - LEGACY_HEADER_SIZE_DELTA)
1118 return IKM_NULL;
1119
1120 size += LEGACY_HEADER_SIZE_DELTA;
1121 #endif
1122 return ipc_kmsg_alloc(size);
1123 }
1124
1125
1126 /*
1127 * Routine: ipc_kmsg_get
1128 * Purpose:
1129 * Allocates a kernel message buffer.
1130 * Copies a user message to the message buffer.
1131 * Conditions:
1132 * Nothing locked.
1133 * Returns:
1134 * MACH_MSG_SUCCESS Acquired a message buffer.
1135 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
1136 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
1137 * MACH_SEND_TOO_LARGE Message too large to ever be sent.
1138 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
1139 * MACH_SEND_INVALID_DATA Couldn't copy message data.
1140 */
1141
1142 mach_msg_return_t
1143 ipc_kmsg_get(
1144 mach_vm_address_t msg_addr,
1145 mach_msg_size_t size,
1146 ipc_kmsg_t *kmsgp)
1147 {
1148 mach_msg_size_t msg_and_trailer_size;
1149 ipc_kmsg_t kmsg;
1150 mach_msg_max_trailer_t *trailer;
1151 mach_msg_legacy_base_t legacy_base;
1152 mach_msg_size_t len_copied;
1153 legacy_base.body.msgh_descriptor_count = 0;
1154
1155 if ((size < sizeof(mach_msg_legacy_header_t)) || (size & 3))
1156 return MACH_SEND_MSG_TOO_SMALL;
1157
1158 if (size > ipc_kmsg_max_body_space)
1159 return MACH_SEND_TOO_LARGE;
1160
1161 if(size == sizeof(mach_msg_legacy_header_t))
1162 len_copied = sizeof(mach_msg_legacy_header_t);
1163 else
1164 len_copied = sizeof(mach_msg_legacy_base_t);
1165
1166 if (copyinmsg(msg_addr, (char *)&legacy_base, len_copied))
1167 return MACH_SEND_INVALID_DATA;
1168
1169 msg_addr += sizeof(legacy_base.header);
1170 #if defined(__LP64__)
1171 size += LEGACY_HEADER_SIZE_DELTA;
1172 #endif
1173 /* unreachable if !DEBUG */
1174 __unreachable_ok_push
1175 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) {
1176 unsigned int j;
1177 for (j=0; j<sizeof(legacy_base.header); j++) {
1178 kprintf("%02x\n", ((unsigned char*)&legacy_base.header)[j]);
1179 }
1180 }
1181 __unreachable_ok_pop
1182
1183 msg_and_trailer_size = size + MAX_TRAILER_SIZE;
1184 kmsg = ipc_kmsg_alloc(msg_and_trailer_size);
1185 if (kmsg == IKM_NULL)
1186 return MACH_SEND_NO_BUFFER;
1187
1188 kmsg->ikm_header->msgh_size = size;
1189 kmsg->ikm_header->msgh_bits = legacy_base.header.msgh_bits;
1190 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(legacy_base.header.msgh_remote_port);
1191 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(legacy_base.header.msgh_local_port);
1192 kmsg->ikm_header->msgh_voucher_port = legacy_base.header.msgh_voucher_port;
1193 kmsg->ikm_header->msgh_id = legacy_base.header.msgh_id;
1194
1195 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_get header:\n"
1196 " size: 0x%.8x\n"
1197 " bits: 0x%.8x\n"
1198 " remote_port: %p\n"
1199 " local_port: %p\n"
1200 " voucher_port: 0x%.8x\n"
1201 " id: %.8d\n",
1202 kmsg->ikm_header->msgh_size,
1203 kmsg->ikm_header->msgh_bits,
1204 kmsg->ikm_header->msgh_remote_port,
1205 kmsg->ikm_header->msgh_local_port,
1206 kmsg->ikm_header->msgh_voucher_port,
1207 kmsg->ikm_header->msgh_id);
1208
1209 if (copyinmsg(msg_addr, (char *)(kmsg->ikm_header + 1), size - (mach_msg_size_t)sizeof(mach_msg_header_t))) {
1210 ipc_kmsg_free(kmsg);
1211 return MACH_SEND_INVALID_DATA;
1212 }
1213
1214 /* unreachable if !DEBUG */
1215 __unreachable_ok_push
1216 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK))
1217 {
1218 kprintf("body: size: %lu\n", (size - sizeof(mach_msg_header_t)));
1219 uint32_t i;
1220 for(i=0;i*4 < (size - sizeof(mach_msg_header_t));i++)
1221 {
1222 kprintf("%.4x\n",((uint32_t *)(kmsg->ikm_header + 1))[i]);
1223 }
1224 }
1225 __unreachable_ok_pop
1226 DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_get()");
1227
1228 /*
1229 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
1230 * However, the internal size field of the trailer (msgh_trailer_size)
1231 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
1232 * the cases where no implicit data is requested.
1233 */
1234 trailer = (mach_msg_max_trailer_t *) ((vm_offset_t)kmsg->ikm_header + size);
1235 trailer->msgh_sender = current_thread()->task->sec_token;
1236 trailer->msgh_audit = current_thread()->task->audit_token;
1237 trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
1238 trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
1239
1240 #ifdef ppc
1241 if(trcWork.traceMask) dbgTrace(0x1100, (unsigned int)kmsg->ikm_header->msgh_id,
1242 (unsigned int)kmsg->ikm_header->msgh_remote_port,
1243 (unsigned int)kmsg->ikm_header->msgh_local_port, 0);
1244 #endif
1245
1246 trailer->msgh_labels.sender = 0;
1247 *kmsgp = kmsg;
1248 return MACH_MSG_SUCCESS;
1249 }
1250
1251 /*
1252 * Routine: ipc_kmsg_get_from_kernel
1253 * Purpose:
1254 * First checks for a preallocated message
1255 * reserved for kernel clients. If not found -
1256 * allocates a new kernel message buffer.
1257 * Copies a kernel message to the message buffer.
1258 * Only resource errors are allowed.
1259 * Conditions:
1260 * Nothing locked.
1261 * Ports in header are ipc_port_t.
1262 * Returns:
1263 * MACH_MSG_SUCCESS Acquired a message buffer.
1264 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
1265 */
1266
1267 mach_msg_return_t
1268 ipc_kmsg_get_from_kernel(
1269 mach_msg_header_t *msg,
1270 mach_msg_size_t size,
1271 ipc_kmsg_t *kmsgp)
1272 {
1273 ipc_kmsg_t kmsg;
1274 mach_msg_size_t msg_and_trailer_size;
1275 mach_msg_max_trailer_t *trailer;
1276 ipc_port_t dest_port;
1277
1278 assert(size >= sizeof(mach_msg_header_t));
1279 assert((size & 3) == 0);
1280
1281 dest_port = (ipc_port_t)msg->msgh_remote_port;
1282
1283 msg_and_trailer_size = size + MAX_TRAILER_SIZE;
1284
1285 /*
1286 * See if the port has a pre-allocated kmsg for kernel
1287 * clients. These are set up for those kernel clients
1288 * which cannot afford to wait.
1289 */
1290 if (IP_VALID(dest_port) && IP_PREALLOC(dest_port)) {
1291 mach_msg_size_t max_desc = 0;
1292
1293 ip_lock(dest_port);
1294 if (!ip_active(dest_port)) {
1295 ip_unlock(dest_port);
1296 return MACH_SEND_NO_BUFFER;
1297 }
1298 assert(IP_PREALLOC(dest_port));
1299 kmsg = dest_port->ip_premsg;
1300 if (ikm_prealloc_inuse(kmsg)) {
1301 ip_unlock(dest_port);
1302 return MACH_SEND_NO_BUFFER;
1303 }
1304 #if !defined(__LP64__)
1305 if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
1306 assert(size > sizeof(mach_msg_base_t));
1307 max_desc = ((mach_msg_base_t *)msg)->body.msgh_descriptor_count *
1308 DESC_SIZE_ADJUSTMENT;
1309 }
1310 #endif
1311 if (msg_and_trailer_size > kmsg->ikm_size - max_desc) {
1312 ip_unlock(dest_port);
1313 return MACH_SEND_TOO_LARGE;
1314 }
1315 ikm_prealloc_set_inuse(kmsg, dest_port);
1316 ikm_set_header(kmsg, msg_and_trailer_size);
1317 ip_unlock(dest_port);
1318 }
1319 else
1320 {
1321 kmsg = ipc_kmsg_alloc(msg_and_trailer_size);
1322 if (kmsg == IKM_NULL)
1323 return MACH_SEND_NO_BUFFER;
1324 }
1325
1326 (void) memcpy((void *) kmsg->ikm_header, (const void *) msg, size);
1327
1328 kmsg->ikm_header->msgh_size = size;
1329
1330 /*
1331 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
1332 * However, the internal size field of the trailer (msgh_trailer_size)
1333 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
1334 * optimize the cases where no implicit data is requested.
1335 */
1336 trailer = (mach_msg_max_trailer_t *)
1337 ((vm_offset_t)kmsg->ikm_header + size);
1338 trailer->msgh_sender = KERNEL_SECURITY_TOKEN;
1339 trailer->msgh_audit = KERNEL_AUDIT_TOKEN;
1340 trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
1341 trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
1342
1343 trailer->msgh_labels.sender = 0;
1344
1345 *kmsgp = kmsg;
1346 return MACH_MSG_SUCCESS;
1347 }
1348
1349 /*
1350 * Routine: ipc_kmsg_send
1351 * Purpose:
1352 * Send a message. The message holds a reference
1353 * for the destination port in the msgh_remote_port field.
1354 *
1355 * If unsuccessful, the caller still has possession of
1356 * the message and must do something with it. If successful,
1357 * the message is queued, given to a receiver, destroyed,
1358 * or handled directly by the kernel via mach_msg.
1359 * Conditions:
1360 * Nothing locked.
1361 * Returns:
1362 * MACH_MSG_SUCCESS The message was accepted.
1363 * MACH_SEND_TIMED_OUT Caller still has message.
1364 * MACH_SEND_INTERRUPTED Caller still has message.
1365 * MACH_SEND_INVALID_DEST Caller still has message.
1366 */
1367
1368
1369 mach_msg_return_t
1370 ipc_kmsg_send(
1371 ipc_kmsg_t kmsg,
1372 mach_msg_option_t option,
1373 mach_msg_timeout_t send_timeout)
1374 {
1375 ipc_port_t port;
1376 thread_t th = current_thread();
1377 mach_msg_return_t error = MACH_MSG_SUCCESS;
1378 boolean_t kernel_reply = FALSE;
1379 spl_t s;
1380
1381 /* Check if honor qlimit flag is set on thread. */
1382 if ((th->options & TH_OPT_HONOR_QLIMIT) == TH_OPT_HONOR_QLIMIT) {
1383 /* Remove the MACH_SEND_ALWAYS flag to honor queue limit. */
1384 option &= (~MACH_SEND_ALWAYS);
1385 /* Add the timeout flag since the message queue might be full. */
1386 option |= MACH_SEND_TIMEOUT;
1387 th->options &= (~TH_OPT_HONOR_QLIMIT);
1388 }
1389
1390 #if IMPORTANCE_INHERITANCE
1391 boolean_t did_importance = FALSE;
1392 #if IMPORTANCE_DEBUG
1393 mach_msg_id_t imp_msgh_id = -1;
1394 int sender_pid = -1;
1395 #endif /* IMPORTANCE_DEBUG */
1396 #endif /* IMPORTANCE_INHERITANCE */
1397
1398 /* don't allow the creation of a circular loop */
1399 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_CIRCULAR) {
1400 ipc_kmsg_destroy(kmsg);
1401 return MACH_MSG_SUCCESS;
1402 }
1403
1404 port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port;
1405 assert(IP_VALID(port));
1406 ip_lock(port);
1407
1408 #if IMPORTANCE_INHERITANCE
1409 retry:
1410 #endif /* IMPORTANCE_INHERITANCE */
1411 /*
1412 * Can't deliver to a dead port.
1413 * However, we can pretend it got sent
1414 * and was then immediately destroyed.
1415 */
1416 if (!ip_active(port)) {
1417 ip_unlock(port);
1418 ip_release(port); /* JMM - Future: release right, not just ref */
1419 kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
1420 ipc_kmsg_destroy(kmsg);
1421 return MACH_MSG_SUCCESS;
1422 }
1423
1424 if (port->ip_receiver == ipc_space_kernel) {
1425
1426 /*
1427 * We can check ip_receiver == ipc_space_kernel
1428 * before checking that the port is active because
1429 * ipc_port_dealloc_kernel clears ip_receiver
1430 * before destroying a kernel port.
1431 */
1432 assert(ip_active(port));
1433 port->ip_messages.imq_seqno++;
1434 ip_unlock(port);
1435
1436 current_task()->messages_sent++;
1437
1438 /*
1439 * Call the server routine, and get the reply message to send.
1440 */
1441 kmsg = ipc_kobject_server(kmsg);
1442 if (kmsg == IKM_NULL)
1443 return MACH_MSG_SUCCESS;
1444
1445 port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port;
1446 assert(IP_VALID(port));
1447 ip_lock(port);
1448 /* fall thru with reply - same options */
1449 kernel_reply = TRUE;
1450 }
1451
1452 #if IMPORTANCE_INHERITANCE
1453 /*
1454 * Need to see if this message needs importance donation and/or
1455 * propagation. That routine can drop the port lock temporarily.
1456 * If it does we'll have to revalidate the destination.
1457 */
1458 if (did_importance == FALSE) {
1459 did_importance = TRUE;
1460 if (ipc_importance_send(kmsg, option))
1461 goto retry;
1462 }
1463 #endif /* IMPORTANCE_INHERITANCE */
1464
1465 /*
1466 * We have a valid message and a valid reference on the port.
1467 * we can unlock the port and call mqueue_send() on its message
1468 * queue. Lock message queue while port is locked.
1469 */
1470 s = splsched();
1471 imq_lock(&port->ip_messages);
1472 ip_unlock(port);
1473
1474 error = ipc_mqueue_send(&port->ip_messages, kmsg, option,
1475 send_timeout, s);
1476
1477 #if IMPORTANCE_INHERITANCE
1478 if (did_importance == TRUE) {
1479 __unused int importance_cleared = 0;
1480 switch (error) {
1481 case MACH_SEND_TIMED_OUT:
1482 case MACH_SEND_NO_BUFFER:
1483 case MACH_SEND_INTERRUPTED:
1484 case MACH_SEND_INVALID_DEST:
1485 /*
1486 * We still have the kmsg and its
1487 * reference on the port. But we
1488 * have to back out the importance
1489 * boost.
1490 *
1491 * The port could have changed hands,
1492 * be inflight to another destination,
1493 * etc... But in those cases our
1494 * back-out will find the new owner
1495 * (and all the operations that
1496 * transferred the right should have
1497 * applied their own boost adjustments
1498 * to the old owner(s)).
1499 */
1500 importance_cleared = 1;
1501 ipc_importance_clean(kmsg);
1502 break;
1503
1504 case MACH_MSG_SUCCESS:
1505 default:
1506 break;
1507 }
1508 #if IMPORTANCE_DEBUG
1509 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, (IMPORTANCE_CODE(IMP_MSG, IMP_MSG_SEND)) | DBG_FUNC_END,
1510 task_pid(current_task()), sender_pid, imp_msgh_id, importance_cleared, 0);
1511 #endif /* IMPORTANCE_DEBUG */
1512 }
1513 #endif /* IMPORTANCE_INHERITANCE */
1514
1515 /*
1516 * If the port has been destroyed while we wait, treat the message
1517 * as a successful delivery (like we do for an inactive port).
1518 */
1519 if (error == MACH_SEND_INVALID_DEST) {
1520 ip_release(port); /* JMM - Future: release right, not just ref */
1521 kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
1522 ipc_kmsg_destroy(kmsg);
1523 return MACH_MSG_SUCCESS;
1524 }
1525
1526 if (error != MACH_MSG_SUCCESS && kernel_reply) {
1527 /*
1528 * Kernel reply messages that fail can't be allowed to
1529 * pseudo-receive on error conditions. We need to just treat
1530 * the message as a successful delivery.
1531 */
1532 ip_release(port); /* JMM - Future: release right, not just ref */
1533 kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
1534 ipc_kmsg_destroy(kmsg);
1535 return MACH_MSG_SUCCESS;
1536 }
1537 return error;
1538 }
1539
1540 /*
1541 * Routine: ipc_kmsg_put
1542 * Purpose:
1543 * Copies a message buffer to a user message.
1544 * Copies only the specified number of bytes.
1545 * Frees the message buffer.
1546 * Conditions:
1547 * Nothing locked. The message buffer must have clean
1548 * header fields.
1549 * Returns:
1550 * MACH_MSG_SUCCESS Copied data out of message buffer.
1551 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
1552 */
1553
1554 mach_msg_return_t
1555 ipc_kmsg_put(
1556 mach_vm_address_t msg_addr,
1557 ipc_kmsg_t kmsg,
1558 mach_msg_size_t size)
1559 {
1560 mach_msg_return_t mr;
1561
1562 DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_put()");
1563
1564
1565 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_put header:\n"
1566 " size: 0x%.8x\n"
1567 " bits: 0x%.8x\n"
1568 " remote_port: %p\n"
1569 " local_port: %p\n"
1570 " voucher_port: 0x%.8x\n"
1571 " id: %.8d\n",
1572 kmsg->ikm_header->msgh_size,
1573 kmsg->ikm_header->msgh_bits,
1574 kmsg->ikm_header->msgh_remote_port,
1575 kmsg->ikm_header->msgh_local_port,
1576 kmsg->ikm_header->msgh_voucher_port,
1577 kmsg->ikm_header->msgh_id);
1578
1579 #if defined(__LP64__)
1580 if (current_task() != kernel_task) { /* don't if receiver expects fully-cooked in-kernel msg; ux_exception */
1581 mach_msg_legacy_header_t *legacy_header =
1582 (mach_msg_legacy_header_t *)((vm_offset_t)(kmsg->ikm_header) + LEGACY_HEADER_SIZE_DELTA);
1583
1584 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
1585 mach_msg_size_t msg_size = kmsg->ikm_header->msgh_size;
1586 mach_port_name_t remote_port = CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_remote_port);
1587 mach_port_name_t local_port = CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_local_port);
1588 mach_port_name_t voucher_port = kmsg->ikm_header->msgh_voucher_port;
1589 mach_msg_id_t id = kmsg->ikm_header->msgh_id;
1590
1591 legacy_header->msgh_id = id;
1592 legacy_header->msgh_local_port = local_port;
1593 legacy_header->msgh_remote_port = remote_port;
1594 legacy_header->msgh_voucher_port = voucher_port;
1595 legacy_header->msgh_size = msg_size - LEGACY_HEADER_SIZE_DELTA;
1596 legacy_header->msgh_bits = bits;
1597
1598 size -= LEGACY_HEADER_SIZE_DELTA;
1599 kmsg->ikm_header = (mach_msg_header_t *)legacy_header;
1600 }
1601 #endif
1602
1603 /* unreachable if !DEBUG */
1604 __unreachable_ok_push
1605 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) {
1606 kprintf("ipc_kmsg_put header+body: %d\n", (size));
1607 uint32_t i;
1608 for(i=0;i*4 < size;i++)
1609 {
1610 kprintf("%.4x\n",((uint32_t *)kmsg->ikm_header)[i]);
1611 }
1612 kprintf("type: %d\n", ((mach_msg_type_descriptor_t *)(((mach_msg_base_t *)kmsg->ikm_header)+1))->type);
1613 }
1614 __unreachable_ok_pop
1615 if (copyoutmsg((const char *) kmsg->ikm_header, msg_addr, size))
1616 mr = MACH_RCV_INVALID_DATA;
1617 else
1618 mr = MACH_MSG_SUCCESS;
1619
1620 ipc_kmsg_free(kmsg);
1621 return mr;
1622 }
1623
1624 /*
1625 * Routine: ipc_kmsg_put_to_kernel
1626 * Purpose:
1627 * Copies a message buffer to a kernel message.
1628 * Frees the message buffer.
1629 * No errors allowed.
1630 * Conditions:
1631 * Nothing locked.
1632 */
1633
1634 void
1635 ipc_kmsg_put_to_kernel(
1636 mach_msg_header_t *msg,
1637 ipc_kmsg_t kmsg,
1638 mach_msg_size_t size)
1639 {
1640 (void) memcpy((void *) msg, (const void *) kmsg->ikm_header, size);
1641
1642 ipc_kmsg_free(kmsg);
1643 }
1644
1645 /*
1646 * Routine: ipc_kmsg_copyin_header
1647 * Purpose:
1648 * "Copy-in" port rights in the header of a message.
1649 * Operates atomically; if it doesn't succeed the
1650 * message header and the space are left untouched.
1651 * If it does succeed the remote/local port fields
1652 * contain object pointers instead of port names,
1653 * and the bits field is updated. The destination port
1654 * will be a valid port pointer.
1655 *
1656 * Conditions:
1657 * Nothing locked.
1658 * Returns:
1659 * MACH_MSG_SUCCESS Successful copyin.
1660 * MACH_SEND_INVALID_HEADER
1661 * Illegal value in the message header bits.
1662 * MACH_SEND_INVALID_DEST The space is dead.
1663 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1664 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1665 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1666 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1667 */
1668
1669 mach_msg_return_t
1670 ipc_kmsg_copyin_header(
1671 ipc_kmsg_t kmsg,
1672 ipc_space_t space,
1673 mach_msg_option_t *optionp)
1674 {
1675 mach_msg_header_t *msg = kmsg->ikm_header;
1676 mach_msg_bits_t mbits = msg->msgh_bits & MACH_MSGH_BITS_USER;
1677 mach_port_name_t dest_name = CAST_MACH_PORT_TO_NAME(msg->msgh_remote_port);
1678 mach_port_name_t reply_name = CAST_MACH_PORT_TO_NAME(msg->msgh_local_port);
1679 mach_port_name_t voucher_name = MACH_PORT_NULL;
1680 kern_return_t kr;
1681
1682 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
1683 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
1684 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
1685 ipc_object_t dest_port = IO_NULL;
1686 ipc_object_t reply_port = IO_NULL;
1687 ipc_port_t dest_soright = IP_NULL;
1688 ipc_port_t reply_soright = IP_NULL;
1689 ipc_port_t voucher_soright = IP_NULL;
1690 ipc_port_t release_port = IP_NULL;
1691 ipc_port_t voucher_port = IP_NULL;
1692 ipc_port_t voucher_release_port = IP_NULL;
1693 ipc_entry_t dest_entry = IE_NULL;
1694 ipc_entry_t reply_entry = IE_NULL;
1695 ipc_entry_t voucher_entry = IE_NULL;
1696
1697 int assertcnt = 0;
1698 #if IMPORTANCE_INHERITANCE
1699 boolean_t needboost = FALSE;
1700 #endif /* IMPORTANCE_INHERITANCE */
1701
1702 if ((mbits != msg->msgh_bits) ||
1703 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type)) ||
1704 ((reply_type == 0) ?
1705 (reply_name != MACH_PORT_NULL) :
1706 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type)))
1707 return MACH_SEND_INVALID_HEADER;
1708
1709 if (!MACH_PORT_VALID(dest_name))
1710 return MACH_SEND_INVALID_DEST;
1711
1712 is_write_lock(space);
1713 if (!is_active(space)) {
1714 is_write_unlock(space);
1715 return MACH_SEND_INVALID_DEST;
1716 }
1717 /* space locked and active */
1718
1719 /*
1720 * If there is a voucher specified, make sure the disposition is
1721 * valid and the entry actually refers to a voucher port. Don't
1722 * actually copy in until we validate destination and reply.
1723 */
1724 if (voucher_type != MACH_MSGH_BITS_ZERO) {
1725
1726 voucher_name = msg->msgh_voucher_port;
1727
1728 if (voucher_name == MACH_PORT_DEAD ||
1729 (voucher_type != MACH_MSG_TYPE_MOVE_SEND &&
1730 voucher_type != MACH_MSG_TYPE_COPY_SEND)) {
1731 is_write_unlock(space);
1732 return MACH_SEND_INVALID_VOUCHER;
1733 }
1734
1735 if (voucher_name != MACH_PORT_NULL) {
1736 voucher_entry = ipc_entry_lookup(space, voucher_name);
1737 if (voucher_entry == IE_NULL ||
1738 (voucher_entry->ie_bits & MACH_PORT_TYPE_SEND) == 0 ||
1739 io_kotype(voucher_entry->ie_object) != IKOT_VOUCHER) {
1740 is_write_unlock(space);
1741 return MACH_SEND_INVALID_VOUCHER;
1742 }
1743 } else {
1744 voucher_type = MACH_MSG_TYPE_MOVE_SEND;
1745 }
1746 }
1747
1748 /*
1749 * Handle combinations of validating destination and reply; along
1750 * with copying in destination, reply, and voucher in an atomic way.
1751 */
1752
1753 if (dest_name == voucher_name) {
1754
1755 /*
1756 * If the destination name is the same as the voucher name,
1757 * the voucher_entry must already be known. Either that or
1758 * the destination name is MACH_PORT_NULL (i.e. invalid).
1759 */
1760 dest_entry = voucher_entry;
1761 if (dest_entry == IE_NULL) {
1762 goto invalid_dest;
1763 }
1764
1765 /*
1766 * Make sure a future copyin of the reply port will succeed.
1767 * Once we start copying in the dest/voucher pair, we can't
1768 * back out.
1769 */
1770 if (MACH_PORT_VALID(reply_name)) {
1771 assert(reply_type != 0); /* because reply_name not null */
1772
1773 /* It is just WRONG if dest, voucher, and reply are all the same. */
1774 if (voucher_name == reply_name) {
1775 goto invalid_reply;
1776 }
1777 reply_entry = ipc_entry_lookup(space, reply_name);
1778 if (reply_entry == IE_NULL) {
1779 goto invalid_reply;
1780 }
1781 assert(dest_entry != reply_entry); /* names are not equal */
1782 if (!ipc_right_copyin_check(space, reply_name, reply_entry, reply_type)) {
1783 goto invalid_reply;
1784 }
1785 }
1786
1787 /*
1788 * Do the joint copyin of the dest disposition and
1789 * voucher disposition from the one entry/port. We
1790 * already validated that the voucher copyin would
1791 * succeed (above). So, any failure in combining
1792 * the copyins can be blamed on the destination.
1793 */
1794 kr = ipc_right_copyin_two(space, dest_name, dest_entry,
1795 dest_type, voucher_type,
1796 &dest_port, &dest_soright,
1797 &release_port);
1798 if (kr != KERN_SUCCESS) {
1799 assert(kr != KERN_INVALID_CAPABILITY);
1800 goto invalid_dest;
1801 }
1802 voucher_port = (ipc_port_t)dest_port;
1803
1804 /*
1805 * could not have been one of these dispositions,
1806 * validated the port was a true kernel voucher port above,
1807 * AND was successfully able to copyin both dest and voucher.
1808 */
1809 assert(dest_type != MACH_MSG_TYPE_MAKE_SEND);
1810 assert(dest_type != MACH_MSG_TYPE_MAKE_SEND_ONCE);
1811 assert(dest_type != MACH_MSG_TYPE_MOVE_SEND_ONCE);
1812
1813 /*
1814 * Perform the delayed reply right copyin (guaranteed success).
1815 */
1816 if (reply_entry != IE_NULL) {
1817 kr = ipc_right_copyin(space, reply_name, reply_entry,
1818 reply_type, TRUE,
1819 &reply_port, &reply_soright,
1820 &release_port, &assertcnt);
1821 assert(assertcnt == 0);
1822 assert(kr == KERN_SUCCESS);
1823 }
1824
1825 } else {
1826 if (dest_name == reply_name) {
1827 /*
1828 * Destination and reply ports are the same!
1829 * This is very similar to the case where the
1830 * destination and voucher ports were the same
1831 * (except the reply port disposition is not
1832 * previously validated).
1833 */
1834 dest_entry = ipc_entry_lookup(space, dest_name);
1835 if (dest_entry == IE_NULL) {
1836 goto invalid_dest;
1837 }
1838 reply_entry = dest_entry;
1839 assert(reply_type != 0); /* because name not null */
1840
1841 /*
1842 * Do the joint copyin of the dest disposition and
1843 * reply disposition from the one entry/port.
1844 */
1845 kr = ipc_right_copyin_two(space, dest_name, dest_entry,
1846 dest_type, reply_type,
1847 &dest_port, &dest_soright,
1848 &release_port);
1849 if (kr == KERN_INVALID_CAPABILITY) {
1850 goto invalid_reply;
1851 } else if (kr != KERN_SUCCESS) {
1852 goto invalid_dest;
1853 }
1854 reply_port = dest_port;
1855
1856
1857 } else {
1858 /*
1859 * Handle destination and reply independently, as
1860 * they are independent entries (even if the entries
1861 * refer to the same port).
1862 *
1863 * This can be the tough case to make atomic.
1864 *
1865 * The difficult problem is serializing with port death.
1866 * The bad case is when dest_port dies after its copyin,
1867 * reply_port dies before its copyin, and dest_port dies before
1868 * reply_port. Then the copyins operated as if dest_port was
1869 * alive and reply_port was dead, which shouldn't have happened
1870 * because they died in the other order.
1871 *
1872 * Note that it is easy for a user task to tell if
1873 * a copyin happened before or after a port died.
1874 * If a port dies before copyin, a dead-name notification
1875 * is generated and the dead name's urefs are incremented,
1876 * and if the copyin happens first, a port-deleted
1877 * notification is generated.
1878 *
1879 * Even so, avoiding that potentially detectable race is too
1880 * expensive - and no known code cares about it. So, we just
1881 * do the expedient thing and copy them in one after the other.
1882 */
1883
1884 dest_entry = ipc_entry_lookup(space, dest_name);
1885 if (dest_entry == IE_NULL) {
1886 goto invalid_dest;
1887 }
1888 assert(dest_entry != voucher_entry);
1889
1890 /*
1891 * Make sure reply port entry is valid before dest copyin.
1892 */
1893 if (MACH_PORT_VALID(reply_name)) {
1894 if (reply_name == voucher_name) {
1895 goto invalid_reply;
1896 }
1897 reply_entry = ipc_entry_lookup(space, reply_name);
1898 if (reply_entry == IE_NULL) {
1899 goto invalid_reply;
1900 }
1901 assert(dest_entry != reply_entry); /* names are not equal */
1902 assert(reply_type != 0); /* because reply_name not null */
1903
1904 if (!ipc_right_copyin_check(space, reply_name, reply_entry, reply_type)) {
1905 goto invalid_reply;
1906 }
1907 }
1908
1909 /*
1910 * copyin the destination.
1911 */
1912 kr = ipc_right_copyin(space, dest_name, dest_entry,
1913 dest_type, FALSE,
1914 &dest_port, &dest_soright,
1915 &release_port, &assertcnt);
1916 assert(assertcnt == 0);
1917 if (kr != KERN_SUCCESS) {
1918 goto invalid_dest;
1919 }
1920 assert(IO_VALID(dest_port));
1921 assert(!IP_VALID(release_port));
1922
1923 /*
1924 * Copyin the pre-validated reply right.
1925 * It's OK if the reply right has gone dead in the meantime.
1926 */
1927 if (MACH_PORT_VALID(reply_name)) {
1928 kr = ipc_right_copyin(space, reply_name, reply_entry,
1929 reply_type, TRUE,
1930 &reply_port, &reply_soright,
1931 &release_port, &assertcnt);
1932 assert(assertcnt == 0);
1933 assert(kr == KERN_SUCCESS);
1934 } else {
1935 /* convert invalid name to equivalent ipc_object type */
1936 reply_port = (ipc_object_t)CAST_MACH_NAME_TO_PORT(reply_name);
1937 }
1938 }
1939
1940 /*
1941 * Finally can copyin the voucher right now that dest and reply
1942 * are fully copied in (guaranteed success).
1943 */
1944 if (IE_NULL != voucher_entry) {
1945 kr = ipc_right_copyin(space, voucher_name, voucher_entry,
1946 voucher_type, FALSE,
1947 (ipc_object_t *)&voucher_port,
1948 &voucher_soright,
1949 &voucher_release_port,
1950 &assertcnt);
1951 assert(assertcnt == 0);
1952 assert(KERN_SUCCESS == kr);
1953 assert(IP_VALID(voucher_port));
1954 assert(ip_active(voucher_port));
1955 }
1956 }
1957
1958 /* the entry(s) might need to be deallocated */
1959 assert(IE_NULL != dest_entry);
1960 if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1961 ipc_entry_dealloc(space, dest_name, dest_entry);
1962 dest_entry = IE_NULL;
1963 }
1964 if (dest_entry != reply_entry && IE_NULL != reply_entry &&
1965 IE_BITS_TYPE(reply_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1966 ipc_entry_dealloc(space, reply_name, reply_entry);
1967 reply_entry = IE_NULL;
1968 }
1969 if (dest_entry != voucher_entry && IE_NULL != voucher_entry &&
1970 IE_BITS_TYPE(voucher_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1971 ipc_entry_dealloc(space, voucher_name, voucher_entry);
1972 voucher_entry = IE_NULL;
1973 }
1974
1975 /*
1976 * No room to store voucher port in in-kernel msg header,
1977 * so we store it back in the kmsg itself.
1978 */
1979 if (IP_VALID(voucher_port)) {
1980 assert(ip_active(voucher_port));
1981 kmsg->ikm_voucher = voucher_port;
1982 voucher_type = MACH_MSG_TYPE_MOVE_SEND;
1983 }
1984
1985 dest_type = ipc_object_copyin_type(dest_type);
1986 reply_type = ipc_object_copyin_type(reply_type);
1987
1988 /*
1989 * JMM - Without rdar://problem/6275821, this is the last place we can
1990 * re-arm the send-possible notifications. It may trigger unexpectedly
1991 * early (send may NOT have failed), but better than missing. We assure
1992 * we won't miss by forcing MACH_SEND_ALWAYS if we got past arming.
1993 */
1994 if (((*optionp & MACH_SEND_NOTIFY) != 0) &&
1995 dest_type != MACH_MSG_TYPE_PORT_SEND_ONCE &&
1996 dest_entry != IE_NULL && dest_entry->ie_request != IE_REQ_NONE) {
1997 ipc_port_t dport = (ipc_port_t)dest_port;
1998
1999 assert(dport != IP_NULL);
2000 ip_lock(dport);
2001 if (ip_active(dport) && dport->ip_receiver != ipc_space_kernel) {
2002 if (ip_full(dport)) {
2003 #if IMPORTANCE_INHERITANCE
2004 needboost = ipc_port_request_sparm(dport, dest_name,
2005 dest_entry->ie_request,
2006 (*optionp & MACH_SEND_NOIMPORTANCE));
2007 if (needboost == FALSE)
2008 ip_unlock(dport);
2009 #else
2010 ipc_port_request_sparm(dport, dest_name, dest_entry->ie_request);
2011 ip_unlock(dport);
2012 #endif /* IMPORTANCE_INHERITANCE */
2013 } else {
2014 *optionp |= MACH_SEND_ALWAYS;
2015 ip_unlock(dport);
2016 }
2017 } else {
2018 ip_unlock(dport);
2019 }
2020 }
2021
2022 is_write_unlock(space);
2023
2024 #if IMPORTANCE_INHERITANCE
2025 /*
2026 * If our request is the first boosting send-possible
2027 * notification this cycle, push the boost down the
2028 * destination port.
2029 */
2030 if (needboost == TRUE) {
2031 ipc_port_t dport = (ipc_port_t)dest_port;
2032
2033 /* dport still locked from above */
2034 if (ipc_port_importance_delta(dport, IPID_OPTION_SENDPOSSIBLE, 1) == FALSE) {
2035 ip_unlock(dport);
2036 }
2037 }
2038 #endif /* IMPORTANCE_INHERITANCE */
2039
2040 if (dest_soright != IP_NULL) {
2041 ipc_notify_port_deleted(dest_soright, dest_name);
2042 }
2043 if (reply_soright != IP_NULL) {
2044 ipc_notify_port_deleted(reply_soright, reply_name);
2045 }
2046 if (voucher_soright != IP_NULL) {
2047 ipc_notify_port_deleted(voucher_soright, voucher_name);
2048 }
2049 msg->msgh_bits = MACH_MSGH_BITS_SET(dest_type, reply_type, voucher_type, mbits);
2050 msg->msgh_remote_port = (ipc_port_t)dest_port;
2051 msg->msgh_local_port = (ipc_port_t)reply_port;
2052
2053 if (release_port != IP_NULL)
2054 ip_release(release_port);
2055
2056 if (voucher_release_port != IP_NULL)
2057 ip_release(voucher_release_port);
2058
2059 return MACH_MSG_SUCCESS;
2060
2061 invalid_reply:
2062 is_write_unlock(space);
2063
2064 if (release_port != IP_NULL)
2065 ip_release(release_port);
2066
2067 assert(voucher_port == IP_NULL);
2068 assert(voucher_soright == IP_NULL);
2069
2070 return MACH_SEND_INVALID_REPLY;
2071
2072 invalid_dest:
2073 is_write_unlock(space);
2074
2075 if (release_port != IP_NULL)
2076 ip_release(release_port);
2077
2078 if (reply_soright != IP_NULL)
2079 ipc_notify_port_deleted(reply_soright, reply_name);
2080
2081 assert(voucher_port == IP_NULL);
2082 assert(voucher_soright == IP_NULL);
2083
2084 return MACH_SEND_INVALID_DEST;
2085 }
2086
2087 mach_msg_descriptor_t *ipc_kmsg_copyin_port_descriptor(
2088 volatile mach_msg_port_descriptor_t *dsc,
2089 mach_msg_legacy_port_descriptor_t *user_dsc,
2090 ipc_space_t space,
2091 ipc_object_t dest,
2092 ipc_kmsg_t kmsg,
2093 mach_msg_return_t *mr);
2094
2095 void ipc_print_type_name(
2096 int type_name);
2097 mach_msg_descriptor_t *
2098 ipc_kmsg_copyin_port_descriptor(
2099 volatile mach_msg_port_descriptor_t *dsc,
2100 mach_msg_legacy_port_descriptor_t *user_dsc_in,
2101 ipc_space_t space,
2102 ipc_object_t dest,
2103 ipc_kmsg_t kmsg,
2104 mach_msg_return_t *mr)
2105 {
2106 volatile mach_msg_legacy_port_descriptor_t *user_dsc = user_dsc_in;
2107 mach_msg_type_name_t user_disp;
2108 mach_msg_type_name_t result_disp;
2109 mach_port_name_t name;
2110 ipc_object_t object;
2111
2112 user_disp = user_dsc->disposition;
2113 result_disp = ipc_object_copyin_type(user_disp);
2114
2115 name = (mach_port_name_t)user_dsc->name;
2116 if (MACH_PORT_VALID(name)) {
2117
2118 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object);
2119 if (kr != KERN_SUCCESS) {
2120 *mr = MACH_SEND_INVALID_RIGHT;
2121 return NULL;
2122 }
2123
2124 if ((result_disp == MACH_MSG_TYPE_PORT_RECEIVE) &&
2125 ipc_port_check_circularity((ipc_port_t) object,
2126 (ipc_port_t) dest)) {
2127 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2128 }
2129 dsc->name = (ipc_port_t) object;
2130 } else {
2131 dsc->name = CAST_MACH_NAME_TO_PORT(name);
2132 }
2133 dsc->disposition = result_disp;
2134 dsc->type = MACH_MSG_PORT_DESCRIPTOR;
2135
2136 dsc->pad_end = 0; // debug, unnecessary
2137
2138 return (mach_msg_descriptor_t *)(user_dsc_in+1);
2139 }
2140
2141 mach_msg_descriptor_t * ipc_kmsg_copyin_ool_descriptor(
2142 mach_msg_ool_descriptor_t *dsc,
2143 mach_msg_descriptor_t *user_dsc,
2144 int is_64bit,
2145 vm_offset_t *paddr,
2146 vm_map_copy_t *copy,
2147 vm_size_t *space_needed,
2148 vm_map_t map,
2149 mach_msg_return_t *mr);
2150 mach_msg_descriptor_t *
2151 ipc_kmsg_copyin_ool_descriptor(
2152 mach_msg_ool_descriptor_t *dsc,
2153 mach_msg_descriptor_t *user_dsc,
2154 int is_64bit,
2155 vm_offset_t *paddr,
2156 vm_map_copy_t *copy,
2157 vm_size_t *space_needed,
2158 vm_map_t map,
2159 mach_msg_return_t *mr)
2160 {
2161 vm_size_t length;
2162 boolean_t dealloc;
2163 mach_msg_copy_options_t copy_options;
2164 mach_vm_offset_t addr;
2165 mach_msg_descriptor_type_t dsc_type;
2166
2167 if (is_64bit) {
2168 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2169
2170 addr = (mach_vm_offset_t) user_ool_dsc->address;
2171 length = user_ool_dsc->size;
2172 dealloc = user_ool_dsc->deallocate;
2173 copy_options = user_ool_dsc->copy;
2174 dsc_type = user_ool_dsc->type;
2175
2176 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2177 } else {
2178 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2179
2180 addr = CAST_USER_ADDR_T(user_ool_dsc->address);
2181 dealloc = user_ool_dsc->deallocate;
2182 copy_options = user_ool_dsc->copy;
2183 dsc_type = user_ool_dsc->type;
2184 length = user_ool_dsc->size;
2185
2186 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2187 }
2188
2189 dsc->size = (mach_msg_size_t)length;
2190 dsc->deallocate = dealloc;
2191 dsc->copy = copy_options;
2192 dsc->type = dsc_type;
2193
2194 if (length == 0) {
2195 dsc->address = NULL;
2196 } else if ((length >= MSG_OOL_SIZE_SMALL) &&
2197 (copy_options == MACH_MSG_PHYSICAL_COPY) && !dealloc) {
2198
2199 /*
2200 * If the request is a physical copy and the source
2201 * is not being deallocated, then allocate space
2202 * in the kernel's pageable ipc copy map and copy
2203 * the data in. The semantics guarantee that the
2204 * data will have been physically copied before
2205 * the send operation terminates. Thus if the data
2206 * is not being deallocated, we must be prepared
2207 * to page if the region is sufficiently large.
2208 */
2209 if (copyin(addr, (char *)*paddr, length)) {
2210 *mr = MACH_SEND_INVALID_MEMORY;
2211 return NULL;
2212 }
2213
2214 /*
2215 * The kernel ipc copy map is marked no_zero_fill.
2216 * If the transfer is not a page multiple, we need
2217 * to zero fill the balance.
2218 */
2219 if (!page_aligned(length)) {
2220 (void) memset((void *) (*paddr + length), 0,
2221 round_page(length) - length);
2222 }
2223 if (vm_map_copyin(ipc_kernel_copy_map, (vm_map_address_t)*paddr,
2224 (vm_map_size_t)length, TRUE, copy) != KERN_SUCCESS) {
2225 *mr = MACH_MSG_VM_KERNEL;
2226 return NULL;
2227 }
2228 dsc->address = (void *)*copy;
2229 *paddr += round_page(length);
2230 *space_needed -= round_page(length);
2231 } else {
2232
2233 /*
2234 * Make a vm_map_copy_t of the of the data. If the
2235 * data is small, this will do an optimized physical
2236 * copy. Otherwise, it will do a virtual copy.
2237 *
2238 * NOTE: A virtual copy is OK if the original is being
2239 * deallocted, even if a physical copy was requested.
2240 */
2241 kern_return_t kr = vm_map_copyin(map, addr,
2242 (vm_map_size_t)length, dealloc, copy);
2243 if (kr != KERN_SUCCESS) {
2244 *mr = (kr == KERN_RESOURCE_SHORTAGE) ?
2245 MACH_MSG_VM_KERNEL :
2246 MACH_SEND_INVALID_MEMORY;
2247 return NULL;
2248 }
2249 dsc->address = (void *)*copy;
2250 }
2251 return user_dsc;
2252 }
2253
2254 mach_msg_descriptor_t * ipc_kmsg_copyin_ool_ports_descriptor(
2255 mach_msg_ool_ports_descriptor_t *dsc,
2256 mach_msg_descriptor_t *user_dsc,
2257 int is_64bit,
2258 vm_map_t map,
2259 ipc_space_t space,
2260 ipc_object_t dest,
2261 ipc_kmsg_t kmsg,
2262 mach_msg_return_t *mr);
2263 mach_msg_descriptor_t *
2264 ipc_kmsg_copyin_ool_ports_descriptor(
2265 mach_msg_ool_ports_descriptor_t *dsc,
2266 mach_msg_descriptor_t *user_dsc,
2267 int is_64bit,
2268 vm_map_t map,
2269 ipc_space_t space,
2270 ipc_object_t dest,
2271 ipc_kmsg_t kmsg,
2272 mach_msg_return_t *mr)
2273 {
2274 void *data;
2275 ipc_object_t *objects;
2276 unsigned int i;
2277 mach_vm_offset_t addr;
2278 mach_msg_type_name_t user_disp;
2279 mach_msg_type_name_t result_disp;
2280 mach_msg_type_number_t count;
2281 mach_msg_copy_options_t copy_option;
2282 boolean_t deallocate;
2283 mach_msg_descriptor_type_t type;
2284 vm_size_t ports_length, names_length;
2285
2286 if (is_64bit) {
2287 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2288
2289 addr = (mach_vm_offset_t)user_ool_dsc->address;
2290 count = user_ool_dsc->count;
2291 deallocate = user_ool_dsc->deallocate;
2292 copy_option = user_ool_dsc->copy;
2293 user_disp = user_ool_dsc->disposition;
2294 type = user_ool_dsc->type;
2295
2296 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2297 } else {
2298 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2299
2300 addr = CAST_USER_ADDR_T(user_ool_dsc->address);
2301 count = user_ool_dsc->count;
2302 deallocate = user_ool_dsc->deallocate;
2303 copy_option = user_ool_dsc->copy;
2304 user_disp = user_ool_dsc->disposition;
2305 type = user_ool_dsc->type;
2306
2307 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2308 }
2309
2310 dsc->deallocate = deallocate;
2311 dsc->copy = copy_option;
2312 dsc->type = type;
2313 dsc->count = count;
2314 dsc->address = NULL; /* for now */
2315
2316 result_disp = ipc_object_copyin_type(user_disp);
2317 dsc->disposition = result_disp;
2318
2319 if (count > (INT_MAX / sizeof(mach_port_t))) {
2320 *mr = MACH_SEND_TOO_LARGE;
2321 return NULL;
2322 }
2323
2324 /* calculate length of data in bytes, rounding up */
2325 ports_length = count * sizeof(mach_port_t);
2326 names_length = count * sizeof(mach_port_name_t);
2327
2328 if (ports_length == 0) {
2329 return user_dsc;
2330 }
2331
2332 data = kalloc(ports_length);
2333
2334 if (data == NULL) {
2335 *mr = MACH_SEND_NO_BUFFER;
2336 return NULL;
2337 }
2338
2339 #ifdef __LP64__
2340 mach_port_name_t *names = &((mach_port_name_t *)data)[count];
2341 #else
2342 mach_port_name_t *names = ((mach_port_name_t *)data);
2343 #endif
2344
2345 if (copyinmap(map, addr, names, names_length) != KERN_SUCCESS) {
2346 kfree(data, ports_length);
2347 *mr = MACH_SEND_INVALID_MEMORY;
2348 return NULL;
2349 }
2350
2351 if (deallocate) {
2352 (void) mach_vm_deallocate(map, addr, (mach_vm_size_t)ports_length);
2353 }
2354
2355 objects = (ipc_object_t *) data;
2356 dsc->address = data;
2357
2358 for ( i = 0; i < count; i++) {
2359 mach_port_name_t name = names[i];
2360 ipc_object_t object;
2361
2362 if (!MACH_PORT_VALID(name)) {
2363 objects[i] = (ipc_object_t)CAST_MACH_NAME_TO_PORT(name);
2364 continue;
2365 }
2366
2367 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object);
2368
2369 if (kr != KERN_SUCCESS) {
2370 unsigned int j;
2371
2372 for(j = 0; j < i; j++) {
2373 object = objects[j];
2374 if (IPC_OBJECT_VALID(object))
2375 ipc_object_destroy(object, result_disp);
2376 }
2377 kfree(data, ports_length);
2378 dsc->address = NULL;
2379 *mr = MACH_SEND_INVALID_RIGHT;
2380 return NULL;
2381 }
2382
2383 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2384 ipc_port_check_circularity(
2385 (ipc_port_t) object,
2386 (ipc_port_t) dest))
2387 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2388
2389 objects[i] = object;
2390 }
2391
2392 return user_dsc;
2393 }
2394
2395 /*
2396 * Routine: ipc_kmsg_copyin_body
2397 * Purpose:
2398 * "Copy-in" port rights and out-of-line memory
2399 * in the message body.
2400 *
2401 * In all failure cases, the message is left holding
2402 * no rights or memory. However, the message buffer
2403 * is not deallocated. If successful, the message
2404 * contains a valid destination port.
2405 * Conditions:
2406 * Nothing locked.
2407 * Returns:
2408 * MACH_MSG_SUCCESS Successful copyin.
2409 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
2410 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
2411 * MACH_SEND_INVALID_TYPE Bad type specification.
2412 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
2413 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
2414 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
2415 */
2416
2417 mach_msg_return_t
2418 ipc_kmsg_copyin_body(
2419 ipc_kmsg_t kmsg,
2420 ipc_space_t space,
2421 vm_map_t map)
2422 {
2423 ipc_object_t dest;
2424 mach_msg_body_t *body;
2425 mach_msg_descriptor_t *daddr, *naddr;
2426 mach_msg_descriptor_t *user_addr, *kern_addr;
2427 mach_msg_type_number_t dsc_count;
2428 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
2429 boolean_t complex = FALSE;
2430 vm_size_t space_needed = 0;
2431 vm_offset_t paddr = 0;
2432 vm_map_copy_t copy = VM_MAP_COPY_NULL;
2433 mach_msg_type_number_t i;
2434 mach_msg_return_t mr = MACH_MSG_SUCCESS;
2435
2436 vm_size_t descriptor_size = 0;
2437
2438 /*
2439 * Determine if the target is a kernel port.
2440 */
2441 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2442 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2443 naddr = (mach_msg_descriptor_t *) (body + 1);
2444
2445 dsc_count = body->msgh_descriptor_count;
2446 if (dsc_count == 0)
2447 return MACH_MSG_SUCCESS;
2448
2449 /*
2450 * Make an initial pass to determine kernal VM space requirements for
2451 * physical copies and possible contraction of the descriptors from
2452 * processes with pointers larger than the kernel's.
2453 */
2454 daddr = NULL;
2455 for (i = 0; i < dsc_count; i++) {
2456 mach_msg_size_t size;
2457
2458 daddr = naddr;
2459
2460 /* make sure the descriptor fits in the message */
2461 if (is_task_64bit) {
2462 switch (daddr->type.type) {
2463 case MACH_MSG_OOL_DESCRIPTOR:
2464 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2465 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2466 descriptor_size += 16;
2467 naddr = (typeof(naddr))((vm_offset_t)daddr + 16);
2468 break;
2469 default:
2470 descriptor_size += 12;
2471 naddr = (typeof(naddr))((vm_offset_t)daddr + 12);
2472 break;
2473 }
2474 } else {
2475 descriptor_size += 12;
2476 naddr = (typeof(naddr))((vm_offset_t)daddr + 12);
2477 }
2478
2479 if (naddr > (mach_msg_descriptor_t *)
2480 ((vm_offset_t)kmsg->ikm_header + kmsg->ikm_header->msgh_size)) {
2481 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2482 mr = MACH_SEND_MSG_TOO_SMALL;
2483 goto out;
2484 }
2485
2486 switch (daddr->type.type) {
2487 case MACH_MSG_OOL_DESCRIPTOR:
2488 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2489 size = (is_task_64bit) ?
2490 ((mach_msg_ool_descriptor64_t *)daddr)->size :
2491 daddr->out_of_line.size;
2492
2493 if (daddr->out_of_line.copy != MACH_MSG_PHYSICAL_COPY &&
2494 daddr->out_of_line.copy != MACH_MSG_VIRTUAL_COPY) {
2495 /*
2496 * Invalid copy option
2497 */
2498 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2499 mr = MACH_SEND_INVALID_TYPE;
2500 goto out;
2501 }
2502
2503 if ((size >= MSG_OOL_SIZE_SMALL) &&
2504 (daddr->out_of_line.copy == MACH_MSG_PHYSICAL_COPY) &&
2505 !(daddr->out_of_line.deallocate)) {
2506
2507 /*
2508 * Out-of-line memory descriptor, accumulate kernel
2509 * memory requirements
2510 */
2511 if (space_needed + round_page(size) <= space_needed) {
2512 /* Overflow dectected */
2513 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2514 mr = MACH_MSG_VM_KERNEL;
2515 goto out;
2516 }
2517
2518 space_needed += round_page(size);
2519 if (space_needed > ipc_kmsg_max_vm_space) {
2520
2521 /*
2522 * Per message kernel memory limit exceeded
2523 */
2524 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2525 mr = MACH_MSG_VM_KERNEL;
2526 goto out;
2527 }
2528 }
2529 }
2530 }
2531
2532 /*
2533 * Allocate space in the pageable kernel ipc copy map for all the
2534 * ool data that is to be physically copied. Map is marked wait for
2535 * space.
2536 */
2537 if (space_needed) {
2538 if (vm_allocate(ipc_kernel_copy_map, &paddr, space_needed,
2539 VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_IPC)) != KERN_SUCCESS) {
2540 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2541 mr = MACH_MSG_VM_KERNEL;
2542 goto out;
2543 }
2544 }
2545
2546 /* user_addr = just after base as it was copied in */
2547 user_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2548
2549 /* Shift the mach_msg_base_t down to make room for dsc_count*16bytes of descriptors */
2550 if(descriptor_size != 16*dsc_count) {
2551 vm_offset_t dsc_adjust = 16*dsc_count - descriptor_size;
2552
2553 memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
2554 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust);
2555
2556 /* Update the message size for the larger in-kernel representation */
2557 kmsg->ikm_header->msgh_size += (mach_msg_size_t)dsc_adjust;
2558 }
2559
2560
2561 /* kern_addr = just after base after it has been (conditionally) moved */
2562 kern_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2563
2564 /* handle the OOL regions and port descriptors. */
2565 for(i=0;i<dsc_count;i++) {
2566 switch (user_addr->type.type) {
2567 case MACH_MSG_PORT_DESCRIPTOR:
2568 user_addr = ipc_kmsg_copyin_port_descriptor((mach_msg_port_descriptor_t *)kern_addr,
2569 (mach_msg_legacy_port_descriptor_t *)user_addr, space, dest, kmsg, &mr);
2570 kern_addr++;
2571 complex = TRUE;
2572 break;
2573 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2574 case MACH_MSG_OOL_DESCRIPTOR:
2575 user_addr = ipc_kmsg_copyin_ool_descriptor((mach_msg_ool_descriptor_t *)kern_addr,
2576 user_addr, is_task_64bit, &paddr, &copy, &space_needed, map, &mr);
2577 kern_addr++;
2578 complex = TRUE;
2579 break;
2580 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2581 user_addr = ipc_kmsg_copyin_ool_ports_descriptor((mach_msg_ool_ports_descriptor_t *)kern_addr,
2582 user_addr, is_task_64bit, map, space, dest, kmsg, &mr);
2583 kern_addr++;
2584 complex = TRUE;
2585 break;
2586 default:
2587 /* Invalid descriptor */
2588 mr = MACH_SEND_INVALID_TYPE;
2589 break;
2590 }
2591
2592 if (MACH_MSG_SUCCESS != mr) {
2593 /* clean from start of message descriptors to i */
2594 ipc_kmsg_clean_partial(kmsg, i,
2595 (mach_msg_descriptor_t *)((mach_msg_base_t *)kmsg->ikm_header + 1),
2596 paddr, space_needed);
2597 goto out;
2598 }
2599 } /* End of loop */
2600
2601 if (!complex) {
2602 kmsg->ikm_header->msgh_bits &= ~MACH_MSGH_BITS_COMPLEX;
2603 }
2604 out:
2605 return mr;
2606 }
2607
2608
2609 /*
2610 * Routine: ipc_kmsg_copyin
2611 * Purpose:
2612 * "Copy-in" port rights and out-of-line memory
2613 * in the message.
2614 *
2615 * In all failure cases, the message is left holding
2616 * no rights or memory. However, the message buffer
2617 * is not deallocated. If successful, the message
2618 * contains a valid destination port.
2619 * Conditions:
2620 * Nothing locked.
2621 * Returns:
2622 * MACH_MSG_SUCCESS Successful copyin.
2623 * MACH_SEND_INVALID_HEADER
2624 * Illegal value in the message header bits.
2625 * MACH_SEND_INVALID_DEST Can't copyin destination port.
2626 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
2627 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
2628 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
2629 * MACH_SEND_INVALID_TYPE Bad type specification.
2630 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
2631 */
2632
2633 mach_msg_return_t
2634 ipc_kmsg_copyin(
2635 ipc_kmsg_t kmsg,
2636 ipc_space_t space,
2637 vm_map_t map,
2638 mach_msg_option_t *optionp)
2639 {
2640 mach_msg_return_t mr;
2641
2642 kmsg->ikm_header->msgh_bits &= MACH_MSGH_BITS_USER;
2643
2644 mr = ipc_kmsg_copyin_header(kmsg, space, optionp);
2645
2646 if (mr != MACH_MSG_SUCCESS)
2647 return mr;
2648
2649 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC,MACH_IPC_MSG_SEND) | DBG_FUNC_NONE,
2650 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
2651 (uintptr_t)kmsg->ikm_header->msgh_bits,
2652 (uintptr_t)kmsg->ikm_header->msgh_id,
2653 VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(kmsg->ikm_voucher)),
2654 0);
2655
2656 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_copyin header:\n%.8x\n%.8x\n%p\n%p\n%p\n%.8x\n",
2657 kmsg->ikm_header->msgh_size,
2658 kmsg->ikm_header->msgh_bits,
2659 kmsg->ikm_header->msgh_remote_port,
2660 kmsg->ikm_header->msgh_local_port,
2661 kmsg->ikm_voucher,
2662 kmsg->ikm_header->msgh_id);
2663
2664 if ((kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0)
2665 return MACH_MSG_SUCCESS;
2666
2667 mr = ipc_kmsg_copyin_body( kmsg, space, map);
2668
2669 /* unreachable if !DEBUG */
2670 __unreachable_ok_push
2671 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK))
2672 {
2673 kprintf("body:\n");
2674 uint32_t i;
2675 for(i=0;i*4 < (kmsg->ikm_header->msgh_size - sizeof(mach_msg_header_t));i++)
2676 {
2677 kprintf("%.4x\n",((uint32_t *)(kmsg->ikm_header + 1))[i]);
2678 }
2679 }
2680 __unreachable_ok_pop
2681
2682 return mr;
2683 }
2684
2685 /*
2686 * Routine: ipc_kmsg_copyin_from_kernel
2687 * Purpose:
2688 * "Copy-in" port rights and out-of-line memory
2689 * in a message sent from the kernel.
2690 *
2691 * Because the message comes from the kernel,
2692 * the implementation assumes there are no errors
2693 * or peculiarities in the message.
2694 * Conditions:
2695 * Nothing locked.
2696 */
2697
2698 mach_msg_return_t
2699 ipc_kmsg_copyin_from_kernel(
2700 ipc_kmsg_t kmsg)
2701 {
2702 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
2703 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
2704 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
2705 ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2706 ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
2707
2708 /* translate the destination and reply ports */
2709 if (!IO_VALID(remote))
2710 return MACH_SEND_INVALID_DEST;
2711
2712 ipc_object_copyin_from_kernel(remote, rname);
2713 if (IO_VALID(local))
2714 ipc_object_copyin_from_kernel(local, lname);
2715
2716 /*
2717 * The common case is a complex message with no reply port,
2718 * because that is what the memory_object interface uses.
2719 */
2720
2721 if (bits == (MACH_MSGH_BITS_COMPLEX |
2722 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
2723 bits = (MACH_MSGH_BITS_COMPLEX |
2724 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
2725
2726 kmsg->ikm_header->msgh_bits = bits;
2727 } else {
2728 bits = (MACH_MSGH_BITS_OTHER(bits) |
2729 MACH_MSGH_BITS(ipc_object_copyin_type(rname),
2730 ipc_object_copyin_type(lname)));
2731
2732 kmsg->ikm_header->msgh_bits = bits;
2733 if ((bits & MACH_MSGH_BITS_COMPLEX) == 0)
2734 return MACH_MSG_SUCCESS;
2735 }
2736 {
2737 mach_msg_descriptor_t *saddr;
2738 mach_msg_body_t *body;
2739 mach_msg_type_number_t i, count;
2740
2741 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2742 saddr = (mach_msg_descriptor_t *) (body + 1);
2743 count = body->msgh_descriptor_count;
2744
2745 for (i = 0; i < count; i++, saddr++) {
2746
2747 switch (saddr->type.type) {
2748
2749 case MACH_MSG_PORT_DESCRIPTOR: {
2750 mach_msg_type_name_t name;
2751 ipc_object_t object;
2752 mach_msg_port_descriptor_t *dsc;
2753
2754 dsc = &saddr->port;
2755
2756 /* this is really the type SEND, SEND_ONCE, etc. */
2757 name = dsc->disposition;
2758 object = (ipc_object_t) dsc->name;
2759 dsc->disposition = ipc_object_copyin_type(name);
2760
2761 if (!IO_VALID(object)) {
2762 break;
2763 }
2764
2765 ipc_object_copyin_from_kernel(object, name);
2766
2767 /* CDY avoid circularity when the destination is also */
2768 /* the kernel. This check should be changed into an */
2769 /* assert when the new kobject model is in place since*/
2770 /* ports will not be used in kernel to kernel chats */
2771
2772 if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) {
2773 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2774 ipc_port_check_circularity((ipc_port_t) object,
2775 (ipc_port_t) remote)) {
2776 kmsg->ikm_header->msgh_bits |=
2777 MACH_MSGH_BITS_CIRCULAR;
2778 }
2779 }
2780 break;
2781 }
2782 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2783 case MACH_MSG_OOL_DESCRIPTOR: {
2784 /*
2785 * The sender should supply ready-made memory, i.e.
2786 * a vm_map_copy_t, so we don't need to do anything.
2787 */
2788 break;
2789 }
2790 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
2791 ipc_object_t *objects;
2792 unsigned int j;
2793 mach_msg_type_name_t name;
2794 mach_msg_ool_ports_descriptor_t *dsc;
2795
2796 dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports;
2797
2798 /* this is really the type SEND, SEND_ONCE, etc. */
2799 name = dsc->disposition;
2800 dsc->disposition = ipc_object_copyin_type(name);
2801
2802 objects = (ipc_object_t *) dsc->address;
2803
2804 for ( j = 0; j < dsc->count; j++) {
2805 ipc_object_t object = objects[j];
2806
2807 if (!IO_VALID(object))
2808 continue;
2809
2810 ipc_object_copyin_from_kernel(object, name);
2811
2812 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2813 ipc_port_check_circularity(
2814 (ipc_port_t) object,
2815 (ipc_port_t) remote))
2816 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2817 }
2818 break;
2819 }
2820 default: {
2821 #if MACH_ASSERT
2822 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2823 #endif /* MACH_ASSERT */
2824 }
2825 }
2826 }
2827 }
2828 return MACH_MSG_SUCCESS;
2829 }
2830
2831 #if IKM_SUPPORT_LEGACY
2832 mach_msg_return_t
2833 ipc_kmsg_copyin_from_kernel_legacy(
2834 ipc_kmsg_t kmsg)
2835 {
2836 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
2837 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
2838 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
2839 ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2840 ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
2841
2842 /* translate the destination and reply ports */
2843 if (!IO_VALID(remote))
2844 return MACH_SEND_INVALID_DEST;
2845
2846 ipc_object_copyin_from_kernel(remote, rname);
2847 if (IO_VALID(local))
2848 ipc_object_copyin_from_kernel(local, lname);
2849
2850 /*
2851 * The common case is a complex message with no reply port,
2852 * because that is what the memory_object interface uses.
2853 */
2854
2855 if (bits == (MACH_MSGH_BITS_COMPLEX |
2856 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
2857 bits = (MACH_MSGH_BITS_COMPLEX |
2858 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
2859
2860 kmsg->ikm_header->msgh_bits = bits;
2861 } else {
2862 bits = (MACH_MSGH_BITS_OTHER(bits) |
2863 MACH_MSGH_BITS(ipc_object_copyin_type(rname),
2864 ipc_object_copyin_type(lname)));
2865
2866 kmsg->ikm_header->msgh_bits = bits;
2867 if ((bits & MACH_MSGH_BITS_COMPLEX) == 0)
2868 return MACH_MSG_SUCCESS;
2869 }
2870 {
2871 mach_msg_legacy_descriptor_t *saddr;
2872 mach_msg_descriptor_t *daddr;
2873 mach_msg_body_t *body;
2874 mach_msg_type_number_t i, count;
2875
2876 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2877 saddr = (typeof(saddr)) (body + 1);
2878 count = body->msgh_descriptor_count;
2879
2880 if(count) {
2881 vm_offset_t dsc_adjust = 4*count;
2882 memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
2883 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust);
2884 /* Update the message size for the larger in-kernel representation */
2885 kmsg->ikm_header->msgh_size += dsc_adjust;
2886 }
2887 daddr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2888
2889 for (i = 0; i < count; i++, saddr++, daddr++) {
2890 switch (saddr->type.type) {
2891
2892 case MACH_MSG_PORT_DESCRIPTOR: {
2893 mach_msg_type_name_t name;
2894 ipc_object_t object;
2895 mach_msg_legacy_port_descriptor_t *dsc;
2896 mach_msg_port_descriptor_t *dest_dsc;
2897
2898 dsc = (typeof(dsc))&saddr->port;
2899 dest_dsc = &daddr->port;
2900
2901 /* this is really the type SEND, SEND_ONCE, etc. */
2902 name = dsc->disposition;
2903 object = (ipc_object_t) CAST_MACH_NAME_TO_PORT(dsc->name);
2904 dest_dsc->disposition = ipc_object_copyin_type(name);
2905 dest_dsc->name = (mach_port_t)object;
2906 dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
2907
2908 if (!IO_VALID(object)) {
2909 break;
2910 }
2911
2912 ipc_object_copyin_from_kernel(object, name);
2913
2914 /* CDY avoid circularity when the destination is also */
2915 /* the kernel. This check should be changed into an */
2916 /* assert when the new kobject model is in place since*/
2917 /* ports will not be used in kernel to kernel chats */
2918
2919 if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) {
2920 if ((dest_dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2921 ipc_port_check_circularity((ipc_port_t) object,
2922 (ipc_port_t) remote)) {
2923 kmsg->ikm_header->msgh_bits |=
2924 MACH_MSGH_BITS_CIRCULAR;
2925 }
2926 }
2927 break;
2928 }
2929 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2930 case MACH_MSG_OOL_DESCRIPTOR: {
2931 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
2932 * so we don't need to do anything special. */
2933
2934 mach_msg_ool_descriptor32_t *source_dsc = &saddr->out_of_line32;
2935 mach_msg_ool_descriptor_t *dest_dsc = (typeof(dest_dsc))&daddr->out_of_line;
2936
2937 vm_offset_t address = source_dsc->address;
2938 vm_size_t size = source_dsc->size;
2939 boolean_t deallocate = source_dsc->deallocate;
2940 mach_msg_copy_options_t copy = source_dsc->copy;
2941 mach_msg_descriptor_type_t type = source_dsc->type;
2942
2943 dest_dsc->address = (void *)address;
2944 dest_dsc->size = size;
2945 dest_dsc->deallocate = deallocate;
2946 dest_dsc->copy = copy;
2947 dest_dsc->type = type;
2948 break;
2949 }
2950 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
2951 ipc_object_t *objects;
2952 unsigned int j;
2953 mach_msg_type_name_t name;
2954 mach_msg_ool_ports_descriptor_t *dest_dsc;
2955
2956 mach_msg_ool_ports_descriptor32_t *source_dsc = &saddr->ool_ports32;
2957 dest_dsc = (typeof(dest_dsc))&daddr->ool_ports;
2958
2959 boolean_t deallocate = source_dsc->deallocate;
2960 mach_msg_copy_options_t copy = source_dsc->copy;
2961 mach_msg_size_t port_count = source_dsc->count;
2962 mach_msg_type_name_t disposition = source_dsc->disposition;
2963
2964 /* this is really the type SEND, SEND_ONCE, etc. */
2965 name = disposition;
2966 disposition = ipc_object_copyin_type(name);
2967
2968 objects = (ipc_object_t *) (uintptr_t)source_dsc->address;
2969
2970 for ( j = 0; j < port_count; j++) {
2971 ipc_object_t object = objects[j];
2972
2973 if (!IO_VALID(object))
2974 continue;
2975
2976 ipc_object_copyin_from_kernel(object, name);
2977
2978 if ((disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2979 ipc_port_check_circularity(
2980 (ipc_port_t) object,
2981 (ipc_port_t) remote))
2982 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2983 }
2984
2985 dest_dsc->address = objects;
2986 dest_dsc->deallocate = deallocate;
2987 dest_dsc->copy = copy;
2988 dest_dsc->disposition = disposition;
2989 dest_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
2990 dest_dsc->count = port_count;
2991 break;
2992 }
2993 default: {
2994 #if MACH_ASSERT
2995 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2996 #endif /* MACH_ASSERT */
2997 }
2998 }
2999 }
3000 }
3001 return MACH_MSG_SUCCESS;
3002 }
3003 #endif /* IKM_SUPPORT_LEGACY */
3004
3005 /*
3006 * Routine: ipc_kmsg_copyout_header
3007 * Purpose:
3008 * "Copy-out" port rights in the header of a message.
3009 * Operates atomically; if it doesn't succeed the
3010 * message header and the space are left untouched.
3011 * If it does succeed the remote/local port fields
3012 * contain port names instead of object pointers,
3013 * and the bits field is updated.
3014 * Conditions:
3015 * Nothing locked.
3016 * Returns:
3017 * MACH_MSG_SUCCESS Copied out port rights.
3018 * MACH_RCV_INVALID_NOTIFY
3019 * Notify is non-null and doesn't name a receive right.
3020 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
3021 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3022 * The space is dead.
3023 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3024 * No room in space for another name.
3025 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3026 * Couldn't allocate memory for the reply port.
3027 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3028 * Couldn't allocate memory for the dead-name request.
3029 */
3030
3031 mach_msg_return_t
3032 ipc_kmsg_copyout_header(
3033 ipc_kmsg_t kmsg,
3034 ipc_space_t space,
3035 mach_msg_option_t option)
3036 {
3037 mach_msg_header_t *msg = kmsg->ikm_header;
3038 mach_msg_bits_t mbits = msg->msgh_bits;
3039 ipc_port_t dest = (ipc_port_t) msg->msgh_remote_port;
3040
3041 assert(IP_VALID(dest));
3042
3043 /*
3044 * While we still hold a reference on the received-from port,
3045 * process all send-possible notfications we received along with
3046 * the message.
3047 */
3048 ipc_port_spnotify(dest);
3049
3050 {
3051 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3052 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3053 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3054 ipc_port_t reply = msg->msgh_local_port;
3055 ipc_port_t release_reply_port = IP_NULL;
3056 mach_port_name_t dest_name, reply_name;
3057
3058 ipc_port_t voucher = kmsg->ikm_voucher;
3059 ipc_port_t release_voucher_port = IP_NULL;
3060 mach_port_name_t voucher_name;
3061
3062 uint32_t entries_held = 0;
3063 boolean_t need_write_lock = FALSE;
3064 kern_return_t kr;
3065
3066 /*
3067 * Reserve any potentially needed entries in the target space.
3068 * We'll free any unused before unlocking the space.
3069 */
3070 if (IP_VALID(reply)) {
3071 entries_held++;
3072 need_write_lock = TRUE;
3073 }
3074 if (IP_VALID(voucher)) {
3075 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3076
3077 if ((option & MACH_RCV_VOUCHER) != 0)
3078 entries_held++;
3079 need_write_lock = TRUE;
3080 }
3081
3082 if (need_write_lock) {
3083
3084 is_write_lock(space);
3085
3086 while(entries_held) {
3087 if (!is_active(space)) {
3088 is_write_unlock(space);
3089 return (MACH_RCV_HEADER_ERROR|
3090 MACH_MSG_IPC_SPACE);
3091 }
3092
3093 kr = ipc_entries_hold(space, entries_held);
3094 if (KERN_SUCCESS == kr)
3095 break;
3096
3097 kr = ipc_entry_grow_table(space, ITS_SIZE_NONE);
3098 if (KERN_SUCCESS != kr)
3099 return(MACH_RCV_HEADER_ERROR|
3100 MACH_MSG_IPC_SPACE);
3101 /* space was unlocked and relocked - retry */
3102 }
3103
3104 /* Handle reply port. */
3105 if (IP_VALID(reply)) {
3106 ipc_entry_t entry;
3107
3108 /* Is there already an entry we can use? */
3109 if ((reply_type != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
3110 ipc_right_reverse(space, (ipc_object_t) reply, &reply_name, &entry)) {
3111 /* reply port is locked and active */
3112 assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE);
3113 } else {
3114 ip_lock(reply);
3115 if (!ip_active(reply)) {
3116 ip_unlock(reply);
3117
3118 release_reply_port = reply;
3119 reply = IP_DEAD;
3120 reply_name = MACH_PORT_DEAD;
3121 goto done_with_reply;
3122 }
3123
3124 /* claim a held entry for the reply port */
3125 assert(entries_held > 0);
3126 entries_held--;
3127 ipc_entry_claim(space, &reply_name, &entry);
3128 assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
3129 assert(entry->ie_object == IO_NULL);
3130 entry->ie_object = (ipc_object_t) reply;
3131 }
3132
3133 /* space and reply port are locked and active */
3134 ip_reference(reply); /* hold onto the reply port */
3135
3136 kr = ipc_right_copyout(space, reply_name, entry,
3137 reply_type, TRUE, (ipc_object_t) reply);
3138 assert(kr == KERN_SUCCESS);
3139 /* reply port is unlocked */
3140 } else
3141 reply_name = CAST_MACH_PORT_TO_NAME(reply);
3142
3143 done_with_reply:
3144
3145 /* Handle voucher port. */
3146 if (voucher_type != MACH_MSGH_BITS_ZERO) {
3147 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3148
3149 if (!IP_VALID(voucher)) {
3150 if ((option & MACH_RCV_VOUCHER) == 0) {
3151 voucher_type = MACH_MSGH_BITS_ZERO;
3152 }
3153 voucher_name = MACH_PORT_NULL;
3154 goto done_with_voucher;
3155 }
3156
3157 /* clear voucher from its hiding place back in the kmsg */
3158 kmsg->ikm_voucher = IP_NULL;
3159
3160 if ((option & MACH_RCV_VOUCHER) != 0) {
3161 ipc_entry_t entry;
3162
3163 if (ipc_right_reverse(space, (ipc_object_t) voucher,
3164 &voucher_name, &entry)) {
3165 /* voucher port locked */
3166 assert(entry->ie_bits & MACH_PORT_TYPE_SEND);
3167 } else {
3168 assert(entries_held > 0);
3169 entries_held--;
3170 ipc_entry_claim(space, &voucher_name, &entry);
3171 assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
3172 assert(entry->ie_object == IO_NULL);
3173 entry->ie_object = (ipc_object_t) voucher;
3174 ip_lock(voucher);
3175 }
3176 /* space is locked and active */
3177
3178 assert(ip_active(voucher));
3179 assert(ip_kotype(voucher) == IKOT_VOUCHER);
3180 kr = ipc_right_copyout(space, voucher_name, entry,
3181 MACH_MSG_TYPE_MOVE_SEND, TRUE,
3182 (ipc_object_t) voucher);
3183 /* voucher port is unlocked */
3184 } else {
3185 voucher_type = MACH_MSGH_BITS_ZERO;
3186 release_voucher_port = voucher;
3187 voucher_name = MACH_PORT_NULL;
3188 }
3189 } else {
3190 voucher_name = msg->msgh_voucher_port;
3191 }
3192
3193 done_with_voucher:
3194
3195 ip_lock(dest);
3196 is_write_unlock(space);
3197
3198 } else {
3199 /*
3200 * No reply or voucher port! This is an easy case.
3201 * We only need to have the space locked
3202 * when locking the destination.
3203 */
3204
3205 is_read_lock(space);
3206 if (!is_active(space)) {
3207 is_read_unlock(space);
3208 return MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE;
3209 }
3210
3211 ip_lock(dest);
3212 is_read_unlock(space);
3213
3214 reply_name = CAST_MACH_PORT_TO_NAME(reply);
3215
3216 if (voucher_type != MACH_MSGH_BITS_ZERO) {
3217 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3218 if ((option & MACH_RCV_VOUCHER) == 0) {
3219 voucher_type = MACH_MSGH_BITS_ZERO;
3220 }
3221 voucher_name = MACH_PORT_NULL;
3222 } else {
3223 voucher_name = msg->msgh_voucher_port;
3224 }
3225 }
3226
3227 /*
3228 * At this point, the space is unlocked and the destination
3229 * port is locked. (Lock taken while space was locked.)
3230 * reply_name is taken care of; we still need dest_name.
3231 * We still hold a ref for reply (if it is valid).
3232 *
3233 * If the space holds receive rights for the destination,
3234 * we return its name for the right. Otherwise the task
3235 * managed to destroy or give away the receive right between
3236 * receiving the message and this copyout. If the destination
3237 * is dead, return MACH_PORT_DEAD, and if the receive right
3238 * exists somewhere else (another space, in transit)
3239 * return MACH_PORT_NULL.
3240 *
3241 * Making this copyout operation atomic with the previous
3242 * copyout of the reply port is a bit tricky. If there was
3243 * no real reply port (it wasn't IP_VALID) then this isn't
3244 * an issue. If the reply port was dead at copyout time,
3245 * then we are OK, because if dest is dead we serialize
3246 * after the death of both ports and if dest is alive
3247 * we serialize after reply died but before dest's (later) death.
3248 * So assume reply was alive when we copied it out. If dest
3249 * is alive, then we are OK because we serialize before
3250 * the ports' deaths. So assume dest is dead when we look at it.
3251 * If reply dies/died after dest, then we are OK because
3252 * we serialize after dest died but before reply dies.
3253 * So the hard case is when reply is alive at copyout,
3254 * dest is dead at copyout, and reply died before dest died.
3255 * In this case pretend that dest is still alive, so
3256 * we serialize while both ports are alive.
3257 *
3258 * Because the space lock is held across the copyout of reply
3259 * and locking dest, the receive right for dest can't move
3260 * in or out of the space while the copyouts happen, so
3261 * that isn't an atomicity problem. In the last hard case
3262 * above, this implies that when dest is dead that the
3263 * space couldn't have had receive rights for dest at
3264 * the time reply was copied-out, so when we pretend
3265 * that dest is still alive, we can return MACH_PORT_NULL.
3266 *
3267 * If dest == reply, then we have to make it look like
3268 * either both copyouts happened before the port died,
3269 * or both happened after the port died. This special
3270 * case works naturally if the timestamp comparison
3271 * is done correctly.
3272 */
3273
3274 if (ip_active(dest)) {
3275 ipc_object_copyout_dest(space, (ipc_object_t) dest,
3276 dest_type, &dest_name);
3277 /* dest is unlocked */
3278
3279 } else {
3280 ipc_port_timestamp_t timestamp;
3281
3282 timestamp = dest->ip_timestamp;
3283 ip_unlock(dest);
3284 ip_release(dest);
3285
3286 if (IP_VALID(reply)) {
3287 ip_lock(reply);
3288 if (ip_active(reply) ||
3289 IP_TIMESTAMP_ORDER(timestamp,
3290 reply->ip_timestamp))
3291 dest_name = MACH_PORT_DEAD;
3292 else
3293 dest_name = MACH_PORT_NULL;
3294 ip_unlock(reply);
3295 } else
3296 dest_name = MACH_PORT_DEAD;
3297 }
3298
3299 if (IP_VALID(reply))
3300 ip_release(reply);
3301
3302 if (IP_VALID(release_reply_port)) {
3303 if (reply_type == MACH_MSG_TYPE_PORT_SEND_ONCE)
3304 ipc_port_release_sonce(release_reply_port);
3305 else
3306 ipc_port_release_send(release_reply_port);
3307 }
3308
3309 if (IP_VALID(release_voucher_port))
3310 ipc_port_release_send(release_voucher_port);
3311
3312
3313 if ((option & MACH_RCV_VOUCHER) != 0) {
3314 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV) | DBG_FUNC_NONE,
3315 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3316 (uintptr_t)kmsg->ikm_header->msgh_bits,
3317 (uintptr_t)kmsg->ikm_header->msgh_id,
3318 VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(voucher)),
3319 0);
3320 } else {
3321 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV_VOUCHER_REFUSED) | DBG_FUNC_NONE,
3322 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3323 (uintptr_t)kmsg->ikm_header->msgh_bits,
3324 (uintptr_t)kmsg->ikm_header->msgh_id,
3325 VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(voucher)),
3326 0);
3327 }
3328
3329 msg->msgh_bits = MACH_MSGH_BITS_SET(reply_type, dest_type,
3330 voucher_type, mbits);
3331 msg->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
3332 msg->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3333 msg->msgh_voucher_port = voucher_name;
3334 }
3335
3336 return MACH_MSG_SUCCESS;
3337 }
3338
3339 /*
3340 * Routine: ipc_kmsg_copyout_object
3341 * Purpose:
3342 * Copy-out a port right. Always returns a name,
3343 * even for unsuccessful return codes. Always
3344 * consumes the supplied object.
3345 * Conditions:
3346 * Nothing locked.
3347 * Returns:
3348 * MACH_MSG_SUCCESS The space acquired the right
3349 * (name is valid) or the object is dead (MACH_PORT_DEAD).
3350 * MACH_MSG_IPC_SPACE No room in space for the right,
3351 * or the space is dead. (Name is MACH_PORT_NULL.)
3352 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
3353 * (Name is MACH_PORT_NULL.)
3354 */
3355
3356 mach_msg_return_t
3357 ipc_kmsg_copyout_object(
3358 ipc_space_t space,
3359 ipc_object_t object,
3360 mach_msg_type_name_t msgt_name,
3361 mach_port_name_t *namep)
3362 {
3363 kern_return_t kr;
3364
3365 if (!IO_VALID(object)) {
3366 *namep = CAST_MACH_PORT_TO_NAME(object);
3367 return MACH_MSG_SUCCESS;
3368 }
3369
3370 kr = ipc_object_copyout(space, object, msgt_name, TRUE, namep);
3371 if (kr != KERN_SUCCESS) {
3372 ipc_object_destroy(object, msgt_name);
3373
3374 if (kr == KERN_INVALID_CAPABILITY)
3375 *namep = MACH_PORT_DEAD;
3376 else {
3377 *namep = MACH_PORT_NULL;
3378
3379 if (kr == KERN_RESOURCE_SHORTAGE)
3380 return MACH_MSG_IPC_KERNEL;
3381 else
3382 return MACH_MSG_IPC_SPACE;
3383 }
3384 }
3385
3386 return MACH_MSG_SUCCESS;
3387 }
3388
3389 mach_msg_descriptor_t *
3390 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc,
3391 mach_msg_descriptor_t *user_dsc,
3392 ipc_space_t space,
3393 kern_return_t *mr);
3394 mach_msg_descriptor_t *
3395 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc,
3396 mach_msg_descriptor_t *dest_dsc,
3397 ipc_space_t space,
3398 kern_return_t *mr)
3399 {
3400 mach_port_t port;
3401 mach_port_name_t name;
3402 mach_msg_type_name_t disp;
3403
3404
3405 /* Copyout port right carried in the message */
3406 port = dsc->port.name;
3407 disp = dsc->port.disposition;
3408 *mr |= ipc_kmsg_copyout_object(space,
3409 (ipc_object_t)port,
3410 disp,
3411 &name);
3412
3413 if(current_task() == kernel_task)
3414 {
3415 mach_msg_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc;
3416 user_dsc--; // point to the start of this port descriptor
3417 user_dsc->name = CAST_MACH_NAME_TO_PORT(name);
3418 user_dsc->disposition = disp;
3419 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
3420 dest_dsc = (typeof(dest_dsc))user_dsc;
3421 } else {
3422 mach_msg_legacy_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc;
3423 user_dsc--; // point to the start of this port descriptor
3424 user_dsc->name = CAST_MACH_PORT_TO_NAME(name);
3425 user_dsc->disposition = disp;
3426 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
3427 dest_dsc = (typeof(dest_dsc))user_dsc;
3428 }
3429
3430 return (mach_msg_descriptor_t *)dest_dsc;
3431 }
3432
3433 mach_msg_descriptor_t *
3434 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);
3435 mach_msg_descriptor_t *
3436 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)
3437 {
3438 vm_map_copy_t copy;
3439 vm_map_address_t rcv_addr;
3440 mach_msg_copy_options_t copy_options;
3441 mach_msg_size_t size;
3442 mach_msg_descriptor_type_t dsc_type;
3443
3444 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3445
3446 copy = (vm_map_copy_t) dsc->address;
3447 size = dsc->size;
3448 copy_options = dsc->copy;
3449 assert(copy_options != MACH_MSG_KALLOC_COPY_T);
3450 dsc_type = dsc->type;
3451
3452 if (copy != VM_MAP_COPY_NULL) {
3453 kern_return_t kr;
3454
3455 rcv_addr = 0;
3456 if (vm_map_copy_validate_size(map, copy, (vm_map_size_t)size) == FALSE)
3457 panic("Inconsistent OOL/copyout size on %p: expected %d, got %lld @%p",
3458 dsc, size, (unsigned long long)copy->size, copy);
3459 kr = vm_map_copyout(map, &rcv_addr, copy);
3460 if (kr != KERN_SUCCESS) {
3461 if (kr == KERN_RESOURCE_SHORTAGE)
3462 *mr |= MACH_MSG_VM_KERNEL;
3463 else
3464 *mr |= MACH_MSG_VM_SPACE;
3465 vm_map_copy_discard(copy);
3466 rcv_addr = 0;
3467 size = 0;
3468 }
3469 } else {
3470 rcv_addr = 0;
3471 size = 0;
3472 }
3473
3474 /*
3475 * Now update the descriptor as the user would see it.
3476 * This may require expanding the descriptor to the user
3477 * visible size. There is already space allocated for
3478 * this in what naddr points to.
3479 */
3480 if(current_task() == kernel_task)
3481 {
3482 mach_msg_ool_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3483 user_ool_dsc--;
3484
3485 user_ool_dsc->address = (void *)(uintptr_t)rcv_addr;
3486 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3487 TRUE : FALSE;
3488 user_ool_dsc->copy = copy_options;
3489 user_ool_dsc->type = dsc_type;
3490 user_ool_dsc->size = size;
3491
3492 user_dsc = (typeof(user_dsc))user_ool_dsc;
3493 } else if (is_64bit) {
3494 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3495 user_ool_dsc--;
3496
3497 user_ool_dsc->address = rcv_addr;
3498 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3499 TRUE : FALSE;
3500 user_ool_dsc->copy = copy_options;
3501 user_ool_dsc->type = dsc_type;
3502 user_ool_dsc->size = size;
3503
3504 user_dsc = (typeof(user_dsc))user_ool_dsc;
3505 } else {
3506 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3507 user_ool_dsc--;
3508
3509 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
3510 user_ool_dsc->size = size;
3511 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3512 TRUE : FALSE;
3513 user_ool_dsc->copy = copy_options;
3514 user_ool_dsc->type = dsc_type;
3515
3516 user_dsc = (typeof(user_dsc))user_ool_dsc;
3517 }
3518 return user_dsc;
3519 }
3520
3521 mach_msg_descriptor_t *
3522 ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc,
3523 mach_msg_descriptor_t *user_dsc,
3524 int is_64bit,
3525 vm_map_t map,
3526 ipc_space_t space,
3527 ipc_kmsg_t kmsg,
3528 mach_msg_return_t *mr);
3529 mach_msg_descriptor_t *
3530 ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc,
3531 mach_msg_descriptor_t *user_dsc,
3532 int is_64bit,
3533 vm_map_t map,
3534 ipc_space_t space,
3535 ipc_kmsg_t kmsg,
3536 mach_msg_return_t *mr)
3537 {
3538 mach_vm_offset_t rcv_addr = 0;
3539 mach_msg_type_name_t disp;
3540 mach_msg_type_number_t count, i;
3541 vm_size_t ports_length, names_length;
3542
3543 mach_msg_copy_options_t copy_options = MACH_MSG_VIRTUAL_COPY;
3544
3545 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3546
3547 count = dsc->count;
3548 disp = dsc->disposition;
3549 ports_length = count * sizeof(mach_port_t);
3550 names_length = count * sizeof(mach_port_name_t);
3551
3552 if (ports_length != 0 && dsc->address != 0) {
3553
3554 /*
3555 * Check to see if there is an overwrite descriptor
3556 * specified in the scatter list for this ool data.
3557 * The descriptor has already been verified.
3558 */
3559 #if 0
3560 if (saddr != MACH_MSG_DESCRIPTOR_NULL) {
3561 if (differs) {
3562 OTHER_OOL_DESCRIPTOR *scatter_dsc;
3563
3564 scatter_dsc = (OTHER_OOL_DESCRIPTOR *)saddr;
3565 rcv_addr = (mach_vm_offset_t) scatter_dsc->address;
3566 copy_options = scatter_dsc->copy;
3567 } else {
3568 mach_msg_ool_descriptor_t *scatter_dsc;
3569
3570 scatter_dsc = &saddr->out_of_line;
3571 rcv_addr = CAST_USER_ADDR_T(scatter_dsc->address);
3572 copy_options = scatter_dsc->copy;
3573 }
3574 INCREMENT_SCATTER(saddr, sdsc_count, differs);
3575 }
3576 #endif
3577
3578 if (copy_options == MACH_MSG_VIRTUAL_COPY) {
3579 /*
3580 * Dynamically allocate the region
3581 */
3582 int anywhere = VM_FLAGS_ANYWHERE;
3583 if (vm_kernel_map_is_kernel(map)) anywhere |= VM_MAKE_TAG(VM_KERN_MEMORY_IPC);
3584 else anywhere |= VM_MAKE_TAG(VM_MEMORY_MACH_MSG);
3585
3586 kern_return_t kr;
3587 if ((kr = mach_vm_allocate(map, &rcv_addr,
3588 (mach_vm_size_t)names_length,
3589 anywhere)) != KERN_SUCCESS) {
3590 ipc_kmsg_clean_body(kmsg, 1, (mach_msg_descriptor_t *)dsc);
3591 rcv_addr = 0;
3592
3593 if (kr == KERN_RESOURCE_SHORTAGE){
3594 *mr |= MACH_MSG_VM_KERNEL;
3595 } else {
3596 *mr |= MACH_MSG_VM_SPACE;
3597 }
3598 }
3599 }
3600
3601 /*
3602 * Handle the port rights and copy out the names
3603 * for those rights out to user-space.
3604 */
3605 if (rcv_addr != 0) {
3606 mach_port_t *objects = (mach_port_t *) dsc->address;
3607 mach_port_name_t *names = (mach_port_name_t *) dsc->address;
3608
3609 /* copyout port rights carried in the message */
3610
3611 for ( i = 0; i < count ; i++) {
3612 ipc_object_t object = (ipc_object_t)objects[i];
3613
3614 *mr |= ipc_kmsg_copyout_object(space, object,
3615 disp, &names[i]);
3616 }
3617
3618 /* copyout to memory allocated above */
3619 void *data = dsc->address;
3620 if (copyoutmap(map, data, rcv_addr, names_length) != KERN_SUCCESS)
3621 *mr |= MACH_MSG_VM_SPACE;
3622 kfree(data, ports_length);
3623 }
3624 } else {
3625 rcv_addr = 0;
3626 }
3627
3628 /*
3629 * Now update the descriptor based on the information
3630 * calculated above.
3631 */
3632 if(current_task() == kernel_task) {
3633 mach_msg_ool_ports_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3634 user_ool_dsc--;
3635
3636 user_ool_dsc->address = (void *)(uintptr_t)rcv_addr;
3637 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3638 TRUE : FALSE;
3639 user_ool_dsc->copy = copy_options;
3640 user_ool_dsc->disposition = disp;
3641 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3642 user_ool_dsc->count = count;
3643
3644 user_dsc = (typeof(user_dsc))user_ool_dsc;
3645 } if (is_64bit) {
3646 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3647 user_ool_dsc--;
3648
3649 user_ool_dsc->address = rcv_addr;
3650 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3651 TRUE : FALSE;
3652 user_ool_dsc->copy = copy_options;
3653 user_ool_dsc->disposition = disp;
3654 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3655 user_ool_dsc->count = count;
3656
3657 user_dsc = (typeof(user_dsc))user_ool_dsc;
3658 } else {
3659 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3660 user_ool_dsc--;
3661
3662 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
3663 user_ool_dsc->count = count;
3664 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3665 TRUE : FALSE;
3666 user_ool_dsc->copy = copy_options;
3667 user_ool_dsc->disposition = disp;
3668 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3669
3670 user_dsc = (typeof(user_dsc))user_ool_dsc;
3671 }
3672 return user_dsc;
3673 }
3674
3675 /*
3676 * Routine: ipc_kmsg_copyout_body
3677 * Purpose:
3678 * "Copy-out" port rights and out-of-line memory
3679 * in the body of a message.
3680 *
3681 * The error codes are a combination of special bits.
3682 * The copyout proceeds despite errors.
3683 * Conditions:
3684 * Nothing locked.
3685 * Returns:
3686 * MACH_MSG_SUCCESS Successful copyout.
3687 * MACH_MSG_IPC_SPACE No room for port right in name space.
3688 * MACH_MSG_VM_SPACE No room for memory in address space.
3689 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
3690 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
3691 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
3692 */
3693
3694 mach_msg_return_t
3695 ipc_kmsg_copyout_body(
3696 ipc_kmsg_t kmsg,
3697 ipc_space_t space,
3698 vm_map_t map,
3699 mach_msg_body_t *slist)
3700 {
3701 mach_msg_body_t *body;
3702 mach_msg_descriptor_t *kern_dsc, *user_dsc;
3703 mach_msg_descriptor_t *saddr;
3704 mach_msg_type_number_t dsc_count, sdsc_count;
3705 int i;
3706 mach_msg_return_t mr = MACH_MSG_SUCCESS;
3707 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
3708
3709 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3710 dsc_count = body->msgh_descriptor_count;
3711 kern_dsc = (mach_msg_descriptor_t *) (body + 1);
3712 /* Point user_dsc just after the end of all the descriptors */
3713 user_dsc = &kern_dsc[dsc_count];
3714
3715 /* Do scatter list setup */
3716 if (slist != MACH_MSG_BODY_NULL) {
3717 panic("Scatter lists disabled");
3718 saddr = (mach_msg_descriptor_t *) (slist + 1);
3719 sdsc_count = slist->msgh_descriptor_count;
3720 }
3721 else {
3722 saddr = MACH_MSG_DESCRIPTOR_NULL;
3723 sdsc_count = 0;
3724 }
3725
3726 /* Now process the descriptors */
3727 for (i = dsc_count-1; i >= 0; i--) {
3728 switch (kern_dsc[i].type.type) {
3729
3730 case MACH_MSG_PORT_DESCRIPTOR:
3731 user_dsc = ipc_kmsg_copyout_port_descriptor(&kern_dsc[i], user_dsc, space, &mr);
3732 break;
3733 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3734 case MACH_MSG_OOL_DESCRIPTOR :
3735 user_dsc = ipc_kmsg_copyout_ool_descriptor(
3736 (mach_msg_ool_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, &mr);
3737 break;
3738 case MACH_MSG_OOL_PORTS_DESCRIPTOR :
3739 user_dsc = ipc_kmsg_copyout_ool_ports_descriptor(
3740 (mach_msg_ool_ports_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, space, kmsg, &mr);
3741 break;
3742 default : {
3743 panic("untyped IPC copyout body: invalid message descriptor");
3744 }
3745 }
3746 }
3747
3748 if(user_dsc != kern_dsc) {
3749 vm_offset_t dsc_adjust = (vm_offset_t)user_dsc - (vm_offset_t)kern_dsc;
3750 memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
3751 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust);
3752 /* Update the message size for the smaller user representation */
3753 kmsg->ikm_header->msgh_size -= (mach_msg_size_t)dsc_adjust;
3754 }
3755
3756 return mr;
3757 }
3758
3759 /*
3760 * Routine: ipc_kmsg_copyout_size
3761 * Purpose:
3762 * Compute the size of the message as copied out to the given
3763 * map. If the destination map's pointers are a different size
3764 * than the kernel's, we have to allow for expansion/
3765 * contraction of the descriptors as appropriate.
3766 * Conditions:
3767 * Nothing locked.
3768 * Returns:
3769 * size of the message as it would be received.
3770 */
3771
3772 mach_msg_size_t
3773 ipc_kmsg_copyout_size(
3774 ipc_kmsg_t kmsg,
3775 vm_map_t map)
3776 {
3777 mach_msg_size_t send_size;
3778
3779 send_size = kmsg->ikm_header->msgh_size;
3780
3781 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
3782
3783 #if defined(__LP64__)
3784 send_size -= LEGACY_HEADER_SIZE_DELTA;
3785 #endif
3786
3787 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3788
3789 mach_msg_body_t *body;
3790 mach_msg_descriptor_t *saddr, *eaddr;
3791
3792 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3793 saddr = (mach_msg_descriptor_t *) (body + 1);
3794 eaddr = saddr + body->msgh_descriptor_count;
3795
3796 for ( ; saddr < eaddr; saddr++ ) {
3797 switch (saddr->type.type) {
3798 case MACH_MSG_OOL_DESCRIPTOR:
3799 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3800 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
3801 if(!is_task_64bit)
3802 send_size -= DESC_SIZE_ADJUSTMENT;
3803 break;
3804 case MACH_MSG_PORT_DESCRIPTOR:
3805 send_size -= DESC_SIZE_ADJUSTMENT;
3806 break;
3807 default:
3808 break;
3809 }
3810 }
3811 }
3812 return send_size;
3813 }
3814
3815 /*
3816 * Routine: ipc_kmsg_copyout
3817 * Purpose:
3818 * "Copy-out" port rights and out-of-line memory
3819 * in the message.
3820 * Conditions:
3821 * Nothing locked.
3822 * Returns:
3823 * MACH_MSG_SUCCESS Copied out all rights and memory.
3824 * MACH_RCV_HEADER_ERROR + special bits
3825 * Rights and memory in the message are intact.
3826 * MACH_RCV_BODY_ERROR + special bits
3827 * The message header was successfully copied out.
3828 * As much of the body was handled as possible.
3829 */
3830
3831 mach_msg_return_t
3832 ipc_kmsg_copyout(
3833 ipc_kmsg_t kmsg,
3834 ipc_space_t space,
3835 vm_map_t map,
3836 mach_msg_body_t *slist,
3837 mach_msg_option_t option)
3838 {
3839 mach_msg_return_t mr;
3840
3841 mr = ipc_kmsg_copyout_header(kmsg, space, option);
3842 if (mr != MACH_MSG_SUCCESS) {
3843 return mr;
3844 }
3845
3846 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3847 mr = ipc_kmsg_copyout_body(kmsg, space, map, slist);
3848
3849 if (mr != MACH_MSG_SUCCESS)
3850 mr |= MACH_RCV_BODY_ERROR;
3851 }
3852
3853 return mr;
3854 }
3855
3856 /*
3857 * Routine: ipc_kmsg_copyout_pseudo
3858 * Purpose:
3859 * Does a pseudo-copyout of the message.
3860 * This is like a regular copyout, except
3861 * that the ports in the header are handled
3862 * as if they are in the body. They aren't reversed.
3863 *
3864 * The error codes are a combination of special bits.
3865 * The copyout proceeds despite errors.
3866 * Conditions:
3867 * Nothing locked.
3868 * Returns:
3869 * MACH_MSG_SUCCESS Successful copyout.
3870 * MACH_MSG_IPC_SPACE No room for port right in name space.
3871 * MACH_MSG_VM_SPACE No room for memory in address space.
3872 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
3873 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
3874 */
3875
3876 mach_msg_return_t
3877 ipc_kmsg_copyout_pseudo(
3878 ipc_kmsg_t kmsg,
3879 ipc_space_t space,
3880 vm_map_t map,
3881 mach_msg_body_t *slist)
3882 {
3883 mach_msg_bits_t mbits = kmsg->ikm_header->msgh_bits;
3884 ipc_object_t dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
3885 ipc_object_t reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
3886 ipc_object_t voucher = (ipc_object_t) kmsg->ikm_voucher;
3887 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3888 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3889 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3890 mach_port_name_t voucher_name = kmsg->ikm_header->msgh_voucher_port;
3891 mach_port_name_t dest_name, reply_name;
3892 mach_msg_return_t mr;
3893
3894 assert(IO_VALID(dest));
3895
3896 #if 0
3897 /*
3898 * If we did this here, it looks like we wouldn't need the undo logic
3899 * at the end of ipc_kmsg_send() in the error cases. Not sure which
3900 * would be more elegant to keep.
3901 */
3902 ipc_importance_clean(kmsg);
3903 #else
3904 /* just assert it is already clean */
3905 ipc_importance_assert_clean(kmsg);
3906 #endif
3907
3908 mr = (ipc_kmsg_copyout_object(space, dest, dest_type, &dest_name) |
3909 ipc_kmsg_copyout_object(space, reply, reply_type, &reply_name));
3910
3911 kmsg->ikm_header->msgh_bits = mbits & MACH_MSGH_BITS_USER;
3912 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(dest_name);
3913 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(reply_name);
3914
3915 if (IO_VALID(voucher)) {
3916 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3917
3918 kmsg->ikm_voucher = IP_NULL;
3919 mr |= ipc_kmsg_copyout_object(space, voucher, voucher_type, &voucher_name);
3920 kmsg->ikm_header->msgh_voucher_port = voucher_name;
3921 }
3922
3923 if (mbits & MACH_MSGH_BITS_COMPLEX) {
3924 mr |= ipc_kmsg_copyout_body(kmsg, space, map, slist);
3925 }
3926
3927 return mr;
3928 }
3929
3930 /*
3931 * Routine: ipc_kmsg_copyout_dest
3932 * Purpose:
3933 * Copies out the destination port in the message.
3934 * Destroys all other rights and memory in the message.
3935 * Conditions:
3936 * Nothing locked.
3937 */
3938
3939 void
3940 ipc_kmsg_copyout_dest(
3941 ipc_kmsg_t kmsg,
3942 ipc_space_t space)
3943 {
3944 mach_msg_bits_t mbits;
3945 ipc_object_t dest;
3946 ipc_object_t reply;
3947 ipc_object_t voucher;
3948 mach_msg_type_name_t dest_type;
3949 mach_msg_type_name_t reply_type;
3950 mach_msg_type_name_t voucher_type;
3951 mach_port_name_t dest_name, reply_name, voucher_name;
3952
3953 mbits = kmsg->ikm_header->msgh_bits;
3954 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
3955 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
3956 voucher = (ipc_object_t) kmsg->ikm_voucher;
3957 voucher_name = kmsg->ikm_header->msgh_voucher_port;
3958 dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3959 reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3960 voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3961
3962 assert(IO_VALID(dest));
3963
3964 ipc_importance_assert_clean(kmsg);
3965
3966 io_lock(dest);
3967 if (io_active(dest)) {
3968 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
3969 /* dest is unlocked */
3970 } else {
3971 io_unlock(dest);
3972 io_release(dest);
3973 dest_name = MACH_PORT_DEAD;
3974 }
3975
3976 if (IO_VALID(reply)) {
3977 ipc_object_destroy(reply, reply_type);
3978 reply_name = MACH_PORT_NULL;
3979 } else
3980 reply_name = CAST_MACH_PORT_TO_NAME(reply);
3981
3982 if (IO_VALID(voucher)) {
3983 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3984
3985 kmsg->ikm_voucher = IP_NULL;
3986 ipc_object_destroy((ipc_object_t)voucher, voucher_type);
3987 voucher_name = MACH_PORT_NULL;
3988 }
3989
3990 kmsg->ikm_header->msgh_bits = MACH_MSGH_BITS_SET(reply_type, dest_type,
3991 voucher_type, mbits);
3992 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
3993 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3994 kmsg->ikm_header->msgh_voucher_port = voucher_name;
3995
3996 if (mbits & MACH_MSGH_BITS_COMPLEX) {
3997 mach_msg_body_t *body;
3998
3999 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
4000 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count,
4001 (mach_msg_descriptor_t *)(body + 1));
4002 }
4003 }
4004
4005 /*
4006 * Routine: ipc_kmsg_copyout_to_kernel
4007 * Purpose:
4008 * Copies out the destination and reply ports in the message.
4009 * Leaves all other rights and memory in the message alone.
4010 * Conditions:
4011 * Nothing locked.
4012 *
4013 * Derived from ipc_kmsg_copyout_dest.
4014 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
4015 * We really do want to save rights and memory.
4016 */
4017
4018 void
4019 ipc_kmsg_copyout_to_kernel(
4020 ipc_kmsg_t kmsg,
4021 ipc_space_t space)
4022 {
4023 ipc_object_t dest;
4024 ipc_object_t reply;
4025 mach_msg_type_name_t dest_type;
4026 mach_msg_type_name_t reply_type;
4027 mach_port_name_t dest_name, reply_name;
4028
4029 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
4030 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
4031 dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits);
4032 reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits);
4033
4034 assert(IO_VALID(dest));
4035
4036 io_lock(dest);
4037 if (io_active(dest)) {
4038 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
4039 /* dest is unlocked */
4040 } else {
4041 io_unlock(dest);
4042 io_release(dest);
4043 dest_name = MACH_PORT_DEAD;
4044 }
4045
4046 reply_name = CAST_MACH_PORT_TO_NAME(reply);
4047
4048 kmsg->ikm_header->msgh_bits =
4049 (MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) |
4050 MACH_MSGH_BITS(reply_type, dest_type));
4051 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
4052 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
4053 }
4054
4055 #if IKM_SUPPORT_LEGACY
4056 void
4057 ipc_kmsg_copyout_to_kernel_legacy(
4058 ipc_kmsg_t kmsg,
4059 ipc_space_t space)
4060 {
4061 ipc_object_t dest;
4062 ipc_object_t reply;
4063 mach_msg_type_name_t dest_type;
4064 mach_msg_type_name_t reply_type;
4065 mach_port_name_t dest_name, reply_name;
4066
4067 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
4068 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
4069 dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits);
4070 reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits);
4071
4072 assert(IO_VALID(dest));
4073
4074 io_lock(dest);
4075 if (io_active(dest)) {
4076 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
4077 /* dest is unlocked */
4078 } else {
4079 io_unlock(dest);
4080 io_release(dest);
4081 dest_name = MACH_PORT_DEAD;
4082 }
4083
4084 reply_name = CAST_MACH_PORT_TO_NAME(reply);
4085
4086 kmsg->ikm_header->msgh_bits =
4087 (MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) |
4088 MACH_MSGH_BITS(reply_type, dest_type));
4089 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
4090 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
4091
4092 mach_msg_descriptor_t *saddr;
4093 mach_msg_legacy_descriptor_t *daddr;
4094 mach_msg_type_number_t i, count = ((mach_msg_base_t *)kmsg->ikm_header)->body.msgh_descriptor_count;
4095 saddr = (mach_msg_descriptor_t *) (((mach_msg_base_t *)kmsg->ikm_header) + 1);
4096 saddr = &saddr[count-1];
4097 daddr = (mach_msg_legacy_descriptor_t *)&saddr[count];
4098 daddr--;
4099
4100 vm_offset_t dsc_adjust = 0;
4101
4102 for (i = 0; i < count; i++, saddr--, daddr--) {
4103 switch (saddr->type.type) {
4104 case MACH_MSG_PORT_DESCRIPTOR: {
4105 mach_msg_port_descriptor_t *dsc = &saddr->port;
4106 mach_msg_legacy_port_descriptor_t *dest_dsc = &daddr->port;
4107
4108 mach_port_t name = dsc->name;
4109 mach_msg_type_name_t disposition = dsc->disposition;
4110
4111 dest_dsc->name = CAST_MACH_PORT_TO_NAME(name);
4112 dest_dsc->disposition = disposition;
4113 dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
4114 break;
4115 }
4116 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4117 case MACH_MSG_OOL_DESCRIPTOR: {
4118 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
4119 * so we don't need to do anything special. */
4120
4121 mach_msg_ool_descriptor_t *source_dsc = (typeof(source_dsc))&saddr->out_of_line;
4122
4123 mach_msg_ool_descriptor32_t *dest_dsc = &daddr->out_of_line32;
4124
4125 vm_offset_t address = (vm_offset_t)source_dsc->address;
4126 vm_size_t size = source_dsc->size;
4127 boolean_t deallocate = source_dsc->deallocate;
4128 mach_msg_copy_options_t copy = source_dsc->copy;
4129 mach_msg_descriptor_type_t type = source_dsc->type;
4130
4131 dest_dsc->address = address;
4132 dest_dsc->size = size;
4133 dest_dsc->deallocate = deallocate;
4134 dest_dsc->copy = copy;
4135 dest_dsc->type = type;
4136 break;
4137 }
4138 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
4139 mach_msg_ool_ports_descriptor_t *source_dsc = (typeof(source_dsc))&saddr->ool_ports;
4140
4141 mach_msg_ool_ports_descriptor32_t *dest_dsc = &daddr->ool_ports32;
4142
4143 vm_offset_t address = (vm_offset_t)source_dsc->address;
4144 vm_size_t port_count = source_dsc->count;
4145 boolean_t deallocate = source_dsc->deallocate;
4146 mach_msg_copy_options_t copy = source_dsc->copy;
4147 mach_msg_descriptor_type_t type = source_dsc->type;
4148
4149 dest_dsc->address = address;
4150 dest_dsc->count = port_count;
4151 dest_dsc->deallocate = deallocate;
4152 dest_dsc->copy = copy;
4153 dest_dsc->type = type;
4154 break;
4155 }
4156 default: {
4157 #if MACH_ASSERT
4158 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
4159 #endif /* MACH_ASSERT */
4160 }
4161 }
4162 }
4163
4164 if(count) {
4165 dsc_adjust = 4*count;
4166 memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
4167 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust);
4168 /* Update the message size for the smaller user representation */
4169 kmsg->ikm_header->msgh_size -= dsc_adjust;
4170 }
4171 }
4172 #endif /* IKM_SUPPORT_LEGACY */
4173
4174
4175 mach_msg_trailer_size_t
4176 ipc_kmsg_add_trailer(ipc_kmsg_t kmsg, ipc_space_t space __unused,
4177 mach_msg_option_t option, thread_t thread,
4178 mach_port_seqno_t seqno, boolean_t minimal_trailer,
4179 mach_vm_offset_t context)
4180 {
4181 mach_msg_max_trailer_t *trailer;
4182
4183 (void)thread;
4184 trailer = (mach_msg_max_trailer_t *)
4185 ((vm_offset_t)kmsg->ikm_header +
4186 round_msg(kmsg->ikm_header->msgh_size));
4187
4188 if (!(option & MACH_RCV_TRAILER_MASK)) {
4189 return trailer->msgh_trailer_size;
4190 }
4191
4192 trailer->msgh_seqno = seqno;
4193 trailer->msgh_context = context;
4194 trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit(thread), option);
4195
4196 if (minimal_trailer) {
4197 goto done;
4198 }
4199
4200 if (MACH_RCV_TRAILER_ELEMENTS(option) >=
4201 MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV)){
4202 trailer->msgh_ad = 0;
4203 }
4204
4205 /*
4206 * The ipc_kmsg_t holds a reference to the label of a label
4207 * handle, not the port. We must get a reference to the port
4208 * and a send right to copyout to the receiver.
4209 */
4210
4211 if (option & MACH_RCV_TRAILER_ELEMENTS (MACH_RCV_TRAILER_LABELS)) {
4212 trailer->msgh_labels.sender = 0;
4213 }
4214
4215 done:
4216
4217 return trailer->msgh_trailer_size;
4218 }