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.
74 #include <mach/mach_types.h>
75 #include <mach/boolean.h>
76 #include <mach/kern_return.h>
77 #include <mach/message.h>
78 #include <mach/port.h>
79 #include <mach/vm_map.h>
80 #include <mach/mach_vm.h>
81 #include <mach/vm_statistics.h>
83 #include <kern/kern_types.h>
84 #include <kern/assert.h>
85 #include <kern/debug.h>
86 #include <kern/ipc_kobject.h>
87 #include <kern/kalloc.h>
88 #include <kern/zalloc.h>
89 #include <kern/processor.h>
90 #include <kern/thread.h>
91 #include <kern/sched_prim.h>
93 #include <kern/misc_protos.h>
94 #include <kern/counters.h>
95 #include <kern/cpu_data.h>
97 #include <machine/machlimits.h>
99 #include <vm/vm_map.h>
100 #include <vm/vm_object.h>
101 #include <vm/vm_kern.h>
103 #include <ipc/port.h>
104 #include <ipc/ipc_types.h>
105 #include <ipc/ipc_entry.h>
106 #include <ipc/ipc_kmsg.h>
107 #include <ipc/ipc_notify.h>
108 #include <ipc/ipc_object.h>
109 #include <ipc/ipc_space.h>
110 #include <ipc/ipc_port.h>
111 #include <ipc/ipc_right.h>
112 #include <ipc/ipc_hash.h>
113 #include <ipc/ipc_table.h>
115 #include <security/mac_mach_internal.h>
120 #include <ppc/Firmware.h>
121 #include <ppc/low_trace.h>
125 #define DEBUG_MSGS_K64 1
128 #include <sys/kdebug.h>
129 #include <libkern/OSAtomic.h>
135 mach_msg_bits_t msgh_bits
;
136 mach_msg_size_t msgh_size
;
137 uint32_t msgh_remote_port
;
138 uint32_t msgh_local_port
;
139 mach_msg_size_t msgh_reserved
;
140 mach_msg_id_t msgh_id
;
141 } mach_msg_legacy_header_t
;
145 mach_msg_legacy_header_t header
;
146 mach_msg_body_t body
;
147 } mach_msg_legacy_base_t
;
151 mach_port_name_t name
;
152 mach_msg_size_t pad1
;
154 mach_msg_type_name_t disposition
: 8;
155 mach_msg_descriptor_type_t type
: 8;
156 } mach_msg_legacy_port_descriptor_t
;
161 mach_msg_legacy_port_descriptor_t port
;
162 mach_msg_ool_descriptor32_t out_of_line32
;
163 mach_msg_ool_ports_descriptor32_t ool_ports32
;
164 mach_msg_type_descriptor_t type
;
165 } mach_msg_legacy_descriptor_t
;
169 #define LEGACY_HEADER_SIZE_DELTA ((mach_msg_size_t)(sizeof(mach_msg_header_t) - sizeof(mach_msg_legacy_header_t)))
174 extern void ipc_pset_print64(
177 extern void ipc_kmsg_print64(
181 extern void ipc_msg_print64(
182 mach_msg_header_t
*msgh
);
184 extern ipc_port_t
ipc_name_to_data64(
186 mach_port_name_t name
);
189 * Forward declarations
191 void ipc_msg_print_untyped64(
192 mach_msg_body_t
*body
);
194 const char * ipc_type_name64(
198 void ipc_print_type_name64(
203 mach_msg_bits_t bit
);
206 mm_copy_options_string64(
207 mach_msg_copy_options_t option
);
209 void db_print_msg_uid64(mach_msg_header_t
*);
212 ipc_msg_body_print64(void *body
, int size
)
214 uint32_t *word
= (uint32_t *) body
;
215 uint32_t *end
= (uint32_t *)(((uintptr_t) body
) + size
216 - sizeof(mach_msg_header_t
));
219 kprintf(" body(%p-%p):\n %p: ", body
, end
, word
);
221 for (i
= 0; i
< 8; i
++, word
++) {
226 kprintf("%08x ", *word
);
228 kprintf("\n %p: ", word
);
239 case MACH_MSG_TYPE_PORT_NAME
:
242 case MACH_MSG_TYPE_MOVE_RECEIVE
:
244 return "port_receive";
246 return "move_receive";
249 case MACH_MSG_TYPE_MOVE_SEND
:
256 case MACH_MSG_TYPE_MOVE_SEND_ONCE
:
258 return "port_send_once";
260 return "move_send_once";
263 case MACH_MSG_TYPE_COPY_SEND
:
266 case MACH_MSG_TYPE_MAKE_SEND
:
269 case MACH_MSG_TYPE_MAKE_SEND_ONCE
:
270 return "make_send_once";
278 ipc_print_type_name64(
281 const char *name
= ipc_type_name64(type_name
, TRUE
);
285 kprintf("type%d", type_name
);
290 * ipc_kmsg_print64 [ debug ]
297 kprintf("%s kmsg=%p:\n", str
, kmsg
);
298 kprintf(" next=%p, prev=%p, size=%d",
303 ipc_msg_print64(kmsg
->ikm_header
);
311 case MACH_MSGH_BITS_COMPLEX
: return "complex";
312 case MACH_MSGH_BITS_CIRCULAR
: return "circular";
313 default: return (char *) 0;
318 * ipc_msg_print64 [ debug ]
322 mach_msg_header_t
*msgh
)
324 mach_msg_bits_t mbits
;
326 const char *bit_name
;
329 mbits
= msgh
->msgh_bits
;
330 kprintf(" msgh_bits=0x%x: l=0x%x,r=0x%x\n",
332 MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
),
333 MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
335 mbits
= MACH_MSGH_BITS_OTHER(mbits
) & MACH_MSGH_BITS_USED
;
336 kprintf(" decoded bits: ");
338 for (i
= 0, bit
= 1; i
< sizeof(mbits
) * 8; ++i
, bit
<<= 1) {
339 if ((mbits
& bit
) == 0)
341 bit_name
= msgh_bit_decode64((mach_msg_bits_t
)bit
);
343 kprintf("%s%s", needs_comma
? "," : "", bit_name
);
345 kprintf("%sunknown(0x%x),", needs_comma
? "," : "", bit
);
348 if (msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
) {
349 kprintf("%sunused=0x%x,", needs_comma
? "," : "",
350 msgh
->msgh_bits
& ~MACH_MSGH_BITS_USED
);
355 if (msgh
->msgh_remote_port
) {
356 kprintf(" remote=%p(", msgh
->msgh_remote_port
);
357 ipc_print_type_name64(MACH_MSGH_BITS_REMOTE(msgh
->msgh_bits
));
360 kprintf(" remote=null");
363 if (msgh
->msgh_local_port
) {
364 kprintf("%slocal=%p(", needs_comma
? "," : "",
365 msgh
->msgh_local_port
);
366 ipc_print_type_name64(MACH_MSGH_BITS_LOCAL(msgh
->msgh_bits
));
369 kprintf("local=null\n");
372 kprintf(" msgh_id=%d, size=%d\n",
376 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
377 ipc_msg_print_untyped64((mach_msg_body_t
*) (msgh
+ 1));
380 ipc_msg_body_print64((void *)(msgh
+ 1), msgh
->msgh_size
);
385 mm_copy_options_string64(
386 mach_msg_copy_options_t option
)
391 case MACH_MSG_PHYSICAL_COPY
:
394 case MACH_MSG_VIRTUAL_COPY
:
397 case MACH_MSG_OVERWRITE
:
400 case MACH_MSG_ALLOCATE
:
403 case MACH_MSG_KALLOC_COPY_T
:
404 name
= "KALLOC_COPY_T";
414 ipc_msg_print_untyped64(
415 mach_msg_body_t
*body
)
417 mach_msg_descriptor_t
*saddr
, *send
;
418 mach_msg_descriptor_type_t type
;
420 kprintf(" %d descriptors: \n", body
->msgh_descriptor_count
);
422 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
423 send
= saddr
+ body
->msgh_descriptor_count
;
425 for ( ; saddr
< send
; saddr
++ ) {
427 type
= saddr
->type
.type
;
431 case MACH_MSG_PORT_DESCRIPTOR
: {
432 mach_msg_port_descriptor_t
*dsc
;
435 kprintf(" PORT name = %p disp = ", dsc
->name
);
436 ipc_print_type_name64(dsc
->disposition
);
440 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
441 case MACH_MSG_OOL_DESCRIPTOR
: {
442 mach_msg_ool_descriptor_t
*dsc
;
444 dsc
= (mach_msg_ool_descriptor_t
*) &saddr
->out_of_line
;
445 kprintf(" OOL%s addr = %p size = 0x%x copy = %s %s\n",
446 type
== MACH_MSG_OOL_DESCRIPTOR
? "" : " VOLATILE",
447 dsc
->address
, dsc
->size
,
448 mm_copy_options_string64(dsc
->copy
),
449 dsc
->deallocate
? "DEALLOC" : "");
452 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
453 mach_msg_ool_ports_descriptor_t
*dsc
;
455 dsc
= (mach_msg_ool_ports_descriptor_t
*) &saddr
->ool_ports
;
457 kprintf(" OOL_PORTS addr = %p count = 0x%x ",
458 dsc
->address
, dsc
->count
);
460 ipc_print_type_name64(dsc
->disposition
);
461 kprintf(" copy = %s %s\n",
462 mm_copy_options_string64(dsc
->copy
),
463 dsc
->deallocate
? "DEALLOC" : "");
468 kprintf(" UNKNOWN DESCRIPTOR 0x%x\n", type
);
475 #define DEBUG_IPC_KMSG_PRINT(kmsg,string) \
476 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \
477 ipc_kmsg_print64(kmsg, string); \
479 #define DEBUG_IPC_MSG_BODY_PRINT(body,size) \
480 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \
481 ipc_msg_body_print64(body,size);\
483 #else /* !DEBUG_MSGS_K64 */
484 #define DEBUG_IPC_KMSG_PRINT(kmsg,string)
485 #define DEBUG_IPC_MSG_BODY_PRINT(body,size)
486 #endif /* !DEBUG_MSGS_K64 */
488 extern vm_map_t ipc_kernel_copy_map
;
489 extern vm_size_t ipc_kmsg_max_space
;
490 extern vm_size_t ipc_kmsg_max_vm_space
;
491 extern vm_size_t ipc_kmsg_max_body_space
;
492 extern vm_size_t msg_ool_size_small
;
494 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
496 #if defined(__LP64__)
497 #define MAP_SIZE_DIFFERS(map) (map->max_offset < MACH_VM_MAX_ADDRESS)
498 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor32_t
499 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor32_t
501 #define MAP_SIZE_DIFFERS(map) (map->max_offset > VM_MAX_ADDRESS)
502 #define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor64_t
503 #define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor64_t
506 #define DESC_SIZE_ADJUSTMENT ((mach_msg_size_t)(sizeof(mach_msg_ool_descriptor64_t) - \
507 sizeof(mach_msg_ool_descriptor32_t)))
509 /* scatter list macros */
511 #define SKIP_PORT_DESCRIPTORS(s, c) \
513 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
515 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \
520 (s) = MACH_MSG_DESCRIPTOR_NULL; \
524 #define INCREMENT_SCATTER(s, c, d) \
526 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \
527 s = (d) ? (mach_msg_descriptor_t *) \
528 ((OTHER_OOL_DESCRIPTOR *)(s) + 1) : \
534 /* zone for cached ipc_kmsg_t structures */
535 zone_t ipc_kmsg_zone
;
538 * Forward declarations
544 void ipc_kmsg_clean_body(
546 mach_msg_type_number_t number
,
547 mach_msg_descriptor_t
*desc
);
549 void ipc_kmsg_clean_partial(
551 mach_msg_type_number_t number
,
552 mach_msg_descriptor_t
*desc
,
556 mach_msg_return_t
ipc_kmsg_copyin_body(
562 * We keep a per-processor cache of kernel message buffers.
563 * The cache saves the overhead/locking of using kalloc/kfree.
564 * The per-processor cache seems to miss less than a per-thread cache,
565 * and it also uses less memory. Access to the cache doesn't
570 * Routine: ipc_kmsg_alloc
572 * Allocate a kernel message structure. If we can get one from
573 * the cache, that is best. Otherwise, allocate a new one.
579 mach_msg_size_t msg_and_trailer_size
)
581 mach_msg_size_t max_expanded_size
;
586 * Pad the allocation in case we need to expand the
587 * message descrptors for user spaces with pointers larger than
588 * the kernel's own, or vice versa. We don't know how many descriptors
589 * there are yet, so just assume the whole body could be
590 * descriptors (if there could be any at all).
592 * The expansion space is left in front of the header,
593 * because it is easier to pull the header and descriptors
594 * forward as we process them than it is to push all the
597 mach_msg_size_t size
= msg_and_trailer_size
- MAX_TRAILER_SIZE
;
599 /* compare against implementation upper limit for the body */
600 if (size
> ipc_kmsg_max_body_space
)
603 if (size
> sizeof(mach_msg_base_t
)) {
604 mach_msg_size_t max_desc
= (mach_msg_size_t
)(((size
- sizeof(mach_msg_base_t
)) /
605 sizeof(mach_msg_ool_descriptor32_t
)) *
606 DESC_SIZE_ADJUSTMENT
);
608 /* make sure expansion won't cause wrap */
609 if (msg_and_trailer_size
> MACH_MSG_SIZE_MAX
- max_desc
)
612 max_expanded_size
= msg_and_trailer_size
+ max_desc
;
614 max_expanded_size
= msg_and_trailer_size
;
616 if (max_expanded_size
< IKM_SAVED_MSG_SIZE
)
617 max_expanded_size
= IKM_SAVED_MSG_SIZE
; /* round up for ikm_cache */
619 if (max_expanded_size
== IKM_SAVED_MSG_SIZE
) {
620 struct ikm_cache
*cache
;
623 disable_preemption();
624 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
625 if ((i
= cache
->avail
) > 0) {
626 assert(i
<= IKM_STASH
);
627 kmsg
= cache
->entries
[--i
];
630 ikm_check_init(kmsg
, max_expanded_size
);
631 ikm_set_header(kmsg
, msg_and_trailer_size
);
635 kmsg
= (ipc_kmsg_t
)zalloc(ipc_kmsg_zone
);
637 kmsg
= (ipc_kmsg_t
)kalloc(ikm_plus_overhead(max_expanded_size
));
640 if (kmsg
!= IKM_NULL
) {
641 ikm_init(kmsg
, max_expanded_size
);
642 ikm_set_header(kmsg
, msg_and_trailer_size
);
649 * Routine: ipc_kmsg_free
651 * Free a kernel message buffer. If the kms is preallocated
652 * to a port, just "put it back (marked unused)." We have to
653 * do this with the port locked. The port may have its hold
654 * on our message released. In that case, we have to just
655 * revert the message to a traditional one and free it normally.
664 mach_msg_size_t size
= kmsg
->ikm_size
;
668 if (kmsg
->ikm_sender
!= NULL
) {
669 task_deallocate(kmsg
->ikm_sender
);
670 kmsg
->ikm_sender
= NULL
;
675 * Check to see if the message is bound to the port. If so,
676 * mark it not in use. If the port isn't already dead, then
677 * leave the message associated with it. Otherwise, free it.
679 port
= ikm_prealloc_inuse_port(kmsg
);
680 if (port
!= IP_NULL
) {
682 ikm_prealloc_clear_inuse(kmsg
, port
);
683 if (ip_active(port
) && (port
->ip_premsg
== kmsg
)) {
684 assert(IP_PREALLOC(port
));
690 ip_release(port
); /* May be last reference */
694 * Peek and see if it has to go back in the cache.
696 if (kmsg
->ikm_size
== IKM_SAVED_MSG_SIZE
) {
697 struct ikm_cache
*cache
;
700 disable_preemption();
701 cache
= &PROCESSOR_DATA(current_processor(), ikm_cache
);
702 if ((i
= cache
->avail
) < IKM_STASH
) {
703 cache
->entries
[i
] = kmsg
;
704 cache
->avail
= i
+ 1;
709 zfree(ipc_kmsg_zone
, kmsg
);
712 kfree(kmsg
, ikm_plus_overhead(size
));
717 * Routine: ipc_kmsg_enqueue
724 ipc_kmsg_queue_t queue
,
727 ipc_kmsg_enqueue_macro(queue
, kmsg
);
731 * Routine: ipc_kmsg_dequeue
733 * Dequeue and return a kmsg.
738 ipc_kmsg_queue_t queue
)
742 first
= ipc_kmsg_queue_first(queue
);
744 if (first
!= IKM_NULL
)
745 ipc_kmsg_rmqueue_first_macro(queue
, first
);
751 * Routine: ipc_kmsg_rmqueue
753 * Pull a kmsg out of a queue.
758 ipc_kmsg_queue_t queue
,
761 ipc_kmsg_t next
, prev
;
763 assert(queue
->ikmq_base
!= IKM_NULL
);
765 next
= kmsg
->ikm_next
;
766 prev
= kmsg
->ikm_prev
;
769 assert(prev
== kmsg
);
770 assert(queue
->ikmq_base
== kmsg
);
772 queue
->ikmq_base
= IKM_NULL
;
774 if (queue
->ikmq_base
== kmsg
)
775 queue
->ikmq_base
= next
;
777 next
->ikm_prev
= prev
;
778 prev
->ikm_next
= next
;
780 /* XXX Temporary debug logic */
781 assert((kmsg
->ikm_next
= IKM_BOGUS
) == IKM_BOGUS
);
782 assert((kmsg
->ikm_prev
= IKM_BOGUS
) == IKM_BOGUS
);
786 * Routine: ipc_kmsg_queue_next
788 * Return the kmsg following the given kmsg.
789 * (Or IKM_NULL if it is the last one in the queue.)
794 ipc_kmsg_queue_t queue
,
799 assert(queue
->ikmq_base
!= IKM_NULL
);
801 next
= kmsg
->ikm_next
;
802 if (queue
->ikmq_base
== next
)
809 * Routine: ipc_kmsg_destroy
811 * Destroys a kernel message. Releases all rights,
812 * references, and memory held by the message.
823 * Destroying a message can cause more messages to be destroyed.
824 * Curtail recursion by putting messages on the deferred
825 * destruction queue. If this was the first message on the
826 * queue, this instance must process the full queue.
828 if (ipc_kmsg_delayed_destroy(kmsg
))
829 ipc_kmsg_reap_delayed();
833 * Routine: ipc_kmsg_delayed_destroy
835 * Enqueues a kernel message for deferred destruction.
837 * Boolean indicator that the caller is responsible to reap
841 boolean_t
ipc_kmsg_delayed_destroy(
844 ipc_kmsg_queue_t queue
= &(current_thread()->ith_messages
);
845 boolean_t first
= ipc_kmsg_queue_empty(queue
);
847 ipc_kmsg_enqueue(queue
, kmsg
);
852 * Routine: ipc_kmsg_destroy_queue
854 * Destroys messages from the per-thread
855 * deferred reaping queue.
861 ipc_kmsg_reap_delayed(void)
863 ipc_kmsg_queue_t queue
= &(current_thread()->ith_messages
);
867 * must leave kmsg in queue while cleaning it to assure
868 * no nested calls recurse into here.
870 while ((kmsg
= ipc_kmsg_queue_first(queue
)) != IKM_NULL
) {
871 ipc_kmsg_clean(kmsg
);
872 ipc_kmsg_rmqueue(queue
, kmsg
);
878 * Routine: ipc_kmsg_clean_body
880 * Cleans the body of a kernel message.
881 * Releases all rights, references, and memory.
886 static unsigned int _ipc_kmsg_clean_invalid_desc
= 0;
889 __unused ipc_kmsg_t kmsg
,
890 mach_msg_type_number_t number
,
891 mach_msg_descriptor_t
*saddr
)
893 mach_msg_type_number_t i
;
898 for (i
= 0 ; i
< number
; i
++, saddr
++ ) {
900 switch (saddr
->type
.type
) {
902 case MACH_MSG_PORT_DESCRIPTOR
: {
903 mach_msg_port_descriptor_t
*dsc
;
908 * Destroy port rights carried in the message
910 if (!IO_VALID((ipc_object_t
) dsc
->name
))
912 ipc_object_destroy((ipc_object_t
) dsc
->name
, dsc
->disposition
);
915 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
916 case MACH_MSG_OOL_DESCRIPTOR
: {
917 mach_msg_ool_descriptor_t
*dsc
;
919 dsc
= (mach_msg_ool_descriptor_t
*)&saddr
->out_of_line
;
922 * Destroy memory carried in the message
924 if (dsc
->size
== 0) {
925 assert(dsc
->address
== (void *) 0);
927 vm_map_copy_discard((vm_map_copy_t
) dsc
->address
);
931 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
932 ipc_object_t
*objects
;
933 mach_msg_type_number_t j
;
934 mach_msg_ool_ports_descriptor_t
*dsc
;
936 dsc
= (mach_msg_ool_ports_descriptor_t
*)&saddr
->ool_ports
;
937 objects
= (ipc_object_t
*) dsc
->address
;
939 if (dsc
->count
== 0) {
943 assert(objects
!= (ipc_object_t
*) 0);
945 /* destroy port rights carried in the message */
947 for (j
= 0; j
< dsc
->count
; j
++) {
948 ipc_object_t object
= objects
[j
];
950 if (!IO_VALID(object
))
953 ipc_object_destroy(object
, dsc
->disposition
);
956 /* destroy memory carried in the message */
958 assert(dsc
->count
!= 0);
961 (vm_size_t
) dsc
->count
* sizeof(mach_port_t
));
965 _ipc_kmsg_clean_invalid_desc
++; /* don't understand this type of descriptor */
972 * Routine: ipc_kmsg_clean_partial
974 * Cleans a partially-acquired kernel message.
975 * number is the index of the type descriptor
976 * in the body of the message that contained the error.
977 * If dolast, the memory and port rights in this last
978 * type spec are also cleaned. In that case, number
979 * specifies the number of port rights to clean.
985 ipc_kmsg_clean_partial(
987 mach_msg_type_number_t number
,
988 mach_msg_descriptor_t
*desc
,
993 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
995 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
996 assert(IO_VALID(object
));
997 ipc_object_destroy_dest(object
, MACH_MSGH_BITS_REMOTE(mbits
));
999 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
1000 if (IO_VALID(object
))
1001 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
1004 (void) vm_deallocate(ipc_kernel_copy_map
, paddr
, length
);
1007 ipc_kmsg_clean_body(kmsg
, number
, desc
);
1011 * Routine: ipc_kmsg_clean
1013 * Cleans a kernel message. Releases all rights,
1014 * references, and memory held by the message.
1023 ipc_object_t object
;
1024 mach_msg_bits_t mbits
;
1026 mbits
= kmsg
->ikm_header
->msgh_bits
;
1027 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
1028 if (IO_VALID(object
))
1029 ipc_object_destroy_dest(object
, MACH_MSGH_BITS_REMOTE(mbits
));
1031 object
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
1032 if (IO_VALID(object
))
1033 ipc_object_destroy(object
, MACH_MSGH_BITS_LOCAL(mbits
));
1035 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
1036 mach_msg_body_t
*body
;
1038 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
1039 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
1040 (mach_msg_descriptor_t
*)(body
+ 1));
1043 #if CONFIG_MACF_MACH
1044 if (kmsg
->ikm_sender
!= NULL
) {
1045 task_deallocate(kmsg
->ikm_sender
);
1046 kmsg
->ikm_sender
= NULL
;
1052 * Routine: ipc_kmsg_set_prealloc
1054 * Assign a kmsg as a preallocated message buffer to a port.
1060 ipc_kmsg_set_prealloc(
1064 assert(kmsg
->ikm_prealloc
== IP_NULL
);
1066 kmsg
->ikm_prealloc
= IP_NULL
;
1067 IP_SET_PREALLOC(port
, kmsg
);
1071 * Routine: ipc_kmsg_clear_prealloc
1073 * Release the Assignment of a preallocated message buffer from a port.
1078 ipc_kmsg_clear_prealloc(
1082 assert(kmsg
->ikm_prealloc
== port
);
1084 kmsg
->ikm_prealloc
= IP_NULL
;
1085 IP_CLEAR_PREALLOC(port
, kmsg
);
1089 * Routine: ipc_kmsg_prealloc
1091 * Wraper to ipc_kmsg_alloc() to account for
1092 * header expansion requirements.
1095 ipc_kmsg_prealloc(mach_msg_size_t size
)
1097 #if defined(__LP64__)
1098 if (size
> MACH_MSG_SIZE_MAX
- LEGACY_HEADER_SIZE_DELTA
)
1101 size
+= LEGACY_HEADER_SIZE_DELTA
;
1103 return ipc_kmsg_alloc(size
);
1108 * Routine: ipc_kmsg_get
1110 * Allocates a kernel message buffer.
1111 * Copies a user message to the message buffer.
1115 * MACH_MSG_SUCCESS Acquired a message buffer.
1116 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
1117 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
1118 * MACH_SEND_TOO_LARGE Message too large to ever be sent.
1119 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
1120 * MACH_SEND_INVALID_DATA Couldn't copy message data.
1125 mach_vm_address_t msg_addr
,
1126 mach_msg_size_t size
,
1129 mach_msg_size_t msg_and_trailer_size
;
1131 mach_msg_max_trailer_t
*trailer
;
1132 mach_msg_legacy_base_t legacy_base
;
1133 mach_msg_size_t len_copied
;
1134 legacy_base
.body
.msgh_descriptor_count
= 0;
1136 if ((size
< sizeof(mach_msg_legacy_header_t
)) || (size
& 3))
1137 return MACH_SEND_MSG_TOO_SMALL
;
1139 if (size
> ipc_kmsg_max_body_space
)
1140 return MACH_SEND_TOO_LARGE
;
1142 if(size
== sizeof(mach_msg_legacy_header_t
))
1143 len_copied
= sizeof(mach_msg_legacy_header_t
);
1145 len_copied
= sizeof(mach_msg_legacy_base_t
);
1147 if (copyinmsg(msg_addr
, (char *)&legacy_base
, len_copied
))
1148 return MACH_SEND_INVALID_DATA
;
1150 msg_addr
+= sizeof(legacy_base
.header
);
1151 #if defined(__LP64__)
1152 size
+= LEGACY_HEADER_SIZE_DELTA
;
1154 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
)) {
1156 for (j
=0; j
<sizeof(legacy_base
.header
); j
++) {
1157 kprintf("%02x\n", ((unsigned char*)&legacy_base
.header
)[j
]);
1161 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
1162 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
1163 if (kmsg
== IKM_NULL
)
1164 return MACH_SEND_NO_BUFFER
;
1166 kmsg
->ikm_header
->msgh_size
= size
;
1167 kmsg
->ikm_header
->msgh_bits
= legacy_base
.header
.msgh_bits
;
1168 kmsg
->ikm_header
->msgh_remote_port
= CAST_MACH_NAME_TO_PORT(legacy_base
.header
.msgh_remote_port
);
1169 kmsg
->ikm_header
->msgh_local_port
= CAST_MACH_NAME_TO_PORT(legacy_base
.header
.msgh_local_port
);
1170 kmsg
->ikm_header
->msgh_reserved
= legacy_base
.header
.msgh_reserved
;
1171 kmsg
->ikm_header
->msgh_id
= legacy_base
.header
.msgh_id
;
1173 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_get header:\n"
1176 " remote_port: %p\n"
1178 " reserved: 0x%.8x\n"
1180 kmsg
->ikm_header
->msgh_size
,
1181 kmsg
->ikm_header
->msgh_bits
,
1182 kmsg
->ikm_header
->msgh_remote_port
,
1183 kmsg
->ikm_header
->msgh_local_port
,
1184 kmsg
->ikm_header
->msgh_reserved
,
1185 kmsg
->ikm_header
->msgh_id
);
1187 if (copyinmsg(msg_addr
, (char *)(kmsg
->ikm_header
+ 1), size
- (mach_msg_size_t
)sizeof(mach_msg_header_t
))) {
1188 ipc_kmsg_free(kmsg
);
1189 return MACH_SEND_INVALID_DATA
;
1192 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
))
1194 kprintf("body: size: %lu\n", (size
- sizeof(mach_msg_header_t
)));
1196 for(i
=0;i
*4 < (size
- sizeof(mach_msg_header_t
));i
++)
1198 kprintf("%.4x\n",((uint32_t *)(kmsg
->ikm_header
+ 1))[i
]);
1201 DEBUG_IPC_KMSG_PRINT(kmsg
, "ipc_kmsg_get()");
1204 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
1205 * However, the internal size field of the trailer (msgh_trailer_size)
1206 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
1207 * the cases where no implicit data is requested.
1209 trailer
= (mach_msg_max_trailer_t
*) ((vm_offset_t
)kmsg
->ikm_header
+ size
);
1210 trailer
->msgh_sender
= current_thread()->task
->sec_token
;
1211 trailer
->msgh_audit
= current_thread()->task
->audit_token
;
1212 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
1213 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
1216 if(trcWork
.traceMask
) dbgTrace(0x1100, (unsigned int)kmsg
->ikm_header
->msgh_id
,
1217 (unsigned int)kmsg
->ikm_header
->msgh_remote_port
,
1218 (unsigned int)kmsg
->ikm_header
->msgh_local_port
, 0);
1221 #if CONFIG_MACF_MACH
1222 /* XXX - why do we zero sender labels here instead of in mach_msg()? */
1223 task_t cur
= current_task();
1225 task_reference(cur
);
1226 kmsg
->ikm_sender
= cur
;
1228 trailer
->msgh_labels
.sender
= 0;
1230 trailer
->msgh_labels
.sender
= 0;
1234 return MACH_MSG_SUCCESS
;
1238 * Routine: ipc_kmsg_get_from_kernel
1240 * First checks for a preallocated message
1241 * reserved for kernel clients. If not found -
1242 * allocates a new kernel message buffer.
1243 * Copies a kernel message to the message buffer.
1244 * Only resource errors are allowed.
1247 * Ports in header are ipc_port_t.
1249 * MACH_MSG_SUCCESS Acquired a message buffer.
1250 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
1254 ipc_kmsg_get_from_kernel(
1255 mach_msg_header_t
*msg
,
1256 mach_msg_size_t size
,
1260 mach_msg_size_t msg_and_trailer_size
;
1261 mach_msg_max_trailer_t
*trailer
;
1262 ipc_port_t dest_port
;
1264 assert(size
>= sizeof(mach_msg_header_t
));
1265 assert((size
& 3) == 0);
1267 dest_port
= (ipc_port_t
)msg
->msgh_remote_port
;
1269 msg_and_trailer_size
= size
+ MAX_TRAILER_SIZE
;
1272 * See if the port has a pre-allocated kmsg for kernel
1273 * clients. These are set up for those kernel clients
1274 * which cannot afford to wait.
1276 if (IP_VALID(dest_port
) && IP_PREALLOC(dest_port
)) {
1277 mach_msg_size_t max_desc
= 0;
1280 if (!ip_active(dest_port
)) {
1281 ip_unlock(dest_port
);
1282 return MACH_SEND_NO_BUFFER
;
1284 assert(IP_PREALLOC(dest_port
));
1285 kmsg
= dest_port
->ip_premsg
;
1286 if (ikm_prealloc_inuse(kmsg
)) {
1287 ip_unlock(dest_port
);
1288 return MACH_SEND_NO_BUFFER
;
1290 #if !defined(__LP64__)
1291 if (msg
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
1292 assert(size
> sizeof(mach_msg_base_t
));
1293 max_desc
= ((mach_msg_base_t
*)msg
)->body
.msgh_descriptor_count
*
1294 DESC_SIZE_ADJUSTMENT
;
1297 if (msg_and_trailer_size
> kmsg
->ikm_size
- max_desc
) {
1298 ip_unlock(dest_port
);
1299 return MACH_SEND_TOO_LARGE
;
1301 ikm_prealloc_set_inuse(kmsg
, dest_port
);
1302 ikm_set_header(kmsg
, msg_and_trailer_size
);
1303 ip_unlock(dest_port
);
1307 kmsg
= ipc_kmsg_alloc(msg_and_trailer_size
);
1308 if (kmsg
== IKM_NULL
)
1309 return MACH_SEND_NO_BUFFER
;
1312 (void) memcpy((void *) kmsg
->ikm_header
, (const void *) msg
, size
);
1314 kmsg
->ikm_header
->msgh_size
= size
;
1317 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
1318 * However, the internal size field of the trailer (msgh_trailer_size)
1319 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
1320 * optimize the cases where no implicit data is requested.
1322 trailer
= (mach_msg_max_trailer_t
*)
1323 ((vm_offset_t
)kmsg
->ikm_header
+ size
);
1324 trailer
->msgh_sender
= KERNEL_SECURITY_TOKEN
;
1325 trailer
->msgh_audit
= KERNEL_AUDIT_TOKEN
;
1326 trailer
->msgh_trailer_type
= MACH_MSG_TRAILER_FORMAT_0
;
1327 trailer
->msgh_trailer_size
= MACH_MSG_TRAILER_MINIMUM_SIZE
;
1329 trailer
->msgh_labels
.sender
= 0;
1331 #if CONFIG_MACF_MACH
1332 kmsg
->ikm_sender
= NULL
;
1335 return MACH_MSG_SUCCESS
;
1339 * Routine: ipc_kmsg_send
1341 * Send a message. The message holds a reference
1342 * for the destination port in the msgh_remote_port field.
1344 * If unsuccessful, the caller still has possession of
1345 * the message and must do something with it. If successful,
1346 * the message is queued, given to a receiver, destroyed,
1347 * or handled directly by the kernel via mach_msg.
1351 * MACH_MSG_SUCCESS The message was accepted.
1352 * MACH_SEND_TIMED_OUT Caller still has message.
1353 * MACH_SEND_INTERRUPTED Caller still has message.
1354 * MACH_SEND_INVALID_DEST Caller still has message.
1361 mach_msg_option_t option
,
1362 mach_msg_timeout_t send_timeout
)
1365 mach_msg_return_t error
= MACH_MSG_SUCCESS
;
1368 #if IMPORTANCE_INHERITANCE
1369 boolean_t did_importance
= FALSE
;
1370 #if IMPORTANCE_DEBUG
1371 mach_msg_id_t imp_msgh_id
= -1;
1372 int sender_pid
= -1;
1373 #endif /* IMPORTANCE_DEBUG */
1374 #endif /* IMPORTANCE_INHERITANCE */
1376 /* don't allow the creation of a circular loop */
1377 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_CIRCULAR
) {
1378 ipc_kmsg_destroy(kmsg
);
1379 return MACH_MSG_SUCCESS
;
1382 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
1383 assert(IP_VALID(port
));
1386 if (port
->ip_receiver
== ipc_space_kernel
) {
1389 * We can check ip_receiver == ipc_space_kernel
1390 * before checking that the port is active because
1391 * ipc_port_dealloc_kernel clears ip_receiver
1392 * before destroying a kernel port.
1394 assert(ip_active(port
));
1395 port
->ip_messages
.imq_seqno
++;
1398 current_task()->messages_sent
++;
1401 * Call the server routine, and get the reply message to send.
1403 kmsg
= ipc_kobject_server(kmsg
);
1404 if (kmsg
== IKM_NULL
)
1405 return MACH_MSG_SUCCESS
;
1407 port
= (ipc_port_t
) kmsg
->ikm_header
->msgh_remote_port
;
1408 assert(IP_VALID(port
));
1410 /* fall thru with reply - same options */
1413 #if IMPORTANCE_INHERITANCE
1415 #endif /* IMPORTANCE_INHERITANCE */
1418 * Can't deliver to a dead port.
1419 * However, we can pretend it got sent
1420 * and was then immediately destroyed.
1422 if (!ip_active(port
)) {
1424 * We can't let ipc_kmsg_destroy deallocate
1425 * the port right, because we might end up
1426 * in an infinite loop trying to deliver
1427 * a send-once notification.
1431 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
1432 ipc_kmsg_destroy(kmsg
);
1433 return MACH_MSG_SUCCESS
;
1436 #if IMPORTANCE_INHERITANCE
1438 * Need to see if this message needs importance donation and/or
1439 * propagation. That routine can drop the port lock. If it does
1440 * we'll have to revalidate the destination.
1442 if ((did_importance
== FALSE
) &&
1443 (port
->ip_impdonation
!= 0) &&
1444 ((option
& MACH_SEND_NOIMPORTANCE
) == 0) &&
1445 (((option
& MACH_SEND_IMPORTANCE
) != 0) ||
1446 (task_is_importance_donor(current_task())))) {
1448 did_importance
= TRUE
;
1449 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_RAISEIMP
;
1451 #if IMPORTANCE_DEBUG
1452 if (kdebug_enable
) {
1453 mach_msg_max_trailer_t
*dbgtrailer
= (mach_msg_max_trailer_t
*)
1454 ((vm_offset_t
)kmsg
->ikm_header
+ round_msg(kmsg
->ikm_header
->msgh_size
));
1455 sender_pid
= dbgtrailer
->msgh_audit
.val
[5];
1456 imp_msgh_id
= kmsg
->ikm_header
->msgh_id
;
1458 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
, (IMPORTANCE_CODE(IMP_MSG
, IMP_MSG_SEND
)) | DBG_FUNC_START
,
1459 audit_token_pid_from_task(current_task()), sender_pid
, imp_msgh_id
, 0, 0);
1461 #endif /* IMPORTANCE_DEBUG */
1463 if (ipc_port_importance_delta(port
, 1) == TRUE
) {
1468 #endif /* IMPORTANCE_INHERITANCE */
1471 * We have a valid message and a valid reference on the port.
1472 * we can unlock the port and call mqueue_send() on its message
1473 * queue. Lock message queue while port is locked.
1476 imq_lock(&port
->ip_messages
);
1479 error
= ipc_mqueue_send(&port
->ip_messages
, kmsg
, option
,
1482 #if IMPORTANCE_INHERITANCE
1483 if (did_importance
== TRUE
) {
1484 __unused
int importance_cleared
= 0;
1486 case MACH_SEND_TIMED_OUT
:
1487 case MACH_SEND_NO_BUFFER
:
1488 case MACH_SEND_INTERRUPTED
:
1490 * We still have the kmsg and its
1491 * reference on the port. But we
1492 * have to back out the importance
1495 * The port could have changed hands,
1496 * be inflight to another destination,
1497 * etc... But in those cases our
1498 * back-out will find the new owner
1499 * (and all the operations that
1500 * transferred the right should have
1501 * applied their own boost adjustments
1502 * to the old owner(s)).
1504 importance_cleared
= 1;
1506 if (ipc_port_importance_delta(port
, -1) == FALSE
)
1510 case MACH_SEND_INVALID_DEST
:
1512 * In the case that the receive right has
1513 * gone away, the assertion count for the
1514 * message we were trying to enqueue was
1515 * already subtracted from the destination
1516 * task (as part of port destruction).
1520 case MACH_MSG_SUCCESS
:
1524 #if IMPORTANCE_DEBUG
1525 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE
, (IMPORTANCE_CODE(IMP_MSG
, IMP_MSG_SEND
)) | DBG_FUNC_END
,
1526 audit_token_pid_from_task(current_task()), sender_pid
, imp_msgh_id
, importance_cleared
, 0);
1527 #endif /* IMPORTANCE_DEBUG */
1529 #endif /* IMPORTANCE_INHERITANCE */
1532 * If the port has been destroyed while we wait, treat the message
1533 * as a successful delivery (like we do for an inactive port).
1535 if (error
== MACH_SEND_INVALID_DEST
) {
1536 kmsg
->ikm_header
->msgh_remote_port
= MACH_PORT_NULL
;
1537 ipc_kmsg_destroy(kmsg
);
1538 return MACH_MSG_SUCCESS
;
1544 * Routine: ipc_kmsg_put
1546 * Copies a message buffer to a user message.
1547 * Copies only the specified number of bytes.
1548 * Frees the message buffer.
1550 * Nothing locked. The message buffer must have clean
1553 * MACH_MSG_SUCCESS Copied data out of message buffer.
1554 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
1559 mach_vm_address_t msg_addr
,
1561 mach_msg_size_t size
)
1563 mach_msg_return_t mr
;
1565 DEBUG_IPC_KMSG_PRINT(kmsg
, "ipc_kmsg_put()");
1568 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_put header:\n"
1571 " remote_port: %p\n"
1573 " reserved: 0x%.8x\n"
1575 kmsg
->ikm_header
->msgh_size
,
1576 kmsg
->ikm_header
->msgh_bits
,
1577 kmsg
->ikm_header
->msgh_remote_port
,
1578 kmsg
->ikm_header
->msgh_local_port
,
1579 kmsg
->ikm_header
->msgh_reserved
,
1580 kmsg
->ikm_header
->msgh_id
);
1582 #if defined(__LP64__)
1583 if (current_task() != kernel_task
) { /* don't if receiver expects fully-cooked in-kernel msg; ux_exception */
1584 mach_msg_legacy_header_t
*legacy_header
=
1585 (mach_msg_legacy_header_t
*)((vm_offset_t
)(kmsg
->ikm_header
) + LEGACY_HEADER_SIZE_DELTA
);
1587 mach_msg_bits_t bits
= kmsg
->ikm_header
->msgh_bits
;
1588 mach_msg_size_t msg_size
= kmsg
->ikm_header
->msgh_size
;
1589 mach_port_name_t remote_port
= CAST_MACH_PORT_TO_NAME(kmsg
->ikm_header
->msgh_remote_port
);
1590 mach_port_name_t local_port
= CAST_MACH_PORT_TO_NAME(kmsg
->ikm_header
->msgh_local_port
);
1591 mach_msg_size_t reserved
= kmsg
->ikm_header
->msgh_reserved
;
1592 mach_msg_id_t id
= kmsg
->ikm_header
->msgh_id
;
1594 legacy_header
->msgh_id
= id
;
1595 legacy_header
->msgh_reserved
= reserved
;
1596 legacy_header
->msgh_local_port
= local_port
;
1597 legacy_header
->msgh_remote_port
= remote_port
;
1598 legacy_header
->msgh_size
= msg_size
- LEGACY_HEADER_SIZE_DELTA
;
1599 legacy_header
->msgh_bits
= bits
;
1601 size
-= LEGACY_HEADER_SIZE_DELTA
;
1602 kmsg
->ikm_header
= (mach_msg_header_t
*)legacy_header
;
1606 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
)) {
1607 kprintf("ipc_kmsg_put header+body: %d\n", (size
));
1609 for(i
=0;i
*4 < size
;i
++)
1611 kprintf("%.4x\n",((uint32_t *)kmsg
->ikm_header
)[i
]);
1613 kprintf("type: %d\n", ((mach_msg_type_descriptor_t
*)(((mach_msg_base_t
*)kmsg
->ikm_header
)+1))->type
);
1615 if (copyoutmsg((const char *) kmsg
->ikm_header
, msg_addr
, size
))
1616 mr
= MACH_RCV_INVALID_DATA
;
1618 mr
= MACH_MSG_SUCCESS
;
1620 ipc_kmsg_free(kmsg
);
1625 * Routine: ipc_kmsg_put_to_kernel
1627 * Copies a message buffer to a kernel message.
1628 * Frees the message buffer.
1629 * No errors allowed.
1635 ipc_kmsg_put_to_kernel(
1636 mach_msg_header_t
*msg
,
1638 mach_msg_size_t size
)
1640 (void) memcpy((void *) msg
, (const void *) kmsg
->ikm_header
, size
);
1642 ipc_kmsg_free(kmsg
);
1646 * Routine: ipc_kmsg_copyin_header
1648 * "Copy-in" port rights in the header of a message.
1649 * Operates atomically; if it doesn't succeed the
1650 * message header and the space are left untouched.
1651 * If it does succeed the remote/local port fields
1652 * contain object pointers instead of port names,
1653 * and the bits field is updated. The destination port
1654 * will be a valid port pointer.
1659 * MACH_MSG_SUCCESS Successful copyin.
1660 * MACH_SEND_INVALID_HEADER
1661 * Illegal value in the message header bits.
1662 * MACH_SEND_INVALID_DEST The space is dead.
1663 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1664 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1665 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1666 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1670 ipc_kmsg_copyin_header(
1671 mach_msg_header_t
*msg
,
1673 mach_msg_option_t
*optionp
)
1675 mach_msg_bits_t mbits
= msg
->msgh_bits
& MACH_MSGH_BITS_USER
;
1676 mach_port_name_t dest_name
= CAST_MACH_PORT_TO_NAME(msg
->msgh_remote_port
);
1677 mach_port_name_t reply_name
= CAST_MACH_PORT_TO_NAME(msg
->msgh_local_port
);
1680 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
1681 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
1682 ipc_object_t dest_port
, reply_port
;
1683 ipc_entry_t dest_entry
, reply_entry
;
1684 ipc_port_t dest_soright
, reply_soright
;
1685 ipc_port_t release_port
= IP_NULL
;
1687 #if IMPORTANCE_INHERITANCE
1689 boolean_t needboost
= FALSE
;
1690 #endif /* IMPORTANCE_INHERITANCE */
1692 queue_head_t links_data
;
1693 queue_t links
= &links_data
;
1694 wait_queue_link_t wql
;
1698 if ((mbits
!= msg
->msgh_bits
) ||
1699 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type
)) ||
1700 ((reply_type
== 0) ?
1701 (reply_name
!= MACH_PORT_NULL
) :
1702 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type
)))
1703 return MACH_SEND_INVALID_HEADER
;
1705 reply_soright
= IP_NULL
; /* in case we go to invalid dest early */
1707 is_write_lock(space
);
1708 if (!is_active(space
))
1711 if (!MACH_PORT_VALID(dest_name
))
1714 #if CONFIG_MACF_MACH
1716 * We do the port send check here instead of in ipc_kmsg_send()
1717 * because copying the header involves copying the port rights too
1718 * and we need to do the send check before anything is actually copied.
1720 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1721 if (dest_entry
!= IE_NULL
) {
1723 ipc_port_t port
= (ipc_port_t
) dest_entry
->ie_object
;
1724 if (port
== IP_NULL
)
1727 if (ip_active(port
)) {
1728 task_t self
= current_task();
1729 tasklabel_lock(self
);
1730 error
= mac_port_check_send(&self
->maclabel
,
1732 tasklabel_unlock(self
);
1740 if (dest_name
== reply_name
) {
1741 mach_port_name_t name
= dest_name
;
1744 * Destination and reply ports are the same!
1745 * This is a little tedious to make atomic, because
1746 * there are 25 combinations of dest_type/reply_type.
1747 * However, most are easy. If either is move-sonce,
1748 * then there must be an error. If either are
1749 * make-send or make-sonce, then we must be looking
1750 * at a receive right so the port can't die.
1751 * The hard cases are the combinations of
1752 * copy-send and make-send.
1755 dest_entry
= ipc_entry_lookup(space
, name
);
1756 if (dest_entry
== IE_NULL
)
1759 reply_entry
= dest_entry
;
1760 assert(reply_type
!= 0); /* because name not null */
1762 if (!ipc_right_copyin_check(space
, name
, reply_entry
, reply_type
))
1765 if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
) ||
1766 (reply_type
== MACH_MSG_TYPE_MOVE_SEND_ONCE
)) {
1768 * Why must there be an error? To get a valid
1769 * destination, this entry must name a live
1770 * port (not a dead name or dead port). However
1771 * a successful move-sonce will destroy a
1772 * live entry. Therefore the other copyin,
1773 * whatever it is, would fail. We've already
1774 * checked for reply port errors above,
1775 * so report a destination error.
1779 } else if ((dest_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1780 (dest_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
) ||
1781 (reply_type
== MACH_MSG_TYPE_MAKE_SEND
) ||
1782 (reply_type
== MACH_MSG_TYPE_MAKE_SEND_ONCE
)) {
1784 #if IMPORTANCE_INHERITANCE
1785 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1787 &dest_port
, &dest_soright
,
1791 assert(assertcnt
== 0);
1793 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1795 &dest_port
, &dest_soright
,
1798 #endif /* IMPORTANCE_INHERITANCE */
1800 if (kr
!= KERN_SUCCESS
)
1804 * Either dest or reply needs a receive right.
1805 * We know the receive right is there, because
1806 * of the copyin_check and copyin calls. Hence
1807 * the port is not in danger of dying. If dest
1808 * used the receive right, then the right needed
1809 * by reply (and verified by copyin_check) will
1813 assert(IO_VALID(dest_port
));
1814 assert(dest_soright
== IP_NULL
);
1816 #if IMPORTANCE_INHERITANCE
1817 kr
= ipc_right_copyin(space
, name
, reply_entry
,
1819 &reply_port
, &reply_soright
,
1823 assert(assertcnt
== 0);
1825 kr
= ipc_right_copyin(space
, name
, reply_entry
,
1827 &reply_port
, &reply_soright
,
1830 #endif /* IMPORTANCE_INHERITANCE */
1832 assert(kr
== KERN_SUCCESS
);
1833 assert(reply_port
== dest_port
);
1834 assert(reply_entry
->ie_bits
& MACH_PORT_TYPE_RECEIVE
);
1835 assert(reply_soright
== IP_NULL
);
1836 } else if ((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1837 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)) {
1839 * To make this atomic, just do one copy-send,
1840 * and dup the send right we get out.
1843 #if IMPORTANCE_INHERITANCE
1844 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1846 &dest_port
, &dest_soright
,
1850 assert(assertcnt
== 0);
1852 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1854 &dest_port
, &dest_soright
,
1857 #endif /* IMPORTANCE_INHERITANCE */
1859 if (kr
!= KERN_SUCCESS
)
1862 assert(dest_entry
->ie_bits
& MACH_PORT_TYPE_SEND
);
1863 assert(dest_soright
== IP_NULL
);
1866 * It's OK if the port we got is dead now,
1867 * so reply_port is IP_DEAD, because the msg
1868 * won't go anywhere anyway.
1871 reply_port
= (ipc_object_t
)
1872 ipc_port_copy_send((ipc_port_t
) dest_port
);
1873 reply_soright
= IP_NULL
;
1874 } else if ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1875 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) {
1877 * This is an easy case. Just use our
1878 * handy-dandy special-purpose copyin call
1879 * to get two send rights for the price of one.
1882 kr
= ipc_right_copyin_two(space
, name
, dest_entry
,
1883 &dest_port
, &dest_soright
,
1885 if (kr
!= KERN_SUCCESS
)
1888 /* the entry might need to be deallocated */
1889 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
) {
1890 ipc_entry_dealloc(space
, name
, dest_entry
);
1891 dest_entry
= IE_NULL
;
1894 reply_port
= dest_port
;
1895 reply_soright
= IP_NULL
;
1899 assert(((dest_type
== MACH_MSG_TYPE_COPY_SEND
) &&
1900 (reply_type
== MACH_MSG_TYPE_MOVE_SEND
)) ||
1901 ((dest_type
== MACH_MSG_TYPE_MOVE_SEND
) &&
1902 (reply_type
== MACH_MSG_TYPE_COPY_SEND
)));
1905 * To make this atomic, just do a move-send,
1906 * and dup the send right we get out.
1909 #if IMPORTANCE_INHERITANCE
1910 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1911 MACH_MSG_TYPE_MOVE_SEND
, FALSE
,
1912 &dest_port
, &soright
,
1916 assert(assertcnt
== 0);
1918 kr
= ipc_right_copyin(space
, name
, dest_entry
,
1919 MACH_MSG_TYPE_MOVE_SEND
, FALSE
,
1920 &dest_port
, &soright
,
1923 #endif /* IMPORTANCE_INHERITANCE */
1925 if (kr
!= KERN_SUCCESS
)
1928 /* the entry might need to be deallocated */
1930 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
) {
1931 ipc_entry_dealloc(space
, name
, dest_entry
);
1932 dest_entry
= IE_NULL
;
1936 * It's OK if the port we got is dead now,
1937 * so reply_port is IP_DEAD, because the msg
1938 * won't go anywhere anyway.
1941 reply_port
= (ipc_object_t
)
1942 ipc_port_copy_send((ipc_port_t
) dest_port
);
1944 if (dest_type
== MACH_MSG_TYPE_MOVE_SEND
) {
1945 dest_soright
= soright
;
1946 reply_soright
= IP_NULL
;
1948 dest_soright
= IP_NULL
;
1949 reply_soright
= soright
;
1952 } else if (!MACH_PORT_VALID(reply_name
)) {
1954 * No reply port! This is an easy case
1955 * to make atomic. Just copyin the destination.
1958 dest_entry
= ipc_entry_lookup(space
, dest_name
);
1959 if (dest_entry
== IE_NULL
)
1962 #if IMPORTANCE_INHERITANCE
1963 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1965 &dest_port
, &dest_soright
,
1969 assert(assertcnt
== 0);
1971 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
1973 &dest_port
, &dest_soright
,
1976 #endif /* IMPORTANCE_INHERITANCE */
1978 if (kr
!= KERN_SUCCESS
)
1981 /* the entry might need to be deallocated */
1982 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
) {
1983 ipc_entry_dealloc(space
, dest_name
, dest_entry
);
1984 dest_entry
= IE_NULL
;
1987 reply_port
= (ipc_object_t
)CAST_MACH_NAME_TO_PORT(reply_name
);
1988 reply_soright
= IP_NULL
;
1991 * This is the tough case to make atomic.
1992 * The difficult problem is serializing with port death.
1993 * At the time we copyin dest_port, it must be alive.
1994 * If reply_port is alive when we copyin it, then
1995 * we are OK, because we serialize before the death
1996 * of both ports. Assume reply_port is dead at copyin.
1997 * Then if dest_port dies/died after reply_port died,
1998 * we are OK, because we serialize between the death
1999 * of the two ports. So the bad case is when dest_port
2000 * dies after its copyin, reply_port dies before its
2001 * copyin, and dest_port dies before reply_port. Then
2002 * the copyins operated as if dest_port was alive
2003 * and reply_port was dead, which shouldn't have happened
2004 * because they died in the other order.
2006 * Note that it is easy for a user task to tell if
2007 * a copyin happened before or after a port died.
2008 * For example, suppose both dest and reply are
2009 * send-once rights (types are both move-sonce) and
2010 * both rights have dead-name requests registered.
2011 * If a port dies before copyin, a dead-name notification
2012 * is generated and the dead name's urefs are incremented,
2013 * and if the copyin happens first, a port-deleted
2014 * notification is generated.
2016 * Note that although the entries are different,
2017 * dest_port and reply_port might still be the same.
2019 * JMM - The code to handle this was too expensive and, anyway,
2020 * we intend to separate the dest lookup from the reply copyin
2021 * by a wide margin, so the user will have to learn to deal!
2022 * I will be making the change soon in rdar://problem/6275821.
2025 dest_entry
= ipc_entry_lookup(space
, dest_name
);
2026 if (dest_entry
== IE_NULL
)
2029 reply_entry
= ipc_entry_lookup(space
, reply_name
);
2030 if (reply_entry
== IE_NULL
)
2033 assert(dest_entry
!= reply_entry
); /* names are not equal */
2034 assert(reply_type
!= 0); /* because reply_name not null */
2036 if (!ipc_right_copyin_check(space
, reply_name
, reply_entry
,
2040 #if IMPORTANCE_INHERITANCE
2041 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
2043 &dest_port
, &dest_soright
,
2047 assert(assertcnt
== 0);
2049 kr
= ipc_right_copyin(space
, dest_name
, dest_entry
,
2051 &dest_port
, &dest_soright
,
2054 #endif /* IMPORTANCE_INHERITANCE */
2056 if (kr
!= KERN_SUCCESS
)
2059 assert(IO_VALID(dest_port
));
2061 #if IMPORTANCE_INHERITANCE
2062 kr
= ipc_right_copyin(space
, reply_name
, reply_entry
,
2064 &reply_port
, &reply_soright
,
2068 assert(assertcnt
== 0);
2070 kr
= ipc_right_copyin(space
, reply_name
, reply_entry
,
2072 &reply_port
, &reply_soright
,
2075 #endif /* IMPORTANCE_INHERITANCE */
2077 assert(kr
== KERN_SUCCESS
);
2079 /* the entries might need to be deallocated */
2081 if (IE_BITS_TYPE(reply_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
) {
2082 ipc_entry_dealloc(space
, reply_name
, reply_entry
);
2083 reply_entry
= IE_NULL
;
2086 if (IE_BITS_TYPE(dest_entry
->ie_bits
) == MACH_PORT_TYPE_NONE
) {
2087 ipc_entry_dealloc(space
, dest_name
, dest_entry
);
2088 dest_entry
= IE_NULL
;
2092 dest_type
= ipc_object_copyin_type(dest_type
);
2093 reply_type
= ipc_object_copyin_type(reply_type
);
2096 * JMM - Without rdar://problem/6275821, this is the last place we can
2097 * re-arm the send-possible notifications. It may trigger unexpectedly
2098 * early (send may NOT have failed), but better than missing. We assure
2099 * we won't miss by forcing MACH_SEND_ALWAYS if we got past arming.
2101 if (((*optionp
& MACH_SEND_NOTIFY
) != 0) &&
2102 dest_type
!= MACH_MSG_TYPE_PORT_SEND_ONCE
&&
2103 dest_entry
!= IE_NULL
&& dest_entry
->ie_request
!= IE_REQ_NONE
) {
2104 ipc_port_t dport
= (ipc_port_t
)dest_port
;
2106 assert(dport
!= IP_NULL
);
2108 if (ip_active(dport
) && dport
->ip_receiver
!= ipc_space_kernel
) {
2109 if (ip_full(dport
)) {
2110 #if IMPORTANCE_INHERITANCE
2111 needboost
= ipc_port_request_sparm(dport
, dest_name
,
2112 dest_entry
->ie_request
,
2113 (*optionp
& MACH_SEND_NOIMPORTANCE
));
2114 if (needboost
== FALSE
)
2118 ipc_port_request_sparm(dport
, dest_name
, dest_entry
->ie_request
);
2120 #endif /* IMPORTANCE_INHERITANCE */
2122 *optionp
|= MACH_SEND_ALWAYS
;
2130 is_write_unlock(space
);
2132 #if IMPORTANCE_INHERITANCE
2134 * If our request is the first boosting send-possible
2135 * notification this cycle, push the boost down the
2138 if (needboost
== TRUE
) {
2139 ipc_port_t dport
= (ipc_port_t
)dest_port
;
2141 /* dport still locked from above */
2142 if (ipc_port_importance_delta(dport
, 1) == FALSE
)
2145 #endif /* IMPORTANCE_INHERITANCE */
2147 if (dest_soright
!= IP_NULL
)
2148 ipc_notify_port_deleted(dest_soright
, dest_name
);
2150 if (reply_soright
!= IP_NULL
)
2151 ipc_notify_port_deleted(reply_soright
, reply_name
);
2153 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
2154 MACH_MSGH_BITS(dest_type
, reply_type
));
2155 msg
->msgh_remote_port
= (ipc_port_t
)dest_port
;
2156 msg
->msgh_local_port
= (ipc_port_t
)reply_port
;
2158 while(!queue_empty(links
)) {
2159 wql
= (wait_queue_link_t
) dequeue(links
);
2160 wait_queue_link_free(wql
);
2163 if (release_port
!= IP_NULL
)
2164 ip_release(release_port
);
2167 return MACH_MSG_SUCCESS
;
2170 is_write_unlock(space
);
2172 while(!queue_empty(links
)) {
2173 wql
= (wait_queue_link_t
) dequeue(links
);
2174 wait_queue_link_free(wql
);
2177 if (release_port
!= IP_NULL
)
2178 ip_release(release_port
);
2180 return MACH_SEND_INVALID_REPLY
;
2183 is_write_unlock(space
);
2185 while(!queue_empty(links
)) {
2186 wql
= (wait_queue_link_t
) dequeue(links
);
2187 wait_queue_link_free(wql
);
2190 if (release_port
!= IP_NULL
)
2191 ip_release(release_port
);
2193 if (reply_soright
!= IP_NULL
)
2194 ipc_notify_port_deleted(reply_soright
, reply_name
);
2196 return MACH_SEND_INVALID_DEST
;
2199 mach_msg_descriptor_t
*ipc_kmsg_copyin_port_descriptor(
2200 volatile mach_msg_port_descriptor_t
*dsc
,
2201 mach_msg_legacy_port_descriptor_t
*user_dsc
,
2205 mach_msg_return_t
*mr
);
2207 void ipc_print_type_name(
2209 mach_msg_descriptor_t
*
2210 ipc_kmsg_copyin_port_descriptor(
2211 volatile mach_msg_port_descriptor_t
*dsc
,
2212 mach_msg_legacy_port_descriptor_t
*user_dsc_in
,
2216 mach_msg_return_t
*mr
)
2218 volatile mach_msg_legacy_port_descriptor_t
*user_dsc
= user_dsc_in
;
2219 mach_msg_type_name_t user_disp
;
2220 mach_msg_type_name_t result_disp
;
2221 mach_port_name_t name
;
2222 ipc_object_t object
;
2224 user_disp
= user_dsc
->disposition
;
2225 result_disp
= ipc_object_copyin_type(user_disp
);
2227 name
= (mach_port_name_t
)user_dsc
->name
;
2228 if (MACH_PORT_VALID(name
)) {
2230 kern_return_t kr
= ipc_object_copyin(space
, name
, user_disp
, &object
);
2231 if (kr
!= KERN_SUCCESS
) {
2232 *mr
= MACH_SEND_INVALID_RIGHT
;
2236 if ((result_disp
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
2237 ipc_port_check_circularity((ipc_port_t
) object
,
2238 (ipc_port_t
) dest
)) {
2239 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
2241 dsc
->name
= (ipc_port_t
) object
;
2243 dsc
->name
= CAST_MACH_NAME_TO_PORT(name
);
2245 dsc
->disposition
= result_disp
;
2246 dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
2248 dsc
->pad_end
= 0; // debug, unnecessary
2250 return (mach_msg_descriptor_t
*)(user_dsc_in
+1);
2253 mach_msg_descriptor_t
* ipc_kmsg_copyin_ool_descriptor(
2254 mach_msg_ool_descriptor_t
*dsc
,
2255 mach_msg_descriptor_t
*user_dsc
,
2258 vm_map_copy_t
*copy
,
2259 vm_size_t
*space_needed
,
2261 mach_msg_return_t
*mr
);
2262 mach_msg_descriptor_t
*
2263 ipc_kmsg_copyin_ool_descriptor(
2264 mach_msg_ool_descriptor_t
*dsc
,
2265 mach_msg_descriptor_t
*user_dsc
,
2268 vm_map_copy_t
*copy
,
2269 vm_size_t
*space_needed
,
2271 mach_msg_return_t
*mr
)
2275 mach_msg_copy_options_t copy_options
;
2276 mach_vm_offset_t addr
;
2277 mach_msg_descriptor_type_t dsc_type
;
2280 mach_msg_ool_descriptor64_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
2282 addr
= (mach_vm_offset_t
) user_ool_dsc
->address
;
2283 length
= user_ool_dsc
->size
;
2284 dealloc
= user_ool_dsc
->deallocate
;
2285 copy_options
= user_ool_dsc
->copy
;
2286 dsc_type
= user_ool_dsc
->type
;
2288 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2290 mach_msg_ool_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
2292 addr
= CAST_USER_ADDR_T(user_ool_dsc
->address
);
2293 dealloc
= user_ool_dsc
->deallocate
;
2294 copy_options
= user_ool_dsc
->copy
;
2295 dsc_type
= user_ool_dsc
->type
;
2296 length
= user_ool_dsc
->size
;
2298 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2301 dsc
->size
= (mach_msg_size_t
)length
;
2302 dsc
->deallocate
= dealloc
;
2303 dsc
->copy
= copy_options
;
2304 dsc
->type
= dsc_type
;
2307 dsc
->address
= NULL
;
2308 } else if ((length
>= MSG_OOL_SIZE_SMALL
) &&
2309 (copy_options
== MACH_MSG_PHYSICAL_COPY
) && !dealloc
) {
2312 * If the request is a physical copy and the source
2313 * is not being deallocated, then allocate space
2314 * in the kernel's pageable ipc copy map and copy
2315 * the data in. The semantics guarantee that the
2316 * data will have been physically copied before
2317 * the send operation terminates. Thus if the data
2318 * is not being deallocated, we must be prepared
2319 * to page if the region is sufficiently large.
2321 if (copyin(addr
, (char *)*paddr
, length
)) {
2322 *mr
= MACH_SEND_INVALID_MEMORY
;
2327 * The kernel ipc copy map is marked no_zero_fill.
2328 * If the transfer is not a page multiple, we need
2329 * to zero fill the balance.
2331 if (!page_aligned(length
)) {
2332 (void) memset((void *) (*paddr
+ length
), 0,
2333 round_page(length
) - length
);
2335 if (vm_map_copyin(ipc_kernel_copy_map
, (vm_map_address_t
)*paddr
,
2336 (vm_map_size_t
)length
, TRUE
, copy
) != KERN_SUCCESS
) {
2337 *mr
= MACH_MSG_VM_KERNEL
;
2340 dsc
->address
= (void *)*copy
;
2341 *paddr
+= round_page(length
);
2342 *space_needed
-= round_page(length
);
2346 * Make a vm_map_copy_t of the of the data. If the
2347 * data is small, this will do an optimized physical
2348 * copy. Otherwise, it will do a virtual copy.
2350 * NOTE: A virtual copy is OK if the original is being
2351 * deallocted, even if a physical copy was requested.
2353 kern_return_t kr
= vm_map_copyin(map
, addr
,
2354 (vm_map_size_t
)length
, dealloc
, copy
);
2355 if (kr
!= KERN_SUCCESS
) {
2356 *mr
= (kr
== KERN_RESOURCE_SHORTAGE
) ?
2357 MACH_MSG_VM_KERNEL
:
2358 MACH_SEND_INVALID_MEMORY
;
2361 dsc
->address
= (void *)*copy
;
2366 mach_msg_descriptor_t
* ipc_kmsg_copyin_ool_ports_descriptor(
2367 mach_msg_ool_ports_descriptor_t
*dsc
,
2368 mach_msg_descriptor_t
*user_dsc
,
2374 mach_msg_return_t
*mr
);
2375 mach_msg_descriptor_t
*
2376 ipc_kmsg_copyin_ool_ports_descriptor(
2377 mach_msg_ool_ports_descriptor_t
*dsc
,
2378 mach_msg_descriptor_t
*user_dsc
,
2384 mach_msg_return_t
*mr
)
2387 ipc_object_t
*objects
;
2389 mach_vm_offset_t addr
;
2390 mach_msg_type_name_t user_disp
;
2391 mach_msg_type_name_t result_disp
;
2392 mach_msg_type_number_t count
;
2393 mach_msg_copy_options_t copy_option
;
2394 boolean_t deallocate
;
2395 mach_msg_descriptor_type_t type
;
2396 vm_size_t ports_length
, names_length
;
2399 mach_msg_ool_ports_descriptor64_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
2401 addr
= (mach_vm_offset_t
)user_ool_dsc
->address
;
2402 count
= user_ool_dsc
->count
;
2403 deallocate
= user_ool_dsc
->deallocate
;
2404 copy_option
= user_ool_dsc
->copy
;
2405 user_disp
= user_ool_dsc
->disposition
;
2406 type
= user_ool_dsc
->type
;
2408 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2410 mach_msg_ool_ports_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
2412 addr
= CAST_USER_ADDR_T(user_ool_dsc
->address
);
2413 count
= user_ool_dsc
->count
;
2414 deallocate
= user_ool_dsc
->deallocate
;
2415 copy_option
= user_ool_dsc
->copy
;
2416 user_disp
= user_ool_dsc
->disposition
;
2417 type
= user_ool_dsc
->type
;
2419 user_dsc
= (typeof(user_dsc
))(user_ool_dsc
+1);
2422 dsc
->deallocate
= deallocate
;
2423 dsc
->copy
= copy_option
;
2426 dsc
->address
= NULL
; /* for now */
2428 result_disp
= ipc_object_copyin_type(user_disp
);
2429 dsc
->disposition
= result_disp
;
2431 if (count
> (INT_MAX
/ sizeof(mach_port_t
))) {
2432 *mr
= MACH_SEND_TOO_LARGE
;
2436 /* calculate length of data in bytes, rounding up */
2437 ports_length
= count
* sizeof(mach_port_t
);
2438 names_length
= count
* sizeof(mach_port_name_t
);
2440 if (ports_length
== 0) {
2444 data
= kalloc(ports_length
);
2447 *mr
= MACH_SEND_NO_BUFFER
;
2452 mach_port_name_t
*names
= &((mach_port_name_t
*)data
)[count
];
2454 mach_port_name_t
*names
= ((mach_port_name_t
*)data
);
2457 if (copyinmap(map
, addr
, names
, names_length
) != KERN_SUCCESS
) {
2458 kfree(data
, ports_length
);
2459 *mr
= MACH_SEND_INVALID_MEMORY
;
2464 (void) mach_vm_deallocate(map
, addr
, (mach_vm_size_t
)ports_length
);
2467 objects
= (ipc_object_t
*) data
;
2468 dsc
->address
= data
;
2470 for ( i
= 0; i
< count
; i
++) {
2471 mach_port_name_t name
= names
[i
];
2472 ipc_object_t object
;
2474 if (!MACH_PORT_VALID(name
)) {
2475 objects
[i
] = (ipc_object_t
)CAST_MACH_NAME_TO_PORT(name
);
2479 kern_return_t kr
= ipc_object_copyin(space
, name
, user_disp
, &object
);
2481 if (kr
!= KERN_SUCCESS
) {
2484 for(j
= 0; j
< i
; j
++) {
2485 object
= objects
[j
];
2486 if (IPC_OBJECT_VALID(object
))
2487 ipc_object_destroy(object
, result_disp
);
2489 kfree(data
, ports_length
);
2490 dsc
->address
= NULL
;
2491 *mr
= MACH_SEND_INVALID_RIGHT
;
2495 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
2496 ipc_port_check_circularity(
2497 (ipc_port_t
) object
,
2499 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
2501 objects
[i
] = object
;
2508 * Routine: ipc_kmsg_copyin_body
2510 * "Copy-in" port rights and out-of-line memory
2511 * in the message body.
2513 * In all failure cases, the message is left holding
2514 * no rights or memory. However, the message buffer
2515 * is not deallocated. If successful, the message
2516 * contains a valid destination port.
2520 * MACH_MSG_SUCCESS Successful copyin.
2521 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
2522 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
2523 * MACH_SEND_INVALID_TYPE Bad type specification.
2524 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
2525 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
2526 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
2530 ipc_kmsg_copyin_body(
2536 mach_msg_body_t
*body
;
2537 mach_msg_descriptor_t
*daddr
, *naddr
;
2538 mach_msg_descriptor_t
*user_addr
, *kern_addr
;
2539 mach_msg_type_number_t dsc_count
;
2540 boolean_t is_task_64bit
= (map
->max_offset
> VM_MAX_ADDRESS
);
2541 boolean_t
complex = FALSE
;
2542 vm_size_t space_needed
= 0;
2543 vm_offset_t paddr
= 0;
2544 vm_map_copy_t copy
= VM_MAP_COPY_NULL
;
2545 mach_msg_type_number_t i
;
2546 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
2548 vm_size_t descriptor_size
= 0;
2551 * Determine if the target is a kernel port.
2553 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2554 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2555 naddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2557 dsc_count
= body
->msgh_descriptor_count
;
2559 return MACH_MSG_SUCCESS
;
2562 * Make an initial pass to determine kernal VM space requirements for
2563 * physical copies and possible contraction of the descriptors from
2564 * processes with pointers larger than the kernel's.
2567 for (i
= 0; i
< dsc_count
; i
++) {
2570 /* make sure the descriptor fits in the message */
2571 if (is_task_64bit
) {
2572 switch (daddr
->type
.type
) {
2573 case MACH_MSG_OOL_DESCRIPTOR
:
2574 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2575 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2576 descriptor_size
+= 16;
2577 naddr
= (typeof(naddr
))((vm_offset_t
)daddr
+ 16);
2580 descriptor_size
+= 12;
2581 naddr
= (typeof(naddr
))((vm_offset_t
)daddr
+ 12);
2585 descriptor_size
+= 12;
2586 naddr
= (typeof(naddr
))((vm_offset_t
)daddr
+ 12);
2589 if (naddr
> (mach_msg_descriptor_t
*)
2590 ((vm_offset_t
)kmsg
->ikm_header
+ kmsg
->ikm_header
->msgh_size
)) {
2591 ipc_kmsg_clean_partial(kmsg
, 0, NULL
, 0, 0);
2592 mr
= MACH_SEND_MSG_TOO_SMALL
;
2596 switch (daddr
->type
.type
) {
2597 mach_msg_size_t size
;
2599 case MACH_MSG_OOL_DESCRIPTOR
:
2600 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2601 size
= (is_task_64bit
) ?
2602 ((mach_msg_ool_descriptor64_t
*)daddr
)->size
:
2603 daddr
->out_of_line
.size
;
2605 if (daddr
->out_of_line
.copy
!= MACH_MSG_PHYSICAL_COPY
&&
2606 daddr
->out_of_line
.copy
!= MACH_MSG_VIRTUAL_COPY
) {
2608 * Invalid copy option
2610 ipc_kmsg_clean_partial(kmsg
, 0, NULL
, 0, 0);
2611 mr
= MACH_SEND_INVALID_TYPE
;
2615 if ((size
>= MSG_OOL_SIZE_SMALL
) &&
2616 (daddr
->out_of_line
.copy
== MACH_MSG_PHYSICAL_COPY
) &&
2617 !(daddr
->out_of_line
.deallocate
)) {
2620 * Out-of-line memory descriptor, accumulate kernel
2621 * memory requirements
2623 if (space_needed
+ round_page(size
) <= space_needed
) {
2624 /* Overflow dectected */
2625 ipc_kmsg_clean_partial(kmsg
, 0, NULL
, 0, 0);
2626 mr
= MACH_MSG_VM_KERNEL
;
2630 space_needed
+= round_page(size
);
2631 if (space_needed
> ipc_kmsg_max_vm_space
) {
2634 * Per message kernel memory limit exceeded
2636 ipc_kmsg_clean_partial(kmsg
, 0, NULL
, 0, 0);
2637 mr
= MACH_MSG_VM_KERNEL
;
2645 * Allocate space in the pageable kernel ipc copy map for all the
2646 * ool data that is to be physically copied. Map is marked wait for
2650 if (vm_allocate(ipc_kernel_copy_map
, &paddr
, space_needed
,
2651 VM_FLAGS_ANYWHERE
) != KERN_SUCCESS
) {
2652 ipc_kmsg_clean_partial(kmsg
, 0, NULL
, 0, 0);
2653 mr
= MACH_MSG_VM_KERNEL
;
2658 /* user_addr = just after base as it was copied in */
2659 user_addr
= (mach_msg_descriptor_t
*)((vm_offset_t
)kmsg
->ikm_header
+ sizeof(mach_msg_base_t
));
2660 /* Shift the mach_msg_base_t down to make for dsc_count*16bytes of descriptors */
2661 if(descriptor_size
!= 16*dsc_count
) {
2662 vm_offset_t dsc_adjust
= 16*dsc_count
- descriptor_size
;
2663 memmove((char *)(((vm_offset_t
)kmsg
->ikm_header
) - dsc_adjust
), kmsg
->ikm_header
, sizeof(mach_msg_base_t
));
2664 kmsg
->ikm_header
= (mach_msg_header_t
*)((vm_offset_t
)kmsg
->ikm_header
- dsc_adjust
);
2665 /* Update the message size for the larger in-kernel representation */
2666 kmsg
->ikm_header
->msgh_size
+= (mach_msg_size_t
)dsc_adjust
;
2670 /* kern_addr = just after base after it has been (conditionally) moved */
2671 kern_addr
= (mach_msg_descriptor_t
*)((vm_offset_t
)kmsg
->ikm_header
+ sizeof(mach_msg_base_t
));
2673 /* handle the OOL regions and port descriptors. */
2674 for(i
=0;i
<dsc_count
;i
++) {
2675 switch (user_addr
->type
.type
) {
2676 case MACH_MSG_PORT_DESCRIPTOR
:
2677 user_addr
= ipc_kmsg_copyin_port_descriptor((mach_msg_port_descriptor_t
*)kern_addr
,
2678 (mach_msg_legacy_port_descriptor_t
*)user_addr
, space
, dest
, kmsg
, &mr
);
2682 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2683 case MACH_MSG_OOL_DESCRIPTOR
:
2684 user_addr
= ipc_kmsg_copyin_ool_descriptor((mach_msg_ool_descriptor_t
*)kern_addr
,
2685 user_addr
, is_task_64bit
, &paddr
, ©
, &space_needed
, map
, &mr
);
2689 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
2690 user_addr
= ipc_kmsg_copyin_ool_ports_descriptor((mach_msg_ool_ports_descriptor_t
*)kern_addr
,
2691 user_addr
, is_task_64bit
, map
, space
, dest
, kmsg
, &mr
);
2696 /* Invalid descriptor */
2697 mr
= MACH_SEND_INVALID_TYPE
;
2701 if (MACH_MSG_SUCCESS
!= mr
) {
2702 /* clean from start of message descriptors to i */
2703 ipc_kmsg_clean_partial(kmsg
, i
,
2704 (mach_msg_descriptor_t
*)((mach_msg_base_t
*)kmsg
->ikm_header
+ 1),
2705 paddr
, space_needed
);
2711 kmsg
->ikm_header
->msgh_bits
&= ~MACH_MSGH_BITS_COMPLEX
;
2719 * Routine: ipc_kmsg_copyin
2721 * "Copy-in" port rights and out-of-line memory
2724 * In all failure cases, the message is left holding
2725 * no rights or memory. However, the message buffer
2726 * is not deallocated. If successful, the message
2727 * contains a valid destination port.
2731 * MACH_MSG_SUCCESS Successful copyin.
2732 * MACH_SEND_INVALID_HEADER
2733 * Illegal value in the message header bits.
2734 * MACH_SEND_INVALID_DEST Can't copyin destination port.
2735 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
2736 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
2737 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
2738 * MACH_SEND_INVALID_TYPE Bad type specification.
2739 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
2747 mach_msg_option_t
*optionp
)
2749 mach_msg_return_t mr
;
2751 kmsg
->ikm_header
->msgh_bits
&= MACH_MSGH_BITS_USER
;
2753 mr
= ipc_kmsg_copyin_header(kmsg
->ikm_header
, space
, optionp
);
2755 if (mr
!= MACH_MSG_SUCCESS
)
2758 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_copyin header:\n%.8x\n%.8x\n%p\n%p\n%.8x\n%.8x\n",
2759 kmsg
->ikm_header
->msgh_size
,
2760 kmsg
->ikm_header
->msgh_bits
,
2761 kmsg
->ikm_header
->msgh_remote_port
,
2762 kmsg
->ikm_header
->msgh_local_port
,
2763 kmsg
->ikm_header
->msgh_reserved
,
2764 kmsg
->ikm_header
->msgh_id
);
2766 if ((kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
2767 return MACH_MSG_SUCCESS
;
2769 mr
= ipc_kmsg_copyin_body( kmsg
, space
, map
);
2771 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK
))
2775 for(i
=0;i
*4 < (kmsg
->ikm_header
->msgh_size
- sizeof(mach_msg_header_t
));i
++)
2777 kprintf("%.4x\n",((uint32_t *)(kmsg
->ikm_header
+ 1))[i
]);
2785 * Routine: ipc_kmsg_copyin_from_kernel
2787 * "Copy-in" port rights and out-of-line memory
2788 * in a message sent from the kernel.
2790 * Because the message comes from the kernel,
2791 * the implementation assumes there are no errors
2792 * or peculiarities in the message.
2798 ipc_kmsg_copyin_from_kernel(
2801 mach_msg_bits_t bits
= kmsg
->ikm_header
->msgh_bits
;
2802 mach_msg_type_name_t rname
= MACH_MSGH_BITS_REMOTE(bits
);
2803 mach_msg_type_name_t lname
= MACH_MSGH_BITS_LOCAL(bits
);
2804 ipc_object_t remote
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2805 ipc_object_t local
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2807 /* translate the destination and reply ports */
2808 if (!IO_VALID(remote
))
2809 return MACH_SEND_INVALID_DEST
;
2811 ipc_object_copyin_from_kernel(remote
, rname
);
2812 if (IO_VALID(local
))
2813 ipc_object_copyin_from_kernel(local
, lname
);
2816 * The common case is a complex message with no reply port,
2817 * because that is what the memory_object interface uses.
2820 if (bits
== (MACH_MSGH_BITS_COMPLEX
|
2821 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0))) {
2822 bits
= (MACH_MSGH_BITS_COMPLEX
|
2823 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND
, 0));
2825 kmsg
->ikm_header
->msgh_bits
= bits
;
2827 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
2828 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
2829 ipc_object_copyin_type(lname
)));
2831 kmsg
->ikm_header
->msgh_bits
= bits
;
2832 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
2833 return MACH_MSG_SUCCESS
;
2836 mach_msg_descriptor_t
*saddr
;
2837 mach_msg_body_t
*body
;
2838 mach_msg_type_number_t i
, count
;
2840 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2841 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
2842 count
= body
->msgh_descriptor_count
;
2844 for (i
= 0; i
< count
; i
++, saddr
++) {
2846 switch (saddr
->type
.type
) {
2848 case MACH_MSG_PORT_DESCRIPTOR
: {
2849 mach_msg_type_name_t name
;
2850 ipc_object_t object
;
2851 mach_msg_port_descriptor_t
*dsc
;
2855 /* this is really the type SEND, SEND_ONCE, etc. */
2856 name
= dsc
->disposition
;
2857 object
= (ipc_object_t
) dsc
->name
;
2858 dsc
->disposition
= ipc_object_copyin_type(name
);
2860 if (!IO_VALID(object
)) {
2864 ipc_object_copyin_from_kernel(object
, name
);
2866 /* CDY avoid circularity when the destination is also */
2867 /* the kernel. This check should be changed into an */
2868 /* assert when the new kobject model is in place since*/
2869 /* ports will not be used in kernel to kernel chats */
2871 if (((ipc_port_t
)remote
)->ip_receiver
!= ipc_space_kernel
) {
2872 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
2873 ipc_port_check_circularity((ipc_port_t
) object
,
2874 (ipc_port_t
) remote
)) {
2875 kmsg
->ikm_header
->msgh_bits
|=
2876 MACH_MSGH_BITS_CIRCULAR
;
2881 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
2882 case MACH_MSG_OOL_DESCRIPTOR
: {
2884 * The sender should supply ready-made memory, i.e.
2885 * a vm_map_copy_t, so we don't need to do anything.
2889 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
2890 ipc_object_t
*objects
;
2892 mach_msg_type_name_t name
;
2893 mach_msg_ool_ports_descriptor_t
*dsc
;
2895 dsc
= (mach_msg_ool_ports_descriptor_t
*)&saddr
->ool_ports
;
2897 /* this is really the type SEND, SEND_ONCE, etc. */
2898 name
= dsc
->disposition
;
2899 dsc
->disposition
= ipc_object_copyin_type(name
);
2901 objects
= (ipc_object_t
*) dsc
->address
;
2903 for ( j
= 0; j
< dsc
->count
; j
++) {
2904 ipc_object_t object
= objects
[j
];
2906 if (!IO_VALID(object
))
2909 ipc_object_copyin_from_kernel(object
, name
);
2911 if ((dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
2912 ipc_port_check_circularity(
2913 (ipc_port_t
) object
,
2914 (ipc_port_t
) remote
))
2915 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
2921 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
2922 #endif /* MACH_ASSERT */
2927 return MACH_MSG_SUCCESS
;
2930 #if IKM_SUPPORT_LEGACY
2932 ipc_kmsg_copyin_from_kernel_legacy(
2935 mach_msg_bits_t bits
= kmsg
->ikm_header
->msgh_bits
;
2936 mach_msg_type_name_t rname
= MACH_MSGH_BITS_REMOTE(bits
);
2937 mach_msg_type_name_t lname
= MACH_MSGH_BITS_LOCAL(bits
);
2938 ipc_object_t remote
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
2939 ipc_object_t local
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
2941 /* translate the destination and reply ports */
2942 if (!IO_VALID(remote
))
2943 return MACH_SEND_INVALID_DEST
;
2945 ipc_object_copyin_from_kernel(remote
, rname
);
2946 if (IO_VALID(local
))
2947 ipc_object_copyin_from_kernel(local
, lname
);
2950 * The common case is a complex message with no reply port,
2951 * because that is what the memory_object interface uses.
2954 if (bits
== (MACH_MSGH_BITS_COMPLEX
|
2955 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, 0))) {
2956 bits
= (MACH_MSGH_BITS_COMPLEX
|
2957 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND
, 0));
2959 kmsg
->ikm_header
->msgh_bits
= bits
;
2961 bits
= (MACH_MSGH_BITS_OTHER(bits
) |
2962 MACH_MSGH_BITS(ipc_object_copyin_type(rname
),
2963 ipc_object_copyin_type(lname
)));
2965 kmsg
->ikm_header
->msgh_bits
= bits
;
2966 if ((bits
& MACH_MSGH_BITS_COMPLEX
) == 0)
2967 return MACH_MSG_SUCCESS
;
2970 mach_msg_legacy_descriptor_t
*saddr
;
2971 mach_msg_descriptor_t
*daddr
;
2972 mach_msg_body_t
*body
;
2973 mach_msg_type_number_t i
, count
;
2975 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
2976 saddr
= (typeof(saddr
)) (body
+ 1);
2977 count
= body
->msgh_descriptor_count
;
2980 vm_offset_t dsc_adjust
= 4*count
;
2981 memmove((char *)(((vm_offset_t
)kmsg
->ikm_header
) - dsc_adjust
), kmsg
->ikm_header
, sizeof(mach_msg_base_t
));
2982 kmsg
->ikm_header
= (mach_msg_header_t
*)((vm_offset_t
)kmsg
->ikm_header
- dsc_adjust
);
2983 /* Update the message size for the larger in-kernel representation */
2984 kmsg
->ikm_header
->msgh_size
+= dsc_adjust
;
2986 daddr
= (mach_msg_descriptor_t
*)((vm_offset_t
)kmsg
->ikm_header
+ sizeof(mach_msg_base_t
));
2988 for (i
= 0; i
< count
; i
++, saddr
++, daddr
++) {
2989 switch (saddr
->type
.type
) {
2991 case MACH_MSG_PORT_DESCRIPTOR
: {
2992 mach_msg_type_name_t name
;
2993 ipc_object_t object
;
2994 mach_msg_legacy_port_descriptor_t
*dsc
;
2995 mach_msg_port_descriptor_t
*dest_dsc
;
2997 dsc
= (typeof(dsc
))&saddr
->port
;
2998 dest_dsc
= &daddr
->port
;
3000 /* this is really the type SEND, SEND_ONCE, etc. */
3001 name
= dsc
->disposition
;
3002 object
= (ipc_object_t
) CAST_MACH_NAME_TO_PORT(dsc
->name
);
3003 dest_dsc
->disposition
= ipc_object_copyin_type(name
);
3004 dest_dsc
->name
= (mach_port_t
)object
;
3005 dest_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
3007 if (!IO_VALID(object
)) {
3011 ipc_object_copyin_from_kernel(object
, name
);
3013 /* CDY avoid circularity when the destination is also */
3014 /* the kernel. This check should be changed into an */
3015 /* assert when the new kobject model is in place since*/
3016 /* ports will not be used in kernel to kernel chats */
3018 if (((ipc_port_t
)remote
)->ip_receiver
!= ipc_space_kernel
) {
3019 if ((dest_dsc
->disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
3020 ipc_port_check_circularity((ipc_port_t
) object
,
3021 (ipc_port_t
) remote
)) {
3022 kmsg
->ikm_header
->msgh_bits
|=
3023 MACH_MSGH_BITS_CIRCULAR
;
3028 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
3029 case MACH_MSG_OOL_DESCRIPTOR
: {
3030 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
3031 * so we don't need to do anything special. */
3033 mach_msg_ool_descriptor32_t
*source_dsc
= &saddr
->out_of_line32
;
3034 mach_msg_ool_descriptor_t
*dest_dsc
= (typeof(dest_dsc
))&daddr
->out_of_line
;
3036 vm_offset_t address
= source_dsc
->address
;
3037 vm_size_t size
= source_dsc
->size
;
3038 boolean_t deallocate
= source_dsc
->deallocate
;
3039 mach_msg_copy_options_t copy
= source_dsc
->copy
;
3040 mach_msg_descriptor_type_t type
= source_dsc
->type
;
3042 dest_dsc
->address
= (void *)address
;
3043 dest_dsc
->size
= size
;
3044 dest_dsc
->deallocate
= deallocate
;
3045 dest_dsc
->copy
= copy
;
3046 dest_dsc
->type
= type
;
3049 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
3050 ipc_object_t
*objects
;
3052 mach_msg_type_name_t name
;
3053 mach_msg_ool_ports_descriptor_t
*dest_dsc
;
3055 mach_msg_ool_ports_descriptor32_t
*source_dsc
= &saddr
->ool_ports32
;
3056 dest_dsc
= (typeof(dest_dsc
))&daddr
->ool_ports
;
3058 boolean_t deallocate
= source_dsc
->deallocate
;
3059 mach_msg_copy_options_t copy
= source_dsc
->copy
;
3060 mach_msg_size_t port_count
= source_dsc
->count
;
3061 mach_msg_type_name_t disposition
= source_dsc
->disposition
;
3063 /* this is really the type SEND, SEND_ONCE, etc. */
3065 disposition
= ipc_object_copyin_type(name
);
3067 objects
= (ipc_object_t
*) (uintptr_t)source_dsc
->address
;
3069 for ( j
= 0; j
< port_count
; j
++) {
3070 ipc_object_t object
= objects
[j
];
3072 if (!IO_VALID(object
))
3075 ipc_object_copyin_from_kernel(object
, name
);
3077 if ((disposition
== MACH_MSG_TYPE_PORT_RECEIVE
) &&
3078 ipc_port_check_circularity(
3079 (ipc_port_t
) object
,
3080 (ipc_port_t
) remote
))
3081 kmsg
->ikm_header
->msgh_bits
|= MACH_MSGH_BITS_CIRCULAR
;
3084 dest_dsc
->address
= objects
;
3085 dest_dsc
->deallocate
= deallocate
;
3086 dest_dsc
->copy
= copy
;
3087 dest_dsc
->disposition
= disposition
;
3088 dest_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
3089 dest_dsc
->count
= port_count
;
3094 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
3095 #endif /* MACH_ASSERT */
3100 return MACH_MSG_SUCCESS
;
3102 #endif /* IKM_SUPPORT_LEGACY */
3105 * Routine: ipc_kmsg_copyout_header
3107 * "Copy-out" port rights in the header of a message.
3108 * Operates atomically; if it doesn't succeed the
3109 * message header and the space are left untouched.
3110 * If it does succeed the remote/local port fields
3111 * contain port names instead of object pointers,
3112 * and the bits field is updated.
3116 * MACH_MSG_SUCCESS Copied out port rights.
3117 * MACH_RCV_INVALID_NOTIFY
3118 * Notify is non-null and doesn't name a receive right.
3119 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
3120 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3121 * The space is dead.
3122 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
3123 * No room in space for another name.
3124 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3125 * Couldn't allocate memory for the reply port.
3126 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
3127 * Couldn't allocate memory for the dead-name request.
3131 ipc_kmsg_copyout_header(
3132 mach_msg_header_t
*msg
,
3135 mach_msg_bits_t mbits
= msg
->msgh_bits
;
3136 ipc_port_t dest
= (ipc_port_t
) msg
->msgh_remote_port
;
3138 assert(IP_VALID(dest
));
3141 * While we still hold a reference on the received-from port,
3142 * process all send-possible notfications we received along with
3145 ipc_port_spnotify(dest
);
3148 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
3149 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
3150 ipc_port_t reply
= (ipc_port_t
) msg
->msgh_local_port
;
3151 ipc_port_t release_port
= IP_NULL
;
3152 mach_port_name_t dest_name
, reply_name
;
3154 if (IP_VALID(reply
)) {
3159 * Get reply port entry (if none, skip to dest port
3160 * copyout). This may require growing the space.
3163 is_write_lock(space
);
3166 if (!is_active(space
)) {
3167 is_write_unlock(space
);
3168 return (MACH_RCV_HEADER_ERROR
|
3169 MACH_MSG_IPC_SPACE
);
3172 if ((reply_type
!= MACH_MSG_TYPE_PORT_SEND_ONCE
) &&
3173 ipc_right_reverse(space
, (ipc_object_t
) reply
,
3174 &reply_name
, &entry
)) {
3175 /* reply port is locked and active */
3176 assert(entry
->ie_bits
&
3177 MACH_PORT_TYPE_SEND_RECEIVE
);
3182 if (!ip_active(reply
)) {
3185 is_write_unlock(space
);
3187 release_port
= reply
;
3189 reply_name
= MACH_PORT_DEAD
;
3193 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
3194 kr
= ipc_entry_get(space
, &reply_name
, &entry
);
3195 if (kr
!= KERN_SUCCESS
) {
3198 /* space is locked */
3199 kr
= ipc_entry_grow_table(space
,
3201 if (kr
!= KERN_SUCCESS
) {
3202 return (MACH_RCV_HEADER_ERROR
|
3203 MACH_MSG_IPC_SPACE
);
3205 /* space is locked again; start over */
3209 assert(IE_BITS_TYPE(entry
->ie_bits
) ==
3210 MACH_PORT_TYPE_NONE
);
3211 assert(entry
->ie_object
== IO_NULL
);
3213 entry
->ie_object
= (ipc_object_t
) reply
;
3217 /* space and reply port are locked and active */
3219 ip_reference(reply
); /* hold onto the reply port */
3221 kr
= ipc_right_copyout(space
, reply_name
, entry
,
3222 reply_type
, TRUE
, (ipc_object_t
) reply
);
3224 /* reply port is unlocked */
3225 assert(kr
== KERN_SUCCESS
);
3228 is_write_unlock(space
);
3232 * No reply port! This is an easy case.
3233 * We only need to have the space locked
3234 * when locking the destination.
3237 is_read_lock(space
);
3238 if (!is_active(space
)) {
3239 is_read_unlock(space
);
3240 return MACH_RCV_HEADER_ERROR
|MACH_MSG_IPC_SPACE
;
3244 is_read_unlock(space
);
3246 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
3250 * At this point, the space is unlocked and the destination
3251 * port is locked. (Lock taken while space was locked.)
3252 * reply_name is taken care of; we still need dest_name.
3253 * We still hold a ref for reply (if it is valid).
3255 * If the space holds receive rights for the destination,
3256 * we return its name for the right. Otherwise the task
3257 * managed to destroy or give away the receive right between
3258 * receiving the message and this copyout. If the destination
3259 * is dead, return MACH_PORT_DEAD, and if the receive right
3260 * exists somewhere else (another space, in transit)
3261 * return MACH_PORT_NULL.
3263 * Making this copyout operation atomic with the previous
3264 * copyout of the reply port is a bit tricky. If there was
3265 * no real reply port (it wasn't IP_VALID) then this isn't
3266 * an issue. If the reply port was dead at copyout time,
3267 * then we are OK, because if dest is dead we serialize
3268 * after the death of both ports and if dest is alive
3269 * we serialize after reply died but before dest's (later) death.
3270 * So assume reply was alive when we copied it out. If dest
3271 * is alive, then we are OK because we serialize before
3272 * the ports' deaths. So assume dest is dead when we look at it.
3273 * If reply dies/died after dest, then we are OK because
3274 * we serialize after dest died but before reply dies.
3275 * So the hard case is when reply is alive at copyout,
3276 * dest is dead at copyout, and reply died before dest died.
3277 * In this case pretend that dest is still alive, so
3278 * we serialize while both ports are alive.
3280 * Because the space lock is held across the copyout of reply
3281 * and locking dest, the receive right for dest can't move
3282 * in or out of the space while the copyouts happen, so
3283 * that isn't an atomicity problem. In the last hard case
3284 * above, this implies that when dest is dead that the
3285 * space couldn't have had receive rights for dest at
3286 * the time reply was copied-out, so when we pretend
3287 * that dest is still alive, we can return MACH_PORT_NULL.
3289 * If dest == reply, then we have to make it look like
3290 * either both copyouts happened before the port died,
3291 * or both happened after the port died. This special
3292 * case works naturally if the timestamp comparison
3293 * is done correctly.
3298 if (ip_active(dest
)) {
3299 ipc_object_copyout_dest(space
, (ipc_object_t
) dest
,
3300 dest_type
, &dest_name
);
3301 /* dest is unlocked */
3304 ipc_port_timestamp_t timestamp
;
3306 timestamp
= dest
->ip_timestamp
;
3310 if (IP_VALID(reply
)) {
3312 if (ip_active(reply
) ||
3313 IP_TIMESTAMP_ORDER(timestamp
,
3314 reply
->ip_timestamp
))
3315 dest_name
= MACH_PORT_DEAD
;
3317 dest_name
= MACH_PORT_NULL
;
3320 dest_name
= MACH_PORT_DEAD
;
3323 if (IP_VALID(reply
))
3326 if (IP_VALID(release_port
))
3327 ip_release(release_port
);
3329 msg
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
3330 MACH_MSGH_BITS(reply_type
, dest_type
));
3331 msg
->msgh_local_port
= CAST_MACH_NAME_TO_PORT(dest_name
);
3332 msg
->msgh_remote_port
= CAST_MACH_NAME_TO_PORT(reply_name
);
3335 return MACH_MSG_SUCCESS
;
3339 * Routine: ipc_kmsg_copyout_object
3341 * Copy-out a port right. Always returns a name,
3342 * even for unsuccessful return codes. Always
3343 * consumes the supplied object.
3347 * MACH_MSG_SUCCESS The space acquired the right
3348 * (name is valid) or the object is dead (MACH_PORT_DEAD).
3349 * MACH_MSG_IPC_SPACE No room in space for the right,
3350 * or the space is dead. (Name is MACH_PORT_NULL.)
3351 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
3352 * (Name is MACH_PORT_NULL.)
3356 ipc_kmsg_copyout_object(
3358 ipc_object_t object
,
3359 mach_msg_type_name_t msgt_name
,
3360 mach_port_name_t
*namep
)
3364 if (!IO_VALID(object
)) {
3365 *namep
= CAST_MACH_PORT_TO_NAME(object
);
3366 return MACH_MSG_SUCCESS
;
3369 kr
= ipc_object_copyout(space
, object
, msgt_name
, TRUE
, namep
);
3370 if (kr
!= KERN_SUCCESS
) {
3371 ipc_object_destroy(object
, msgt_name
);
3373 if (kr
== KERN_INVALID_CAPABILITY
)
3374 *namep
= MACH_PORT_DEAD
;
3376 *namep
= MACH_PORT_NULL
;
3378 if (kr
== KERN_RESOURCE_SHORTAGE
)
3379 return MACH_MSG_IPC_KERNEL
;
3381 return MACH_MSG_IPC_SPACE
;
3385 return MACH_MSG_SUCCESS
;
3388 mach_msg_descriptor_t
*
3389 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t
*dsc
,
3390 mach_msg_descriptor_t
*user_dsc
,
3393 mach_msg_descriptor_t
*
3394 ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t
*dsc
,
3395 mach_msg_descriptor_t
*dest_dsc
,
3400 mach_port_name_t name
;
3401 mach_msg_type_name_t disp
;
3404 /* Copyout port right carried in the message */
3405 port
= dsc
->port
.name
;
3406 disp
= dsc
->port
.disposition
;
3407 *mr
|= ipc_kmsg_copyout_object(space
,
3412 if(current_task() == kernel_task
)
3414 mach_msg_port_descriptor_t
*user_dsc
= (typeof(user_dsc
))dest_dsc
;
3415 user_dsc
--; // point to the start of this port descriptor
3416 user_dsc
->name
= CAST_MACH_NAME_TO_PORT(name
);
3417 user_dsc
->disposition
= disp
;
3418 user_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
3419 dest_dsc
= (typeof(dest_dsc
))user_dsc
;
3421 mach_msg_legacy_port_descriptor_t
*user_dsc
= (typeof(user_dsc
))dest_dsc
;
3422 user_dsc
--; // point to the start of this port descriptor
3423 user_dsc
->name
= CAST_MACH_PORT_TO_NAME(name
);
3424 user_dsc
->disposition
= disp
;
3425 user_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
3426 dest_dsc
= (typeof(dest_dsc
))user_dsc
;
3429 return (mach_msg_descriptor_t
*)dest_dsc
;
3432 mach_msg_descriptor_t
*
3433 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
);
3434 mach_msg_descriptor_t
*
3435 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
)
3438 vm_map_address_t rcv_addr
;
3439 mach_msg_copy_options_t copy_options
;
3440 mach_msg_size_t size
;
3441 mach_msg_descriptor_type_t dsc_type
;
3443 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3445 copy
= (vm_map_copy_t
) dsc
->address
;
3447 copy_options
= dsc
->copy
;
3448 assert(copy_options
!= MACH_MSG_KALLOC_COPY_T
);
3449 dsc_type
= dsc
->type
;
3452 if (copy
!= VM_MAP_COPY_NULL
) {
3454 * Check to see if there is an overwrite descriptor
3455 * specified in the scatter list for this ool data.
3456 * The descriptor has already been verified.
3459 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
3461 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
3463 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
3464 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
3465 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
3466 copy_options
= MACH_MSG_OVERWRITE
;
3468 copy_options
= MACH_MSG_VIRTUAL_COPY
;
3471 mach_msg_ool_descriptor_t
*scatter_dsc
;
3473 scatter_dsc
= &saddr
->out_of_line
;
3474 if (scatter_dsc
->copy
== MACH_MSG_OVERWRITE
) {
3475 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
3476 copy_options
= MACH_MSG_OVERWRITE
;
3478 copy_options
= MACH_MSG_VIRTUAL_COPY
;
3481 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
3487 * Whether the data was virtually or physically
3488 * copied we have a vm_map_copy_t for it.
3489 * If there's an overwrite region specified
3490 * overwrite it, otherwise do a virtual copy out.
3493 if (copy_options
== MACH_MSG_OVERWRITE
&& rcv_addr
!= 0) {
3494 kr
= vm_map_copy_overwrite(map
, rcv_addr
,
3497 kr
= vm_map_copyout(map
, &rcv_addr
, copy
);
3499 if (kr
!= KERN_SUCCESS
) {
3500 if (kr
== KERN_RESOURCE_SHORTAGE
)
3501 *mr
|= MACH_MSG_VM_KERNEL
;
3503 *mr
|= MACH_MSG_VM_SPACE
;
3504 vm_map_copy_discard(copy
);
3514 * Now update the descriptor as the user would see it.
3515 * This may require expanding the descriptor to the user
3516 * visible size. There is already space allocated for
3517 * this in what naddr points to.
3519 if(current_task() == kernel_task
)
3521 mach_msg_ool_descriptor_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3524 user_ool_dsc
->address
= (void *)(uintptr_t)rcv_addr
;
3525 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3527 user_ool_dsc
->copy
= copy_options
;
3528 user_ool_dsc
->type
= dsc_type
;
3529 user_ool_dsc
->size
= size
;
3531 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3532 } else if (is_64bit
) {
3533 mach_msg_ool_descriptor64_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3536 user_ool_dsc
->address
= rcv_addr
;
3537 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3539 user_ool_dsc
->copy
= copy_options
;
3540 user_ool_dsc
->type
= dsc_type
;
3541 user_ool_dsc
->size
= size
;
3543 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3545 mach_msg_ool_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3548 user_ool_dsc
->address
= CAST_DOWN_EXPLICIT(uint32_t, rcv_addr
);
3549 user_ool_dsc
->size
= size
;
3550 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3552 user_ool_dsc
->copy
= copy_options
;
3553 user_ool_dsc
->type
= dsc_type
;
3555 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3560 mach_msg_descriptor_t
*
3561 ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t
*dsc
,
3562 mach_msg_descriptor_t
*user_dsc
,
3567 mach_msg_return_t
*mr
);
3568 mach_msg_descriptor_t
*
3569 ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t
*dsc
,
3570 mach_msg_descriptor_t
*user_dsc
,
3575 mach_msg_return_t
*mr
)
3577 mach_vm_offset_t rcv_addr
= 0;
3578 mach_msg_type_name_t disp
;
3579 mach_msg_type_number_t count
, i
;
3580 vm_size_t ports_length
, names_length
;
3582 mach_msg_copy_options_t copy_options
= MACH_MSG_VIRTUAL_COPY
;
3584 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count);
3587 disp
= dsc
->disposition
;
3588 ports_length
= count
* sizeof(mach_port_t
);
3589 names_length
= count
* sizeof(mach_port_name_t
);
3591 if (ports_length
!= 0 && dsc
->address
!= 0) {
3594 * Check to see if there is an overwrite descriptor
3595 * specified in the scatter list for this ool data.
3596 * The descriptor has already been verified.
3599 if (saddr
!= MACH_MSG_DESCRIPTOR_NULL
) {
3601 OTHER_OOL_DESCRIPTOR
*scatter_dsc
;
3603 scatter_dsc
= (OTHER_OOL_DESCRIPTOR
*)saddr
;
3604 rcv_addr
= (mach_vm_offset_t
) scatter_dsc
->address
;
3605 copy_options
= scatter_dsc
->copy
;
3607 mach_msg_ool_descriptor_t
*scatter_dsc
;
3609 scatter_dsc
= &saddr
->out_of_line
;
3610 rcv_addr
= CAST_USER_ADDR_T(scatter_dsc
->address
);
3611 copy_options
= scatter_dsc
->copy
;
3613 INCREMENT_SCATTER(saddr
, sdsc_count
, differs
);
3617 if (copy_options
== MACH_MSG_VIRTUAL_COPY
) {
3619 * Dynamically allocate the region
3621 int anywhere
= VM_MAKE_TAG(VM_MEMORY_MACH_MSG
)|
3625 if ((kr
= mach_vm_allocate(map
, &rcv_addr
,
3626 (mach_vm_size_t
)names_length
,
3627 anywhere
)) != KERN_SUCCESS
) {
3628 ipc_kmsg_clean_body(kmsg
, 1, (mach_msg_descriptor_t
*)dsc
);
3631 if (kr
== KERN_RESOURCE_SHORTAGE
){
3632 *mr
|= MACH_MSG_VM_KERNEL
;
3634 *mr
|= MACH_MSG_VM_SPACE
;
3640 * Handle the port rights and copy out the names
3641 * for those rights out to user-space.
3643 if (rcv_addr
!= 0) {
3644 mach_port_t
*objects
= (mach_port_t
*) dsc
->address
;
3645 mach_port_name_t
*names
= (mach_port_name_t
*) dsc
->address
;
3647 /* copyout port rights carried in the message */
3649 for ( i
= 0; i
< count
; i
++) {
3650 ipc_object_t object
= (ipc_object_t
)objects
[i
];
3652 *mr
|= ipc_kmsg_copyout_object(space
, object
,
3656 /* copyout to memory allocated above */
3657 void *data
= dsc
->address
;
3658 if (copyoutmap(map
, data
, rcv_addr
, names_length
) != KERN_SUCCESS
)
3659 *mr
|= MACH_MSG_VM_SPACE
;
3660 kfree(data
, ports_length
);
3667 * Now update the descriptor based on the information
3670 if(current_task() == kernel_task
) {
3671 mach_msg_ool_ports_descriptor_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3674 user_ool_dsc
->address
= (void *)(uintptr_t)rcv_addr
;
3675 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3677 user_ool_dsc
->copy
= copy_options
;
3678 user_ool_dsc
->disposition
= disp
;
3679 user_ool_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
3680 user_ool_dsc
->count
= count
;
3682 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3684 mach_msg_ool_ports_descriptor64_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3687 user_ool_dsc
->address
= rcv_addr
;
3688 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3690 user_ool_dsc
->copy
= copy_options
;
3691 user_ool_dsc
->disposition
= disp
;
3692 user_ool_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
3693 user_ool_dsc
->count
= count
;
3695 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3697 mach_msg_ool_ports_descriptor32_t
*user_ool_dsc
= (typeof(user_ool_dsc
))user_dsc
;
3700 user_ool_dsc
->address
= CAST_DOWN_EXPLICIT(uint32_t, rcv_addr
);
3701 user_ool_dsc
->count
= count
;
3702 user_ool_dsc
->deallocate
= (copy_options
== MACH_MSG_VIRTUAL_COPY
) ?
3704 user_ool_dsc
->copy
= copy_options
;
3705 user_ool_dsc
->disposition
= disp
;
3706 user_ool_dsc
->type
= MACH_MSG_OOL_PORTS_DESCRIPTOR
;
3708 user_dsc
= (typeof(user_dsc
))user_ool_dsc
;
3714 * Routine: ipc_kmsg_copyout_body
3716 * "Copy-out" port rights and out-of-line memory
3717 * in the body of a message.
3719 * The error codes are a combination of special bits.
3720 * The copyout proceeds despite errors.
3724 * MACH_MSG_SUCCESS Successful copyout.
3725 * MACH_MSG_IPC_SPACE No room for port right in name space.
3726 * MACH_MSG_VM_SPACE No room for memory in address space.
3727 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
3728 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
3729 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
3733 ipc_kmsg_copyout_body(
3737 mach_msg_body_t
*slist
)
3739 mach_msg_body_t
*body
;
3740 mach_msg_descriptor_t
*kern_dsc
, *user_dsc
;
3741 mach_msg_descriptor_t
*saddr
;
3742 mach_msg_type_number_t dsc_count
, sdsc_count
;
3744 mach_msg_return_t mr
= MACH_MSG_SUCCESS
;
3745 boolean_t is_task_64bit
= (map
->max_offset
> VM_MAX_ADDRESS
);
3747 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
3748 dsc_count
= body
->msgh_descriptor_count
;
3749 kern_dsc
= (mach_msg_descriptor_t
*) (body
+ 1);
3750 /* Point user_dsc just after the end of all the descriptors */
3751 user_dsc
= &kern_dsc
[dsc_count
];
3753 /* Do scatter list setup */
3754 if (slist
!= MACH_MSG_BODY_NULL
) {
3755 panic("Scatter lists disabled");
3756 saddr
= (mach_msg_descriptor_t
*) (slist
+ 1);
3757 sdsc_count
= slist
->msgh_descriptor_count
;
3760 saddr
= MACH_MSG_DESCRIPTOR_NULL
;
3764 /* Now process the descriptors */
3765 for (i
= dsc_count
-1; i
>= 0; i
--) {
3766 switch (kern_dsc
[i
].type
.type
) {
3768 case MACH_MSG_PORT_DESCRIPTOR
:
3769 user_dsc
= ipc_kmsg_copyout_port_descriptor(&kern_dsc
[i
], user_dsc
, space
, &mr
);
3771 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
3772 case MACH_MSG_OOL_DESCRIPTOR
:
3773 user_dsc
= ipc_kmsg_copyout_ool_descriptor(
3774 (mach_msg_ool_descriptor_t
*)&kern_dsc
[i
], user_dsc
, is_task_64bit
, map
, &mr
);
3776 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
3777 user_dsc
= ipc_kmsg_copyout_ool_ports_descriptor(
3778 (mach_msg_ool_ports_descriptor_t
*)&kern_dsc
[i
], user_dsc
, is_task_64bit
, map
, space
, kmsg
, &mr
);
3781 panic("untyped IPC copyout body: invalid message descriptor");
3786 if(user_dsc
!= kern_dsc
) {
3787 vm_offset_t dsc_adjust
= (vm_offset_t
)user_dsc
- (vm_offset_t
)kern_dsc
;
3788 memmove((char *)((vm_offset_t
)kmsg
->ikm_header
+ dsc_adjust
), kmsg
->ikm_header
, sizeof(mach_msg_base_t
));
3789 kmsg
->ikm_header
= (mach_msg_header_t
*)((vm_offset_t
)kmsg
->ikm_header
+ dsc_adjust
);
3790 /* Update the message size for the smaller user representation */
3791 kmsg
->ikm_header
->msgh_size
-= (mach_msg_size_t
)dsc_adjust
;
3798 * Routine: ipc_kmsg_copyout_size
3800 * Compute the size of the message as copied out to the given
3801 * map. If the destination map's pointers are a different size
3802 * than the kernel's, we have to allow for expansion/
3803 * contraction of the descriptors as appropriate.
3807 * size of the message as it would be received.
3811 ipc_kmsg_copyout_size(
3815 mach_msg_size_t send_size
;
3817 send_size
= kmsg
->ikm_header
->msgh_size
;
3819 boolean_t is_task_64bit
= (map
->max_offset
> VM_MAX_ADDRESS
);
3821 #if defined(__LP64__)
3822 send_size
-= LEGACY_HEADER_SIZE_DELTA
;
3825 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
3827 mach_msg_body_t
*body
;
3828 mach_msg_descriptor_t
*saddr
, *eaddr
;
3830 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
3831 saddr
= (mach_msg_descriptor_t
*) (body
+ 1);
3832 eaddr
= saddr
+ body
->msgh_descriptor_count
;
3834 for ( ; saddr
< eaddr
; saddr
++ ) {
3835 switch (saddr
->type
.type
) {
3836 case MACH_MSG_OOL_DESCRIPTOR
:
3837 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
3838 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
3840 send_size
-= DESC_SIZE_ADJUSTMENT
;
3842 case MACH_MSG_PORT_DESCRIPTOR
:
3843 send_size
-= DESC_SIZE_ADJUSTMENT
;
3854 * Routine: ipc_kmsg_copyout
3856 * "Copy-out" port rights and out-of-line memory
3861 * MACH_MSG_SUCCESS Copied out all rights and memory.
3862 * MACH_RCV_HEADER_ERROR + special bits
3863 * Rights and memory in the message are intact.
3864 * MACH_RCV_BODY_ERROR + special bits
3865 * The message header was successfully copied out.
3866 * As much of the body was handled as possible.
3874 mach_msg_body_t
*slist
)
3876 mach_msg_return_t mr
;
3878 mr
= ipc_kmsg_copyout_header(kmsg
->ikm_header
, space
);
3879 if (mr
!= MACH_MSG_SUCCESS
) {
3883 if (kmsg
->ikm_header
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
3884 mr
= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
3886 if (mr
!= MACH_MSG_SUCCESS
)
3887 mr
|= MACH_RCV_BODY_ERROR
;
3894 * Routine: ipc_kmsg_copyout_pseudo
3896 * Does a pseudo-copyout of the message.
3897 * This is like a regular copyout, except
3898 * that the ports in the header are handled
3899 * as if they are in the body. They aren't reversed.
3901 * The error codes are a combination of special bits.
3902 * The copyout proceeds despite errors.
3906 * MACH_MSG_SUCCESS Successful copyout.
3907 * MACH_MSG_IPC_SPACE No room for port right in name space.
3908 * MACH_MSG_VM_SPACE No room for memory in address space.
3909 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
3910 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
3914 ipc_kmsg_copyout_pseudo(
3918 mach_msg_body_t
*slist
)
3920 mach_msg_bits_t mbits
= kmsg
->ikm_header
->msgh_bits
;
3921 ipc_object_t dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
3922 ipc_object_t reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
3923 mach_msg_type_name_t dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
3924 mach_msg_type_name_t reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
3925 mach_port_name_t dest_name
, reply_name
;
3926 mach_msg_return_t mr
;
3928 assert(IO_VALID(dest
));
3930 mr
= (ipc_kmsg_copyout_object(space
, dest
, dest_type
, &dest_name
) |
3931 ipc_kmsg_copyout_object(space
, reply
, reply_type
, &reply_name
));
3933 kmsg
->ikm_header
->msgh_bits
= mbits
& MACH_MSGH_BITS_USER
;
3934 kmsg
->ikm_header
->msgh_remote_port
= CAST_MACH_NAME_TO_PORT(dest_name
);
3935 kmsg
->ikm_header
->msgh_local_port
= CAST_MACH_NAME_TO_PORT(reply_name
);
3937 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
3938 mr
|= ipc_kmsg_copyout_body(kmsg
, space
, map
, slist
);
3945 * Routine: ipc_kmsg_copyout_dest
3947 * Copies out the destination port in the message.
3948 * Destroys all other rights and memory in the message.
3954 ipc_kmsg_copyout_dest(
3958 mach_msg_bits_t mbits
;
3961 mach_msg_type_name_t dest_type
;
3962 mach_msg_type_name_t reply_type
;
3963 mach_port_name_t dest_name
, reply_name
;
3965 mbits
= kmsg
->ikm_header
->msgh_bits
;
3966 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
3967 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
3968 dest_type
= MACH_MSGH_BITS_REMOTE(mbits
);
3969 reply_type
= MACH_MSGH_BITS_LOCAL(mbits
);
3971 assert(IO_VALID(dest
));
3974 if (io_active(dest
)) {
3975 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
3976 /* dest is unlocked */
3980 dest_name
= MACH_PORT_DEAD
;
3983 if (IO_VALID(reply
)) {
3984 ipc_object_destroy(reply
, reply_type
);
3985 reply_name
= MACH_PORT_NULL
;
3987 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
3989 kmsg
->ikm_header
->msgh_bits
= (MACH_MSGH_BITS_OTHER(mbits
) |
3990 MACH_MSGH_BITS(reply_type
, dest_type
));
3991 kmsg
->ikm_header
->msgh_local_port
= CAST_MACH_NAME_TO_PORT(dest_name
);
3992 kmsg
->ikm_header
->msgh_remote_port
= CAST_MACH_NAME_TO_PORT(reply_name
);
3994 if (mbits
& MACH_MSGH_BITS_COMPLEX
) {
3995 mach_msg_body_t
*body
;
3997 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
3998 ipc_kmsg_clean_body(kmsg
, body
->msgh_descriptor_count
,
3999 (mach_msg_descriptor_t
*)(body
+ 1));
4004 * Routine: ipc_kmsg_copyin_scatter
4006 * allocate and copyin a scatter list
4008 * The gather (kmsg) is valid since it has been copied in.
4009 * Gather list descriptors are sequentially paired with scatter
4010 * list descriptors, with port descriptors in either list ignored.
4011 * Descriptors are consistent if the type fileds match and size
4012 * of the scatter descriptor is less than or equal to the
4013 * size of the gather descriptor. A MACH_MSG_ALLOCATE copy
4014 * strategy in a scatter descriptor matches any size in the
4015 * corresponding gather descriptor assuming they are the same type.
4016 * Either list may be larger than the other. During the
4017 * subsequent copy out, excess scatter descriptors are ignored
4018 * and excess gather descriptors default to dynamic allocation.
4020 * In the case of a size error, the scatter list is released.
4024 * the allocated message body containing the scatter list.
4028 ipc_kmsg_get_scatter(
4029 mach_vm_address_t msg_addr
,
4030 mach_msg_size_t slist_size
,
4033 mach_msg_body_t
*slist
;
4034 mach_msg_body_t
*body
;
4035 mach_msg_descriptor_t
*gstart
, *gend
;
4036 mach_msg_descriptor_t
*sstart
, *send
;
4038 #if defined(__LP64__)
4039 panic("ipc_kmsg_get_scatter called!");
4042 if (slist_size
< sizeof(mach_msg_base_t
))
4043 return MACH_MSG_BODY_NULL
;
4045 slist_size
-= (mach_msg_size_t
)sizeof(mach_msg_header_t
);
4046 slist
= (mach_msg_body_t
*)kalloc(slist_size
);
4047 if (slist
== MACH_MSG_BODY_NULL
)
4050 if (copyin(msg_addr
+ sizeof(mach_msg_header_t
), (char *)slist
, slist_size
)) {
4051 kfree(slist
, slist_size
);
4052 return MACH_MSG_BODY_NULL
;
4055 if ((slist
->msgh_descriptor_count
* sizeof(mach_msg_descriptor_t
)
4056 + sizeof(mach_msg_size_t
)) > slist_size
) {
4057 kfree(slist
, slist_size
);
4058 return MACH_MSG_BODY_NULL
;
4061 body
= (mach_msg_body_t
*) (kmsg
->ikm_header
+ 1);
4062 gstart
= (mach_msg_descriptor_t
*) (body
+ 1);
4063 gend
= gstart
+ body
->msgh_descriptor_count
;
4065 sstart
= (mach_msg_descriptor_t
*) (slist
+ 1);
4066 send
= sstart
+ slist
->msgh_descriptor_count
;
4068 while (gstart
< gend
) {
4069 mach_msg_descriptor_type_t g_type
;
4072 * Skip port descriptors in gather list.
4074 g_type
= gstart
->type
.type
;
4076 if (g_type
!= MACH_MSG_PORT_DESCRIPTOR
) {
4079 * A scatter list with a 0 descriptor count is treated as an
4080 * automatic size mismatch.
4082 if (slist
->msgh_descriptor_count
== 0) {
4083 kfree(slist
, slist_size
);
4084 return MACH_MSG_BODY_NULL
;
4088 * Skip port descriptors in scatter list.
4090 while (sstart
< send
) {
4091 if (sstart
->type
.type
!= MACH_MSG_PORT_DESCRIPTOR
)
4097 * No more scatter descriptors, we're done
4099 if (sstart
>= send
) {
4104 * Check type, copy and size fields
4106 if (g_type
== MACH_MSG_OOL_DESCRIPTOR
||
4107 g_type
== MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
4108 if (sstart
->type
.type
!= MACH_MSG_OOL_DESCRIPTOR
&&
4109 sstart
->type
.type
!= MACH_MSG_OOL_VOLATILE_DESCRIPTOR
) {
4110 kfree(slist
, slist_size
);
4111 return MACH_MSG_BODY_NULL
;
4113 if (sstart
->out_of_line
.copy
== MACH_MSG_OVERWRITE
&&
4114 gstart
->out_of_line
.size
> sstart
->out_of_line
.size
) {
4115 kfree(slist
, slist_size
);
4116 return MACH_MSG_BODY_NULL
;
4120 if (sstart
->type
.type
!= MACH_MSG_OOL_PORTS_DESCRIPTOR
) {
4121 kfree(slist
, slist_size
);
4122 return MACH_MSG_BODY_NULL
;
4124 if (sstart
->ool_ports
.copy
== MACH_MSG_OVERWRITE
&&
4125 gstart
->ool_ports
.count
> sstart
->ool_ports
.count
) {
4126 kfree(slist
, slist_size
);
4127 return MACH_MSG_BODY_NULL
;
4139 * Routine: ipc_kmsg_free_scatter
4141 * Deallocate a scatter list. Since we actually allocated
4142 * a body without a header, and since the header was originally
4143 * accounted for in slist_size, we have to ajust it down
4144 * before freeing the scatter list.
4147 ipc_kmsg_free_scatter(
4148 mach_msg_body_t
*slist
,
4149 mach_msg_size_t slist_size
)
4151 #if defined(__LP64__)
4152 panic("%s called; halting!", __func__
);
4155 slist_size
-= (mach_msg_size_t
)sizeof(mach_msg_header_t
);
4156 kfree(slist
, slist_size
);
4161 * Routine: ipc_kmsg_copyout_to_kernel
4163 * Copies out the destination and reply ports in the message.
4164 * Leaves all other rights and memory in the message alone.
4168 * Derived from ipc_kmsg_copyout_dest.
4169 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
4170 * We really do want to save rights and memory.
4174 ipc_kmsg_copyout_to_kernel(
4180 mach_msg_type_name_t dest_type
;
4181 mach_msg_type_name_t reply_type
;
4182 mach_port_name_t dest_name
, reply_name
;
4184 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
4185 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
4186 dest_type
= MACH_MSGH_BITS_REMOTE(kmsg
->ikm_header
->msgh_bits
);
4187 reply_type
= MACH_MSGH_BITS_LOCAL(kmsg
->ikm_header
->msgh_bits
);
4189 assert(IO_VALID(dest
));
4192 if (io_active(dest
)) {
4193 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
4194 /* dest is unlocked */
4198 dest_name
= MACH_PORT_DEAD
;
4201 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
4203 kmsg
->ikm_header
->msgh_bits
=
4204 (MACH_MSGH_BITS_OTHER(kmsg
->ikm_header
->msgh_bits
) |
4205 MACH_MSGH_BITS(reply_type
, dest_type
));
4206 kmsg
->ikm_header
->msgh_local_port
= CAST_MACH_NAME_TO_PORT(dest_name
);
4207 kmsg
->ikm_header
->msgh_remote_port
= CAST_MACH_NAME_TO_PORT(reply_name
);
4210 #if IKM_SUPPORT_LEGACY
4212 ipc_kmsg_copyout_to_kernel_legacy(
4218 mach_msg_type_name_t dest_type
;
4219 mach_msg_type_name_t reply_type
;
4220 mach_port_name_t dest_name
, reply_name
;
4222 dest
= (ipc_object_t
) kmsg
->ikm_header
->msgh_remote_port
;
4223 reply
= (ipc_object_t
) kmsg
->ikm_header
->msgh_local_port
;
4224 dest_type
= MACH_MSGH_BITS_REMOTE(kmsg
->ikm_header
->msgh_bits
);
4225 reply_type
= MACH_MSGH_BITS_LOCAL(kmsg
->ikm_header
->msgh_bits
);
4227 assert(IO_VALID(dest
));
4230 if (io_active(dest
)) {
4231 ipc_object_copyout_dest(space
, dest
, dest_type
, &dest_name
);
4232 /* dest is unlocked */
4236 dest_name
= MACH_PORT_DEAD
;
4239 reply_name
= CAST_MACH_PORT_TO_NAME(reply
);
4241 kmsg
->ikm_header
->msgh_bits
=
4242 (MACH_MSGH_BITS_OTHER(kmsg
->ikm_header
->msgh_bits
) |
4243 MACH_MSGH_BITS(reply_type
, dest_type
));
4244 kmsg
->ikm_header
->msgh_local_port
= CAST_MACH_NAME_TO_PORT(dest_name
);
4245 kmsg
->ikm_header
->msgh_remote_port
= CAST_MACH_NAME_TO_PORT(reply_name
);
4247 mach_msg_descriptor_t
*saddr
;
4248 mach_msg_legacy_descriptor_t
*daddr
;
4249 mach_msg_type_number_t i
, count
= ((mach_msg_base_t
*)kmsg
->ikm_header
)->body
.msgh_descriptor_count
;
4250 saddr
= (mach_msg_descriptor_t
*) (((mach_msg_base_t
*)kmsg
->ikm_header
) + 1);
4251 saddr
= &saddr
[count
-1];
4252 daddr
= (mach_msg_legacy_descriptor_t
*)&saddr
[count
];
4255 vm_offset_t dsc_adjust
= 0;
4257 for (i
= 0; i
< count
; i
++, saddr
--, daddr
--) {
4258 switch (saddr
->type
.type
) {
4259 case MACH_MSG_PORT_DESCRIPTOR
: {
4260 mach_msg_port_descriptor_t
*dsc
= &saddr
->port
;
4261 mach_msg_legacy_port_descriptor_t
*dest_dsc
= &daddr
->port
;
4263 mach_port_t name
= dsc
->name
;
4264 mach_msg_type_name_t disposition
= dsc
->disposition
;
4266 dest_dsc
->name
= CAST_MACH_PORT_TO_NAME(name
);
4267 dest_dsc
->disposition
= disposition
;
4268 dest_dsc
->type
= MACH_MSG_PORT_DESCRIPTOR
;
4271 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
4272 case MACH_MSG_OOL_DESCRIPTOR
: {
4273 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t
4274 * so we don't need to do anything special. */
4276 mach_msg_ool_descriptor_t
*source_dsc
= (typeof(source_dsc
))&saddr
->out_of_line
;
4278 mach_msg_ool_descriptor32_t
*dest_dsc
= &daddr
->out_of_line32
;
4280 vm_offset_t address
= (vm_offset_t
)source_dsc
->address
;
4281 vm_size_t size
= source_dsc
->size
;
4282 boolean_t deallocate
= source_dsc
->deallocate
;
4283 mach_msg_copy_options_t copy
= source_dsc
->copy
;
4284 mach_msg_descriptor_type_t type
= source_dsc
->type
;
4286 dest_dsc
->address
= address
;
4287 dest_dsc
->size
= size
;
4288 dest_dsc
->deallocate
= deallocate
;
4289 dest_dsc
->copy
= copy
;
4290 dest_dsc
->type
= type
;
4293 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: {
4294 mach_msg_ool_ports_descriptor_t
*source_dsc
= (typeof(source_dsc
))&saddr
->ool_ports
;
4296 mach_msg_ool_ports_descriptor32_t
*dest_dsc
= &daddr
->ool_ports32
;
4298 vm_offset_t address
= (vm_offset_t
)source_dsc
->address
;
4299 vm_size_t port_count
= source_dsc
->count
;
4300 boolean_t deallocate
= source_dsc
->deallocate
;
4301 mach_msg_copy_options_t copy
= source_dsc
->copy
;
4302 mach_msg_descriptor_type_t type
= source_dsc
->type
;
4304 dest_dsc
->address
= address
;
4305 dest_dsc
->count
= port_count
;
4306 dest_dsc
->deallocate
= deallocate
;
4307 dest_dsc
->copy
= copy
;
4308 dest_dsc
->type
= type
;
4313 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
4314 #endif /* MACH_ASSERT */
4320 dsc_adjust
= 4*count
;
4321 memmove((char *)((vm_offset_t
)kmsg
->ikm_header
+ dsc_adjust
), kmsg
->ikm_header
, sizeof(mach_msg_base_t
));
4322 kmsg
->ikm_header
= (mach_msg_header_t
*)((vm_offset_t
)kmsg
->ikm_header
+ dsc_adjust
);
4323 /* Update the message size for the smaller user representation */
4324 kmsg
->ikm_header
->msgh_size
-= dsc_adjust
;
4327 #endif /* IKM_SUPPORT_LEGACY */
4329 mach_msg_trailer_size_t
4330 ipc_kmsg_add_trailer(ipc_kmsg_t kmsg
, ipc_space_t space
,
4331 mach_msg_option_t option
, thread_t thread
,
4332 mach_port_seqno_t seqno
, boolean_t minimal_trailer
,
4333 mach_vm_offset_t context
)
4335 mach_msg_max_trailer_t
*trailer
;
4338 trailer
= (mach_msg_max_trailer_t
*)
4339 ((vm_offset_t
)kmsg
->ikm_header
+
4340 round_msg(kmsg
->ikm_header
->msgh_size
));
4342 if (!(option
& MACH_RCV_TRAILER_MASK
)) {
4343 return trailer
->msgh_trailer_size
;
4346 trailer
->msgh_seqno
= seqno
;
4347 trailer
->msgh_context
= context
;
4348 trailer
->msgh_trailer_size
= REQUESTED_TRAILER_SIZE(thread_is_64bit(thread
), option
);
4350 if (minimal_trailer
) {
4354 if (MACH_RCV_TRAILER_ELEMENTS(option
) >=
4355 MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV
)){
4356 #if CONFIG_MACF_MACH
4357 if (kmsg
->ikm_sender
!= NULL
&&
4358 IP_VALID(kmsg
->ikm_header
->msgh_remote_port
) &&
4359 mac_port_check_method(kmsg
->ikm_sender
,
4360 &kmsg
->ikm_sender
->maclabel
,
4361 &kmsg
->ikm_header
->msgh_remote_port
->ip_label
,
4362 kmsg
->ikm_header
->msgh_id
) == 0)
4363 trailer
->msgh_ad
= 1;
4366 trailer
->msgh_ad
= 0;
4370 * The ipc_kmsg_t holds a reference to the label of a label
4371 * handle, not the port. We must get a reference to the port
4372 * and a send right to copyout to the receiver.
4375 if (option
& MACH_RCV_TRAILER_ELEMENTS (MACH_RCV_TRAILER_LABELS
)) {
4376 #if CONFIG_MACF_MACH
4377 if (kmsg
->ikm_sender
!= NULL
) {
4378 ipc_labelh_t lh
= kmsg
->ikm_sender
->label
;
4381 ip_lock(lh
->lh_port
);
4382 lh
->lh_port
->ip_mscount
++;
4383 lh
->lh_port
->ip_srights
++;
4384 ip_reference(lh
->lh_port
);
4385 ip_unlock(lh
->lh_port
);
4387 kr
= ipc_object_copyout(space
, (ipc_object_t
)lh
->lh_port
,
4388 MACH_MSG_TYPE_PORT_SEND
, 0,
4389 &trailer
->msgh_labels
.sender
);
4390 if (kr
!= KERN_SUCCESS
) {
4391 ip_release(lh
->lh_port
);
4392 trailer
->msgh_labels
.sender
= 0;
4395 trailer
->msgh_labels
.sender
= 0;
4399 trailer
->msgh_labels
.sender
= 0;
4406 return trailer
->msgh_trailer_size
;