2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34 * All Rights Reserved.
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.
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.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
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,
61 * Copyright (c) 2005 SPARTA, Inc.
66 * File: ipc/ipc_kmsg.c
70 * Operations on kernel messages.
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>
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>
94 #include <kern/misc_protos.h>
95 #include <kern/counters.h>
96 #include <kern/cpu_data.h>
98 #include <machine/machlimits.h>
100 #include <vm/vm_map.h>
101 #include <vm/vm_object.h>
102 #include <vm/vm_kern.h>
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>
116 #include <security/mac_mach_internal.h>
121 #include <ppc/Firmware.h>
122 #include <ppc/low_trace.h>
126 #define DEBUG_MSGS_K64 1
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
;
143 mach_msg_legacy_header_t header
;
144 mach_msg_body_t body
;
145 } mach_msg_legacy_base_t
;
149 mach_port_name_t name
;
150 mach_msg_size_t pad1
;
152 mach_msg_type_name_t disposition
: 8;
153 mach_msg_descriptor_type_t type
: 8;
154 } mach_msg_legacy_port_descriptor_t
;
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
;
167 #define LEGACY_HEADER_SIZE_DELTA ((mach_msg_size_t)(sizeof(mach_msg_header_t) - sizeof(mach_msg_legacy_header_t)))
172 extern void ipc_pset_print64(
175 extern void ipc_kmsg_print64(
179 extern void ipc_msg_print64(
180 mach_msg_header_t
*msgh
);
182 extern ipc_port_t
ipc_name_to_data64(
184 mach_port_name_t name
);
187 * Forward declarations
189 void ipc_msg_print_untyped64(
190 mach_msg_body_t
*body
);
192 const char * ipc_type_name64(
196 void ipc_print_type_name64(
201 mach_msg_bits_t bit
);
204 mm_copy_options_string64(
205 mach_msg_copy_options_t option
);
207 void db_print_msg_uid64(mach_msg_header_t
*);
210 ipc_msg_body_print64(void *body
, int size
)
212 uint32_t *word
= (uint32_t *) body
;
213 uint32_t *end
= (uint32_t *)(((uintptr_t) body
) + size
214 - sizeof(mach_msg_header_t
));
217 kprintf(" body(%p-%p):\n %p: ", body
, end
, word
);
219 for (i
= 0; i
< 8; i
++, word
++) {
224 kprintf("%08x ", *word
);
226 kprintf("\n %p: ", word
);
237 case MACH_MSG_TYPE_PORT_NAME
:
240 case MACH_MSG_TYPE_MOVE_RECEIVE
:
242 return "port_receive";
244 return "move_receive";
247 case MACH_MSG_TYPE_MOVE_SEND
:
254 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
256 return "port_send_once";
258 return "move_send_once";
261 case MACH_MSG_TYPE_COPY_SEND
:
264 case MACH_MSG_TYPE_MAKE_SEND
:
267 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
268 return "make_send_once";
276 ipc_print_type_name64(
279 const char *name
= ipc_type_name64(type_name
, TRUE
);
283 kprintf("type%d", type_name
);
288 * ipc_kmsg_print64 [ debug ]
295 kprintf("%s kmsg=%p:\n", str
, kmsg
);
296 kprintf(" next=%p, prev=%p, size=%d",
301 ipc_msg_print64(kmsg
->ikm_header
);
309 case MACH_MSGH_BITS_COMPLEX
: return "complex";
310 case MACH_MSGH_BITS_CIRCULAR
: return "circular";
311 default: return (char *) 0;
316 * ipc_msg_print64 [ debug ]
320 mach_msg_header_t
*msgh
)
322 mach_msg_bits_t mbits
;
324 const char *bit_name
;
327 mbits
= msgh
->msgh_bits
;
328 kprintf(" msgh_bits=0x%x: l=0x%x,r=0x%x\n",
330 MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
),
331 MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
333 mbits
= MACH_MSGH_BITS_OTHER(mbits
) & MACH_MSGH_BITS_USED
;
334 kprintf(" decoded bits: ");
336 for (i
= 0, bit
= 1; i
< sizeof(mbits
) * 8; ++i
, bit
<<= 1) {
337 if ((mbits
& bit
) == 0)
339 bit_name
= msgh_bit_decode64((mach_msg_bits_t
)bit
);
341 kprintf("%s%s", needs_comma
? "," : "", bit_name
);
343 kprintf("%sunknown(0x%x),", needs_comma
? "," : "", bit
);
346 if (msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
) {
347 kprintf("%sunused=0x%x,", needs_comma
? "," : "",
348 msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
);
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
));
358 kprintf(" remote=null");
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
));
367 kprintf("local=null\n");
370 kprintf(" msgh_id=%d, size=%d\n",
374 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
375 ipc_msg_print_untyped64((mach_msg_body_t
*) (msgh
+ 1));
378 ipc_msg_body_print64((void *)(msgh
+ 1), msgh
->msgh_size
);
383 mm_copy_options_string64(
384 mach_msg_copy_options_t option
)
389 case MACH_MSG_PHYSICAL_COPY
:
392 case MACH_MSG_VIRTUAL_COPY
:
395 case MACH_MSG_OVERWRITE
:
398 case MACH_MSG_ALLOCATE
:
401 case MACH_MSG_KALLOC_COPY_T
:
402 name
= "KALLOC_COPY_T";
412 ipc_msg_print_untyped64(
413 mach_msg_body_t
*body
)
415 mach_msg_descriptor_t
*saddr
, *send
;
416 mach_msg_descriptor_type_t type
;
418 kprintf(" %d descriptors: \n", body
->msgh_descriptor_count
);
420 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
421 send
= saddr
+ body
->msgh_descriptor_count
;
423 for ( ; saddr
< send
; saddr
++ ) {
425 type
= saddr
->type
.type
;
429 case MACH_MSG_PORT_DESCRIPTOR
: {
430 mach_msg_port_descriptor_t
*dsc
;
433 kprintf(" PORT name = %p disp = ", dsc
->name
);
434 ipc_print_type_name64(dsc
->disposition
);
438 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
439 case MACH_MSG_OOL_DESCRIPTOR
: {
440 mach_msg_ool_descriptor_t
*dsc
;
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" : "");
450 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
451 mach_msg_ool_ports_descriptor_t
*dsc
;
453 dsc
= (mach_msg_ool_ports_descriptor_t
*) &saddr
->ool_ports
;
455 kprintf(" OOL_PORTS addr = %p count = 0x%x ",
456 dsc
->address
, dsc
->count
);
458 ipc_print_type_name64(dsc
->disposition
);
459 kprintf(" copy = %s %s\n",
460 mm_copy_options_string64(dsc
->copy
),
461 dsc
->deallocate
? "DEALLOC" : "");
466 kprintf(" UNKNOWN DESCRIPTOR 0x%x\n", type
);
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); \
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);\
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 */
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
;
492 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
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
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
504 #define DESC_SIZE_ADJUSTMENT ((mach_msg_size_t)(sizeof(mach_msg_ool_descriptor64_t) - \
505 sizeof(mach_msg_ool_descriptor32_t)))
507 /* scatter list macros */
509 #define SKIP_PORT_DESCRIPTORS(s, c) \
511 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
513 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \
518 (s) = MACH_MSG_DESCRIPTOR_NULL; \
522 #define INCREMENT_SCATTER(s, c, d) \
524 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
525 s = (d) ? (mach_msg_descriptor_t *) \
526 ((OTHER_OOL_DESCRIPTOR *)(s) + 1) : \
532 /* zone for cached ipc_kmsg_t structures */
533 zone_t ipc_kmsg_zone
;
536 * Forward declarations
542 void ipc_kmsg_clean_body(
544 mach_msg_type_number_t number
,
545 mach_msg_descriptor_t
*desc
);
547 void ipc_kmsg_clean_partial(
549 mach_msg_type_number_t number
,
550 mach_msg_descriptor_t
*desc
,
554 mach_msg_return_t
ipc_kmsg_copyin_body(
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
568 * Routine: ipc_kmsg_alloc
570 * Allocate a kernel message structure. If we can get one from
571 * the cache, that is best. Otherwise, allocate a new one.
577 mach_msg_size_t msg_and_trailer_size
)
579 mach_msg_size_t max_expanded_size
;
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).
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
595 mach_msg_size_t size
= msg_and_trailer_size
- MAX_TRAILER_SIZE
;
597 /* compare against implementation upper limit for the body */
598 if (size
> ipc_kmsg_max_body_space
)
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
);
606 /* make sure expansion won't cause wrap */
607 if (msg_and_trailer_size
> MACH_MSG_SIZE_MAX
- max_desc
)
610 max_expanded_size
= msg_and_trailer_size
+ max_desc
;
612 max_expanded_size
= msg_and_trailer_size
;
614 if (max_expanded_size
< IKM_SAVED_MSG_SIZE
)
615 max_expanded_size
= IKM_SAVED_MSG_SIZE
; /* round up for ikm_cache */
617 if (max_expanded_size
== IKM_SAVED_MSG_SIZE
) {
618 struct ikm_cache
*cache
;
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
];
628 ikm_check_init(kmsg
, max_expanded_size
);
629 ikm_set_header(kmsg
, msg_and_trailer_size
);
633 kmsg
= (ipc_kmsg_t
)zalloc(ipc_kmsg_zone
);
635 kmsg
= (ipc_kmsg_t
)kalloc(ikm_plus_overhead(max_expanded_size
));
638 if (kmsg
!= IKM_NULL
) {
639 ikm_init(kmsg
, max_expanded_size
);
640 ikm_set_header(kmsg
, msg_and_trailer_size
);
647 * Routine: ipc_kmsg_free
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.
662 mach_msg_size_t size
= kmsg
->ikm_size
;
666 if (kmsg
->ikm_sender
!= NULL
) {
667 task_deallocate(kmsg
->ikm_sender
);
668 kmsg
->ikm_sender
= NULL
;
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.
677 port
= ikm_prealloc_inuse_port(kmsg
);
678 if (port
!= IP_NULL
) {
680 ikm_prealloc_clear_inuse(kmsg
, port
);
681 if (ip_active(port
) && (port
->ip_premsg
== kmsg
)) {
682 assert(IP_PREALLOC(port
));
688 ip_release(port
); /* May be last reference */
692 * Peek and see if it has to go back in the cache.
694 if (kmsg
->ikm_size
== IKM_SAVED_MSG_SIZE
) {
695 struct ikm_cache
*cache
;
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;
707 zfree(ipc_kmsg_zone
, kmsg
);
710 kfree(kmsg
, ikm_plus_overhead(size
));
715 * Routine: ipc_kmsg_enqueue
722 ipc_kmsg_queue_t queue
,
725 ipc_kmsg_enqueue_macro(queue
, kmsg
);
729 * Routine: ipc_kmsg_dequeue
731 * Dequeue and return a kmsg.
736 ipc_kmsg_queue_t queue
)
740 first
= ipc_kmsg_queue_first(queue
);
742 if (first
!= IKM_NULL
)
743 ipc_kmsg_rmqueue_first_macro(queue
, first
);
749 * Routine: ipc_kmsg_rmqueue
751 * Pull a kmsg out of a queue.
756 ipc_kmsg_queue_t queue
,
759 ipc_kmsg_t next
, prev
;
761 assert(queue
->ikmq_base
!= IKM_NULL
);
763 next
= kmsg
->ikm_next
;
764 prev
= kmsg
->ikm_prev
;
767 assert(prev
== kmsg
);
768 assert(queue
->ikmq_base
== kmsg
);
770 queue
->ikmq_base
= IKM_NULL
;
772 if (queue
->ikmq_base
== kmsg
)
773 queue
->ikmq_base
= next
;
775 next
->ikm_prev
= prev
;
776 prev
->ikm_next
= next
;
778 /* XXX Temporary debug logic */
779 assert((kmsg
->ikm_next
= IKM_BOGUS
) == IKM_BOGUS
);
780 assert((kmsg
->ikm_prev
= IKM_BOGUS
) == IKM_BOGUS
);
784 * Routine: ipc_kmsg_queue_next
786 * Return the kmsg following the given kmsg.
787 * (Or IKM_NULL if it is the last one in the queue.)
792 ipc_kmsg_queue_t queue
,
797 assert(queue
->ikmq_base
!= IKM_NULL
);
799 next
= kmsg
->ikm_next
;
800 if (queue
->ikmq_base
== next
)
807 * Routine: ipc_kmsg_destroy
809 * Destroys a kernel message. Releases all rights,
810 * references, and memory held by the message.
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.
826 if (ipc_kmsg_delayed_destroy(kmsg
))
827 ipc_kmsg_reap_delayed();
831 * Routine: ipc_kmsg_delayed_destroy
833 * Enqueues a kernel message for deferred destruction.
835 * Boolean indicator that the caller is responsible to reap
839 boolean_t
ipc_kmsg_delayed_destroy(
842 ipc_kmsg_queue_t queue
= &(current_thread()->ith_messages
);
843 boolean_t first
= ipc_kmsg_queue_empty(queue
);
845 ipc_kmsg_enqueue(queue
, kmsg
);
850 * Routine: ipc_kmsg_destroy_queue
852 * Destroys messages from the per-thread
853 * deferred reaping queue.
859 ipc_kmsg_reap_delayed(void)
861 ipc_kmsg_queue_t queue
= &(current_thread()->ith_messages
);
865 * must leave kmsg in queue while cleaning it to assure
866 * no nested calls recurse into here.
868 while ((kmsg
= ipc_kmsg_queue_first(queue
)) != IKM_NULL
) {
869 ipc_kmsg_clean(kmsg
);
870 ipc_kmsg_rmqueue(queue
, kmsg
);
876 * Routine: ipc_kmsg_clean_body
878 * Cleans the body of a kernel message.
879 * Releases all rights, references, and memory.
884 static unsigned int _ipc_kmsg_clean_invalid_desc
= 0;
887 __unused ipc_kmsg_t kmsg
,
888 mach_msg_type_number_t number
,
889 mach_msg_descriptor_t
*saddr
)
891 mach_msg_type_number_t i
;
896 for (i
= 0 ; i
< number
; i
++, saddr
++ ) {
898 switch (saddr
->type
.type
) {
900 case MACH_MSG_PORT_DESCRIPTOR
: {
901 mach_msg_port_descriptor_t
*dsc
;
906 * Destroy port rights carried in the message
908 if (!IO_VALID((ipc_object_t
) dsc
->name
))
910 ipc_object_destroy((ipc_object_t
) dsc
->name
, dsc
->disposition
);
913 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
914 case MACH_MSG_OOL_DESCRIPTOR
: {
915 mach_msg_ool_descriptor_t
*dsc
;
917 dsc
= (mach_msg_ool_descriptor_t
*)&saddr
->out_of_line
;
920 * Destroy memory carried in the message
922 if (dsc
->size
== 0) {
923 assert(dsc
->address
== (void *) 0);
925 vm_map_copy_discard((vm_map_copy_t
) dsc
->address
);
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
;
934 dsc
= (mach_msg_ool_ports_descriptor_t
*)&saddr
->ool_ports
;
935 objects
= (ipc_object_t
*) dsc
->address
;
937 if (dsc
->count
== 0) {
941 assert(objects
!= (ipc_object_t
*) 0);
943 /* destroy port rights carried in the message */
945 for (j
= 0; j
< dsc
->count
; j
++) {
946 ipc_object_t object
= objects
[j
];
948 if (!IO_VALID(object
))
951 ipc_object_destroy(object
, dsc
->disposition
);
954 /* destroy memory carried in the message */
956 assert(dsc
->count
!= 0);
959 (vm_size_t
) dsc
->count
* sizeof(mach_port_t
));
963 _ipc_kmsg_clean_invalid_desc
++; /* don't understand this type of descriptor */
970 * Routine: ipc_kmsg_clean_partial
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.
983 ipc_kmsg_clean_partial(
985 mach_msg_type_number_t number
,
986 mach_msg_descriptor_t
*desc
,
991 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
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
));
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
));
1002 (void) vm_deallocate(ipc_kernel_copy_map
, paddr
, length
);
1005 ipc_kmsg_clean_body(kmsg
, number
, desc
);
1009 * Routine: ipc_kmsg_clean
1011 * Cleans a kernel message. Releases all rights,
1012 * references, and memory held by the message.
1021 ipc_object_t object
;
1022 mach_msg_bits_t mbits
;
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
));
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
));
1033 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
1034 mach_msg_body_t
*body
;
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));
1041 #if CONFIG_MACF_MACH
1042 if (kmsg
->ikm_sender
!= NULL
) {
1043 task_deallocate(kmsg
->ikm_sender
);
1044 kmsg
->ikm_sender
= NULL
;
1050 * Routine: ipc_kmsg_set_prealloc
1052 * Assign a kmsg as a preallocated message buffer to a port.
1058 ipc_kmsg_set_prealloc(
1062 assert(kmsg
->ikm_prealloc
== IP_NULL
);
1064 kmsg
->ikm_prealloc
= IP_NULL
;
1065 IP_SET_PREALLOC(port
, kmsg
);
1069 * Routine: ipc_kmsg_clear_prealloc
1071 * Release the Assignment of a preallocated message buffer from a port.
1076 ipc_kmsg_clear_prealloc(
1080 assert(kmsg
->ikm_prealloc
== port
);
1082 kmsg
->ikm_prealloc
= IP_NULL
;
1083 IP_CLEAR_PREALLOC(port
, kmsg
);
1087 * Routine: ipc_kmsg_prealloc
1089 * Wraper to ipc_kmsg_alloc() to account for
1090 * header expansion requirements.
1093 ipc_kmsg_prealloc(mach_msg_size_t size
)
1095 #if defined(__LP64__)
1096 if (size
> MACH_MSG_SIZE_MAX
- LEGACY_HEADER_SIZE_DELTA
)
1099 size
+= LEGACY_HEADER_SIZE_DELTA
;
1101 return ipc_kmsg_alloc(size
);
1106 * Routine: ipc_kmsg_get
1108 * Allocates a kernel message buffer.
1109 * Copies a user message to the message buffer.
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.
1123 mach_vm_address_t msg_addr
,
1124 mach_msg_size_t size
,
1127 mach_msg_size_t msg_and_trailer_size
;
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;
1134 if ((size
< sizeof(mach_msg_legacy_header_t
)) || (size
& 3))
1135 return MACH_SEND_MSG_TOO_SMALL
;
1137 if (size
> ipc_kmsg_max_body_space
)
1138 return MACH_SEND_TOO_LARGE
;
1140 if(size
== sizeof(mach_msg_legacy_header_t
))
1141 len_copied
= sizeof(mach_msg_legacy_header_t
);
1143 len_copied
= sizeof(mach_msg_legacy_base_t
);
1145 if (copyinmsg(msg_addr
, (char *)&legacy_base
, len_copied
))
1146 return MACH_SEND_INVALID_DATA
;
1148 msg_addr
+= sizeof(legacy_base
.header
);
1149 #if defined(__LP64__)
1150 size
+= LEGACY_HEADER_SIZE_DELTA
;
1152 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
)) {
1154 for (j
=0; j
<sizeof(legacy_base
.header
); j
++) {
1155 kprintf("%02x\n", ((unsigned char*)&legacy_base
.header
)[j
]);
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
;
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
;
1171 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_get header:\n"
1174 " remote_port: %p\n"
1176 " reserved: 0x%.8x\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
);
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
;
1190 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
))
1192 kprintf("body: size: %lu\n", (size
- sizeof(mach_msg_header_t
)));
1194 for(i
=0;i
*4 < (size
- sizeof(mach_msg_header_t
));i
++)
1196 kprintf("%.4x\n",((uint32_t *)(kmsg
->ikm_header
+ 1))[i
]);
1199 DEBUG_IPC_KMSG_PRINT(kmsg
, "ipc_kmsg_get()");
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.
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
;
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);
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();
1223 task_reference(cur
);
1224 kmsg
->ikm_sender
= cur
;
1226 trailer
->msgh_labels
.sender
= 0;
1228 trailer
->msgh_labels
.sender
= 0;
1232 return MACH_MSG_SUCCESS
;
1236 * Routine: ipc_kmsg_get_from_kernel
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.
1245 * Ports in header are ipc_port_t.
1247 * MACH_MSG_SUCCESS Acquired a message buffer.
1248 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
1252 ipc_kmsg_get_from_kernel(
1253 mach_msg_header_t
*msg
,
1254 mach_msg_size_t size
,
1258 mach_msg_size_t msg_and_trailer_size
;
1259 mach_msg_max_trailer_t
*trailer
;
1260 ipc_port_t dest_port
;
1262 assert(size
>= sizeof(mach_msg_header_t
));
1263 assert((size
& 3) == 0);
1265 dest_port
= (ipc_port_t
)msg
->msgh_remote_port
;
1267 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
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.
1274 if (IP_VALID(dest_port
) && IP_PREALLOC(dest_port
)) {
1275 mach_msg_size_t max_desc
= 0;
1278 if (!ip_active(dest_port
)) {
1279 ip_unlock(dest_port
);
1280 return MACH_SEND_NO_BUFFER
;
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
;
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
;
1295 if (msg_and_trailer_size
> kmsg
->ikm_size
- max_desc
) {
1296 ip_unlock(dest_port
);
1297 return MACH_SEND_TOO_LARGE
;
1299 ikm_prealloc_set_inuse(kmsg
, dest_port
);
1300 ikm_set_header(kmsg
, msg_and_trailer_size
);
1301 ip_unlock(dest_port
);
1305 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
1306 if (kmsg
== IKM_NULL
)
1307 return MACH_SEND_NO_BUFFER
;
1310 (void) memcpy((void *) kmsg
->ikm_header
, (const void *) msg
, size
);
1312 kmsg
->ikm_header
->msgh_size
= size
;
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.
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
;
1327 trailer
->msgh_labels
.sender
= 0;
1329 #if CONFIG_MACF_MACH
1330 kmsg
->ikm_sender
= NULL
;
1333 return MACH_MSG_SUCCESS
;
1337 * Routine: ipc_kmsg_send
1339 * Send a message. The message holds a reference
1340 * for the destination port in the msgh_remote_port field.
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.
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.
1357 mach_msg_option_t option
,
1358 mach_msg_timeout_t send_timeout
)
1361 mach_msg_return_t error
= MACH_MSG_SUCCESS
;
1364 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
1365 assert(IP_VALID(port
));
1369 if (port
->ip_receiver
== ipc_space_kernel
) {
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.
1377 assert(ip_active(port
));
1378 port
->ip_messages
.imq_seqno
++;
1381 current_task()->messages_sent
++;
1384 * Call the server routine, and get the reply message to send.
1386 kmsg
= ipc_kobject_server(kmsg
);
1387 if (kmsg
== IKM_NULL
)
1388 return MACH_MSG_SUCCESS
;
1390 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
1391 assert(IP_VALID(port
));
1393 /* fall thru with reply - same options */
1397 * Can't deliver to a dead port.
1398 * However, we can pretend it got sent
1399 * and was then immediately destroyed.
1401 if (!ip_active(port
)) {
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.
1410 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
1411 ipc_kmsg_destroy(kmsg
);
1412 return MACH_MSG_SUCCESS
;
1415 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_CIRCULAR
) {
1418 /* don't allow the creation of a circular loop */
1420 ipc_kmsg_destroy(kmsg
);
1421 return MACH_MSG_SUCCESS
;
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.
1430 imq_lock(&port
->ip_messages
);
1432 error
= ipc_mqueue_send(&port
->ip_messages
, kmsg
, option
,
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).
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
;
1448 * Routine: ipc_kmsg_put
1450 * Copies a message buffer to a user message.
1451 * Copies only the specified number of bytes.
1452 * Frees the message buffer.
1454 * Nothing locked. The message buffer must have clean
1457 * MACH_MSG_SUCCESS Copied data out of message buffer.
1458 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
1463 mach_vm_address_t msg_addr
,
1465 mach_msg_size_t size
)
1467 mach_msg_return_t mr
;
1469 DEBUG_IPC_KMSG_PRINT(kmsg
, "ipc_kmsg_put()");
1472 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_put header:\n"
1475 " remote_port: %p\n"
1477 " reserved: 0x%.8x\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
);
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
);
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
;
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
;
1505 size
-= LEGACY_HEADER_SIZE_DELTA
;
1506 kmsg
->ikm_header
= (mach_msg_header_t
*)legacy_header
;
1510 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
)) {
1511 kprintf("ipc_kmsg_put header+body: %d\n", (size
));
1513 for(i
=0;i
*4 < size
;i
++)
1515 kprintf("%.4x\n",((uint32_t *)kmsg
->ikm_header
)[i
]);
1517 kprintf("type: %d\n", ((mach_msg_type_descriptor_t
*)(((mach_msg_base_t
*)kmsg
->ikm_header
)+1))->type
);
1519 if (copyoutmsg((const char *) kmsg
->ikm_header
, msg_addr
, size
))
1520 mr
= MACH_RCV_INVALID_DATA
;
1522 mr
= MACH_MSG_SUCCESS
;
1524 ipc_kmsg_free(kmsg
);
1529 * Routine: ipc_kmsg_put_to_kernel
1531 * Copies a message buffer to a kernel message.
1532 * Frees the message buffer.
1533 * No errors allowed.
1539 ipc_kmsg_put_to_kernel(
1540 mach_msg_header_t
*msg
,
1542 mach_msg_size_t size
)
1544 (void) memcpy((void *) msg
, (const void *) kmsg
->ikm_header
, size
);
1546 ipc_kmsg_free(kmsg
);
1550 * Routine: ipc_kmsg_copyin_header
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.
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.)
1574 ipc_kmsg_copyin_header(
1575 mach_msg_header_t
*msg
,
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
);
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
;
1591 queue_head_t links_data
;
1592 queue_t links
= &links_data
;
1593 wait_queue_link_t wql
;
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
;
1604 reply_soright
= IP_NULL
; /* in case we go to invalid dest early */
1606 is_write_lock(space
);
1607 if (!is_active(space
))
1610 if (!MACH_PORT_VALID(dest_name
))
1613 #if CONFIG_MACF_MACH
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.
1619 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1620 if (dest_entry
!= IE_NULL
) {
1622 ipc_port_t port
= (ipc_port_t
) dest_entry
->ie_object
;
1623 if (port
== IP_NULL
)
1626 if (ip_active(port
)) {
1627 task_t self
= current_task();
1628 tasklabel_lock(self
);
1629 error
= mac_port_check_send(&self
->maclabel
,
1631 tasklabel_unlock(self
);
1639 if (dest_name
== reply_name
) {
1640 mach_port_name_t name
= dest_name
;
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.
1654 dest_entry
= ipc_entry_lookup(space
, name
);
1655 if (dest_entry
== IE_NULL
)
1658 reply_entry
= dest_entry
;
1659 assert(reply_type
!= 0); /* because name not null */
1661 if (!ipc_right_copyin_check(space
, name
, reply_entry
, reply_type
))
1664 if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
) ||
1665 (reply_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
)) {
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.
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
,
1684 &dest_port
, &dest_soright
,
1687 if (kr
!= KERN_SUCCESS
)
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
1700 assert(IO_VALID(dest_port
));
1701 assert(dest_soright
== IP_NULL
);
1703 kr
= ipc_right_copyin(space
, name
, reply_entry
,
1705 &reply_port
, &reply_soright
,
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
)) {
1716 * To make this atomic, just do one copy-send,
1717 * and dup the send right we get out.
1720 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1722 &dest_port
, &dest_soright
,
1725 if (kr
!= KERN_SUCCESS
)
1728 assert(dest_entry
->ie_bits
& MACH_PORT_TYPE_SEND
);
1729 assert(dest_soright
== IP_NULL
);
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.
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
)) {
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.
1748 kr
= ipc_right_copyin_two(space
, name
, dest_entry
,
1749 &dest_port
, &dest_soright
,
1751 if (kr
!= KERN_SUCCESS
)
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
;
1760 reply_port
= dest_port
;
1761 reply_soright
= IP_NULL
;
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
)));
1771 * To make this atomic, just do a move-send,
1772 * and dup the send right we get out.
1775 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1776 MACH_MSG_TYPE_MOVE_SEND
, FALSE
,
1777 &dest_port
, &soright
,
1780 if (kr
!= KERN_SUCCESS
)
1783 /* the entry might need to be deallocated */
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
;
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.
1796 reply_port
= (ipc_object_t
)
1797 ipc_port_copy_send((ipc_port_t
) dest_port
);
1799 if (dest_type
== MACH_MSG_TYPE_MOVE_SEND
) {
1800 dest_soright
= soright
;
1801 reply_soright
= IP_NULL
;
1803 dest_soright
= IP_NULL
;
1804 reply_soright
= soright
;
1807 } else if (!MACH_PORT_VALID(reply_name
)) {
1809 * No reply port! This is an easy case
1810 * to make atomic. Just copyin the destination.
1813 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1814 if (dest_entry
== IE_NULL
)
1817 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1819 &dest_port
, &dest_soright
,
1822 if (kr
!= KERN_SUCCESS
)
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
;
1831 reply_port
= (ipc_object_t
)CAST_MACH_NAME_TO_PORT(reply_name
);
1832 reply_soright
= IP_NULL
;
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.
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.
1860 * Note that although the entries are different,
1861 * dest_port and reply_port might still be the same.
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.
1869 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1870 if (dest_entry
== IE_NULL
)
1873 reply_entry
= ipc_entry_lookup(space
, reply_name
);
1874 if (reply_entry
== IE_NULL
)
1877 assert(dest_entry
!= reply_entry
); /* names are not equal */
1878 assert(reply_type
!= 0); /* because reply_name not null */
1880 if (!ipc_right_copyin_check(space
, reply_name
, reply_entry
,
1884 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1886 &dest_port
, &dest_soright
,
1889 if (kr
!= KERN_SUCCESS
)
1892 assert(IO_VALID(dest_port
));
1894 kr
= ipc_right_copyin(space
, reply_name
, reply_entry
,
1896 &reply_port
, &reply_soright
,
1899 assert(kr
== KERN_SUCCESS
);
1901 /* the entries might need to be deallocated */
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
;
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
;
1914 dest_type
= ipc_object_copyin_type(dest_type
);
1915 reply_type
= ipc_object_copyin_type(reply_type
);
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.
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
;
1926 assert(dport
!= IP_NULL
);
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
);
1935 is_write_unlock(space
);
1937 if (dest_soright
!= IP_NULL
)
1938 ipc_notify_port_deleted(dest_soright
, dest_name
);
1940 if (reply_soright
!= IP_NULL
)
1941 ipc_notify_port_deleted(reply_soright
, reply_name
);
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
;
1948 while(!queue_empty(links
)) {
1949 wql
= (wait_queue_link_t
) dequeue(links
);
1950 wait_queue_link_free(wql
);
1953 if (release_port
!= IP_NULL
)
1954 ip_release(release_port
);
1956 return MACH_MSG_SUCCESS
;
1959 is_write_unlock(space
);
1961 while(!queue_empty(links
)) {
1962 wql
= (wait_queue_link_t
) dequeue(links
);
1963 wait_queue_link_free(wql
);
1966 if (release_port
!= IP_NULL
)
1967 ip_release(release_port
);
1969 return MACH_SEND_INVALID_REPLY
;
1972 is_write_unlock(space
);
1974 while(!queue_empty(links
)) {
1975 wql
= (wait_queue_link_t
) dequeue(links
);
1976 wait_queue_link_free(wql
);
1979 if (release_port
!= IP_NULL
)
1980 ip_release(release_port
);
1982 if (reply_soright
!= IP_NULL
)
1983 ipc_notify_port_deleted(reply_soright
, reply_name
);
1985 return MACH_SEND_INVALID_DEST
;
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
,
1994 mach_msg_return_t
*mr
);
1996 void ipc_print_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
,
2005 mach_msg_return_t
*mr
)
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
;
2013 user_disp
= user_dsc
->disposition
;
2014 result_disp
= ipc_object_copyin_type(user_disp
);
2016 name
= (mach_port_name_t
)user_dsc
->name
;
2017 if (MACH_PORT_VALID(name
)) {
2019 kern_return_t kr
= ipc_object_copyin(space
, name
, user_disp
, &object
);
2020 if (kr
!= KERN_SUCCESS
) {
2021 *mr
= MACH_SEND_INVALID_RIGHT
;
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
;
2030 dsc
->name
= (ipc_port_t
) object
;
2032 dsc
->name
= CAST_MACH_NAME_TO_PORT(name
);
2034 dsc
->disposition
= result_disp
;
2035 dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
2037 dsc
->pad_end
= 0; // debug, unnecessary
2039 return (mach_msg_descriptor_t
*)(user_dsc_in
+1);
2042 mach_msg_descriptor_t
* ipc_kmsg_copyin_ool_descriptor(
2043 mach_msg_ool_descriptor_t
*dsc
,
2044 mach_msg_descriptor_t
*user_dsc
,
2047 vm_map_copy_t
*copy
,
2048 vm_size_t
*space_needed
,
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
,
2057 vm_map_copy_t
*copy
,
2058 vm_size_t
*space_needed
,
2060 mach_msg_return_t
*mr
)
2064 mach_msg_copy_options_t copy_options
;
2065 mach_vm_offset_t addr
;
2066 mach_msg_descriptor_type_t dsc_type
;
2069 mach_msg_ool_descriptor64_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
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
;
2077 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2079 mach_msg_ool_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
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
;
2087 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2090 dsc
->size
= (mach_msg_size_t
)length
;
2091 dsc
->deallocate
= dealloc
;
2092 dsc
->copy
= copy_options
;
2093 dsc
->type
= dsc_type
;
2096 dsc
->address
= NULL
;
2097 } else if ((length
>= MSG_OOL_SIZE_SMALL
) &&
2098 (copy_options
== MACH_MSG_PHYSICAL_COPY
) && !dealloc
) {
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.
2110 if (copyin(addr
, (char *)*paddr
, length
)) {
2111 *mr
= MACH_SEND_INVALID_MEMORY
;
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.
2120 if (!page_aligned(length
)) {
2121 (void) memset((void *) (*paddr
+ length
), 0,
2122 round_page(length
) - length
);
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
;
2129 dsc
->address
= (void *)*copy
;
2130 *paddr
+= round_page(length
);
2131 *space_needed
-= round_page(length
);
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.
2139 * NOTE: A virtual copy is OK if the original is being
2140 * deallocted, even if a physical copy was requested.
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
;
2150 dsc
->address
= (void *)*copy
;
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
,
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
,
2173 mach_msg_return_t
*mr
)
2176 ipc_object_t
*objects
;
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
;
2188 mach_msg_ool_ports_descriptor64_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
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
;
2197 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2199 mach_msg_ool_ports_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
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
;
2208 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2211 dsc
->deallocate
= deallocate
;
2212 dsc
->copy
= copy_option
;
2215 dsc
->address
= NULL
; /* for now */
2217 result_disp
= ipc_object_copyin_type(user_disp
);
2218 dsc
->disposition
= result_disp
;
2220 if (count
> (INT_MAX
/ sizeof(mach_port_t
))) {
2221 *mr
= MACH_SEND_TOO_LARGE
;
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
);
2229 if (ports_length
== 0) {
2233 data
= kalloc(ports_length
);
2236 *mr
= MACH_SEND_NO_BUFFER
;
2241 mach_port_name_t
*names
= &((mach_port_name_t
*)data
)[count
];
2243 mach_port_name_t
*names
= ((mach_port_name_t
*)data
);
2246 if (copyinmap(map
, addr
, names
, names_length
) != KERN_SUCCESS
) {
2247 kfree(data
, ports_length
);
2248 *mr
= MACH_SEND_INVALID_MEMORY
;
2253 (void) mach_vm_deallocate(map
, addr
, (mach_vm_size_t
)ports_length
);
2256 objects
= (ipc_object_t
*) data
;
2257 dsc
->address
= data
;
2259 for ( i
= 0; i
< count
; i
++) {
2260 mach_port_name_t name
= names
[i
];
2261 ipc_object_t object
;
2263 if (!MACH_PORT_VALID(name
)) {
2264 objects
[i
] = (ipc_object_t
)CAST_MACH_NAME_TO_PORT(name
);
2268 kern_return_t kr
= ipc_object_copyin(space
, name
, user_disp
, &object
);
2270 if (kr
!= KERN_SUCCESS
) {
2273 for(j
= 0; j
< i
; j
++) {
2274 object
= objects
[j
];
2275 if (IPC_OBJECT_VALID(object
))
2276 ipc_object_destroy(object
, result_disp
);
2278 kfree(data
, ports_length
);
2279 dsc
->address
= NULL
;
2280 *mr
= MACH_SEND_INVALID_RIGHT
;
2284 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
2285 ipc_port_check_circularity(
2286 (ipc_port_t
) object
,
2288 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
2290 objects
[i
] = object
;
2297 * Routine: ipc_kmsg_copyin_body
2299 * "Copy-in" port rights and out-of-line memory
2300 * in the message body.
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.
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
2319 ipc_kmsg_copyin_body(
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
;
2337 vm_size_t descriptor_size
= 0;
2340 * Determine if the target is a kernel port.
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);
2346 dsc_count
= body
->msgh_descriptor_count
;
2348 return MACH_MSG_SUCCESS
;
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.
2356 for (i
= 0; i
< dsc_count
; i
++) {
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);
2369 descriptor_size
+= 12;
2370 naddr
= (typeof(naddr
))((vm_offset_t
)daddr
+ 12);
2374 descriptor_size
+= 12;
2375 naddr
= (typeof(naddr
))((vm_offset_t
)daddr
+ 12);
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
;
2385 switch (daddr
->type
.type
) {
2386 mach_msg_size_t size
;
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
;
2394 if (daddr
->out_of_line
.copy
!= MACH_MSG_PHYSICAL_COPY
&&
2395 daddr
->out_of_line
.copy
!= MACH_MSG_VIRTUAL_COPY
) {
2397 * Invalid copy option
2399 ipc_kmsg_clean_partial(kmsg
, 0, NULL
, 0, 0);
2400 mr
= MACH_SEND_INVALID_TYPE
;
2404 if ((size
>= MSG_OOL_SIZE_SMALL
) &&
2405 (daddr
->out_of_line
.copy
== MACH_MSG_PHYSICAL_COPY
) &&
2406 !(daddr
->out_of_line
.deallocate
)) {
2409 * Out-of-line memory descriptor, accumulate kernel
2410 * memory requirements
2412 space_needed
+= round_page(size
);
2413 if (space_needed
> ipc_kmsg_max_vm_space
) {
2416 * Per message kernel memory limit exceeded
2418 ipc_kmsg_clean_partial(kmsg
, 0, NULL
, 0, 0);
2419 mr
= MACH_MSG_VM_KERNEL
;
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
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
;
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
;
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
));
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
);
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
, ©
, &space_needed
, map
, &mr
);
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
);
2478 /* Invalid descriptor */
2479 mr
= MACH_SEND_INVALID_TYPE
;
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
);
2493 kmsg
->ikm_header
->msgh_bits
&= ~MACH_MSGH_BITS_COMPLEX
;
2501 * Routine: ipc_kmsg_copyin
2503 * "Copy-in" port rights and out-of-line memory
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.
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.
2531 mach_msg_return_t mr
;
2533 mr
= ipc_kmsg_copyin_header(kmsg
->ikm_header
, space
, notify
);
2534 if (mr
!= MACH_MSG_SUCCESS
)
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
);
2545 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
2546 return MACH_MSG_SUCCESS
;
2548 mr
= ipc_kmsg_copyin_body( kmsg
, space
, map
);
2550 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
))
2554 for(i
=0;i
*4 < (kmsg
->ikm_header
->msgh_size
- sizeof(mach_msg_header_t
));i
++)
2556 kprintf("%.4x\n",((uint32_t *)(kmsg
->ikm_header
+ 1))[i
]);
2563 * Routine: ipc_kmsg_copyin_from_kernel
2565 * "Copy-in" port rights and out-of-line memory
2566 * in a message sent from the kernel.
2568 * Because the message comes from the kernel,
2569 * the implementation assumes there are no errors
2570 * or peculiarities in the message.
2572 * Returns TRUE if queueing the message
2573 * would result in a circularity.
2579 ipc_kmsg_copyin_from_kernel(
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
;
2588 /* translate the destination and reply ports */
2589 if (!IO_VALID(remote
))
2590 return MACH_SEND_INVALID_DEST
;
2592 ipc_object_copyin_from_kernel(remote
, rname
);
2593 if (IO_VALID(local
))
2594 ipc_object_copyin_from_kernel(local
, lname
);
2597 * The common case is a complex message with no reply port,
2598 * because that is what the memory_object interface uses.
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));
2606 kmsg
->ikm_header
->msgh_bits
= bits
;
2608 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
2609 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
2610 ipc_object_copyin_type(lname
)));
2612 kmsg
->ikm_header
->msgh_bits
= bits
;
2613 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
2614 return MACH_MSG_SUCCESS
;
2617 mach_msg_descriptor_t
*saddr
;
2618 mach_msg_body_t
*body
;
2619 mach_msg_type_number_t i
, count
;
2621 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2622 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2623 count
= body
->msgh_descriptor_count
;
2625 for (i
= 0; i
< count
; i
++, saddr
++) {
2627 switch (saddr
->type
.type
) {
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
;
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
);
2641 if (!IO_VALID(object
)) {
2645 ipc_object_copyin_from_kernel(object
, name
);
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 */
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
;
2662 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2663 case MACH_MSG_OOL_DESCRIPTOR
: {
2665 * The sender should supply ready-made memory, i.e.
2666 * a vm_map_copy_t, so we don't need to do anything.
2670 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
2671 ipc_object_t
*objects
;
2673 mach_msg_type_name_t name
;
2674 mach_msg_ool_ports_descriptor_t
*dsc
;
2676 dsc
= (mach_msg_ool_ports_descriptor_t
*)&saddr
->ool_ports
;
2678 /* this is really the type SEND, SEND_ONCE, etc. */
2679 name
= dsc
->disposition
;
2680 dsc
->disposition
= ipc_object_copyin_type(name
);
2682 objects
= (ipc_object_t
*) dsc
->address
;
2684 for ( j
= 0; j
< dsc
->count
; j
++) {
2685 ipc_object_t object
= objects
[j
];
2687 if (!IO_VALID(object
))
2690 ipc_object_copyin_from_kernel(object
, name
);
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
;
2702 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2703 #endif /* MACH_ASSERT */
2708 return MACH_MSG_SUCCESS
;
2711 #if IKM_SUPPORT_LEGACY
2713 ipc_kmsg_copyin_from_kernel_legacy(
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
;
2722 /* translate the destination and reply ports */
2723 if (!IO_VALID(remote
))
2724 return MACH_SEND_INVALID_DEST
;
2726 ipc_object_copyin_from_kernel(remote
, rname
);
2727 if (IO_VALID(local
))
2728 ipc_object_copyin_from_kernel(local
, lname
);
2731 * The common case is a complex message with no reply port,
2732 * because that is what the memory_object interface uses.
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));
2740 kmsg
->ikm_header
->msgh_bits
= bits
;
2742 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
2743 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
2744 ipc_object_copyin_type(lname
)));
2746 kmsg
->ikm_header
->msgh_bits
= bits
;
2747 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
2748 return MACH_MSG_SUCCESS
;
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
;
2756 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2757 saddr
= (typeof(saddr
)) (body
+ 1);
2758 count
= body
->msgh_descriptor_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
;
2767 daddr
= (mach_msg_descriptor_t
*)((vm_offset_t
)kmsg
->ikm_header
+ sizeof(mach_msg_base_t
));
2769 for (i
= 0; i
< count
; i
++, saddr
++, daddr
++) {
2770 switch (saddr
->type
.type
) {
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
;
2778 dsc
= (typeof(dsc
))&saddr
->port
;
2779 dest_dsc
= &daddr
->port
;
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
;
2788 if (!IO_VALID(object
)) {
2792 ipc_object_copyin_from_kernel(object
, name
);
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 */
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
;
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. */
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
;
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
;
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
;
2830 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
2831 ipc_object_t
*objects
;
2833 mach_msg_type_name_t name
;
2834 mach_msg_ool_ports_descriptor_t
*dest_dsc
;
2836 mach_msg_ool_ports_descriptor32_t
*source_dsc
= &saddr
->ool_ports32
;
2837 dest_dsc
= (typeof(dest_dsc
))&daddr
->ool_ports
;
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
;
2844 /* this is really the type SEND, SEND_ONCE, etc. */
2846 disposition
= ipc_object_copyin_type(name
);
2848 objects
= (ipc_object_t
*) (uintptr_t)source_dsc
->address
;
2850 for ( j
= 0; j
< port_count
; j
++) {
2851 ipc_object_t object
= objects
[j
];
2853 if (!IO_VALID(object
))
2856 ipc_object_copyin_from_kernel(object
, name
);
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
;
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
;
2875 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2876 #endif /* MACH_ASSERT */
2881 return MACH_MSG_SUCCESS
;
2883 #endif /* IKM_SUPPORT_LEGACY */
2886 * Routine: ipc_kmsg_copyout_header
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.
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.
2912 ipc_kmsg_copyout_header(
2913 mach_msg_header_t
*msg
,
2916 mach_msg_bits_t mbits
= msg
->msgh_bits
;
2917 ipc_port_t dest
= (ipc_port_t
) msg
->msgh_remote_port
;
2919 assert(IP_VALID(dest
));
2922 * While we still hold a reference on the received-from port,
2923 * process all send-possible notfications we received along with
2926 ipc_port_spnotify(dest
);
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
;
2935 if (IP_VALID(reply
)) {
2940 * Get reply port entry (if none, skip to dest port
2941 * copyout). This may require growing the space.
2944 is_write_lock(space
);
2947 if (!is_active(space
)) {
2948 is_write_unlock(space
);
2949 return (MACH_RCV_HEADER_ERROR
|
2950 MACH_MSG_IPC_SPACE
);
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
);
2963 if (!ip_active(reply
)) {
2966 is_write_unlock(space
);
2968 release_port
= reply
;
2970 reply_name
= MACH_PORT_DEAD
;
2974 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
2975 kr
= ipc_entry_get(space
, &reply_name
, &entry
);
2976 if (kr
!= KERN_SUCCESS
) {
2979 /* space is locked */
2980 kr
= ipc_entry_grow_table(space
,
2982 if (kr
!= KERN_SUCCESS
) {
2983 return (MACH_RCV_HEADER_ERROR
|
2984 MACH_MSG_IPC_SPACE
);
2986 /* space is locked again; start over */
2990 assert(IE_BITS_TYPE(entry
->ie_bits
) ==
2991 MACH_PORT_TYPE_NONE
);
2992 assert(entry
->ie_object
== IO_NULL
);
2994 entry
->ie_object
= (ipc_object_t
) reply
;
2998 /* space and reply port are locked and active */
3000 ip_reference(reply
); /* hold onto the reply port */
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
);
3008 is_write_unlock(space
);
3011 * No reply port! This is an easy case.
3012 * We only need to have the space locked
3013 * when locking the destination.
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
;
3023 is_read_unlock(space
);
3025 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
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).
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.
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.
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.
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.
3077 if (ip_active(dest
)) {
3078 ipc_object_copyout_dest(space
, (ipc_object_t
) dest
,
3079 dest_type
, &dest_name
);
3080 /* dest is unlocked */
3082 ipc_port_timestamp_t timestamp
;
3084 timestamp
= dest
->ip_timestamp
;
3088 if (IP_VALID(reply
)) {
3090 if (ip_active(reply
) ||
3091 IP_TIMESTAMP_ORDER(timestamp
,
3092 reply
->ip_timestamp
))
3093 dest_name
= MACH_PORT_DEAD
;
3095 dest_name
= MACH_PORT_NULL
;
3098 dest_name
= MACH_PORT_DEAD
;
3101 if (IP_VALID(reply
))
3104 if (IP_VALID(release_port
))
3105 ip_release(release_port
);
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
);
3113 return MACH_MSG_SUCCESS
;
3117 * Routine: ipc_kmsg_copyout_object
3119 * Copy-out a port right. Always returns a name,
3120 * even for unsuccessful return codes. Always
3121 * consumes the supplied object.
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.)
3134 ipc_kmsg_copyout_object(
3136 ipc_object_t object
,
3137 mach_msg_type_name_t msgt_name
,
3138 mach_port_name_t
*namep
)
3142 if (!IO_VALID(object
)) {
3143 *namep
= CAST_MACH_PORT_TO_NAME(object
);
3144 return MACH_MSG_SUCCESS
;
3147 kr
= ipc_object_copyout(space
, object
, msgt_name
, TRUE
, namep
);
3148 if (kr
!= KERN_SUCCESS
) {
3149 ipc_object_destroy(object
, msgt_name
);
3151 if (kr
== KERN_INVALID_CAPABILITY
)
3152 *namep
= MACH_PORT_DEAD
;
3154 *namep
= MACH_PORT_NULL
;
3156 if (kr
== KERN_RESOURCE_SHORTAGE
)
3157 return MACH_MSG_IPC_KERNEL
;
3159 return MACH_MSG_IPC_SPACE
;
3163 return MACH_MSG_SUCCESS
;
3166 mach_msg_descriptor_t
*
3167 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t
*dsc
,
3168 mach_msg_descriptor_t
*user_dsc
,
3171 mach_msg_descriptor_t
*
3172 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t
*dsc
,
3173 mach_msg_descriptor_t
*dest_dsc
,
3178 mach_port_name_t name
;
3179 mach_msg_type_name_t disp
;
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
,
3190 if(current_task() == kernel_task
)
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
;
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
;
3207 return (mach_msg_descriptor_t
*)dest_dsc
;
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
)
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
;
3221 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3223 copy
= (vm_map_copy_t
) dsc
->address
;
3225 copy_options
= dsc
->copy
;
3226 assert(copy_options
!= MACH_MSG_KALLOC_COPY_T
);
3227 dsc_type
= dsc
->type
;
3230 if (copy
!= VM_MAP_COPY_NULL
) {
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.
3237 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
3239 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
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
;
3246 copy_options
= MACH_MSG_VIRTUAL_COPY
;
3249 mach_msg_ool_descriptor_t
*scatter_dsc
;
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
;
3256 copy_options
= MACH_MSG_VIRTUAL_COPY
;
3259 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
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.
3271 if (copy_options
== MACH_MSG_OVERWRITE
&& rcv_addr
!= 0) {
3272 kr
= vm_map_copy_overwrite(map
, rcv_addr
,
3275 kr
= vm_map_copyout(map
, &rcv_addr
, copy
);
3277 if (kr
!= KERN_SUCCESS
) {
3278 if (kr
== KERN_RESOURCE_SHORTAGE
)
3279 *mr
|= MACH_MSG_VM_KERNEL
;
3281 *mr
|= MACH_MSG_VM_SPACE
;
3282 vm_map_copy_discard(copy
);
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.
3297 if(current_task() == kernel_task
)
3299 mach_msg_ool_descriptor_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3302 user_ool_dsc
->address
= (void *)(uintptr_t)rcv_addr
;
3303 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3305 user_ool_dsc
->copy
= copy_options
;
3306 user_ool_dsc
->type
= dsc_type
;
3307 user_ool_dsc
->size
= size
;
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
;
3314 user_ool_dsc
->address
= rcv_addr
;
3315 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3317 user_ool_dsc
->copy
= copy_options
;
3318 user_ool_dsc
->type
= dsc_type
;
3319 user_ool_dsc
->size
= size
;
3321 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3323 mach_msg_ool_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
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
) ?
3330 user_ool_dsc
->copy
= copy_options
;
3331 user_ool_dsc
->type
= dsc_type
;
3333 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
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
,
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
,
3353 mach_msg_return_t
*mr
)
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
;
3360 mach_msg_copy_options_t copy_options
= MACH_MSG_VIRTUAL_COPY
;
3362 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3365 disp
= dsc
->disposition
;
3366 ports_length
= count
* sizeof(mach_port_t
);
3367 names_length
= count
* sizeof(mach_port_name_t
);
3369 if (ports_length
!= 0 && dsc
->address
!= 0) {
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.
3377 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
3379 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
3381 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
3382 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
3383 copy_options
= scatter_dsc
->copy
;
3385 mach_msg_ool_descriptor_t
*scatter_dsc
;
3387 scatter_dsc
= &saddr
->out_of_line
;
3388 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
3389 copy_options
= scatter_dsc
->copy
;
3391 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
3395 if (copy_options
== MACH_MSG_VIRTUAL_COPY
) {
3397 * Dynamically allocate the region
3399 int anywhere
= VM_MAKE_TAG(VM_MEMORY_MACH_MSG
)|
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
);
3409 if (kr
== KERN_RESOURCE_SHORTAGE
){
3410 *mr
|= MACH_MSG_VM_KERNEL
;
3412 *mr
|= MACH_MSG_VM_SPACE
;
3418 * Handle the port rights and copy out the names
3419 * for those rights out to user-space.
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
;
3425 /* copyout port rights carried in the message */
3427 for ( i
= 0; i
< count
; i
++) {
3428 ipc_object_t object
= (ipc_object_t
)objects
[i
];
3430 *mr
|= ipc_kmsg_copyout_object(space
, object
,
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
);
3445 * Now update the descriptor based on the information
3448 if(current_task() == kernel_task
) {
3449 mach_msg_ool_ports_descriptor_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3452 user_ool_dsc
->address
= (void *)(uintptr_t)rcv_addr
;
3453 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
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
;
3460 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3462 mach_msg_ool_ports_descriptor64_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3465 user_ool_dsc
->address
= rcv_addr
;
3466 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
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
;
3473 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3475 mach_msg_ool_ports_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
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
) ?
3482 user_ool_dsc
->copy
= copy_options
;
3483 user_ool_dsc
->disposition
= disp
;
3484 user_ool_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
3486 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3492 * Routine: ipc_kmsg_copyout_body
3494 * "Copy-out" port rights and out-of-line memory
3495 * in the body of a message.
3497 * The error codes are a combination of special bits.
3498 * The copyout proceeds despite errors.
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
3511 ipc_kmsg_copyout_body(
3515 mach_msg_body_t
*slist
)
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
;
3522 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
3523 boolean_t is_task_64bit
= (map
->max_offset
> VM_MAX_ADDRESS
);
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
];
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
;
3538 saddr
= MACH_MSG_DESCRIPTOR_NULL
;
3542 /* Now process the descriptors */
3543 for (i
= dsc_count
-1; i
>= 0; i
--) {
3544 switch (kern_dsc
[i
].type
.type
) {
3546 case MACH_MSG_PORT_DESCRIPTOR
:
3547 user_dsc
= ipc_kmsg_copyout_port_descriptor(&kern_dsc
[i
], user_dsc
, space
, &mr
);
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
);
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
);
3559 panic("untyped IPC copyout body: invalid message descriptor");
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
;
3576 * Routine: ipc_kmsg_copyout_size
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.
3585 * size of the message as it would be received.
3589 ipc_kmsg_copyout_size(
3593 mach_msg_size_t send_size
;
3595 send_size
= kmsg
->ikm_header
->msgh_size
;
3597 boolean_t is_task_64bit
= (map
->max_offset
> VM_MAX_ADDRESS
);
3599 #if defined(__LP64__)
3600 send_size
-= LEGACY_HEADER_SIZE_DELTA
;
3603 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
3605 mach_msg_body_t
*body
;
3606 mach_msg_descriptor_t
*saddr
, *eaddr
;
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
;
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
:
3618 send_size
-= DESC_SIZE_ADJUSTMENT
;
3620 case MACH_MSG_PORT_DESCRIPTOR
:
3621 send_size
-= DESC_SIZE_ADJUSTMENT
;
3632 * Routine: ipc_kmsg_copyout
3634 * "Copy-out" port rights and out-of-line memory
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.
3652 mach_msg_body_t
*slist
)
3654 mach_msg_return_t mr
;
3656 mr
= ipc_kmsg_copyout_header(kmsg
->ikm_header
, space
);
3657 if (mr
!= MACH_MSG_SUCCESS
) {
3661 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
3662 mr
= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
3664 if (mr
!= MACH_MSG_SUCCESS
)
3665 mr
|= MACH_RCV_BODY_ERROR
;
3672 * Routine: ipc_kmsg_copyout_pseudo
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.
3679 * The error codes are a combination of special bits.
3680 * The copyout proceeds despite errors.
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.
3692 ipc_kmsg_copyout_pseudo(
3696 mach_msg_body_t
*slist
)
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
;
3706 assert(IO_VALID(dest
));
3708 mr
= (ipc_kmsg_copyout_object(space
, dest
, dest_type
, &dest_name
) |
3709 ipc_kmsg_copyout_object(space
, reply
, reply_type
, &reply_name
));
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
);
3715 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
3716 mr
|= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
3723 * Routine: ipc_kmsg_copyout_dest
3725 * Copies out the destination port in the message.
3726 * Destroys all other rights and memory in the message.
3732 ipc_kmsg_copyout_dest(
3736 mach_msg_bits_t mbits
;
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
;
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
);
3749 assert(IO_VALID(dest
));
3752 if (io_active(dest
)) {
3753 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
3754 /* dest is unlocked */
3758 dest_name
= MACH_PORT_DEAD
;
3761 if (IO_VALID(reply
)) {
3762 ipc_object_destroy(reply
, reply_type
);
3763 reply_name
= MACH_PORT_NULL
;
3765 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
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
);
3772 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
3773 mach_msg_body_t
*body
;
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));
3782 * Routine: ipc_kmsg_copyin_scatter
3784 * allocate and copyin a scatter list
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.
3798 * In the case of a size error, the scatter list is released.
3802 * the allocated message body containing the scatter list.
3806 ipc_kmsg_get_scatter(
3807 mach_vm_address_t msg_addr
,
3808 mach_msg_size_t slist_size
,
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
;
3816 #if defined(__LP64__)
3817 panic("ipc_kmsg_get_scatter called!");
3820 if (slist_size
< sizeof(mach_msg_base_t
))
3821 return MACH_MSG_BODY_NULL
;
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
)
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
;
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
;
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
;
3843 sstart
= (mach_msg_descriptor_t
*) (slist
+ 1);
3844 send
= sstart
+ slist
->msgh_descriptor_count
;
3846 while (gstart
< gend
) {
3847 mach_msg_descriptor_type_t g_type
;
3850 * Skip port descriptors in gather list.
3852 g_type
= gstart
->type
.type
;
3854 if (g_type
!= MACH_MSG_PORT_DESCRIPTOR
) {
3857 * A scatter list with a 0 descriptor count is treated as an
3858 * automatic size mismatch.
3860 if (slist
->msgh_descriptor_count
== 0) {
3861 kfree(slist
, slist_size
);
3862 return MACH_MSG_BODY_NULL
;
3866 * Skip port descriptors in scatter list.
3868 while (sstart
< send
) {
3869 if (sstart
->type
.type
!= MACH_MSG_PORT_DESCRIPTOR
)
3875 * No more scatter descriptors, we're done
3877 if (sstart
>= send
) {
3882 * Check type, copy and size fields
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
;
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
;
3898 if (sstart
->type
.type
!= MACH_MSG_OOL_PORTS_DESCRIPTOR
) {
3899 kfree(slist
, slist_size
);
3900 return MACH_MSG_BODY_NULL
;
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
;
3917 * Routine: ipc_kmsg_free_scatter
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.
3925 ipc_kmsg_free_scatter(
3926 mach_msg_body_t
*slist
,
3927 mach_msg_size_t slist_size
)
3929 #if defined(__LP64__)
3930 panic("%s called; halting!", __func__
);
3933 slist_size
-= (mach_msg_size_t
)sizeof(mach_msg_header_t
);
3934 kfree(slist
, slist_size
);
3939 * Routine: ipc_kmsg_copyout_to_kernel
3941 * Copies out the destination and reply ports in the message.
3942 * Leaves all other rights and memory in the message alone.
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.
3952 ipc_kmsg_copyout_to_kernel(
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
;
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
);
3967 assert(IO_VALID(dest
));
3970 if (io_active(dest
)) {
3971 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
3972 /* dest is unlocked */
3976 dest_name
= MACH_PORT_DEAD
;
3979 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
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
);
3988 #if IKM_SUPPORT_LEGACY
3990 ipc_kmsg_copyout_to_kernel_legacy(
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
;
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
);
4005 assert(IO_VALID(dest
));
4008 if (io_active(dest
)) {
4009 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
4010 /* dest is unlocked */
4014 dest_name
= MACH_PORT_DEAD
;
4017 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
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
);
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
];
4033 vm_offset_t dsc_adjust
= 0;
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
;
4041 mach_port_t name
= dsc
->name
;
4042 mach_msg_type_name_t disposition
= dsc
->disposition
;
4044 dest_dsc
->name
= CAST_MACH_PORT_TO_NAME(name
);
4045 dest_dsc
->disposition
= disposition
;
4046 dest_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
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. */
4054 mach_msg_ool_descriptor_t
*source_dsc
= (typeof(source_dsc
))&saddr
->out_of_line
;
4056 mach_msg_ool_descriptor32_t
*dest_dsc
= &daddr
->out_of_line32
;
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
;
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
;
4071 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
4072 mach_msg_ool_ports_descriptor_t
*source_dsc
= (typeof(source_dsc
))&saddr
->ool_ports
;
4074 mach_msg_ool_ports_descriptor32_t
*dest_dsc
= &daddr
->ool_ports32
;
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
;
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
;
4091 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
4092 #endif /* MACH_ASSERT */
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
;
4105 #endif /* IKM_SUPPORT_LEGACY */
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
)
4113 mach_msg_max_trailer_t
*trailer
;
4116 trailer
= (mach_msg_max_trailer_t
*)
4117 ((vm_offset_t
)kmsg
->ikm_header
+
4118 round_msg(kmsg
->ikm_header
->msgh_size
));
4120 if (!(option
& MACH_RCV_TRAILER_MASK
)) {
4121 return trailer
->msgh_trailer_size
;
4124 trailer
->msgh_seqno
= seqno
;
4125 trailer
->msgh_context
= context
;
4126 trailer
->msgh_trailer_size
= REQUESTED_TRAILER_SIZE(thread_is_64bit(thread
), option
);
4128 if (minimal_trailer
) {
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;
4144 trailer
->msgh_ad
= 0;
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.
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
;
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
);
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;
4173 trailer
->msgh_labels
.sender
= 0;
4177 trailer
->msgh_labels
.sender
= 0;
4183 return trailer
->msgh_trailer_size
;