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