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