]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ipc/ipc_kmsg.c
xnu-3247.1.106.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 spl_t s;
1379
1380 /* Check if honor qlimit flag is set on thread. */
1381 if ((th->options & TH_OPT_HONOR_QLIMIT) == TH_OPT_HONOR_QLIMIT) {
1382 /* Remove the MACH_SEND_ALWAYS flag to honor queue limit. */
1383 option &= (~MACH_SEND_ALWAYS);
1384 /* Add the timeout flag since the message queue might be full. */
1385 option |= MACH_SEND_TIMEOUT;
1386 th->options &= (~TH_OPT_HONOR_QLIMIT);
1387 }
1388
1389 #if IMPORTANCE_INHERITANCE
1390 boolean_t did_importance = FALSE;
1391 #if IMPORTANCE_DEBUG
1392 mach_msg_id_t imp_msgh_id = -1;
1393 int sender_pid = -1;
1394 #endif /* IMPORTANCE_DEBUG */
1395 #endif /* IMPORTANCE_INHERITANCE */
1396
1397 /* don't allow the creation of a circular loop */
1398 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_CIRCULAR) {
1399 ipc_kmsg_destroy(kmsg);
1400 return MACH_MSG_SUCCESS;
1401 }
1402
1403 port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port;
1404 assert(IP_VALID(port));
1405 ip_lock(port);
1406
1407 #if IMPORTANCE_INHERITANCE
1408 retry:
1409 #endif /* IMPORTANCE_INHERITANCE */
1410 /*
1411 * Can't deliver to a dead port.
1412 * However, we can pretend it got sent
1413 * and was then immediately destroyed.
1414 */
1415 if (!ip_active(port)) {
1416 ip_unlock(port);
1417 ip_release(port); /* JMM - Future: release right, not just ref */
1418 kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
1419 ipc_kmsg_destroy(kmsg);
1420 return MACH_MSG_SUCCESS;
1421 }
1422
1423 if (port->ip_receiver == ipc_space_kernel) {
1424
1425 /*
1426 * We can check ip_receiver == ipc_space_kernel
1427 * before checking that the port is active because
1428 * ipc_port_dealloc_kernel clears ip_receiver
1429 * before destroying a kernel port.
1430 */
1431 assert(ip_active(port));
1432 port->ip_messages.imq_seqno++;
1433 ip_unlock(port);
1434
1435 current_task()->messages_sent++;
1436
1437 /*
1438 * Call the server routine, and get the reply message to send.
1439 */
1440 kmsg = ipc_kobject_server(kmsg);
1441 if (kmsg == IKM_NULL)
1442 return MACH_MSG_SUCCESS;
1443
1444 port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port;
1445 assert(IP_VALID(port));
1446 ip_lock(port);
1447 /* fall thru with reply - same options */
1448 }
1449
1450 #if IMPORTANCE_INHERITANCE
1451 /*
1452 * Need to see if this message needs importance donation and/or
1453 * propagation. That routine can drop the port lock temporarily.
1454 * If it does we'll have to revalidate the destination.
1455 */
1456 if (did_importance == FALSE) {
1457 did_importance = TRUE;
1458 if (ipc_importance_send(kmsg, option))
1459 goto retry;
1460 }
1461 #endif /* IMPORTANCE_INHERITANCE */
1462
1463 /*
1464 * We have a valid message and a valid reference on the port.
1465 * we can unlock the port and call mqueue_send() on its message
1466 * queue. Lock message queue while port is locked.
1467 */
1468 s = splsched();
1469 imq_lock(&port->ip_messages);
1470 ip_unlock(port);
1471
1472 error = ipc_mqueue_send(&port->ip_messages, kmsg, option,
1473 send_timeout, s);
1474
1475 #if IMPORTANCE_INHERITANCE
1476 if (did_importance == TRUE) {
1477 __unused int importance_cleared = 0;
1478 switch (error) {
1479 case MACH_SEND_TIMED_OUT:
1480 case MACH_SEND_NO_BUFFER:
1481 case MACH_SEND_INTERRUPTED:
1482 case MACH_SEND_INVALID_DEST:
1483 /*
1484 * We still have the kmsg and its
1485 * reference on the port. But we
1486 * have to back out the importance
1487 * boost.
1488 *
1489 * The port could have changed hands,
1490 * be inflight to another destination,
1491 * etc... But in those cases our
1492 * back-out will find the new owner
1493 * (and all the operations that
1494 * transferred the right should have
1495 * applied their own boost adjustments
1496 * to the old owner(s)).
1497 */
1498 importance_cleared = 1;
1499 ipc_importance_clean(kmsg);
1500 break;
1501
1502 case MACH_MSG_SUCCESS:
1503 default:
1504 break;
1505 }
1506 #if IMPORTANCE_DEBUG
1507 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, (IMPORTANCE_CODE(IMP_MSG, IMP_MSG_SEND)) | DBG_FUNC_END,
1508 task_pid(current_task()), sender_pid, imp_msgh_id, importance_cleared, 0);
1509 #endif /* IMPORTANCE_DEBUG */
1510 }
1511 #endif /* IMPORTANCE_INHERITANCE */
1512
1513 /*
1514 * If the port has been destroyed while we wait, treat the message
1515 * as a successful delivery (like we do for an inactive port).
1516 */
1517 if (error == MACH_SEND_INVALID_DEST) {
1518 ip_release(port); /* JMM - Future: release right, not just ref */
1519 kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL;
1520 ipc_kmsg_destroy(kmsg);
1521 return MACH_MSG_SUCCESS;
1522 }
1523 return error;
1524 }
1525
1526 /*
1527 * Routine: ipc_kmsg_put
1528 * Purpose:
1529 * Copies a message buffer to a user message.
1530 * Copies only the specified number of bytes.
1531 * Frees the message buffer.
1532 * Conditions:
1533 * Nothing locked. The message buffer must have clean
1534 * header fields.
1535 * Returns:
1536 * MACH_MSG_SUCCESS Copied data out of message buffer.
1537 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
1538 */
1539
1540 mach_msg_return_t
1541 ipc_kmsg_put(
1542 mach_vm_address_t msg_addr,
1543 ipc_kmsg_t kmsg,
1544 mach_msg_size_t size)
1545 {
1546 mach_msg_return_t mr;
1547
1548 DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_put()");
1549
1550
1551 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_put header:\n"
1552 " size: 0x%.8x\n"
1553 " bits: 0x%.8x\n"
1554 " remote_port: %p\n"
1555 " local_port: %p\n"
1556 " voucher_port: 0x%.8x\n"
1557 " id: %.8d\n",
1558 kmsg->ikm_header->msgh_size,
1559 kmsg->ikm_header->msgh_bits,
1560 kmsg->ikm_header->msgh_remote_port,
1561 kmsg->ikm_header->msgh_local_port,
1562 kmsg->ikm_header->msgh_voucher_port,
1563 kmsg->ikm_header->msgh_id);
1564
1565 #if defined(__LP64__)
1566 if (current_task() != kernel_task) { /* don't if receiver expects fully-cooked in-kernel msg; ux_exception */
1567 mach_msg_legacy_header_t *legacy_header =
1568 (mach_msg_legacy_header_t *)((vm_offset_t)(kmsg->ikm_header) + LEGACY_HEADER_SIZE_DELTA);
1569
1570 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
1571 mach_msg_size_t msg_size = kmsg->ikm_header->msgh_size;
1572 mach_port_name_t remote_port = CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_remote_port);
1573 mach_port_name_t local_port = CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_local_port);
1574 mach_port_name_t voucher_port = kmsg->ikm_header->msgh_voucher_port;
1575 mach_msg_id_t id = kmsg->ikm_header->msgh_id;
1576
1577 legacy_header->msgh_id = id;
1578 legacy_header->msgh_local_port = local_port;
1579 legacy_header->msgh_remote_port = remote_port;
1580 legacy_header->msgh_voucher_port = voucher_port;
1581 legacy_header->msgh_size = msg_size - LEGACY_HEADER_SIZE_DELTA;
1582 legacy_header->msgh_bits = bits;
1583
1584 size -= LEGACY_HEADER_SIZE_DELTA;
1585 kmsg->ikm_header = (mach_msg_header_t *)legacy_header;
1586 }
1587 #endif
1588
1589 /* unreachable if !DEBUG */
1590 __unreachable_ok_push
1591 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) {
1592 kprintf("ipc_kmsg_put header+body: %d\n", (size));
1593 uint32_t i;
1594 for(i=0;i*4 < size;i++)
1595 {
1596 kprintf("%.4x\n",((uint32_t *)kmsg->ikm_header)[i]);
1597 }
1598 kprintf("type: %d\n", ((mach_msg_type_descriptor_t *)(((mach_msg_base_t *)kmsg->ikm_header)+1))->type);
1599 }
1600 __unreachable_ok_pop
1601 if (copyoutmsg((const char *) kmsg->ikm_header, msg_addr, size))
1602 mr = MACH_RCV_INVALID_DATA;
1603 else
1604 mr = MACH_MSG_SUCCESS;
1605
1606 ipc_kmsg_free(kmsg);
1607 return mr;
1608 }
1609
1610 /*
1611 * Routine: ipc_kmsg_put_to_kernel
1612 * Purpose:
1613 * Copies a message buffer to a kernel message.
1614 * Frees the message buffer.
1615 * No errors allowed.
1616 * Conditions:
1617 * Nothing locked.
1618 */
1619
1620 void
1621 ipc_kmsg_put_to_kernel(
1622 mach_msg_header_t *msg,
1623 ipc_kmsg_t kmsg,
1624 mach_msg_size_t size)
1625 {
1626 (void) memcpy((void *) msg, (const void *) kmsg->ikm_header, size);
1627
1628 ipc_kmsg_free(kmsg);
1629 }
1630
1631 /*
1632 * Routine: ipc_kmsg_copyin_header
1633 * Purpose:
1634 * "Copy-in" port rights in the header of a message.
1635 * Operates atomically; if it doesn't succeed the
1636 * message header and the space are left untouched.
1637 * If it does succeed the remote/local port fields
1638 * contain object pointers instead of port names,
1639 * and the bits field is updated. The destination port
1640 * will be a valid port pointer.
1641 *
1642 * Conditions:
1643 * Nothing locked.
1644 * Returns:
1645 * MACH_MSG_SUCCESS Successful copyin.
1646 * MACH_SEND_INVALID_HEADER
1647 * Illegal value in the message header bits.
1648 * MACH_SEND_INVALID_DEST The space is dead.
1649 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1650 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1651 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1652 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1653 */
1654
1655 mach_msg_return_t
1656 ipc_kmsg_copyin_header(
1657 ipc_kmsg_t kmsg,
1658 ipc_space_t space,
1659 mach_msg_option_t *optionp)
1660 {
1661 mach_msg_header_t *msg = kmsg->ikm_header;
1662 mach_msg_bits_t mbits = msg->msgh_bits & MACH_MSGH_BITS_USER;
1663 mach_port_name_t dest_name = CAST_MACH_PORT_TO_NAME(msg->msgh_remote_port);
1664 mach_port_name_t reply_name = CAST_MACH_PORT_TO_NAME(msg->msgh_local_port);
1665 mach_port_name_t voucher_name = MACH_PORT_NULL;
1666 kern_return_t kr;
1667
1668 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
1669 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
1670 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
1671 ipc_object_t dest_port = IO_NULL;
1672 ipc_object_t reply_port = IO_NULL;
1673 ipc_port_t dest_soright = IP_NULL;
1674 ipc_port_t reply_soright = IP_NULL;
1675 ipc_port_t voucher_soright = IP_NULL;
1676 ipc_port_t release_port = IP_NULL;
1677 ipc_port_t voucher_port = IP_NULL;
1678 ipc_port_t voucher_release_port = IP_NULL;
1679 ipc_entry_t dest_entry = IE_NULL;
1680 ipc_entry_t reply_entry = IE_NULL;
1681 ipc_entry_t voucher_entry = IE_NULL;
1682
1683 int assertcnt = 0;
1684 #if IMPORTANCE_INHERITANCE
1685 boolean_t needboost = FALSE;
1686 #endif /* IMPORTANCE_INHERITANCE */
1687
1688 if ((mbits != msg->msgh_bits) ||
1689 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type)) ||
1690 ((reply_type == 0) ?
1691 (reply_name != MACH_PORT_NULL) :
1692 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type)))
1693 return MACH_SEND_INVALID_HEADER;
1694
1695 if (!MACH_PORT_VALID(dest_name))
1696 return MACH_SEND_INVALID_DEST;
1697
1698 is_write_lock(space);
1699 if (!is_active(space)) {
1700 is_write_unlock(space);
1701 return MACH_SEND_INVALID_DEST;
1702 }
1703 /* space locked and active */
1704
1705 /*
1706 * If there is a voucher specified, make sure the disposition is
1707 * valid and the entry actually refers to a voucher port. Don't
1708 * actually copy in until we validate destination and reply.
1709 */
1710 if (voucher_type != MACH_MSGH_BITS_ZERO) {
1711
1712 voucher_name = msg->msgh_voucher_port;
1713
1714 if (voucher_name == MACH_PORT_DEAD ||
1715 (voucher_type != MACH_MSG_TYPE_MOVE_SEND &&
1716 voucher_type != MACH_MSG_TYPE_COPY_SEND)) {
1717 is_write_unlock(space);
1718 return MACH_SEND_INVALID_VOUCHER;
1719 }
1720
1721 if (voucher_name != MACH_PORT_NULL) {
1722 voucher_entry = ipc_entry_lookup(space, voucher_name);
1723 if (voucher_entry == IE_NULL ||
1724 (voucher_entry->ie_bits & MACH_PORT_TYPE_SEND) == 0 ||
1725 io_kotype(voucher_entry->ie_object) != IKOT_VOUCHER) {
1726 is_write_unlock(space);
1727 return MACH_SEND_INVALID_VOUCHER;
1728 }
1729 } else {
1730 voucher_type = MACH_MSG_TYPE_MOVE_SEND;
1731 }
1732 }
1733
1734 /*
1735 * Handle combinations of validating destination and reply; along
1736 * with copying in destination, reply, and voucher in an atomic way.
1737 */
1738
1739 if (dest_name == voucher_name) {
1740
1741 /*
1742 * If the destination name is the same as the voucher name,
1743 * the voucher_entry must already be known. Either that or
1744 * the destination name is MACH_PORT_NULL (i.e. invalid).
1745 */
1746 dest_entry = voucher_entry;
1747 if (dest_entry == IE_NULL) {
1748 goto invalid_dest;
1749 }
1750
1751 /*
1752 * Make sure a future copyin of the reply port will succeed.
1753 * Once we start copying in the dest/voucher pair, we can't
1754 * back out.
1755 */
1756 if (MACH_PORT_VALID(reply_name)) {
1757 assert(reply_type != 0); /* because reply_name not null */
1758
1759 /* It is just WRONG if dest, voucher, and reply are all the same. */
1760 if (voucher_name == reply_name) {
1761 goto invalid_reply;
1762 }
1763 reply_entry = ipc_entry_lookup(space, reply_name);
1764 if (reply_entry == IE_NULL) {
1765 goto invalid_reply;
1766 }
1767 assert(dest_entry != reply_entry); /* names are not equal */
1768 if (!ipc_right_copyin_check(space, reply_name, reply_entry, reply_type)) {
1769 goto invalid_reply;
1770 }
1771 }
1772
1773 /*
1774 * Do the joint copyin of the dest disposition and
1775 * voucher disposition from the one entry/port. We
1776 * already validated that the voucher copyin would
1777 * succeed (above). So, any failure in combining
1778 * the copyins can be blamed on the destination.
1779 */
1780 kr = ipc_right_copyin_two(space, dest_name, dest_entry,
1781 dest_type, voucher_type,
1782 &dest_port, &dest_soright,
1783 &release_port);
1784 if (kr != KERN_SUCCESS) {
1785 assert(kr != KERN_INVALID_CAPABILITY);
1786 goto invalid_dest;
1787 }
1788 voucher_port = (ipc_port_t)dest_port;
1789
1790 /*
1791 * could not have been one of these dispositions,
1792 * validated the port was a true kernel voucher port above,
1793 * AND was successfully able to copyin both dest and voucher.
1794 */
1795 assert(dest_type != MACH_MSG_TYPE_MAKE_SEND);
1796 assert(dest_type != MACH_MSG_TYPE_MAKE_SEND_ONCE);
1797 assert(dest_type != MACH_MSG_TYPE_MOVE_SEND_ONCE);
1798
1799 /*
1800 * Perform the delayed reply right copyin (guaranteed success).
1801 */
1802 if (reply_entry != IE_NULL) {
1803 kr = ipc_right_copyin(space, reply_name, reply_entry,
1804 reply_type, TRUE,
1805 &reply_port, &reply_soright,
1806 &release_port, &assertcnt);
1807 assert(assertcnt == 0);
1808 assert(kr == KERN_SUCCESS);
1809 }
1810
1811 } else {
1812 if (dest_name == reply_name) {
1813 /*
1814 * Destination and reply ports are the same!
1815 * This is very similar to the case where the
1816 * destination and voucher ports were the same
1817 * (except the reply port disposition is not
1818 * previously validated).
1819 */
1820 dest_entry = ipc_entry_lookup(space, dest_name);
1821 if (dest_entry == IE_NULL) {
1822 goto invalid_dest;
1823 }
1824 reply_entry = dest_entry;
1825 assert(reply_type != 0); /* because name not null */
1826
1827 /*
1828 * Do the joint copyin of the dest disposition and
1829 * reply disposition from the one entry/port.
1830 */
1831 kr = ipc_right_copyin_two(space, dest_name, dest_entry,
1832 dest_type, reply_type,
1833 &dest_port, &dest_soright,
1834 &release_port);
1835 if (kr == KERN_INVALID_CAPABILITY) {
1836 goto invalid_reply;
1837 } else if (kr != KERN_SUCCESS) {
1838 goto invalid_dest;
1839 }
1840 reply_port = dest_port;
1841
1842
1843 } else {
1844 /*
1845 * Handle destination and reply independently, as
1846 * they are independent entries (even if the entries
1847 * refer to the same port).
1848 *
1849 * This can be the tough case to make atomic.
1850 *
1851 * The difficult problem is serializing with port death.
1852 * The bad case is when dest_port dies after its copyin,
1853 * reply_port dies before its copyin, and dest_port dies before
1854 * reply_port. Then the copyins operated as if dest_port was
1855 * alive and reply_port was dead, which shouldn't have happened
1856 * because they died in the other order.
1857 *
1858 * Note that it is easy for a user task to tell if
1859 * a copyin happened before or after a port died.
1860 * If a port dies before copyin, a dead-name notification
1861 * is generated and the dead name's urefs are incremented,
1862 * and if the copyin happens first, a port-deleted
1863 * notification is generated.
1864 *
1865 * Even so, avoiding that potentially detectable race is too
1866 * expensive - and no known code cares about it. So, we just
1867 * do the expedient thing and copy them in one after the other.
1868 */
1869
1870 dest_entry = ipc_entry_lookup(space, dest_name);
1871 if (dest_entry == IE_NULL) {
1872 goto invalid_dest;
1873 }
1874 assert(dest_entry != voucher_entry);
1875
1876 /*
1877 * Make sure reply port entry is valid before dest copyin.
1878 */
1879 if (MACH_PORT_VALID(reply_name)) {
1880 if (reply_name == voucher_name) {
1881 goto invalid_reply;
1882 }
1883 reply_entry = ipc_entry_lookup(space, reply_name);
1884 if (reply_entry == IE_NULL) {
1885 goto invalid_reply;
1886 }
1887 assert(dest_entry != reply_entry); /* names are not equal */
1888 assert(reply_type != 0); /* because reply_name not null */
1889
1890 if (!ipc_right_copyin_check(space, reply_name, reply_entry, reply_type)) {
1891 goto invalid_reply;
1892 }
1893 }
1894
1895 /*
1896 * copyin the destination.
1897 */
1898 kr = ipc_right_copyin(space, dest_name, dest_entry,
1899 dest_type, FALSE,
1900 &dest_port, &dest_soright,
1901 &release_port, &assertcnt);
1902 assert(assertcnt == 0);
1903 if (kr != KERN_SUCCESS) {
1904 goto invalid_dest;
1905 }
1906 assert(IO_VALID(dest_port));
1907 assert(!IP_VALID(release_port));
1908
1909 /*
1910 * Copyin the pre-validated reply right.
1911 * It's OK if the reply right has gone dead in the meantime.
1912 */
1913 if (MACH_PORT_VALID(reply_name)) {
1914 kr = ipc_right_copyin(space, reply_name, reply_entry,
1915 reply_type, TRUE,
1916 &reply_port, &reply_soright,
1917 &release_port, &assertcnt);
1918 assert(assertcnt == 0);
1919 assert(kr == KERN_SUCCESS);
1920 } else {
1921 /* convert invalid name to equivalent ipc_object type */
1922 reply_port = (ipc_object_t)CAST_MACH_NAME_TO_PORT(reply_name);
1923 }
1924 }
1925
1926 /*
1927 * Finally can copyin the voucher right now that dest and reply
1928 * are fully copied in (guaranteed success).
1929 */
1930 if (IE_NULL != voucher_entry) {
1931 kr = ipc_right_copyin(space, voucher_name, voucher_entry,
1932 voucher_type, FALSE,
1933 (ipc_object_t *)&voucher_port,
1934 &voucher_soright,
1935 &voucher_release_port,
1936 &assertcnt);
1937 assert(assertcnt == 0);
1938 assert(KERN_SUCCESS == kr);
1939 assert(IP_VALID(voucher_port));
1940 assert(ip_active(voucher_port));
1941 }
1942 }
1943
1944 /* the entry(s) might need to be deallocated */
1945 assert(IE_NULL != dest_entry);
1946 if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1947 ipc_entry_dealloc(space, dest_name, dest_entry);
1948 dest_entry = IE_NULL;
1949 }
1950 if (dest_entry != reply_entry && IE_NULL != reply_entry &&
1951 IE_BITS_TYPE(reply_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1952 ipc_entry_dealloc(space, reply_name, reply_entry);
1953 reply_entry = IE_NULL;
1954 }
1955 if (dest_entry != voucher_entry && IE_NULL != voucher_entry &&
1956 IE_BITS_TYPE(voucher_entry->ie_bits) == MACH_PORT_TYPE_NONE) {
1957 ipc_entry_dealloc(space, voucher_name, voucher_entry);
1958 voucher_entry = IE_NULL;
1959 }
1960
1961 /*
1962 * No room to store voucher port in in-kernel msg header,
1963 * so we store it back in the kmsg itself.
1964 */
1965 if (IP_VALID(voucher_port)) {
1966 assert(ip_active(voucher_port));
1967 kmsg->ikm_voucher = voucher_port;
1968 voucher_type = MACH_MSG_TYPE_MOVE_SEND;
1969 }
1970
1971 dest_type = ipc_object_copyin_type(dest_type);
1972 reply_type = ipc_object_copyin_type(reply_type);
1973
1974 /*
1975 * JMM - Without rdar://problem/6275821, this is the last place we can
1976 * re-arm the send-possible notifications. It may trigger unexpectedly
1977 * early (send may NOT have failed), but better than missing. We assure
1978 * we won't miss by forcing MACH_SEND_ALWAYS if we got past arming.
1979 */
1980 if (((*optionp & MACH_SEND_NOTIFY) != 0) &&
1981 dest_type != MACH_MSG_TYPE_PORT_SEND_ONCE &&
1982 dest_entry != IE_NULL && dest_entry->ie_request != IE_REQ_NONE) {
1983 ipc_port_t dport = (ipc_port_t)dest_port;
1984
1985 assert(dport != IP_NULL);
1986 ip_lock(dport);
1987 if (ip_active(dport) && dport->ip_receiver != ipc_space_kernel) {
1988 if (ip_full(dport)) {
1989 #if IMPORTANCE_INHERITANCE
1990 needboost = ipc_port_request_sparm(dport, dest_name,
1991 dest_entry->ie_request,
1992 (*optionp & MACH_SEND_NOIMPORTANCE));
1993 if (needboost == FALSE)
1994 ip_unlock(dport);
1995 #else
1996 ipc_port_request_sparm(dport, dest_name, dest_entry->ie_request);
1997 ip_unlock(dport);
1998 #endif /* IMPORTANCE_INHERITANCE */
1999 } else {
2000 *optionp |= MACH_SEND_ALWAYS;
2001 ip_unlock(dport);
2002 }
2003 } else {
2004 ip_unlock(dport);
2005 }
2006 }
2007
2008 is_write_unlock(space);
2009
2010 #if IMPORTANCE_INHERITANCE
2011 /*
2012 * If our request is the first boosting send-possible
2013 * notification this cycle, push the boost down the
2014 * destination port.
2015 */
2016 if (needboost == TRUE) {
2017 ipc_port_t dport = (ipc_port_t)dest_port;
2018
2019 /* dport still locked from above */
2020 if (ipc_port_importance_delta(dport, 1) == FALSE) {
2021 ip_unlock(dport);
2022 }
2023 }
2024 #endif /* IMPORTANCE_INHERITANCE */
2025
2026 if (dest_soright != IP_NULL) {
2027 ipc_notify_port_deleted(dest_soright, dest_name);
2028 }
2029 if (reply_soright != IP_NULL) {
2030 ipc_notify_port_deleted(reply_soright, reply_name);
2031 }
2032 if (voucher_soright != IP_NULL) {
2033 ipc_notify_port_deleted(voucher_soright, voucher_name);
2034 }
2035 msg->msgh_bits = MACH_MSGH_BITS_SET(dest_type, reply_type, voucher_type, mbits);
2036 msg->msgh_remote_port = (ipc_port_t)dest_port;
2037 msg->msgh_local_port = (ipc_port_t)reply_port;
2038
2039 if (release_port != IP_NULL)
2040 ip_release(release_port);
2041
2042 if (voucher_release_port != IP_NULL)
2043 ip_release(voucher_release_port);
2044
2045 return MACH_MSG_SUCCESS;
2046
2047 invalid_reply:
2048 is_write_unlock(space);
2049
2050 if (release_port != IP_NULL)
2051 ip_release(release_port);
2052
2053 assert(voucher_port == IP_NULL);
2054 assert(voucher_soright == IP_NULL);
2055
2056 return MACH_SEND_INVALID_REPLY;
2057
2058 invalid_dest:
2059 is_write_unlock(space);
2060
2061 if (release_port != IP_NULL)
2062 ip_release(release_port);
2063
2064 if (reply_soright != IP_NULL)
2065 ipc_notify_port_deleted(reply_soright, reply_name);
2066
2067 assert(voucher_port == IP_NULL);
2068 assert(voucher_soright == IP_NULL);
2069
2070 return MACH_SEND_INVALID_DEST;
2071 }
2072
2073 mach_msg_descriptor_t *ipc_kmsg_copyin_port_descriptor(
2074 volatile mach_msg_port_descriptor_t *dsc,
2075 mach_msg_legacy_port_descriptor_t *user_dsc,
2076 ipc_space_t space,
2077 ipc_object_t dest,
2078 ipc_kmsg_t kmsg,
2079 mach_msg_return_t *mr);
2080
2081 void ipc_print_type_name(
2082 int type_name);
2083 mach_msg_descriptor_t *
2084 ipc_kmsg_copyin_port_descriptor(
2085 volatile mach_msg_port_descriptor_t *dsc,
2086 mach_msg_legacy_port_descriptor_t *user_dsc_in,
2087 ipc_space_t space,
2088 ipc_object_t dest,
2089 ipc_kmsg_t kmsg,
2090 mach_msg_return_t *mr)
2091 {
2092 volatile mach_msg_legacy_port_descriptor_t *user_dsc = user_dsc_in;
2093 mach_msg_type_name_t user_disp;
2094 mach_msg_type_name_t result_disp;
2095 mach_port_name_t name;
2096 ipc_object_t object;
2097
2098 user_disp = user_dsc->disposition;
2099 result_disp = ipc_object_copyin_type(user_disp);
2100
2101 name = (mach_port_name_t)user_dsc->name;
2102 if (MACH_PORT_VALID(name)) {
2103
2104 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object);
2105 if (kr != KERN_SUCCESS) {
2106 *mr = MACH_SEND_INVALID_RIGHT;
2107 return NULL;
2108 }
2109
2110 if ((result_disp == MACH_MSG_TYPE_PORT_RECEIVE) &&
2111 ipc_port_check_circularity((ipc_port_t) object,
2112 (ipc_port_t) dest)) {
2113 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2114 }
2115 dsc->name = (ipc_port_t) object;
2116 } else {
2117 dsc->name = CAST_MACH_NAME_TO_PORT(name);
2118 }
2119 dsc->disposition = result_disp;
2120 dsc->type = MACH_MSG_PORT_DESCRIPTOR;
2121
2122 dsc->pad_end = 0; // debug, unnecessary
2123
2124 return (mach_msg_descriptor_t *)(user_dsc_in+1);
2125 }
2126
2127 mach_msg_descriptor_t * ipc_kmsg_copyin_ool_descriptor(
2128 mach_msg_ool_descriptor_t *dsc,
2129 mach_msg_descriptor_t *user_dsc,
2130 int is_64bit,
2131 vm_offset_t *paddr,
2132 vm_map_copy_t *copy,
2133 vm_size_t *space_needed,
2134 vm_map_t map,
2135 mach_msg_return_t *mr);
2136 mach_msg_descriptor_t *
2137 ipc_kmsg_copyin_ool_descriptor(
2138 mach_msg_ool_descriptor_t *dsc,
2139 mach_msg_descriptor_t *user_dsc,
2140 int is_64bit,
2141 vm_offset_t *paddr,
2142 vm_map_copy_t *copy,
2143 vm_size_t *space_needed,
2144 vm_map_t map,
2145 mach_msg_return_t *mr)
2146 {
2147 vm_size_t length;
2148 boolean_t dealloc;
2149 mach_msg_copy_options_t copy_options;
2150 mach_vm_offset_t addr;
2151 mach_msg_descriptor_type_t dsc_type;
2152
2153 if (is_64bit) {
2154 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2155
2156 addr = (mach_vm_offset_t) user_ool_dsc->address;
2157 length = user_ool_dsc->size;
2158 dealloc = user_ool_dsc->deallocate;
2159 copy_options = user_ool_dsc->copy;
2160 dsc_type = user_ool_dsc->type;
2161
2162 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2163 } else {
2164 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2165
2166 addr = CAST_USER_ADDR_T(user_ool_dsc->address);
2167 dealloc = user_ool_dsc->deallocate;
2168 copy_options = user_ool_dsc->copy;
2169 dsc_type = user_ool_dsc->type;
2170 length = user_ool_dsc->size;
2171
2172 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2173 }
2174
2175 dsc->size = (mach_msg_size_t)length;
2176 dsc->deallocate = dealloc;
2177 dsc->copy = copy_options;
2178 dsc->type = dsc_type;
2179
2180 if (length == 0) {
2181 dsc->address = NULL;
2182 } else if ((length >= MSG_OOL_SIZE_SMALL) &&
2183 (copy_options == MACH_MSG_PHYSICAL_COPY) && !dealloc) {
2184
2185 /*
2186 * If the request is a physical copy and the source
2187 * is not being deallocated, then allocate space
2188 * in the kernel's pageable ipc copy map and copy
2189 * the data in. The semantics guarantee that the
2190 * data will have been physically copied before
2191 * the send operation terminates. Thus if the data
2192 * is not being deallocated, we must be prepared
2193 * to page if the region is sufficiently large.
2194 */
2195 if (copyin(addr, (char *)*paddr, length)) {
2196 *mr = MACH_SEND_INVALID_MEMORY;
2197 return NULL;
2198 }
2199
2200 /*
2201 * The kernel ipc copy map is marked no_zero_fill.
2202 * If the transfer is not a page multiple, we need
2203 * to zero fill the balance.
2204 */
2205 if (!page_aligned(length)) {
2206 (void) memset((void *) (*paddr + length), 0,
2207 round_page(length) - length);
2208 }
2209 if (vm_map_copyin(ipc_kernel_copy_map, (vm_map_address_t)*paddr,
2210 (vm_map_size_t)length, TRUE, copy) != KERN_SUCCESS) {
2211 *mr = MACH_MSG_VM_KERNEL;
2212 return NULL;
2213 }
2214 dsc->address = (void *)*copy;
2215 *paddr += round_page(length);
2216 *space_needed -= round_page(length);
2217 } else {
2218
2219 /*
2220 * Make a vm_map_copy_t of the of the data. If the
2221 * data is small, this will do an optimized physical
2222 * copy. Otherwise, it will do a virtual copy.
2223 *
2224 * NOTE: A virtual copy is OK if the original is being
2225 * deallocted, even if a physical copy was requested.
2226 */
2227 kern_return_t kr = vm_map_copyin(map, addr,
2228 (vm_map_size_t)length, dealloc, copy);
2229 if (kr != KERN_SUCCESS) {
2230 *mr = (kr == KERN_RESOURCE_SHORTAGE) ?
2231 MACH_MSG_VM_KERNEL :
2232 MACH_SEND_INVALID_MEMORY;
2233 return NULL;
2234 }
2235 dsc->address = (void *)*copy;
2236 }
2237 return user_dsc;
2238 }
2239
2240 mach_msg_descriptor_t * ipc_kmsg_copyin_ool_ports_descriptor(
2241 mach_msg_ool_ports_descriptor_t *dsc,
2242 mach_msg_descriptor_t *user_dsc,
2243 int is_64bit,
2244 vm_map_t map,
2245 ipc_space_t space,
2246 ipc_object_t dest,
2247 ipc_kmsg_t kmsg,
2248 mach_msg_return_t *mr);
2249 mach_msg_descriptor_t *
2250 ipc_kmsg_copyin_ool_ports_descriptor(
2251 mach_msg_ool_ports_descriptor_t *dsc,
2252 mach_msg_descriptor_t *user_dsc,
2253 int is_64bit,
2254 vm_map_t map,
2255 ipc_space_t space,
2256 ipc_object_t dest,
2257 ipc_kmsg_t kmsg,
2258 mach_msg_return_t *mr)
2259 {
2260 void *data;
2261 ipc_object_t *objects;
2262 unsigned int i;
2263 mach_vm_offset_t addr;
2264 mach_msg_type_name_t user_disp;
2265 mach_msg_type_name_t result_disp;
2266 mach_msg_type_number_t count;
2267 mach_msg_copy_options_t copy_option;
2268 boolean_t deallocate;
2269 mach_msg_descriptor_type_t type;
2270 vm_size_t ports_length, names_length;
2271
2272 if (is_64bit) {
2273 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2274
2275 addr = (mach_vm_offset_t)user_ool_dsc->address;
2276 count = user_ool_dsc->count;
2277 deallocate = user_ool_dsc->deallocate;
2278 copy_option = user_ool_dsc->copy;
2279 user_disp = user_ool_dsc->disposition;
2280 type = user_ool_dsc->type;
2281
2282 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2283 } else {
2284 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
2285
2286 addr = CAST_USER_ADDR_T(user_ool_dsc->address);
2287 count = user_ool_dsc->count;
2288 deallocate = user_ool_dsc->deallocate;
2289 copy_option = user_ool_dsc->copy;
2290 user_disp = user_ool_dsc->disposition;
2291 type = user_ool_dsc->type;
2292
2293 user_dsc = (typeof(user_dsc))(user_ool_dsc+1);
2294 }
2295
2296 dsc->deallocate = deallocate;
2297 dsc->copy = copy_option;
2298 dsc->type = type;
2299 dsc->count = count;
2300 dsc->address = NULL; /* for now */
2301
2302 result_disp = ipc_object_copyin_type(user_disp);
2303 dsc->disposition = result_disp;
2304
2305 if (count > (INT_MAX / sizeof(mach_port_t))) {
2306 *mr = MACH_SEND_TOO_LARGE;
2307 return NULL;
2308 }
2309
2310 /* calculate length of data in bytes, rounding up */
2311 ports_length = count * sizeof(mach_port_t);
2312 names_length = count * sizeof(mach_port_name_t);
2313
2314 if (ports_length == 0) {
2315 return user_dsc;
2316 }
2317
2318 data = kalloc(ports_length);
2319
2320 if (data == NULL) {
2321 *mr = MACH_SEND_NO_BUFFER;
2322 return NULL;
2323 }
2324
2325 #ifdef __LP64__
2326 mach_port_name_t *names = &((mach_port_name_t *)data)[count];
2327 #else
2328 mach_port_name_t *names = ((mach_port_name_t *)data);
2329 #endif
2330
2331 if (copyinmap(map, addr, names, names_length) != KERN_SUCCESS) {
2332 kfree(data, ports_length);
2333 *mr = MACH_SEND_INVALID_MEMORY;
2334 return NULL;
2335 }
2336
2337 if (deallocate) {
2338 (void) mach_vm_deallocate(map, addr, (mach_vm_size_t)ports_length);
2339 }
2340
2341 objects = (ipc_object_t *) data;
2342 dsc->address = data;
2343
2344 for ( i = 0; i < count; i++) {
2345 mach_port_name_t name = names[i];
2346 ipc_object_t object;
2347
2348 if (!MACH_PORT_VALID(name)) {
2349 objects[i] = (ipc_object_t)CAST_MACH_NAME_TO_PORT(name);
2350 continue;
2351 }
2352
2353 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object);
2354
2355 if (kr != KERN_SUCCESS) {
2356 unsigned int j;
2357
2358 for(j = 0; j < i; j++) {
2359 object = objects[j];
2360 if (IPC_OBJECT_VALID(object))
2361 ipc_object_destroy(object, result_disp);
2362 }
2363 kfree(data, ports_length);
2364 dsc->address = NULL;
2365 *mr = MACH_SEND_INVALID_RIGHT;
2366 return NULL;
2367 }
2368
2369 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2370 ipc_port_check_circularity(
2371 (ipc_port_t) object,
2372 (ipc_port_t) dest))
2373 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2374
2375 objects[i] = object;
2376 }
2377
2378 return user_dsc;
2379 }
2380
2381 /*
2382 * Routine: ipc_kmsg_copyin_body
2383 * Purpose:
2384 * "Copy-in" port rights and out-of-line memory
2385 * in the message body.
2386 *
2387 * In all failure cases, the message is left holding
2388 * no rights or memory. However, the message buffer
2389 * is not deallocated. If successful, the message
2390 * contains a valid destination port.
2391 * Conditions:
2392 * Nothing locked.
2393 * Returns:
2394 * MACH_MSG_SUCCESS Successful copyin.
2395 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
2396 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
2397 * MACH_SEND_INVALID_TYPE Bad type specification.
2398 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
2399 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
2400 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
2401 */
2402
2403 mach_msg_return_t
2404 ipc_kmsg_copyin_body(
2405 ipc_kmsg_t kmsg,
2406 ipc_space_t space,
2407 vm_map_t map)
2408 {
2409 ipc_object_t dest;
2410 mach_msg_body_t *body;
2411 mach_msg_descriptor_t *daddr, *naddr;
2412 mach_msg_descriptor_t *user_addr, *kern_addr;
2413 mach_msg_type_number_t dsc_count;
2414 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
2415 boolean_t complex = FALSE;
2416 vm_size_t space_needed = 0;
2417 vm_offset_t paddr = 0;
2418 vm_map_copy_t copy = VM_MAP_COPY_NULL;
2419 mach_msg_type_number_t i;
2420 mach_msg_return_t mr = MACH_MSG_SUCCESS;
2421
2422 vm_size_t descriptor_size = 0;
2423
2424 /*
2425 * Determine if the target is a kernel port.
2426 */
2427 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2428 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2429 naddr = (mach_msg_descriptor_t *) (body + 1);
2430
2431 dsc_count = body->msgh_descriptor_count;
2432 if (dsc_count == 0)
2433 return MACH_MSG_SUCCESS;
2434
2435 /*
2436 * Make an initial pass to determine kernal VM space requirements for
2437 * physical copies and possible contraction of the descriptors from
2438 * processes with pointers larger than the kernel's.
2439 */
2440 daddr = NULL;
2441 for (i = 0; i < dsc_count; i++) {
2442 mach_msg_size_t size;
2443
2444 daddr = naddr;
2445
2446 /* make sure the descriptor fits in the message */
2447 if (is_task_64bit) {
2448 switch (daddr->type.type) {
2449 case MACH_MSG_OOL_DESCRIPTOR:
2450 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2451 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2452 descriptor_size += 16;
2453 naddr = (typeof(naddr))((vm_offset_t)daddr + 16);
2454 break;
2455 default:
2456 descriptor_size += 12;
2457 naddr = (typeof(naddr))((vm_offset_t)daddr + 12);
2458 break;
2459 }
2460 } else {
2461 descriptor_size += 12;
2462 naddr = (typeof(naddr))((vm_offset_t)daddr + 12);
2463 }
2464
2465 if (naddr > (mach_msg_descriptor_t *)
2466 ((vm_offset_t)kmsg->ikm_header + kmsg->ikm_header->msgh_size)) {
2467 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2468 mr = MACH_SEND_MSG_TOO_SMALL;
2469 goto out;
2470 }
2471
2472 switch (daddr->type.type) {
2473 case MACH_MSG_OOL_DESCRIPTOR:
2474 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2475 size = (is_task_64bit) ?
2476 ((mach_msg_ool_descriptor64_t *)daddr)->size :
2477 daddr->out_of_line.size;
2478
2479 if (daddr->out_of_line.copy != MACH_MSG_PHYSICAL_COPY &&
2480 daddr->out_of_line.copy != MACH_MSG_VIRTUAL_COPY) {
2481 /*
2482 * Invalid copy option
2483 */
2484 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2485 mr = MACH_SEND_INVALID_TYPE;
2486 goto out;
2487 }
2488
2489 if ((size >= MSG_OOL_SIZE_SMALL) &&
2490 (daddr->out_of_line.copy == MACH_MSG_PHYSICAL_COPY) &&
2491 !(daddr->out_of_line.deallocate)) {
2492
2493 /*
2494 * Out-of-line memory descriptor, accumulate kernel
2495 * memory requirements
2496 */
2497 if (space_needed + round_page(size) <= space_needed) {
2498 /* Overflow dectected */
2499 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2500 mr = MACH_MSG_VM_KERNEL;
2501 goto out;
2502 }
2503
2504 space_needed += round_page(size);
2505 if (space_needed > ipc_kmsg_max_vm_space) {
2506
2507 /*
2508 * Per message kernel memory limit exceeded
2509 */
2510 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2511 mr = MACH_MSG_VM_KERNEL;
2512 goto out;
2513 }
2514 }
2515 }
2516 }
2517
2518 /*
2519 * Allocate space in the pageable kernel ipc copy map for all the
2520 * ool data that is to be physically copied. Map is marked wait for
2521 * space.
2522 */
2523 if (space_needed) {
2524 if (vm_allocate(ipc_kernel_copy_map, &paddr, space_needed,
2525 VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_KERN_MEMORY_IPC)) != KERN_SUCCESS) {
2526 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0);
2527 mr = MACH_MSG_VM_KERNEL;
2528 goto out;
2529 }
2530 }
2531
2532 /* user_addr = just after base as it was copied in */
2533 user_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2534
2535 /* Shift the mach_msg_base_t down to make room for dsc_count*16bytes of descriptors */
2536 if(descriptor_size != 16*dsc_count) {
2537 vm_offset_t dsc_adjust = 16*dsc_count - descriptor_size;
2538
2539 memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
2540 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust);
2541
2542 /* Update the message size for the larger in-kernel representation */
2543 kmsg->ikm_header->msgh_size += (mach_msg_size_t)dsc_adjust;
2544 }
2545
2546
2547 /* kern_addr = just after base after it has been (conditionally) moved */
2548 kern_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2549
2550 /* handle the OOL regions and port descriptors. */
2551 for(i=0;i<dsc_count;i++) {
2552 switch (user_addr->type.type) {
2553 case MACH_MSG_PORT_DESCRIPTOR:
2554 user_addr = ipc_kmsg_copyin_port_descriptor((mach_msg_port_descriptor_t *)kern_addr,
2555 (mach_msg_legacy_port_descriptor_t *)user_addr, space, dest, kmsg, &mr);
2556 kern_addr++;
2557 complex = TRUE;
2558 break;
2559 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2560 case MACH_MSG_OOL_DESCRIPTOR:
2561 user_addr = ipc_kmsg_copyin_ool_descriptor((mach_msg_ool_descriptor_t *)kern_addr,
2562 user_addr, is_task_64bit, &paddr, &copy, &space_needed, map, &mr);
2563 kern_addr++;
2564 complex = TRUE;
2565 break;
2566 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
2567 user_addr = ipc_kmsg_copyin_ool_ports_descriptor((mach_msg_ool_ports_descriptor_t *)kern_addr,
2568 user_addr, is_task_64bit, map, space, dest, kmsg, &mr);
2569 kern_addr++;
2570 complex = TRUE;
2571 break;
2572 default:
2573 /* Invalid descriptor */
2574 mr = MACH_SEND_INVALID_TYPE;
2575 break;
2576 }
2577
2578 if (MACH_MSG_SUCCESS != mr) {
2579 /* clean from start of message descriptors to i */
2580 ipc_kmsg_clean_partial(kmsg, i,
2581 (mach_msg_descriptor_t *)((mach_msg_base_t *)kmsg->ikm_header + 1),
2582 paddr, space_needed);
2583 goto out;
2584 }
2585 } /* End of loop */
2586
2587 if (!complex) {
2588 kmsg->ikm_header->msgh_bits &= ~MACH_MSGH_BITS_COMPLEX;
2589 }
2590 out:
2591 return mr;
2592 }
2593
2594
2595 /*
2596 * Routine: ipc_kmsg_copyin
2597 * Purpose:
2598 * "Copy-in" port rights and out-of-line memory
2599 * in the message.
2600 *
2601 * In all failure cases, the message is left holding
2602 * no rights or memory. However, the message buffer
2603 * is not deallocated. If successful, the message
2604 * contains a valid destination port.
2605 * Conditions:
2606 * Nothing locked.
2607 * Returns:
2608 * MACH_MSG_SUCCESS Successful copyin.
2609 * MACH_SEND_INVALID_HEADER
2610 * Illegal value in the message header bits.
2611 * MACH_SEND_INVALID_DEST Can't copyin destination port.
2612 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
2613 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
2614 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
2615 * MACH_SEND_INVALID_TYPE Bad type specification.
2616 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
2617 */
2618
2619 mach_msg_return_t
2620 ipc_kmsg_copyin(
2621 ipc_kmsg_t kmsg,
2622 ipc_space_t space,
2623 vm_map_t map,
2624 mach_msg_option_t *optionp)
2625 {
2626 mach_msg_return_t mr;
2627
2628 kmsg->ikm_header->msgh_bits &= MACH_MSGH_BITS_USER;
2629
2630 mr = ipc_kmsg_copyin_header(kmsg, space, optionp);
2631
2632 if (mr != MACH_MSG_SUCCESS)
2633 return mr;
2634
2635 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC,MACH_IPC_MSG_SEND) | DBG_FUNC_NONE,
2636 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
2637 (uintptr_t)kmsg->ikm_header->msgh_bits,
2638 (uintptr_t)kmsg->ikm_header->msgh_id,
2639 VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(kmsg->ikm_voucher)),
2640 0);
2641
2642 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_copyin header:\n%.8x\n%.8x\n%p\n%p\n%p\n%.8x\n",
2643 kmsg->ikm_header->msgh_size,
2644 kmsg->ikm_header->msgh_bits,
2645 kmsg->ikm_header->msgh_remote_port,
2646 kmsg->ikm_header->msgh_local_port,
2647 kmsg->ikm_voucher,
2648 kmsg->ikm_header->msgh_id);
2649
2650 if ((kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0)
2651 return MACH_MSG_SUCCESS;
2652
2653 mr = ipc_kmsg_copyin_body( kmsg, space, map);
2654
2655 /* unreachable if !DEBUG */
2656 __unreachable_ok_push
2657 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK))
2658 {
2659 kprintf("body:\n");
2660 uint32_t i;
2661 for(i=0;i*4 < (kmsg->ikm_header->msgh_size - sizeof(mach_msg_header_t));i++)
2662 {
2663 kprintf("%.4x\n",((uint32_t *)(kmsg->ikm_header + 1))[i]);
2664 }
2665 }
2666 __unreachable_ok_pop
2667
2668 return mr;
2669 }
2670
2671 /*
2672 * Routine: ipc_kmsg_copyin_from_kernel
2673 * Purpose:
2674 * "Copy-in" port rights and out-of-line memory
2675 * in a message sent from the kernel.
2676 *
2677 * Because the message comes from the kernel,
2678 * the implementation assumes there are no errors
2679 * or peculiarities in the message.
2680 * Conditions:
2681 * Nothing locked.
2682 */
2683
2684 mach_msg_return_t
2685 ipc_kmsg_copyin_from_kernel(
2686 ipc_kmsg_t kmsg)
2687 {
2688 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
2689 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
2690 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
2691 ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2692 ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
2693
2694 /* translate the destination and reply ports */
2695 if (!IO_VALID(remote))
2696 return MACH_SEND_INVALID_DEST;
2697
2698 ipc_object_copyin_from_kernel(remote, rname);
2699 if (IO_VALID(local))
2700 ipc_object_copyin_from_kernel(local, lname);
2701
2702 /*
2703 * The common case is a complex message with no reply port,
2704 * because that is what the memory_object interface uses.
2705 */
2706
2707 if (bits == (MACH_MSGH_BITS_COMPLEX |
2708 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
2709 bits = (MACH_MSGH_BITS_COMPLEX |
2710 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
2711
2712 kmsg->ikm_header->msgh_bits = bits;
2713 } else {
2714 bits = (MACH_MSGH_BITS_OTHER(bits) |
2715 MACH_MSGH_BITS(ipc_object_copyin_type(rname),
2716 ipc_object_copyin_type(lname)));
2717
2718 kmsg->ikm_header->msgh_bits = bits;
2719 if ((bits & MACH_MSGH_BITS_COMPLEX) == 0)
2720 return MACH_MSG_SUCCESS;
2721 }
2722 {
2723 mach_msg_descriptor_t *saddr;
2724 mach_msg_body_t *body;
2725 mach_msg_type_number_t i, count;
2726
2727 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2728 saddr = (mach_msg_descriptor_t *) (body + 1);
2729 count = body->msgh_descriptor_count;
2730
2731 for (i = 0; i < count; i++, saddr++) {
2732
2733 switch (saddr->type.type) {
2734
2735 case MACH_MSG_PORT_DESCRIPTOR: {
2736 mach_msg_type_name_t name;
2737 ipc_object_t object;
2738 mach_msg_port_descriptor_t *dsc;
2739
2740 dsc = &saddr->port;
2741
2742 /* this is really the type SEND, SEND_ONCE, etc. */
2743 name = dsc->disposition;
2744 object = (ipc_object_t) dsc->name;
2745 dsc->disposition = ipc_object_copyin_type(name);
2746
2747 if (!IO_VALID(object)) {
2748 break;
2749 }
2750
2751 ipc_object_copyin_from_kernel(object, name);
2752
2753 /* CDY avoid circularity when the destination is also */
2754 /* the kernel. This check should be changed into an */
2755 /* assert when the new kobject model is in place since*/
2756 /* ports will not be used in kernel to kernel chats */
2757
2758 if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) {
2759 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2760 ipc_port_check_circularity((ipc_port_t) object,
2761 (ipc_port_t) remote)) {
2762 kmsg->ikm_header->msgh_bits |=
2763 MACH_MSGH_BITS_CIRCULAR;
2764 }
2765 }
2766 break;
2767 }
2768 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2769 case MACH_MSG_OOL_DESCRIPTOR: {
2770 /*
2771 * The sender should supply ready-made memory, i.e.
2772 * a vm_map_copy_t, so we don't need to do anything.
2773 */
2774 break;
2775 }
2776 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
2777 ipc_object_t *objects;
2778 unsigned int j;
2779 mach_msg_type_name_t name;
2780 mach_msg_ool_ports_descriptor_t *dsc;
2781
2782 dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports;
2783
2784 /* this is really the type SEND, SEND_ONCE, etc. */
2785 name = dsc->disposition;
2786 dsc->disposition = ipc_object_copyin_type(name);
2787
2788 objects = (ipc_object_t *) dsc->address;
2789
2790 for ( j = 0; j < dsc->count; j++) {
2791 ipc_object_t object = objects[j];
2792
2793 if (!IO_VALID(object))
2794 continue;
2795
2796 ipc_object_copyin_from_kernel(object, name);
2797
2798 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2799 ipc_port_check_circularity(
2800 (ipc_port_t) object,
2801 (ipc_port_t) remote))
2802 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2803 }
2804 break;
2805 }
2806 default: {
2807 #if MACH_ASSERT
2808 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2809 #endif /* MACH_ASSERT */
2810 }
2811 }
2812 }
2813 }
2814 return MACH_MSG_SUCCESS;
2815 }
2816
2817 #if IKM_SUPPORT_LEGACY
2818 mach_msg_return_t
2819 ipc_kmsg_copyin_from_kernel_legacy(
2820 ipc_kmsg_t kmsg)
2821 {
2822 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits;
2823 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
2824 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
2825 ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
2826 ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
2827
2828 /* translate the destination and reply ports */
2829 if (!IO_VALID(remote))
2830 return MACH_SEND_INVALID_DEST;
2831
2832 ipc_object_copyin_from_kernel(remote, rname);
2833 if (IO_VALID(local))
2834 ipc_object_copyin_from_kernel(local, lname);
2835
2836 /*
2837 * The common case is a complex message with no reply port,
2838 * because that is what the memory_object interface uses.
2839 */
2840
2841 if (bits == (MACH_MSGH_BITS_COMPLEX |
2842 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
2843 bits = (MACH_MSGH_BITS_COMPLEX |
2844 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
2845
2846 kmsg->ikm_header->msgh_bits = bits;
2847 } else {
2848 bits = (MACH_MSGH_BITS_OTHER(bits) |
2849 MACH_MSGH_BITS(ipc_object_copyin_type(rname),
2850 ipc_object_copyin_type(lname)));
2851
2852 kmsg->ikm_header->msgh_bits = bits;
2853 if ((bits & MACH_MSGH_BITS_COMPLEX) == 0)
2854 return MACH_MSG_SUCCESS;
2855 }
2856 {
2857 mach_msg_legacy_descriptor_t *saddr;
2858 mach_msg_descriptor_t *daddr;
2859 mach_msg_body_t *body;
2860 mach_msg_type_number_t i, count;
2861
2862 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
2863 saddr = (typeof(saddr)) (body + 1);
2864 count = body->msgh_descriptor_count;
2865
2866 if(count) {
2867 vm_offset_t dsc_adjust = 4*count;
2868 memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
2869 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust);
2870 /* Update the message size for the larger in-kernel representation */
2871 kmsg->ikm_header->msgh_size += dsc_adjust;
2872 }
2873 daddr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t));
2874
2875 for (i = 0; i < count; i++, saddr++, daddr++) {
2876 switch (saddr->type.type) {
2877
2878 case MACH_MSG_PORT_DESCRIPTOR: {
2879 mach_msg_type_name_t name;
2880 ipc_object_t object;
2881 mach_msg_legacy_port_descriptor_t *dsc;
2882 mach_msg_port_descriptor_t *dest_dsc;
2883
2884 dsc = (typeof(dsc))&saddr->port;
2885 dest_dsc = &daddr->port;
2886
2887 /* this is really the type SEND, SEND_ONCE, etc. */
2888 name = dsc->disposition;
2889 object = (ipc_object_t) CAST_MACH_NAME_TO_PORT(dsc->name);
2890 dest_dsc->disposition = ipc_object_copyin_type(name);
2891 dest_dsc->name = (mach_port_t)object;
2892 dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
2893
2894 if (!IO_VALID(object)) {
2895 break;
2896 }
2897
2898 ipc_object_copyin_from_kernel(object, name);
2899
2900 /* CDY avoid circularity when the destination is also */
2901 /* the kernel. This check should be changed into an */
2902 /* assert when the new kobject model is in place since*/
2903 /* ports will not be used in kernel to kernel chats */
2904
2905 if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) {
2906 if ((dest_dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2907 ipc_port_check_circularity((ipc_port_t) object,
2908 (ipc_port_t) remote)) {
2909 kmsg->ikm_header->msgh_bits |=
2910 MACH_MSGH_BITS_CIRCULAR;
2911 }
2912 }
2913 break;
2914 }
2915 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2916 case MACH_MSG_OOL_DESCRIPTOR: {
2917 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
2918 * so we don't need to do anything special. */
2919
2920 mach_msg_ool_descriptor32_t *source_dsc = &saddr->out_of_line32;
2921 mach_msg_ool_descriptor_t *dest_dsc = (typeof(dest_dsc))&daddr->out_of_line;
2922
2923 vm_offset_t address = source_dsc->address;
2924 vm_size_t size = source_dsc->size;
2925 boolean_t deallocate = source_dsc->deallocate;
2926 mach_msg_copy_options_t copy = source_dsc->copy;
2927 mach_msg_descriptor_type_t type = source_dsc->type;
2928
2929 dest_dsc->address = (void *)address;
2930 dest_dsc->size = size;
2931 dest_dsc->deallocate = deallocate;
2932 dest_dsc->copy = copy;
2933 dest_dsc->type = type;
2934 break;
2935 }
2936 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
2937 ipc_object_t *objects;
2938 unsigned int j;
2939 mach_msg_type_name_t name;
2940 mach_msg_ool_ports_descriptor_t *dest_dsc;
2941
2942 mach_msg_ool_ports_descriptor32_t *source_dsc = &saddr->ool_ports32;
2943 dest_dsc = (typeof(dest_dsc))&daddr->ool_ports;
2944
2945 boolean_t deallocate = source_dsc->deallocate;
2946 mach_msg_copy_options_t copy = source_dsc->copy;
2947 mach_msg_size_t port_count = source_dsc->count;
2948 mach_msg_type_name_t disposition = source_dsc->disposition;
2949
2950 /* this is really the type SEND, SEND_ONCE, etc. */
2951 name = disposition;
2952 disposition = ipc_object_copyin_type(name);
2953
2954 objects = (ipc_object_t *) (uintptr_t)source_dsc->address;
2955
2956 for ( j = 0; j < port_count; j++) {
2957 ipc_object_t object = objects[j];
2958
2959 if (!IO_VALID(object))
2960 continue;
2961
2962 ipc_object_copyin_from_kernel(object, name);
2963
2964 if ((disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
2965 ipc_port_check_circularity(
2966 (ipc_port_t) object,
2967 (ipc_port_t) remote))
2968 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
2969 }
2970
2971 dest_dsc->address = objects;
2972 dest_dsc->deallocate = deallocate;
2973 dest_dsc->copy = copy;
2974 dest_dsc->disposition = disposition;
2975 dest_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
2976 dest_dsc->count = port_count;
2977 break;
2978 }
2979 default: {
2980 #if MACH_ASSERT
2981 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2982 #endif /* MACH_ASSERT */
2983 }
2984 }
2985 }
2986 }
2987 return MACH_MSG_SUCCESS;
2988 }
2989 #endif /* IKM_SUPPORT_LEGACY */
2990
2991 /*
2992 * Routine: ipc_kmsg_copyout_header
2993 * Purpose:
2994 * "Copy-out" port rights in the header of a message.
2995 * Operates atomically; if it doesn't succeed the
2996 * message header and the space are left untouched.
2997 * If it does succeed the remote/local port fields
2998 * contain port names instead of object pointers,
2999 * and the bits field is updated.
3000 * Conditions:
3001 * Nothing locked.
3002 * Returns:
3003 * MACH_MSG_SUCCESS Copied out port rights.
3004 * MACH_RCV_INVALID_NOTIFY
3005 * Notify is non-null and doesn't name a receive right.
3006 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
3007 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3008 * The space is dead.
3009 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3010 * No room in space for another name.
3011 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3012 * Couldn't allocate memory for the reply port.
3013 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3014 * Couldn't allocate memory for the dead-name request.
3015 */
3016
3017 mach_msg_return_t
3018 ipc_kmsg_copyout_header(
3019 ipc_kmsg_t kmsg,
3020 ipc_space_t space,
3021 mach_msg_option_t option)
3022 {
3023 mach_msg_header_t *msg = kmsg->ikm_header;
3024 mach_msg_bits_t mbits = msg->msgh_bits;
3025 ipc_port_t dest = (ipc_port_t) msg->msgh_remote_port;
3026
3027 assert(IP_VALID(dest));
3028
3029 /*
3030 * While we still hold a reference on the received-from port,
3031 * process all send-possible notfications we received along with
3032 * the message.
3033 */
3034 ipc_port_spnotify(dest);
3035
3036 {
3037 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3038 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3039 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3040 ipc_port_t reply = msg->msgh_local_port;
3041 ipc_port_t release_reply_port = IP_NULL;
3042 mach_port_name_t dest_name, reply_name;
3043
3044 ipc_port_t voucher = kmsg->ikm_voucher;
3045 ipc_port_t release_voucher_port = IP_NULL;
3046 mach_port_name_t voucher_name;
3047
3048 uint32_t entries_held = 0;
3049 boolean_t need_write_lock = FALSE;
3050 kern_return_t kr;
3051
3052 /*
3053 * Reserve any potentially needed entries in the target space.
3054 * We'll free any unused before unlocking the space.
3055 */
3056 if (IP_VALID(reply)) {
3057 entries_held++;
3058 need_write_lock = TRUE;
3059 }
3060 if (IP_VALID(voucher)) {
3061 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3062
3063 if ((option & MACH_RCV_VOUCHER) != 0)
3064 entries_held++;
3065 need_write_lock = TRUE;
3066 }
3067
3068 if (need_write_lock) {
3069
3070 is_write_lock(space);
3071
3072 while(entries_held) {
3073 if (!is_active(space)) {
3074 is_write_unlock(space);
3075 return (MACH_RCV_HEADER_ERROR|
3076 MACH_MSG_IPC_SPACE);
3077 }
3078
3079 kr = ipc_entries_hold(space, entries_held);
3080 if (KERN_SUCCESS == kr)
3081 break;
3082
3083 kr = ipc_entry_grow_table(space, ITS_SIZE_NONE);
3084 if (KERN_SUCCESS != kr)
3085 return(MACH_RCV_HEADER_ERROR|
3086 MACH_MSG_IPC_SPACE);
3087 /* space was unlocked and relocked - retry */
3088 }
3089
3090 /* Handle reply port. */
3091 if (IP_VALID(reply)) {
3092 ipc_entry_t entry;
3093
3094 /* Is there already an entry we can use? */
3095 if ((reply_type != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
3096 ipc_right_reverse(space, (ipc_object_t) reply, &reply_name, &entry)) {
3097 /* reply port is locked and active */
3098 assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE);
3099 } else {
3100 ip_lock(reply);
3101 if (!ip_active(reply)) {
3102 ip_unlock(reply);
3103
3104 release_reply_port = reply;
3105 reply = IP_DEAD;
3106 reply_name = MACH_PORT_DEAD;
3107 goto done_with_reply;
3108 }
3109
3110 /* claim a held entry for the reply port */
3111 assert(entries_held > 0);
3112 entries_held--;
3113 ipc_entry_claim(space, &reply_name, &entry);
3114 assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
3115 assert(entry->ie_object == IO_NULL);
3116 entry->ie_object = (ipc_object_t) reply;
3117 }
3118
3119 /* space and reply port are locked and active */
3120 ip_reference(reply); /* hold onto the reply port */
3121
3122 kr = ipc_right_copyout(space, reply_name, entry,
3123 reply_type, TRUE, (ipc_object_t) reply);
3124 assert(kr == KERN_SUCCESS);
3125 /* reply port is unlocked */
3126 } else
3127 reply_name = CAST_MACH_PORT_TO_NAME(reply);
3128
3129 done_with_reply:
3130
3131 /* Handle voucher port. */
3132 if (voucher_type != MACH_MSGH_BITS_ZERO) {
3133 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3134
3135 if (!IP_VALID(voucher)) {
3136 if ((option & MACH_RCV_VOUCHER) == 0) {
3137 voucher_type = MACH_MSGH_BITS_ZERO;
3138 }
3139 voucher_name = MACH_PORT_NULL;
3140 goto done_with_voucher;
3141 }
3142
3143 /* clear voucher from its hiding place back in the kmsg */
3144 kmsg->ikm_voucher = IP_NULL;
3145
3146 if ((option & MACH_RCV_VOUCHER) != 0) {
3147 ipc_entry_t entry;
3148
3149 if (ipc_right_reverse(space, (ipc_object_t) voucher,
3150 &voucher_name, &entry)) {
3151 /* voucher port locked */
3152 assert(entry->ie_bits & MACH_PORT_TYPE_SEND);
3153 } else {
3154 assert(entries_held > 0);
3155 entries_held--;
3156 ipc_entry_claim(space, &voucher_name, &entry);
3157 assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE);
3158 assert(entry->ie_object == IO_NULL);
3159 entry->ie_object = (ipc_object_t) voucher;
3160 ip_lock(voucher);
3161 }
3162 /* space is locked and active */
3163
3164 assert(ip_active(voucher));
3165 assert(ip_kotype(voucher) == IKOT_VOUCHER);
3166 kr = ipc_right_copyout(space, voucher_name, entry,
3167 MACH_MSG_TYPE_MOVE_SEND, TRUE,
3168 (ipc_object_t) voucher);
3169 /* voucher port is unlocked */
3170 } else {
3171 voucher_type = MACH_MSGH_BITS_ZERO;
3172 release_voucher_port = voucher;
3173 voucher_name = MACH_PORT_NULL;
3174 }
3175 } else {
3176 voucher_name = msg->msgh_voucher_port;
3177 }
3178
3179 done_with_voucher:
3180
3181 ip_lock(dest);
3182 is_write_unlock(space);
3183
3184 } else {
3185 /*
3186 * No reply or voucher port! This is an easy case.
3187 * We only need to have the space locked
3188 * when locking the destination.
3189 */
3190
3191 is_read_lock(space);
3192 if (!is_active(space)) {
3193 is_read_unlock(space);
3194 return MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE;
3195 }
3196
3197 ip_lock(dest);
3198 is_read_unlock(space);
3199
3200 reply_name = CAST_MACH_PORT_TO_NAME(reply);
3201
3202 if (voucher_type != MACH_MSGH_BITS_ZERO) {
3203 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3204 if ((option & MACH_RCV_VOUCHER) == 0) {
3205 voucher_type = MACH_MSGH_BITS_ZERO;
3206 }
3207 voucher_name = MACH_PORT_NULL;
3208 } else {
3209 voucher_name = msg->msgh_voucher_port;
3210 }
3211 }
3212
3213 /*
3214 * At this point, the space is unlocked and the destination
3215 * port is locked. (Lock taken while space was locked.)
3216 * reply_name is taken care of; we still need dest_name.
3217 * We still hold a ref for reply (if it is valid).
3218 *
3219 * If the space holds receive rights for the destination,
3220 * we return its name for the right. Otherwise the task
3221 * managed to destroy or give away the receive right between
3222 * receiving the message and this copyout. If the destination
3223 * is dead, return MACH_PORT_DEAD, and if the receive right
3224 * exists somewhere else (another space, in transit)
3225 * return MACH_PORT_NULL.
3226 *
3227 * Making this copyout operation atomic with the previous
3228 * copyout of the reply port is a bit tricky. If there was
3229 * no real reply port (it wasn't IP_VALID) then this isn't
3230 * an issue. If the reply port was dead at copyout time,
3231 * then we are OK, because if dest is dead we serialize
3232 * after the death of both ports and if dest is alive
3233 * we serialize after reply died but before dest's (later) death.
3234 * So assume reply was alive when we copied it out. If dest
3235 * is alive, then we are OK because we serialize before
3236 * the ports' deaths. So assume dest is dead when we look at it.
3237 * If reply dies/died after dest, then we are OK because
3238 * we serialize after dest died but before reply dies.
3239 * So the hard case is when reply is alive at copyout,
3240 * dest is dead at copyout, and reply died before dest died.
3241 * In this case pretend that dest is still alive, so
3242 * we serialize while both ports are alive.
3243 *
3244 * Because the space lock is held across the copyout of reply
3245 * and locking dest, the receive right for dest can't move
3246 * in or out of the space while the copyouts happen, so
3247 * that isn't an atomicity problem. In the last hard case
3248 * above, this implies that when dest is dead that the
3249 * space couldn't have had receive rights for dest at
3250 * the time reply was copied-out, so when we pretend
3251 * that dest is still alive, we can return MACH_PORT_NULL.
3252 *
3253 * If dest == reply, then we have to make it look like
3254 * either both copyouts happened before the port died,
3255 * or both happened after the port died. This special
3256 * case works naturally if the timestamp comparison
3257 * is done correctly.
3258 */
3259
3260 if (ip_active(dest)) {
3261 ipc_object_copyout_dest(space, (ipc_object_t) dest,
3262 dest_type, &dest_name);
3263 /* dest is unlocked */
3264
3265 } else {
3266 ipc_port_timestamp_t timestamp;
3267
3268 timestamp = dest->ip_timestamp;
3269 ip_unlock(dest);
3270 ip_release(dest);
3271
3272 if (IP_VALID(reply)) {
3273 ip_lock(reply);
3274 if (ip_active(reply) ||
3275 IP_TIMESTAMP_ORDER(timestamp,
3276 reply->ip_timestamp))
3277 dest_name = MACH_PORT_DEAD;
3278 else
3279 dest_name = MACH_PORT_NULL;
3280 ip_unlock(reply);
3281 } else
3282 dest_name = MACH_PORT_DEAD;
3283 }
3284
3285 if (IP_VALID(reply))
3286 ip_release(reply);
3287
3288 if (IP_VALID(release_reply_port)) {
3289 if (reply_type == MACH_MSG_TYPE_PORT_SEND_ONCE)
3290 ipc_port_release_sonce(release_reply_port);
3291 else
3292 ipc_port_release_send(release_reply_port);
3293 }
3294
3295 if (IP_VALID(release_voucher_port))
3296 ipc_port_release_send(release_voucher_port);
3297
3298
3299 if ((option & MACH_RCV_VOUCHER) != 0) {
3300 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV) | DBG_FUNC_NONE,
3301 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3302 (uintptr_t)kmsg->ikm_header->msgh_bits,
3303 (uintptr_t)kmsg->ikm_header->msgh_id,
3304 VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(voucher)),
3305 0);
3306 } else {
3307 KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_IPC, MACH_IPC_MSG_RECV_VOUCHER_REFUSED) | DBG_FUNC_NONE,
3308 VM_KERNEL_ADDRPERM((uintptr_t)kmsg),
3309 (uintptr_t)kmsg->ikm_header->msgh_bits,
3310 (uintptr_t)kmsg->ikm_header->msgh_id,
3311 VM_KERNEL_ADDRPERM((uintptr_t)unsafe_convert_port_to_voucher(voucher)),
3312 0);
3313 }
3314
3315 msg->msgh_bits = MACH_MSGH_BITS_SET(reply_type, dest_type,
3316 voucher_type, mbits);
3317 msg->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
3318 msg->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3319 msg->msgh_voucher_port = voucher_name;
3320 }
3321
3322 return MACH_MSG_SUCCESS;
3323 }
3324
3325 /*
3326 * Routine: ipc_kmsg_copyout_object
3327 * Purpose:
3328 * Copy-out a port right. Always returns a name,
3329 * even for unsuccessful return codes. Always
3330 * consumes the supplied object.
3331 * Conditions:
3332 * Nothing locked.
3333 * Returns:
3334 * MACH_MSG_SUCCESS The space acquired the right
3335 * (name is valid) or the object is dead (MACH_PORT_DEAD).
3336 * MACH_MSG_IPC_SPACE No room in space for the right,
3337 * or the space is dead. (Name is MACH_PORT_NULL.)
3338 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
3339 * (Name is MACH_PORT_NULL.)
3340 */
3341
3342 mach_msg_return_t
3343 ipc_kmsg_copyout_object(
3344 ipc_space_t space,
3345 ipc_object_t object,
3346 mach_msg_type_name_t msgt_name,
3347 mach_port_name_t *namep)
3348 {
3349 kern_return_t kr;
3350
3351 if (!IO_VALID(object)) {
3352 *namep = CAST_MACH_PORT_TO_NAME(object);
3353 return MACH_MSG_SUCCESS;
3354 }
3355
3356 kr = ipc_object_copyout(space, object, msgt_name, TRUE, namep);
3357 if (kr != KERN_SUCCESS) {
3358 ipc_object_destroy(object, msgt_name);
3359
3360 if (kr == KERN_INVALID_CAPABILITY)
3361 *namep = MACH_PORT_DEAD;
3362 else {
3363 *namep = MACH_PORT_NULL;
3364
3365 if (kr == KERN_RESOURCE_SHORTAGE)
3366 return MACH_MSG_IPC_KERNEL;
3367 else
3368 return MACH_MSG_IPC_SPACE;
3369 }
3370 }
3371
3372 return MACH_MSG_SUCCESS;
3373 }
3374
3375 mach_msg_descriptor_t *
3376 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc,
3377 mach_msg_descriptor_t *user_dsc,
3378 ipc_space_t space,
3379 kern_return_t *mr);
3380 mach_msg_descriptor_t *
3381 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc,
3382 mach_msg_descriptor_t *dest_dsc,
3383 ipc_space_t space,
3384 kern_return_t *mr)
3385 {
3386 mach_port_t port;
3387 mach_port_name_t name;
3388 mach_msg_type_name_t disp;
3389
3390
3391 /* Copyout port right carried in the message */
3392 port = dsc->port.name;
3393 disp = dsc->port.disposition;
3394 *mr |= ipc_kmsg_copyout_object(space,
3395 (ipc_object_t)port,
3396 disp,
3397 &name);
3398
3399 if(current_task() == kernel_task)
3400 {
3401 mach_msg_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc;
3402 user_dsc--; // point to the start of this port descriptor
3403 user_dsc->name = CAST_MACH_NAME_TO_PORT(name);
3404 user_dsc->disposition = disp;
3405 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
3406 dest_dsc = (typeof(dest_dsc))user_dsc;
3407 } else {
3408 mach_msg_legacy_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc;
3409 user_dsc--; // point to the start of this port descriptor
3410 user_dsc->name = CAST_MACH_PORT_TO_NAME(name);
3411 user_dsc->disposition = disp;
3412 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
3413 dest_dsc = (typeof(dest_dsc))user_dsc;
3414 }
3415
3416 return (mach_msg_descriptor_t *)dest_dsc;
3417 }
3418
3419 mach_msg_descriptor_t *
3420 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);
3421 mach_msg_descriptor_t *
3422 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)
3423 {
3424 vm_map_copy_t copy;
3425 vm_map_address_t rcv_addr;
3426 mach_msg_copy_options_t copy_options;
3427 mach_msg_size_t size;
3428 mach_msg_descriptor_type_t dsc_type;
3429
3430 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3431
3432 copy = (vm_map_copy_t) dsc->address;
3433 size = dsc->size;
3434 copy_options = dsc->copy;
3435 assert(copy_options != MACH_MSG_KALLOC_COPY_T);
3436 dsc_type = dsc->type;
3437
3438 if (copy != VM_MAP_COPY_NULL) {
3439 kern_return_t kr;
3440
3441 rcv_addr = 0;
3442 kr = vm_map_copyout(map, &rcv_addr, copy);
3443 if (kr != KERN_SUCCESS) {
3444 if (kr == KERN_RESOURCE_SHORTAGE)
3445 *mr |= MACH_MSG_VM_KERNEL;
3446 else
3447 *mr |= MACH_MSG_VM_SPACE;
3448 vm_map_copy_discard(copy);
3449 rcv_addr = 0;
3450 size = 0;
3451 }
3452 } else {
3453 rcv_addr = 0;
3454 size = 0;
3455 }
3456
3457 /*
3458 * Now update the descriptor as the user would see it.
3459 * This may require expanding the descriptor to the user
3460 * visible size. There is already space allocated for
3461 * this in what naddr points to.
3462 */
3463 if(current_task() == kernel_task)
3464 {
3465 mach_msg_ool_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3466 user_ool_dsc--;
3467
3468 user_ool_dsc->address = (void *)(uintptr_t)rcv_addr;
3469 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3470 TRUE : FALSE;
3471 user_ool_dsc->copy = copy_options;
3472 user_ool_dsc->type = dsc_type;
3473 user_ool_dsc->size = size;
3474
3475 user_dsc = (typeof(user_dsc))user_ool_dsc;
3476 } else if (is_64bit) {
3477 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3478 user_ool_dsc--;
3479
3480 user_ool_dsc->address = rcv_addr;
3481 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3482 TRUE : FALSE;
3483 user_ool_dsc->copy = copy_options;
3484 user_ool_dsc->type = dsc_type;
3485 user_ool_dsc->size = size;
3486
3487 user_dsc = (typeof(user_dsc))user_ool_dsc;
3488 } else {
3489 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3490 user_ool_dsc--;
3491
3492 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
3493 user_ool_dsc->size = size;
3494 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3495 TRUE : FALSE;
3496 user_ool_dsc->copy = copy_options;
3497 user_ool_dsc->type = dsc_type;
3498
3499 user_dsc = (typeof(user_dsc))user_ool_dsc;
3500 }
3501 return user_dsc;
3502 }
3503
3504 mach_msg_descriptor_t *
3505 ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc,
3506 mach_msg_descriptor_t *user_dsc,
3507 int is_64bit,
3508 vm_map_t map,
3509 ipc_space_t space,
3510 ipc_kmsg_t kmsg,
3511 mach_msg_return_t *mr);
3512 mach_msg_descriptor_t *
3513 ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc,
3514 mach_msg_descriptor_t *user_dsc,
3515 int is_64bit,
3516 vm_map_t map,
3517 ipc_space_t space,
3518 ipc_kmsg_t kmsg,
3519 mach_msg_return_t *mr)
3520 {
3521 mach_vm_offset_t rcv_addr = 0;
3522 mach_msg_type_name_t disp;
3523 mach_msg_type_number_t count, i;
3524 vm_size_t ports_length, names_length;
3525
3526 mach_msg_copy_options_t copy_options = MACH_MSG_VIRTUAL_COPY;
3527
3528 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3529
3530 count = dsc->count;
3531 disp = dsc->disposition;
3532 ports_length = count * sizeof(mach_port_t);
3533 names_length = count * sizeof(mach_port_name_t);
3534
3535 if (ports_length != 0 && dsc->address != 0) {
3536
3537 /*
3538 * Check to see if there is an overwrite descriptor
3539 * specified in the scatter list for this ool data.
3540 * The descriptor has already been verified.
3541 */
3542 #if 0
3543 if (saddr != MACH_MSG_DESCRIPTOR_NULL) {
3544 if (differs) {
3545 OTHER_OOL_DESCRIPTOR *scatter_dsc;
3546
3547 scatter_dsc = (OTHER_OOL_DESCRIPTOR *)saddr;
3548 rcv_addr = (mach_vm_offset_t) scatter_dsc->address;
3549 copy_options = scatter_dsc->copy;
3550 } else {
3551 mach_msg_ool_descriptor_t *scatter_dsc;
3552
3553 scatter_dsc = &saddr->out_of_line;
3554 rcv_addr = CAST_USER_ADDR_T(scatter_dsc->address);
3555 copy_options = scatter_dsc->copy;
3556 }
3557 INCREMENT_SCATTER(saddr, sdsc_count, differs);
3558 }
3559 #endif
3560
3561 if (copy_options == MACH_MSG_VIRTUAL_COPY) {
3562 /*
3563 * Dynamically allocate the region
3564 */
3565 int anywhere = VM_FLAGS_ANYWHERE;
3566 if (vm_kernel_map_is_kernel(map)) anywhere |= VM_MAKE_TAG(VM_KERN_MEMORY_IPC);
3567 else anywhere |= VM_MAKE_TAG(VM_MEMORY_MACH_MSG);
3568
3569 kern_return_t kr;
3570 if ((kr = mach_vm_allocate(map, &rcv_addr,
3571 (mach_vm_size_t)names_length,
3572 anywhere)) != KERN_SUCCESS) {
3573 ipc_kmsg_clean_body(kmsg, 1, (mach_msg_descriptor_t *)dsc);
3574 rcv_addr = 0;
3575
3576 if (kr == KERN_RESOURCE_SHORTAGE){
3577 *mr |= MACH_MSG_VM_KERNEL;
3578 } else {
3579 *mr |= MACH_MSG_VM_SPACE;
3580 }
3581 }
3582 }
3583
3584 /*
3585 * Handle the port rights and copy out the names
3586 * for those rights out to user-space.
3587 */
3588 if (rcv_addr != 0) {
3589 mach_port_t *objects = (mach_port_t *) dsc->address;
3590 mach_port_name_t *names = (mach_port_name_t *) dsc->address;
3591
3592 /* copyout port rights carried in the message */
3593
3594 for ( i = 0; i < count ; i++) {
3595 ipc_object_t object = (ipc_object_t)objects[i];
3596
3597 *mr |= ipc_kmsg_copyout_object(space, object,
3598 disp, &names[i]);
3599 }
3600
3601 /* copyout to memory allocated above */
3602 void *data = dsc->address;
3603 if (copyoutmap(map, data, rcv_addr, names_length) != KERN_SUCCESS)
3604 *mr |= MACH_MSG_VM_SPACE;
3605 kfree(data, ports_length);
3606 }
3607 } else {
3608 rcv_addr = 0;
3609 }
3610
3611 /*
3612 * Now update the descriptor based on the information
3613 * calculated above.
3614 */
3615 if(current_task() == kernel_task) {
3616 mach_msg_ool_ports_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3617 user_ool_dsc--;
3618
3619 user_ool_dsc->address = (void *)(uintptr_t)rcv_addr;
3620 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3621 TRUE : FALSE;
3622 user_ool_dsc->copy = copy_options;
3623 user_ool_dsc->disposition = disp;
3624 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3625 user_ool_dsc->count = count;
3626
3627 user_dsc = (typeof(user_dsc))user_ool_dsc;
3628 } if (is_64bit) {
3629 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3630 user_ool_dsc--;
3631
3632 user_ool_dsc->address = rcv_addr;
3633 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3634 TRUE : FALSE;
3635 user_ool_dsc->copy = copy_options;
3636 user_ool_dsc->disposition = disp;
3637 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3638 user_ool_dsc->count = count;
3639
3640 user_dsc = (typeof(user_dsc))user_ool_dsc;
3641 } else {
3642 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc;
3643 user_ool_dsc--;
3644
3645 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr);
3646 user_ool_dsc->count = count;
3647 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ?
3648 TRUE : FALSE;
3649 user_ool_dsc->copy = copy_options;
3650 user_ool_dsc->disposition = disp;
3651 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
3652
3653 user_dsc = (typeof(user_dsc))user_ool_dsc;
3654 }
3655 return user_dsc;
3656 }
3657
3658 /*
3659 * Routine: ipc_kmsg_copyout_body
3660 * Purpose:
3661 * "Copy-out" port rights and out-of-line memory
3662 * in the body of a message.
3663 *
3664 * The error codes are a combination of special bits.
3665 * The copyout proceeds despite errors.
3666 * Conditions:
3667 * Nothing locked.
3668 * Returns:
3669 * MACH_MSG_SUCCESS Successful copyout.
3670 * MACH_MSG_IPC_SPACE No room for port right in name space.
3671 * MACH_MSG_VM_SPACE No room for memory in address space.
3672 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
3673 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
3674 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
3675 */
3676
3677 mach_msg_return_t
3678 ipc_kmsg_copyout_body(
3679 ipc_kmsg_t kmsg,
3680 ipc_space_t space,
3681 vm_map_t map,
3682 mach_msg_body_t *slist)
3683 {
3684 mach_msg_body_t *body;
3685 mach_msg_descriptor_t *kern_dsc, *user_dsc;
3686 mach_msg_descriptor_t *saddr;
3687 mach_msg_type_number_t dsc_count, sdsc_count;
3688 int i;
3689 mach_msg_return_t mr = MACH_MSG_SUCCESS;
3690 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
3691
3692 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3693 dsc_count = body->msgh_descriptor_count;
3694 kern_dsc = (mach_msg_descriptor_t *) (body + 1);
3695 /* Point user_dsc just after the end of all the descriptors */
3696 user_dsc = &kern_dsc[dsc_count];
3697
3698 /* Do scatter list setup */
3699 if (slist != MACH_MSG_BODY_NULL) {
3700 panic("Scatter lists disabled");
3701 saddr = (mach_msg_descriptor_t *) (slist + 1);
3702 sdsc_count = slist->msgh_descriptor_count;
3703 }
3704 else {
3705 saddr = MACH_MSG_DESCRIPTOR_NULL;
3706 sdsc_count = 0;
3707 }
3708
3709 /* Now process the descriptors */
3710 for (i = dsc_count-1; i >= 0; i--) {
3711 switch (kern_dsc[i].type.type) {
3712
3713 case MACH_MSG_PORT_DESCRIPTOR:
3714 user_dsc = ipc_kmsg_copyout_port_descriptor(&kern_dsc[i], user_dsc, space, &mr);
3715 break;
3716 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3717 case MACH_MSG_OOL_DESCRIPTOR :
3718 user_dsc = ipc_kmsg_copyout_ool_descriptor(
3719 (mach_msg_ool_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, &mr);
3720 break;
3721 case MACH_MSG_OOL_PORTS_DESCRIPTOR :
3722 user_dsc = ipc_kmsg_copyout_ool_ports_descriptor(
3723 (mach_msg_ool_ports_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, space, kmsg, &mr);
3724 break;
3725 default : {
3726 panic("untyped IPC copyout body: invalid message descriptor");
3727 }
3728 }
3729 }
3730
3731 if(user_dsc != kern_dsc) {
3732 vm_offset_t dsc_adjust = (vm_offset_t)user_dsc - (vm_offset_t)kern_dsc;
3733 memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
3734 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust);
3735 /* Update the message size for the smaller user representation */
3736 kmsg->ikm_header->msgh_size -= (mach_msg_size_t)dsc_adjust;
3737 }
3738
3739 return mr;
3740 }
3741
3742 /*
3743 * Routine: ipc_kmsg_copyout_size
3744 * Purpose:
3745 * Compute the size of the message as copied out to the given
3746 * map. If the destination map's pointers are a different size
3747 * than the kernel's, we have to allow for expansion/
3748 * contraction of the descriptors as appropriate.
3749 * Conditions:
3750 * Nothing locked.
3751 * Returns:
3752 * size of the message as it would be received.
3753 */
3754
3755 mach_msg_size_t
3756 ipc_kmsg_copyout_size(
3757 ipc_kmsg_t kmsg,
3758 vm_map_t map)
3759 {
3760 mach_msg_size_t send_size;
3761
3762 send_size = kmsg->ikm_header->msgh_size;
3763
3764 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS);
3765
3766 #if defined(__LP64__)
3767 send_size -= LEGACY_HEADER_SIZE_DELTA;
3768 #endif
3769
3770 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3771
3772 mach_msg_body_t *body;
3773 mach_msg_descriptor_t *saddr, *eaddr;
3774
3775 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3776 saddr = (mach_msg_descriptor_t *) (body + 1);
3777 eaddr = saddr + body->msgh_descriptor_count;
3778
3779 for ( ; saddr < eaddr; saddr++ ) {
3780 switch (saddr->type.type) {
3781 case MACH_MSG_OOL_DESCRIPTOR:
3782 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3783 case MACH_MSG_OOL_PORTS_DESCRIPTOR:
3784 if(!is_task_64bit)
3785 send_size -= DESC_SIZE_ADJUSTMENT;
3786 break;
3787 case MACH_MSG_PORT_DESCRIPTOR:
3788 send_size -= DESC_SIZE_ADJUSTMENT;
3789 break;
3790 default:
3791 break;
3792 }
3793 }
3794 }
3795 return send_size;
3796 }
3797
3798 /*
3799 * Routine: ipc_kmsg_copyout
3800 * Purpose:
3801 * "Copy-out" port rights and out-of-line memory
3802 * in the message.
3803 * Conditions:
3804 * Nothing locked.
3805 * Returns:
3806 * MACH_MSG_SUCCESS Copied out all rights and memory.
3807 * MACH_RCV_HEADER_ERROR + special bits
3808 * Rights and memory in the message are intact.
3809 * MACH_RCV_BODY_ERROR + special bits
3810 * The message header was successfully copied out.
3811 * As much of the body was handled as possible.
3812 */
3813
3814 mach_msg_return_t
3815 ipc_kmsg_copyout(
3816 ipc_kmsg_t kmsg,
3817 ipc_space_t space,
3818 vm_map_t map,
3819 mach_msg_body_t *slist,
3820 mach_msg_option_t option)
3821 {
3822 mach_msg_return_t mr;
3823
3824 mr = ipc_kmsg_copyout_header(kmsg, space, option);
3825 if (mr != MACH_MSG_SUCCESS) {
3826 return mr;
3827 }
3828
3829 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
3830 mr = ipc_kmsg_copyout_body(kmsg, space, map, slist);
3831
3832 if (mr != MACH_MSG_SUCCESS)
3833 mr |= MACH_RCV_BODY_ERROR;
3834 }
3835
3836 return mr;
3837 }
3838
3839 /*
3840 * Routine: ipc_kmsg_copyout_pseudo
3841 * Purpose:
3842 * Does a pseudo-copyout of the message.
3843 * This is like a regular copyout, except
3844 * that the ports in the header are handled
3845 * as if they are in the body. They aren't reversed.
3846 *
3847 * The error codes are a combination of special bits.
3848 * The copyout proceeds despite errors.
3849 * Conditions:
3850 * Nothing locked.
3851 * Returns:
3852 * MACH_MSG_SUCCESS Successful copyout.
3853 * MACH_MSG_IPC_SPACE No room for port right in name space.
3854 * MACH_MSG_VM_SPACE No room for memory in address space.
3855 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
3856 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
3857 */
3858
3859 mach_msg_return_t
3860 ipc_kmsg_copyout_pseudo(
3861 ipc_kmsg_t kmsg,
3862 ipc_space_t space,
3863 vm_map_t map,
3864 mach_msg_body_t *slist)
3865 {
3866 mach_msg_bits_t mbits = kmsg->ikm_header->msgh_bits;
3867 ipc_object_t dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
3868 ipc_object_t reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
3869 ipc_object_t voucher = (ipc_object_t) kmsg->ikm_voucher;
3870 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3871 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3872 mach_msg_type_name_t voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3873 mach_port_name_t voucher_name = kmsg->ikm_header->msgh_voucher_port;
3874 mach_port_name_t dest_name, reply_name;
3875 mach_msg_return_t mr;
3876
3877 assert(IO_VALID(dest));
3878
3879 #if 0
3880 /*
3881 * If we did this here, it looks like we wouldn't need the undo logic
3882 * at the end of ipc_kmsg_send() in the error cases. Not sure which
3883 * would be more elegant to keep.
3884 */
3885 ipc_importance_clean(kmsg);
3886 #else
3887 /* just assert it is already clean */
3888 ipc_importance_assert_clean(kmsg);
3889 #endif
3890
3891 mr = (ipc_kmsg_copyout_object(space, dest, dest_type, &dest_name) |
3892 ipc_kmsg_copyout_object(space, reply, reply_type, &reply_name));
3893
3894 kmsg->ikm_header->msgh_bits = mbits & MACH_MSGH_BITS_USER;
3895 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(dest_name);
3896 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(reply_name);
3897
3898 if (IO_VALID(voucher)) {
3899 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3900
3901 kmsg->ikm_voucher = IP_NULL;
3902 mr |= ipc_kmsg_copyout_object(space, voucher, voucher_type, &voucher_name);
3903 kmsg->ikm_header->msgh_voucher_port = voucher_name;
3904 }
3905
3906 if (mbits & MACH_MSGH_BITS_COMPLEX) {
3907 mr |= ipc_kmsg_copyout_body(kmsg, space, map, slist);
3908 }
3909
3910 return mr;
3911 }
3912
3913 /*
3914 * Routine: ipc_kmsg_copyout_dest
3915 * Purpose:
3916 * Copies out the destination port in the message.
3917 * Destroys all other rights and memory in the message.
3918 * Conditions:
3919 * Nothing locked.
3920 */
3921
3922 void
3923 ipc_kmsg_copyout_dest(
3924 ipc_kmsg_t kmsg,
3925 ipc_space_t space)
3926 {
3927 mach_msg_bits_t mbits;
3928 ipc_object_t dest;
3929 ipc_object_t reply;
3930 ipc_object_t voucher;
3931 mach_msg_type_name_t dest_type;
3932 mach_msg_type_name_t reply_type;
3933 mach_msg_type_name_t voucher_type;
3934 mach_port_name_t dest_name, reply_name, voucher_name;
3935
3936 mbits = kmsg->ikm_header->msgh_bits;
3937 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
3938 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
3939 voucher = (ipc_object_t) kmsg->ikm_voucher;
3940 voucher_name = kmsg->ikm_header->msgh_voucher_port;
3941 dest_type = MACH_MSGH_BITS_REMOTE(mbits);
3942 reply_type = MACH_MSGH_BITS_LOCAL(mbits);
3943 voucher_type = MACH_MSGH_BITS_VOUCHER(mbits);
3944
3945 assert(IO_VALID(dest));
3946
3947 ipc_importance_assert_clean(kmsg);
3948
3949 io_lock(dest);
3950 if (io_active(dest)) {
3951 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
3952 /* dest is unlocked */
3953 } else {
3954 io_unlock(dest);
3955 io_release(dest);
3956 dest_name = MACH_PORT_DEAD;
3957 }
3958
3959 if (IO_VALID(reply)) {
3960 ipc_object_destroy(reply, reply_type);
3961 reply_name = MACH_PORT_NULL;
3962 } else
3963 reply_name = CAST_MACH_PORT_TO_NAME(reply);
3964
3965 if (IO_VALID(voucher)) {
3966 assert(voucher_type == MACH_MSG_TYPE_MOVE_SEND);
3967
3968 kmsg->ikm_voucher = IP_NULL;
3969 ipc_object_destroy((ipc_object_t)voucher, voucher_type);
3970 voucher_name = MACH_PORT_NULL;
3971 }
3972
3973 kmsg->ikm_header->msgh_bits = MACH_MSGH_BITS_SET(reply_type, dest_type,
3974 voucher_type, mbits);
3975 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
3976 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
3977 kmsg->ikm_header->msgh_voucher_port = voucher_name;
3978
3979 if (mbits & MACH_MSGH_BITS_COMPLEX) {
3980 mach_msg_body_t *body;
3981
3982 body = (mach_msg_body_t *) (kmsg->ikm_header + 1);
3983 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count,
3984 (mach_msg_descriptor_t *)(body + 1));
3985 }
3986 }
3987
3988 /*
3989 * Routine: ipc_kmsg_copyout_to_kernel
3990 * Purpose:
3991 * Copies out the destination and reply ports in the message.
3992 * Leaves all other rights and memory in the message alone.
3993 * Conditions:
3994 * Nothing locked.
3995 *
3996 * Derived from ipc_kmsg_copyout_dest.
3997 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
3998 * We really do want to save rights and memory.
3999 */
4000
4001 void
4002 ipc_kmsg_copyout_to_kernel(
4003 ipc_kmsg_t kmsg,
4004 ipc_space_t space)
4005 {
4006 ipc_object_t dest;
4007 ipc_object_t reply;
4008 mach_msg_type_name_t dest_type;
4009 mach_msg_type_name_t reply_type;
4010 mach_port_name_t dest_name, reply_name;
4011
4012 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
4013 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
4014 dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits);
4015 reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits);
4016
4017 assert(IO_VALID(dest));
4018
4019 io_lock(dest);
4020 if (io_active(dest)) {
4021 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
4022 /* dest is unlocked */
4023 } else {
4024 io_unlock(dest);
4025 io_release(dest);
4026 dest_name = MACH_PORT_DEAD;
4027 }
4028
4029 reply_name = CAST_MACH_PORT_TO_NAME(reply);
4030
4031 kmsg->ikm_header->msgh_bits =
4032 (MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) |
4033 MACH_MSGH_BITS(reply_type, dest_type));
4034 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
4035 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
4036 }
4037
4038 #if IKM_SUPPORT_LEGACY
4039 void
4040 ipc_kmsg_copyout_to_kernel_legacy(
4041 ipc_kmsg_t kmsg,
4042 ipc_space_t space)
4043 {
4044 ipc_object_t dest;
4045 ipc_object_t reply;
4046 mach_msg_type_name_t dest_type;
4047 mach_msg_type_name_t reply_type;
4048 mach_port_name_t dest_name, reply_name;
4049
4050 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port;
4051 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port;
4052 dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits);
4053 reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits);
4054
4055 assert(IO_VALID(dest));
4056
4057 io_lock(dest);
4058 if (io_active(dest)) {
4059 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
4060 /* dest is unlocked */
4061 } else {
4062 io_unlock(dest);
4063 io_release(dest);
4064 dest_name = MACH_PORT_DEAD;
4065 }
4066
4067 reply_name = CAST_MACH_PORT_TO_NAME(reply);
4068
4069 kmsg->ikm_header->msgh_bits =
4070 (MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) |
4071 MACH_MSGH_BITS(reply_type, dest_type));
4072 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name);
4073 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name);
4074
4075 mach_msg_descriptor_t *saddr;
4076 mach_msg_legacy_descriptor_t *daddr;
4077 mach_msg_type_number_t i, count = ((mach_msg_base_t *)kmsg->ikm_header)->body.msgh_descriptor_count;
4078 saddr = (mach_msg_descriptor_t *) (((mach_msg_base_t *)kmsg->ikm_header) + 1);
4079 saddr = &saddr[count-1];
4080 daddr = (mach_msg_legacy_descriptor_t *)&saddr[count];
4081 daddr--;
4082
4083 vm_offset_t dsc_adjust = 0;
4084
4085 for (i = 0; i < count; i++, saddr--, daddr--) {
4086 switch (saddr->type.type) {
4087 case MACH_MSG_PORT_DESCRIPTOR: {
4088 mach_msg_port_descriptor_t *dsc = &saddr->port;
4089 mach_msg_legacy_port_descriptor_t *dest_dsc = &daddr->port;
4090
4091 mach_port_t name = dsc->name;
4092 mach_msg_type_name_t disposition = dsc->disposition;
4093
4094 dest_dsc->name = CAST_MACH_PORT_TO_NAME(name);
4095 dest_dsc->disposition = disposition;
4096 dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR;
4097 break;
4098 }
4099 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4100 case MACH_MSG_OOL_DESCRIPTOR: {
4101 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
4102 * so we don't need to do anything special. */
4103
4104 mach_msg_ool_descriptor_t *source_dsc = (typeof(source_dsc))&saddr->out_of_line;
4105
4106 mach_msg_ool_descriptor32_t *dest_dsc = &daddr->out_of_line32;
4107
4108 vm_offset_t address = (vm_offset_t)source_dsc->address;
4109 vm_size_t size = source_dsc->size;
4110 boolean_t deallocate = source_dsc->deallocate;
4111 mach_msg_copy_options_t copy = source_dsc->copy;
4112 mach_msg_descriptor_type_t type = source_dsc->type;
4113
4114 dest_dsc->address = address;
4115 dest_dsc->size = size;
4116 dest_dsc->deallocate = deallocate;
4117 dest_dsc->copy = copy;
4118 dest_dsc->type = type;
4119 break;
4120 }
4121 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
4122 mach_msg_ool_ports_descriptor_t *source_dsc = (typeof(source_dsc))&saddr->ool_ports;
4123
4124 mach_msg_ool_ports_descriptor32_t *dest_dsc = &daddr->ool_ports32;
4125
4126 vm_offset_t address = (vm_offset_t)source_dsc->address;
4127 vm_size_t port_count = source_dsc->count;
4128 boolean_t deallocate = source_dsc->deallocate;
4129 mach_msg_copy_options_t copy = source_dsc->copy;
4130 mach_msg_descriptor_type_t type = source_dsc->type;
4131
4132 dest_dsc->address = address;
4133 dest_dsc->count = port_count;
4134 dest_dsc->deallocate = deallocate;
4135 dest_dsc->copy = copy;
4136 dest_dsc->type = type;
4137 break;
4138 }
4139 default: {
4140 #if MACH_ASSERT
4141 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
4142 #endif /* MACH_ASSERT */
4143 }
4144 }
4145 }
4146
4147 if(count) {
4148 dsc_adjust = 4*count;
4149 memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t));
4150 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust);
4151 /* Update the message size for the smaller user representation */
4152 kmsg->ikm_header->msgh_size -= dsc_adjust;
4153 }
4154 }
4155 #endif /* IKM_SUPPORT_LEGACY */
4156
4157
4158 mach_msg_trailer_size_t
4159 ipc_kmsg_add_trailer(ipc_kmsg_t kmsg, ipc_space_t space __unused,
4160 mach_msg_option_t option, thread_t thread,
4161 mach_port_seqno_t seqno, boolean_t minimal_trailer,
4162 mach_vm_offset_t context)
4163 {
4164 mach_msg_max_trailer_t *trailer;
4165
4166 (void)thread;
4167 trailer = (mach_msg_max_trailer_t *)
4168 ((vm_offset_t)kmsg->ikm_header +
4169 round_msg(kmsg->ikm_header->msgh_size));
4170
4171 if (!(option & MACH_RCV_TRAILER_MASK)) {
4172 return trailer->msgh_trailer_size;
4173 }
4174
4175 trailer->msgh_seqno = seqno;
4176 trailer->msgh_context = context;
4177 trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit(thread), option);
4178
4179 if (minimal_trailer) {
4180 goto done;
4181 }
4182
4183 if (MACH_RCV_TRAILER_ELEMENTS(option) >=
4184 MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV)){
4185 trailer->msgh_ad = 0;
4186 }
4187
4188 /*
4189 * The ipc_kmsg_t holds a reference to the label of a label
4190 * handle, not the port. We must get a reference to the port
4191 * and a send right to copyout to the receiver.
4192 */
4193
4194 if (option & MACH_RCV_TRAILER_ELEMENTS (MACH_RCV_TRAILER_LABELS)) {
4195 trailer->msgh_labels.sender = 0;
4196 }
4197
4198 done:
4199
4200 return trailer->msgh_trailer_size;
4201 }