]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ipc/ipc_kmsg.c
xnu-517.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_kmsg.c
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * @OSF_COPYRIGHT@
27 */
28 /*
29 * Mach Operating System
30 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
31 * All Rights Reserved.
32 *
33 * Permission to use, copy, modify and distribute this software and its
34 * documentation is hereby granted, provided that both the copyright
35 * notice and this permission notice appear in all copies of the
36 * software, derivative works or modified versions, and any portions
37 * thereof, and that both notices appear in supporting documentation.
38 *
39 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
40 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
41 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 *
43 * Carnegie Mellon requests users of this software to return to
44 *
45 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
46 * School of Computer Science
47 * Carnegie Mellon University
48 * Pittsburgh PA 15213-3890
49 *
50 * any improvements or extensions that they make and grant Carnegie Mellon
51 * the rights to redistribute these changes.
52 */
53 /*
54 */
55 /*
56 * File: ipc/ipc_kmsg.c
57 * Author: Rich Draves
58 * Date: 1989
59 *
60 * Operations on kernel messages.
61 */
62
63 #include <cpus.h>
64 #include <norma_vm.h>
65
66 #include <mach/boolean.h>
67 #include <mach/kern_return.h>
68 #include <mach/message.h>
69 #include <mach/port.h>
70 #include <mach/vm_statistics.h>
71 #include <kern/assert.h>
72 #include <kern/kalloc.h>
73 #include <kern/thread.h>
74 #include <kern/sched_prim.h>
75 #include <kern/spl.h>
76 #include <kern/misc_protos.h>
77 #include <kern/counters.h>
78 #include <vm/vm_map.h>
79 #include <vm/vm_object.h>
80 #include <vm/vm_kern.h>
81 #include <ipc/port.h>
82 #include <ipc/ipc_entry.h>
83 #include <ipc/ipc_kmsg.h>
84 #include <ipc/ipc_notify.h>
85 #include <ipc/ipc_object.h>
86 #include <ipc/ipc_space.h>
87 #include <ipc/ipc_port.h>
88 #include <ipc/ipc_right.h>
89 #include <ipc/ipc_hash.h>
90 #include <ipc/ipc_table.h>
91
92 #include <string.h>
93
94 #ifdef ppc
95 #include <ppc/Firmware.h>
96 #include <ppc/low_trace.h>
97 #endif
98
99
100 extern vm_map_t ipc_kernel_copy_map;
101 extern vm_size_t ipc_kmsg_max_vm_space;
102 extern vm_size_t msg_ool_size_small;
103
104 #define MSG_OOL_SIZE_SMALL msg_ool_size_small
105
106
107 /*
108 * Forward declarations
109 */
110
111 void ipc_kmsg_clean(
112 ipc_kmsg_t kmsg);
113
114 void ipc_kmsg_clean_body(
115 ipc_kmsg_t kmsg,
116 mach_msg_type_number_t number);
117
118 void ipc_kmsg_clean_partial(
119 ipc_kmsg_t kmsg,
120 mach_msg_type_number_t number,
121 vm_offset_t paddr,
122 vm_size_t length);
123
124 mach_msg_return_t ipc_kmsg_copyout_body(
125 ipc_kmsg_t kmsg,
126 ipc_space_t space,
127 vm_map_t map,
128 mach_msg_body_t *slist);
129
130 mach_msg_return_t ipc_kmsg_copyin_body(
131 ipc_kmsg_t kmsg,
132 ipc_space_t space,
133 vm_map_t map);
134
135 void ikm_cache_init(void);
136 /*
137 * We keep a per-processor cache of kernel message buffers.
138 * The cache saves the overhead/locking of using kalloc/kfree.
139 * The per-processor cache seems to miss less than a per-thread cache,
140 * and it also uses less memory. Access to the cache doesn't
141 * require locking.
142 */
143 #define IKM_STASH 16 /* # of cache entries per cpu */
144 ipc_kmsg_t ipc_kmsg_cache[ NCPUS ][ IKM_STASH ];
145 unsigned int ipc_kmsg_cache_avail[NCPUS];
146
147 /*
148 * Routine: ipc_kmsg_init
149 * Purpose:
150 * Initialize the kmsg system. For each CPU, we need to
151 * pre-stuff the kmsg cache.
152 */
153 void
154 ipc_kmsg_init()
155 {
156 unsigned int cpu, i;
157
158 for (cpu = 0; cpu < NCPUS; ++cpu) {
159 for (i = 0; i < IKM_STASH; ++i) {
160 ipc_kmsg_t kmsg;
161
162 kmsg = (ipc_kmsg_t)
163 kalloc(ikm_plus_overhead(IKM_SAVED_MSG_SIZE));
164 if (kmsg == IKM_NULL)
165 panic("ipc_kmsg_init");
166 ikm_init(kmsg, IKM_SAVED_MSG_SIZE);
167 ipc_kmsg_cache[cpu][i] = kmsg;
168 }
169 ipc_kmsg_cache_avail[cpu] = IKM_STASH;
170 }
171 }
172
173 /*
174 * Routine: ipc_kmsg_alloc
175 * Purpose:
176 * Allocate a kernel message structure. If we can get one from
177 * the cache, that is best. Otherwise, allocate a new one.
178 * Conditions:
179 * Nothing locked.
180 */
181 ipc_kmsg_t
182 ipc_kmsg_alloc(
183 mach_msg_size_t msg_and_trailer_size)
184 {
185 ipc_kmsg_t kmsg;
186
187 if ((msg_and_trailer_size <= IKM_SAVED_MSG_SIZE)) {
188 unsigned int cpu, i;
189
190 disable_preemption();
191 cpu = cpu_number();
192 if ((i = ipc_kmsg_cache_avail[cpu]) > 0) {
193 assert(i <= IKM_STASH);
194 kmsg = ipc_kmsg_cache[cpu][--i];
195 ipc_kmsg_cache_avail[cpu] = i;
196 ikm_check_init(kmsg, IKM_SAVED_MSG_SIZE);
197 enable_preemption();
198 return (kmsg);
199 }
200 enable_preemption();
201 }
202
203 /* round up for ikm_cache */
204 if (msg_and_trailer_size < IKM_SAVED_MSG_SIZE)
205 msg_and_trailer_size = IKM_SAVED_MSG_SIZE;
206
207 kmsg = (ipc_kmsg_t)kalloc(ikm_plus_overhead(msg_and_trailer_size));
208 if (kmsg != IKM_NULL) {
209 ikm_init(kmsg, msg_and_trailer_size);
210 }
211 return(kmsg);
212 }
213
214 /*
215 * Routine: ipc_kmsg_free
216 * Purpose:
217 * Free a kernel message buffer. If the kms is preallocated
218 * to a port, just "put it back (marked unused)." We have to
219 * do this with the port locked. The port may have its hold
220 * on our message released. In that case, we have to just
221 * revert the message to a traditional one and free it normally.
222 * Conditions:
223 * Nothing locked.
224 */
225
226 void
227 ipc_kmsg_free(
228 ipc_kmsg_t kmsg)
229 {
230 mach_msg_size_t size = kmsg->ikm_size;
231 ipc_port_t port;
232
233 /*
234 * Check to see if the message is bound to the port. If so,
235 * mark it not in use. If the port isn't already dead, then
236 * leave the message associated with it. Otherwise, free it
237 * (not to the cache).
238 */
239 port = ikm_prealloc_inuse_port(kmsg);
240 if (port != IP_NULL) {
241 ip_lock(port);
242 ikm_prealloc_clear_inuse(kmsg, port);
243 if (ip_active(port) && (port->ip_premsg == kmsg)) {
244 assert(IP_PREALLOC(port));
245 ip_unlock(port);
246 return;
247 }
248 ip_check_unlock(port); /* May be last reference */
249 goto free_it;
250 }
251
252 /*
253 * Peek and see if it has to go back in the cache.
254 */
255 if (kmsg->ikm_size == IKM_SAVED_MSG_SIZE &&
256 ipc_kmsg_cache_avail[cpu_number()] < IKM_STASH) {
257 unsigned int cpu, i;
258
259 disable_preemption();
260 cpu = cpu_number();
261
262 i = ipc_kmsg_cache_avail[cpu];
263 if (i < IKM_STASH) {
264 assert(i >= 0);
265 ipc_kmsg_cache[cpu][i] = kmsg;
266 ipc_kmsg_cache_avail[cpu] = i + 1;
267 enable_preemption();
268 return;
269 }
270 enable_preemption();
271 }
272
273 free_it:
274 kfree((vm_offset_t) kmsg, ikm_plus_overhead(size));
275 }
276
277
278 /*
279 * Routine: ipc_kmsg_enqueue
280 * Purpose:
281 * Enqueue a kmsg.
282 */
283
284 void
285 ipc_kmsg_enqueue(
286 ipc_kmsg_queue_t queue,
287 ipc_kmsg_t kmsg)
288 {
289 ipc_kmsg_enqueue_macro(queue, kmsg);
290 }
291
292 /*
293 * Routine: ipc_kmsg_dequeue
294 * Purpose:
295 * Dequeue and return a kmsg.
296 */
297
298 ipc_kmsg_t
299 ipc_kmsg_dequeue(
300 ipc_kmsg_queue_t queue)
301 {
302 ipc_kmsg_t first;
303
304 first = ipc_kmsg_queue_first(queue);
305
306 if (first != IKM_NULL)
307 ipc_kmsg_rmqueue_first_macro(queue, first);
308
309 return first;
310 }
311
312 /*
313 * Routine: ipc_kmsg_rmqueue
314 * Purpose:
315 * Pull a kmsg out of a queue.
316 */
317
318 void
319 ipc_kmsg_rmqueue(
320 ipc_kmsg_queue_t queue,
321 ipc_kmsg_t kmsg)
322 {
323 ipc_kmsg_t next, prev;
324
325 assert(queue->ikmq_base != IKM_NULL);
326
327 next = kmsg->ikm_next;
328 prev = kmsg->ikm_prev;
329
330 if (next == kmsg) {
331 assert(prev == kmsg);
332 assert(queue->ikmq_base == kmsg);
333
334 queue->ikmq_base = IKM_NULL;
335 } else {
336 if (queue->ikmq_base == kmsg)
337 queue->ikmq_base = next;
338
339 next->ikm_prev = prev;
340 prev->ikm_next = next;
341 }
342 /* XXX Temporary debug logic */
343 assert(kmsg->ikm_next = IKM_BOGUS);
344 assert(kmsg->ikm_prev = IKM_BOGUS);
345 }
346
347 /*
348 * Routine: ipc_kmsg_queue_next
349 * Purpose:
350 * Return the kmsg following the given kmsg.
351 * (Or IKM_NULL if it is the last one in the queue.)
352 */
353
354 ipc_kmsg_t
355 ipc_kmsg_queue_next(
356 ipc_kmsg_queue_t queue,
357 ipc_kmsg_t kmsg)
358 {
359 ipc_kmsg_t next;
360
361 assert(queue->ikmq_base != IKM_NULL);
362
363 next = kmsg->ikm_next;
364 if (queue->ikmq_base == next)
365 next = IKM_NULL;
366
367 return next;
368 }
369
370 /*
371 * Routine: ipc_kmsg_destroy
372 * Purpose:
373 * Destroys a kernel message. Releases all rights,
374 * references, and memory held by the message.
375 * Frees the message.
376 * Conditions:
377 * No locks held.
378 */
379
380 void
381 ipc_kmsg_destroy(
382 ipc_kmsg_t kmsg)
383 {
384 ipc_kmsg_queue_t queue;
385 boolean_t empty;
386
387 /*
388 * ipc_kmsg_clean can cause more messages to be destroyed.
389 * Curtail recursion by queueing messages. If a message
390 * is already queued, then this is a recursive call.
391 */
392
393 queue = &(current_thread()->ith_messages);
394 empty = ipc_kmsg_queue_empty(queue);
395 ipc_kmsg_enqueue(queue, kmsg);
396
397 if (empty) {
398 /* must leave kmsg in queue while cleaning it */
399
400 while ((kmsg = ipc_kmsg_queue_first(queue)) != IKM_NULL) {
401 ipc_kmsg_clean(kmsg);
402 ipc_kmsg_rmqueue(queue, kmsg);
403 ipc_kmsg_free(kmsg);
404 }
405 }
406 }
407
408 /*
409 * Routine: ipc_kmsg_destroy_dest
410 * Purpose:
411 * Destroys a kernel message. Releases all rights,
412 * references, and memory held by the message (including
413 * the destination port reference.
414 * Frees the message.
415 * Conditions:
416 * No locks held.
417 */
418
419 ipc_kmsg_destroy_dest(
420 ipc_kmsg_t kmsg)
421 {
422 ipc_port_t port;
423
424 port = kmsg->ikm_header.msgh_remote_port;
425
426 ipc_port_release(port);
427 kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
428 ipc_kmsg_destroy(kmsg);
429 }
430
431 /*
432 * Routine: ipc_kmsg_clean_body
433 * Purpose:
434 * Cleans the body of a kernel message.
435 * Releases all rights, references, and memory.
436 *
437 * Conditions:
438 * No locks held.
439 */
440
441 void
442 ipc_kmsg_clean_body(
443 ipc_kmsg_t kmsg,
444 mach_msg_type_number_t number)
445 {
446 mach_msg_descriptor_t *saddr, *eaddr;
447
448 if ( number == 0 )
449 return;
450
451 saddr = (mach_msg_descriptor_t *)
452 ((mach_msg_base_t *) &kmsg->ikm_header + 1);
453 eaddr = saddr + number;
454
455 for ( ; saddr < eaddr; saddr++ ) {
456
457 switch (saddr->type.type) {
458
459 case MACH_MSG_PORT_DESCRIPTOR: {
460 mach_msg_port_descriptor_t *dsc;
461
462 dsc = &saddr->port;
463
464 /*
465 * Destroy port rights carried in the message
466 */
467 if (!IO_VALID((ipc_object_t) dsc->name))
468 continue;
469 ipc_object_destroy((ipc_object_t) dsc->name, dsc->disposition);
470 break;
471 }
472 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
473 case MACH_MSG_OOL_DESCRIPTOR : {
474 mach_msg_ool_descriptor_t *dsc;
475
476 dsc = &saddr->out_of_line;
477
478 /*
479 * Destroy memory carried in the message
480 */
481 if (dsc->size == 0) {
482 assert(dsc->address == (void *) 0);
483 } else {
484 vm_map_copy_discard((vm_map_copy_t) dsc->address);
485 }
486 break;
487 }
488 case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
489 ipc_object_t *objects;
490 mach_msg_type_number_t j;
491 mach_msg_ool_ports_descriptor_t *dsc;
492
493 dsc = &saddr->ool_ports;
494 objects = (ipc_object_t *) dsc->address;
495
496 if (dsc->count == 0) {
497 break;
498 }
499
500 assert(objects != (ipc_object_t *) 0);
501
502 /* destroy port rights carried in the message */
503
504 for (j = 0; j < dsc->count; j++) {
505 ipc_object_t object = objects[j];
506
507 if (!IO_VALID(object))
508 continue;
509
510 ipc_object_destroy(object, dsc->disposition);
511 }
512
513 /* destroy memory carried in the message */
514
515 assert(dsc->count != 0);
516
517 kfree((vm_offset_t) dsc->address,
518 (vm_size_t) dsc->count * sizeof(mach_port_name_t));
519 break;
520 }
521 default : {
522 printf("cleanup: don't understand this type of descriptor\n");
523 }
524 }
525 }
526 }
527
528 /*
529 * Routine: ipc_kmsg_clean_partial
530 * Purpose:
531 * Cleans a partially-acquired kernel message.
532 * number is the index of the type descriptor
533 * in the body of the message that contained the error.
534 * If dolast, the memory and port rights in this last
535 * type spec are also cleaned. In that case, number
536 * specifies the number of port rights to clean.
537 * Conditions:
538 * Nothing locked.
539 */
540
541 void
542 ipc_kmsg_clean_partial(
543 ipc_kmsg_t kmsg,
544 mach_msg_type_number_t number,
545 vm_offset_t paddr,
546 vm_size_t length)
547 {
548 ipc_object_t object;
549 mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
550
551 object = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
552 assert(IO_VALID(object));
553 ipc_object_destroy(object, MACH_MSGH_BITS_REMOTE(mbits));
554
555 object = (ipc_object_t) kmsg->ikm_header.msgh_local_port;
556 if (IO_VALID(object))
557 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
558
559 if (paddr) {
560 (void) vm_deallocate(ipc_kernel_copy_map, paddr, length);
561 }
562
563 ipc_kmsg_clean_body(kmsg, number);
564 }
565
566 /*
567 * Routine: ipc_kmsg_clean
568 * Purpose:
569 * Cleans a kernel message. Releases all rights,
570 * references, and memory held by the message.
571 * Conditions:
572 * No locks held.
573 */
574
575 void
576 ipc_kmsg_clean(
577 ipc_kmsg_t kmsg)
578 {
579 ipc_object_t object;
580 mach_msg_bits_t mbits;
581
582 mbits = kmsg->ikm_header.msgh_bits;
583 object = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
584 if (IO_VALID(object))
585 ipc_object_destroy(object, MACH_MSGH_BITS_REMOTE(mbits));
586
587 object = (ipc_object_t) kmsg->ikm_header.msgh_local_port;
588 if (IO_VALID(object))
589 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits));
590
591 if (mbits & MACH_MSGH_BITS_COMPLEX) {
592 mach_msg_body_t *body;
593
594 body = (mach_msg_body_t *) (&kmsg->ikm_header + 1);
595 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count);
596 }
597 }
598
599 /*
600 * Routine: ipc_kmsg_set_prealloc
601 * Purpose:
602 * Assign a kmsg as a preallocated message buffer to a port.
603 * Conditions:
604 * port locked.
605 */
606
607 void
608 ipc_kmsg_set_prealloc(
609 ipc_kmsg_t kmsg,
610 ipc_port_t port)
611 {
612 assert(kmsg->ikm_prealloc == IP_NULL);
613
614 kmsg->ikm_prealloc = IP_NULL;
615 IP_SET_PREALLOC(port, kmsg);
616 }
617
618 /*
619 * Routine: ipc_kmsg_clear_prealloc
620 * Purpose:
621 * Release the Assignment of a preallocated message buffer from a port.
622 * Conditions:
623 * port locked.
624 */
625 void
626 ipc_kmsg_clear_prealloc(
627 ipc_kmsg_t kmsg,
628 ipc_port_t port)
629 {
630 assert(kmsg->ikm_prealloc == port);
631
632 kmsg->ikm_prealloc = IP_NULL;
633 IP_CLEAR_PREALLOC(port, kmsg);
634 }
635
636 /*
637 * Routine: ipc_kmsg_get
638 * Purpose:
639 * Allocates a kernel message buffer.
640 * Copies a user message to the message buffer.
641 * Conditions:
642 * Nothing locked.
643 * Returns:
644 * MACH_MSG_SUCCESS Acquired a message buffer.
645 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header.
646 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple.
647 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
648 * MACH_SEND_INVALID_DATA Couldn't copy message data.
649 */
650
651 mach_msg_return_t
652 ipc_kmsg_get(
653 mach_msg_header_t *msg,
654 mach_msg_size_t size,
655 ipc_kmsg_t *kmsgp)
656 {
657 mach_msg_size_t msg_and_trailer_size;
658 ipc_kmsg_t kmsg;
659 mach_msg_max_trailer_t *trailer;
660 mach_port_name_t dest_name;
661 ipc_entry_t dest_entry;
662 ipc_port_t dest_port;
663
664 if ((size < sizeof(mach_msg_header_t)) || (size & 3))
665 return MACH_SEND_MSG_TOO_SMALL;
666
667 msg_and_trailer_size = size + MAX_TRAILER_SIZE;
668
669 kmsg = ipc_kmsg_alloc(msg_and_trailer_size);
670
671 if (kmsg == IKM_NULL)
672 return MACH_SEND_NO_BUFFER;
673
674 if (copyinmsg((char *) msg, (char *) &kmsg->ikm_header, size)) {
675 ipc_kmsg_free(kmsg);
676 return MACH_SEND_INVALID_DATA;
677 }
678
679 kmsg->ikm_header.msgh_size = size;
680
681 /*
682 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
683 * However, the internal size field of the trailer (msgh_trailer_size)
684 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize
685 * the cases where no implicit data is requested.
686 */
687 trailer = (mach_msg_max_trailer_t *) ((vm_offset_t)&kmsg->ikm_header + size);
688 trailer->msgh_sender = current_act()->task->sec_token;
689 trailer->msgh_audit = current_act()->task->audit_token;
690 trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
691 trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
692
693 #ifdef ppc
694 if(trcWork.traceMask) dbgTrace((unsigned int)kmsg->ikm_header.msgh_id,
695 (unsigned int)kmsg->ikm_header.msgh_remote_port,
696 (unsigned int)kmsg->ikm_header.msgh_local_port, 0);
697 #endif
698 *kmsgp = kmsg;
699 return MACH_MSG_SUCCESS;
700 }
701
702 /*
703 * Routine: ipc_kmsg_get_from_kernel
704 * Purpose:
705 * Allocates a kernel message buffer.
706 * Copies a kernel message to the message buffer.
707 * Only resource errors are allowed.
708 * Conditions:
709 * Nothing locked.
710 * Ports in header are ipc_port_t.
711 * Returns:
712 * MACH_MSG_SUCCESS Acquired a message buffer.
713 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer.
714 */
715
716 mach_msg_return_t
717 ipc_kmsg_get_from_kernel(
718 mach_msg_header_t *msg,
719 mach_msg_size_t size,
720 ipc_kmsg_t *kmsgp)
721 {
722 ipc_kmsg_t kmsg;
723 mach_msg_size_t msg_and_trailer_size;
724 mach_msg_max_trailer_t *trailer;
725 ipc_port_t dest_port;
726
727 assert(size >= sizeof(mach_msg_header_t));
728 assert((size & 3) == 0);
729
730 assert(IP_VALID((ipc_port_t) msg->msgh_remote_port));
731 dest_port = (ipc_port_t)msg->msgh_remote_port;
732
733 msg_and_trailer_size = size + MAX_TRAILER_SIZE;
734
735 /*
736 * See if the port has a pre-allocated kmsg for kernel
737 * clients. These are set up for those kernel clients
738 * which cannot afford to wait.
739 */
740 if (IP_PREALLOC(dest_port)) {
741 ip_lock(dest_port);
742 if (!ip_active(dest_port)) {
743 ip_unlock(dest_port);
744 return MACH_SEND_NO_BUFFER;
745 }
746 assert(IP_PREALLOC(dest_port));
747 kmsg = dest_port->ip_premsg;
748 if (msg_and_trailer_size > kmsg->ikm_size) {
749 ip_unlock(dest_port);
750 return MACH_SEND_TOO_LARGE;
751 }
752 if (ikm_prealloc_inuse(kmsg)) {
753 ip_unlock(dest_port);
754 return MACH_SEND_NO_BUFFER;
755 }
756 ikm_prealloc_set_inuse(kmsg, dest_port);
757 ip_unlock(dest_port);
758 } else {
759 kmsg = ipc_kmsg_alloc(msg_and_trailer_size);
760 if (kmsg == IKM_NULL)
761 return MACH_SEND_NO_BUFFER;
762 }
763
764 (void) memcpy((void *) &kmsg->ikm_header, (const void *) msg, size);
765
766 kmsg->ikm_header.msgh_size = size;
767
768 /*
769 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE)
770 * However, the internal size field of the trailer (msgh_trailer_size)
771 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to
772 * optimize the cases where no implicit data is requested.
773 */
774 trailer = (mach_msg_max_trailer_t *)
775 ((vm_offset_t)&kmsg->ikm_header + size);
776 trailer->msgh_sender = KERNEL_SECURITY_TOKEN;
777 trailer->msgh_audit = KERNEL_AUDIT_TOKEN;
778 trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
779 trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE;
780
781 *kmsgp = kmsg;
782 return MACH_MSG_SUCCESS;
783 }
784
785 /*
786 * Routine: ipc_kmsg_send
787 * Purpose:
788 * Send a message. The message holds a reference
789 * for the destination port in the msgh_remote_port field.
790 *
791 * If unsuccessful, the caller still has possession of
792 * the message and must do something with it. If successful,
793 * the message is queued, given to a receiver, destroyed,
794 * or handled directly by the kernel via mach_msg.
795 * Conditions:
796 * Nothing locked.
797 * Returns:
798 * MACH_MSG_SUCCESS The message was accepted.
799 * MACH_SEND_TIMED_OUT Caller still has message.
800 * MACH_SEND_INTERRUPTED Caller still has message.
801 */
802 mach_msg_return_t
803 ipc_kmsg_send(
804 ipc_kmsg_t kmsg,
805 mach_msg_option_t option,
806 mach_msg_timeout_t timeout)
807 {
808 kern_return_t save_wait_result;
809
810 ipc_port_t port;
811 port = (ipc_port_t) kmsg->ikm_header.msgh_remote_port;
812 assert(IP_VALID(port));
813
814 ip_lock(port);
815
816 if (port->ip_receiver == ipc_space_kernel) {
817
818 /*
819 * We can check ip_receiver == ipc_space_kernel
820 * before checking that the port is active because
821 * ipc_port_dealloc_kernel clears ip_receiver
822 * before destroying a kernel port.
823 */
824 assert(ip_active(port));
825 port->ip_messages.imq_seqno++;
826 ip_unlock(port);
827
828 current_task()->messages_sent++;
829
830 /*
831 * Call the server routine, and get the reply message to send.
832 */
833 kmsg = ipc_kobject_server(kmsg);
834 if (kmsg == IKM_NULL)
835 return MACH_MSG_SUCCESS;
836
837 port = (ipc_port_t) kmsg->ikm_header.msgh_remote_port;
838 assert(IP_VALID(port));
839 ip_lock(port);
840 /* fall thru with reply - same options */
841 }
842
843 /*
844 * Can't deliver to a dead port.
845 * However, we can pretend it got sent
846 * and was then immediately destroyed.
847 */
848 if (!ip_active(port)) {
849 /*
850 * We can't let ipc_kmsg_destroy deallocate
851 * the port right, because we might end up
852 * in an infinite loop trying to deliver
853 * a send-once notification.
854 */
855
856 ip_release(port);
857 ip_check_unlock(port);
858 kmsg->ikm_header.msgh_remote_port = MACH_PORT_NULL;
859 ipc_kmsg_destroy(kmsg);
860 return MACH_MSG_SUCCESS;
861 }
862
863 if (kmsg->ikm_header.msgh_bits & MACH_MSGH_BITS_CIRCULAR) {
864 ip_unlock(port);
865
866 /* don't allow the creation of a circular loop */
867
868 ipc_kmsg_destroy(kmsg);
869 return MACH_MSG_SUCCESS;
870 }
871
872 /*
873 * We have a valid message and a valid reference on the port.
874 * we can unlock the port and call mqueue_send() on it's message
875 * queue.
876 */
877 ip_unlock(port);
878 return (ipc_mqueue_send(&port->ip_messages, kmsg, option, timeout));
879 }
880
881 /*
882 * Routine: ipc_kmsg_put
883 * Purpose:
884 * Copies a message buffer to a user message.
885 * Copies only the specified number of bytes.
886 * Frees the message buffer.
887 * Conditions:
888 * Nothing locked. The message buffer must have clean
889 * header fields.
890 * Returns:
891 * MACH_MSG_SUCCESS Copied data out of message buffer.
892 * MACH_RCV_INVALID_DATA Couldn't copy to user message.
893 */
894
895 mach_msg_return_t
896 ipc_kmsg_put(
897 mach_msg_header_t *msg,
898 ipc_kmsg_t kmsg,
899 mach_msg_size_t size)
900 {
901 mach_msg_return_t mr;
902
903 if (copyoutmsg((const char *) &kmsg->ikm_header, (char *) msg, size))
904 mr = MACH_RCV_INVALID_DATA;
905 else
906 mr = MACH_MSG_SUCCESS;
907
908 ipc_kmsg_free(kmsg);
909 return mr;
910 }
911
912 /*
913 * Routine: ipc_kmsg_put_to_kernel
914 * Purpose:
915 * Copies a message buffer to a kernel message.
916 * Frees the message buffer.
917 * No errors allowed.
918 * Conditions:
919 * Nothing locked.
920 */
921
922 void
923 ipc_kmsg_put_to_kernel(
924 mach_msg_header_t *msg,
925 ipc_kmsg_t kmsg,
926 mach_msg_size_t size)
927 {
928 (void) memcpy((void *) msg, (const void *) &kmsg->ikm_header, size);
929
930 ipc_kmsg_free(kmsg);
931 }
932
933 /*
934 * Routine: ipc_kmsg_copyin_header
935 * Purpose:
936 * "Copy-in" port rights in the header of a message.
937 * Operates atomically; if it doesn't succeed the
938 * message header and the space are left untouched.
939 * If it does succeed the remote/local port fields
940 * contain object pointers instead of port names,
941 * and the bits field is updated. The destination port
942 * will be a valid port pointer.
943 *
944 * The notify argument implements the MACH_SEND_CANCEL option.
945 * If it is not MACH_PORT_NULL, it should name a receive right.
946 * If the processing of the destination port would generate
947 * a port-deleted notification (because the right for the
948 * destination port is destroyed and it had a request for
949 * a dead-name notification registered), and the port-deleted
950 * notification would be sent to the named receive right,
951 * then it isn't sent and the send-once right for the notify
952 * port is quietly destroyed.
953 *
954 * Conditions:
955 * Nothing locked.
956 * Returns:
957 * MACH_MSG_SUCCESS Successful copyin.
958 * MACH_SEND_INVALID_HEADER
959 * Illegal value in the message header bits.
960 * MACH_SEND_INVALID_DEST The space is dead.
961 * MACH_SEND_INVALID_NOTIFY
962 * Notify is non-null and doesn't name a receive right.
963 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
964 * MACH_SEND_INVALID_DEST Can't copyin destination port.
965 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
966 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
967 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
968 */
969
970 mach_msg_return_t
971 ipc_kmsg_copyin_header(
972 mach_msg_header_t *msg,
973 ipc_space_t space,
974 mach_port_name_t notify)
975 {
976 mach_msg_bits_t mbits = msg->msgh_bits & MACH_MSGH_BITS_USER;
977 mach_port_name_t dest_name = (mach_port_name_t)msg->msgh_remote_port;
978 mach_port_name_t reply_name = (mach_port_name_t)msg->msgh_local_port;
979 kern_return_t kr;
980
981 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
982 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
983 ipc_object_t dest_port, reply_port;
984 ipc_port_t dest_soright, reply_soright;
985 ipc_port_t notify_port;
986
987 if ((mbits != msg->msgh_bits) ||
988 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type)) ||
989 ((reply_type == 0) ?
990 (reply_name != MACH_PORT_NULL) :
991 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type)))
992 return MACH_SEND_INVALID_HEADER;
993
994 reply_soright = IP_NULL; /* in case we go to invalid dest early */
995
996 is_write_lock(space);
997 if (!space->is_active)
998 goto invalid_dest;
999
1000 if (!MACH_PORT_VALID(dest_name))
1001 goto invalid_dest;
1002
1003 if (notify != MACH_PORT_NULL) {
1004 ipc_entry_t entry;
1005
1006 if ((entry = ipc_entry_lookup(space, notify)) == IE_NULL) {
1007 is_write_unlock(space);
1008 return MACH_SEND_INVALID_NOTIFY;
1009 }
1010 if((entry->ie_bits & MACH_PORT_TYPE_RECEIVE) == 0) {
1011 is_write_unlock(space);
1012 return MACH_SEND_INVALID_NOTIFY;
1013 }
1014
1015 notify_port = (ipc_port_t) entry->ie_object;
1016 }
1017
1018 if (dest_name == reply_name) {
1019 ipc_entry_t entry;
1020 mach_port_name_t name = dest_name;
1021
1022 /*
1023 * Destination and reply ports are the same!
1024 * This is a little tedious to make atomic, because
1025 * there are 25 combinations of dest_type/reply_type.
1026 * However, most are easy. If either is move-sonce,
1027 * then there must be an error. If either are
1028 * make-send or make-sonce, then we must be looking
1029 * at a receive right so the port can't die.
1030 * The hard cases are the combinations of
1031 * copy-send and make-send.
1032 */
1033
1034 entry = ipc_entry_lookup(space, name);
1035 if (entry == IE_NULL)
1036 goto invalid_dest;
1037
1038 assert(reply_type != 0); /* because name not null */
1039
1040 if (!ipc_right_copyin_check(space, name, entry, reply_type))
1041 goto invalid_reply;
1042
1043 if ((dest_type == MACH_MSG_TYPE_MOVE_SEND_ONCE) ||
1044 (reply_type == MACH_MSG_TYPE_MOVE_SEND_ONCE)) {
1045 /*
1046 * Why must there be an error? To get a valid
1047 * destination, this entry must name a live
1048 * port (not a dead name or dead port). However
1049 * a successful move-sonce will destroy a
1050 * live entry. Therefore the other copyin,
1051 * whatever it is, would fail. We've already
1052 * checked for reply port errors above,
1053 * so report a destination error.
1054 */
1055
1056 goto invalid_dest;
1057 } else if ((dest_type == MACH_MSG_TYPE_MAKE_SEND) ||
1058 (dest_type == MACH_MSG_TYPE_MAKE_SEND_ONCE) ||
1059 (reply_type == MACH_MSG_TYPE_MAKE_SEND) ||
1060 (reply_type == MACH_MSG_TYPE_MAKE_SEND_ONCE)) {
1061 kr = ipc_right_copyin(space, name, entry,
1062 dest_type, FALSE,
1063 &dest_port, &dest_soright);
1064 if (kr != KERN_SUCCESS)
1065 goto invalid_dest;
1066
1067 /*
1068 * Either dest or reply needs a receive right.
1069 * We know the receive right is there, because
1070 * of the copyin_check and copyin calls. Hence
1071 * the port is not in danger of dying. If dest
1072 * used the receive right, then the right needed
1073 * by reply (and verified by copyin_check) will
1074 * still be there.
1075 */
1076
1077 assert(IO_VALID(dest_port));
1078 assert(entry->ie_bits & MACH_PORT_TYPE_RECEIVE);
1079 assert(dest_soright == IP_NULL);
1080
1081 kr = ipc_right_copyin(space, name, entry,
1082 reply_type, TRUE,
1083 &reply_port, &reply_soright);
1084
1085 assert(kr == KERN_SUCCESS);
1086 assert(reply_port == dest_port);
1087 assert(entry->ie_bits & MACH_PORT_TYPE_RECEIVE);
1088 assert(reply_soright == IP_NULL);
1089 } else if ((dest_type == MACH_MSG_TYPE_COPY_SEND) &&
1090 (reply_type == MACH_MSG_TYPE_COPY_SEND)) {
1091 /*
1092 * To make this atomic, just do one copy-send,
1093 * and dup the send right we get out.
1094 */
1095
1096 kr = ipc_right_copyin(space, name, entry,
1097 dest_type, FALSE,
1098 &dest_port, &dest_soright);
1099 if (kr != KERN_SUCCESS)
1100 goto invalid_dest;
1101
1102 assert(entry->ie_bits & MACH_PORT_TYPE_SEND);
1103 assert(dest_soright == IP_NULL);
1104
1105 /*
1106 * It's OK if the port we got is dead now,
1107 * so reply_port is IP_DEAD, because the msg
1108 * won't go anywhere anyway.
1109 */
1110
1111 reply_port = (ipc_object_t)
1112 ipc_port_copy_send((ipc_port_t) dest_port);
1113 reply_soright = IP_NULL;
1114 } else if ((dest_type == MACH_MSG_TYPE_MOVE_SEND) &&
1115 (reply_type == MACH_MSG_TYPE_MOVE_SEND)) {
1116 /*
1117 * This is an easy case. Just use our
1118 * handy-dandy special-purpose copyin call
1119 * to get two send rights for the price of one.
1120 */
1121
1122 kr = ipc_right_copyin_two(space, name, entry,
1123 &dest_port, &dest_soright);
1124 if (kr != KERN_SUCCESS)
1125 goto invalid_dest;
1126
1127 /* the entry might need to be deallocated */
1128 if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
1129 ipc_entry_dealloc(space, name, entry);
1130
1131 reply_port = dest_port;
1132 reply_soright = IP_NULL;
1133 } else {
1134 ipc_port_t soright;
1135
1136 assert(((dest_type == MACH_MSG_TYPE_COPY_SEND) &&
1137 (reply_type == MACH_MSG_TYPE_MOVE_SEND)) ||
1138 ((dest_type == MACH_MSG_TYPE_MOVE_SEND) &&
1139 (reply_type == MACH_MSG_TYPE_COPY_SEND)));
1140
1141 /*
1142 * To make this atomic, just do a move-send,
1143 * and dup the send right we get out.
1144 */
1145
1146 kr = ipc_right_copyin(space, name, entry,
1147 MACH_MSG_TYPE_MOVE_SEND, FALSE,
1148 &dest_port, &soright);
1149 if (kr != KERN_SUCCESS)
1150 goto invalid_dest;
1151
1152 /* the entry might need to be deallocated */
1153
1154 if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
1155 ipc_entry_dealloc(space, name, entry);
1156
1157 /*
1158 * It's OK if the port we got is dead now,
1159 * so reply_port is IP_DEAD, because the msg
1160 * won't go anywhere anyway.
1161 */
1162
1163 reply_port = (ipc_object_t)
1164 ipc_port_copy_send((ipc_port_t) dest_port);
1165
1166 if (dest_type == MACH_MSG_TYPE_MOVE_SEND) {
1167 dest_soright = soright;
1168 reply_soright = IP_NULL;
1169 } else {
1170 dest_soright = IP_NULL;
1171 reply_soright = soright;
1172 }
1173 }
1174 } else if (!MACH_PORT_VALID(reply_name)) {
1175 ipc_entry_t entry;
1176
1177 /*
1178 * No reply port! This is an easy case
1179 * to make atomic. Just copyin the destination.
1180 */
1181
1182 entry = ipc_entry_lookup(space, dest_name);
1183 if (entry == IE_NULL)
1184 goto invalid_dest;
1185
1186 kr = ipc_right_copyin(space, dest_name, entry,
1187 dest_type, FALSE,
1188 &dest_port, &dest_soright);
1189 if (kr != KERN_SUCCESS)
1190 goto invalid_dest;
1191
1192 /* the entry might need to be deallocated */
1193
1194 if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE)
1195 ipc_entry_dealloc(space, dest_name, entry);
1196
1197 reply_port = (ipc_object_t) reply_name;
1198 reply_soright = IP_NULL;
1199 } else {
1200 ipc_entry_t dest_entry, reply_entry;
1201 ipc_port_t saved_reply;
1202
1203 /*
1204 * This is the tough case to make atomic.
1205 * The difficult problem is serializing with port death.
1206 * At the time we copyin dest_port, it must be alive.
1207 * If reply_port is alive when we copyin it, then
1208 * we are OK, because we serialize before the death
1209 * of both ports. Assume reply_port is dead at copyin.
1210 * Then if dest_port dies/died after reply_port died,
1211 * we are OK, because we serialize between the death
1212 * of the two ports. So the bad case is when dest_port
1213 * dies after its copyin, reply_port dies before its
1214 * copyin, and dest_port dies before reply_port. Then
1215 * the copyins operated as if dest_port was alive
1216 * and reply_port was dead, which shouldn't have happened
1217 * because they died in the other order.
1218 *
1219 * Note that it is easy for a user task to tell if
1220 * a copyin happened before or after a port died.
1221 * For example, suppose both dest and reply are
1222 * send-once rights (types are both move-sonce) and
1223 * both rights have dead-name requests registered.
1224 * If a port dies before copyin, a dead-name notification
1225 * is generated and the dead name's urefs are incremented,
1226 * and if the copyin happens first, a port-deleted
1227 * notification is generated.
1228 *
1229 * Note that although the entries are different,
1230 * dest_port and reply_port might still be the same.
1231 *
1232 * JMM - The code to handle this was too expensive and, anyway,
1233 * we intend to separate the dest lookup from the reply copyin
1234 * by a wide margin, so the user will have to learn to deal!
1235 * I will be making the change soon!
1236 */
1237
1238 dest_entry = ipc_entry_lookup(space, dest_name);
1239 if (dest_entry == IE_NULL)
1240 goto invalid_dest;
1241
1242 reply_entry = ipc_entry_lookup(space, reply_name);
1243 if (reply_entry == IE_NULL)
1244 goto invalid_reply;
1245
1246 assert(dest_entry != reply_entry); /* names are not equal */
1247 assert(reply_type != 0); /* because reply_name not null */
1248
1249 if (!ipc_right_copyin_check(space, reply_name, reply_entry,
1250 reply_type))
1251 goto invalid_reply;
1252
1253 kr = ipc_right_copyin(space, dest_name, dest_entry,
1254 dest_type, FALSE,
1255 &dest_port, &dest_soright);
1256 if (kr != KERN_SUCCESS)
1257 goto invalid_dest;
1258
1259 assert(IO_VALID(dest_port));
1260
1261 kr = ipc_right_copyin(space, reply_name, reply_entry,
1262 reply_type, TRUE,
1263 &reply_port, &reply_soright);
1264
1265 assert(kr == KERN_SUCCESS);
1266
1267 /* the entries might need to be deallocated */
1268
1269 if (IE_BITS_TYPE(reply_entry->ie_bits) == MACH_PORT_TYPE_NONE)
1270 ipc_entry_dealloc(space, reply_name, reply_entry);
1271
1272 if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE)
1273 ipc_entry_dealloc(space, dest_name, dest_entry);
1274 }
1275
1276 /*
1277 * At this point, dest_port, reply_port,
1278 * dest_soright, reply_soright are all initialized.
1279 * Any defunct entries have been deallocated.
1280 * The space is still write-locked, and we need to
1281 * make the MACH_SEND_CANCEL check. The notify_port pointer
1282 * is still usable, because the copyin code above won't ever
1283 * deallocate a receive right, so its entry still exists
1284 * and holds a ref. Note notify_port might even equal
1285 * dest_port or reply_port.
1286 */
1287
1288 if ((notify != MACH_PORT_NULL) &&
1289 (dest_soright == notify_port)) {
1290 ipc_port_release_sonce(dest_soright);
1291 dest_soright = IP_NULL;
1292 }
1293
1294 is_write_unlock(space);
1295
1296 if (dest_soright != IP_NULL)
1297 ipc_notify_port_deleted(dest_soright, dest_name);
1298
1299 if (reply_soright != IP_NULL)
1300 ipc_notify_port_deleted(reply_soright, reply_name);
1301
1302 dest_type = ipc_object_copyin_type(dest_type);
1303 reply_type = ipc_object_copyin_type(reply_type);
1304
1305 msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
1306 MACH_MSGH_BITS(dest_type, reply_type));
1307 msg->msgh_remote_port = (ipc_port_t)dest_port;
1308 msg->msgh_local_port = (ipc_port_t)reply_port;
1309
1310 return MACH_MSG_SUCCESS;
1311
1312 invalid_reply:
1313 is_write_unlock(space);
1314 return MACH_SEND_INVALID_REPLY;
1315
1316 invalid_dest:
1317 is_write_unlock(space);
1318 if (reply_soright != IP_NULL)
1319 ipc_notify_port_deleted(reply_soright, reply_name);
1320 return MACH_SEND_INVALID_DEST;
1321 }
1322
1323 /*
1324 * Routine: ipc_kmsg_copyin_body
1325 * Purpose:
1326 * "Copy-in" port rights and out-of-line memory
1327 * in the message body.
1328 *
1329 * In all failure cases, the message is left holding
1330 * no rights or memory. However, the message buffer
1331 * is not deallocated. If successful, the message
1332 * contains a valid destination port.
1333 * Conditions:
1334 * Nothing locked.
1335 * Returns:
1336 * MACH_MSG_SUCCESS Successful copyin.
1337 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1338 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1339 * MACH_SEND_INVALID_TYPE Bad type specification.
1340 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1341 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT
1342 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible
1343 */
1344
1345 mach_msg_return_t
1346 ipc_kmsg_copyin_body(
1347 ipc_kmsg_t kmsg,
1348 ipc_space_t space,
1349 vm_map_t map)
1350 {
1351 ipc_object_t dest;
1352 mach_msg_body_t *body;
1353 mach_msg_descriptor_t *saddr, *eaddr;
1354 boolean_t complex;
1355 mach_msg_return_t mr;
1356 int i;
1357 kern_return_t kr;
1358 vm_size_t space_needed = 0;
1359 vm_offset_t paddr = 0;
1360 mach_msg_descriptor_t *sstart;
1361 vm_map_copy_t copy = VM_MAP_COPY_NULL;
1362
1363 /*
1364 * Determine if the target is a kernel port.
1365 */
1366 dest = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
1367 complex = FALSE;
1368
1369 body = (mach_msg_body_t *) (&kmsg->ikm_header + 1);
1370 saddr = (mach_msg_descriptor_t *) (body + 1);
1371 eaddr = saddr + body->msgh_descriptor_count;
1372
1373 /* make sure the message does not ask for more msg descriptors
1374 * than the message can hold.
1375 */
1376
1377 if (eaddr <= saddr ||
1378 eaddr > (mach_msg_descriptor_t *) (&kmsg->ikm_header +
1379 kmsg->ikm_header.msgh_size)) {
1380 ipc_kmsg_clean_partial(kmsg,0,0,0);
1381 return MACH_SEND_MSG_TOO_SMALL;
1382 }
1383
1384 /*
1385 * Make an initial pass to determine kernal VM space requirements for
1386 * physical copies.
1387 */
1388 for (sstart = saddr; sstart < eaddr; sstart++) {
1389
1390 if (sstart->type.type == MACH_MSG_OOL_DESCRIPTOR ||
1391 sstart->type.type == MACH_MSG_OOL_VOLATILE_DESCRIPTOR) {
1392
1393 if (sstart->out_of_line.copy != MACH_MSG_PHYSICAL_COPY &&
1394 sstart->out_of_line.copy != MACH_MSG_VIRTUAL_COPY) {
1395 /*
1396 * Invalid copy option
1397 */
1398 ipc_kmsg_clean_partial(kmsg,0,0,0);
1399 return MACH_SEND_INVALID_TYPE;
1400 }
1401
1402 if ((sstart->out_of_line.size >= MSG_OOL_SIZE_SMALL) &&
1403 (sstart->out_of_line.copy == MACH_MSG_PHYSICAL_COPY) &&
1404 !(sstart->out_of_line.deallocate)) {
1405
1406 /*
1407 * Out-of-line memory descriptor, accumulate kernel
1408 * memory requirements
1409 */
1410 space_needed += round_page_32(sstart->out_of_line.size);
1411 if (space_needed > ipc_kmsg_max_vm_space) {
1412
1413 /*
1414 * Per message kernel memory limit exceeded
1415 */
1416 ipc_kmsg_clean_partial(kmsg,0,0,0);
1417 return MACH_MSG_VM_KERNEL;
1418 }
1419 }
1420 }
1421 }
1422
1423 /*
1424 * Allocate space in the pageable kernel ipc copy map for all the
1425 * ool data that is to be physically copied. Map is marked wait for
1426 * space.
1427 */
1428 if (space_needed) {
1429 if (vm_allocate(ipc_kernel_copy_map, &paddr, space_needed, TRUE) !=
1430 KERN_SUCCESS) {
1431 ipc_kmsg_clean_partial(kmsg,0,0,0);
1432 return MACH_MSG_VM_KERNEL;
1433 }
1434 }
1435
1436 /*
1437 * handle the OOL regions and port descriptors.
1438 * the check for complex messages was done earlier.
1439 */
1440
1441 for (i = 0, sstart = saddr; sstart < eaddr; sstart++) {
1442
1443 switch (sstart->type.type) {
1444
1445 case MACH_MSG_PORT_DESCRIPTOR: {
1446 mach_msg_type_name_t name;
1447 ipc_object_t object;
1448 mach_msg_port_descriptor_t *dsc;
1449
1450 dsc = &sstart->port;
1451
1452 /* this is really the type SEND, SEND_ONCE, etc. */
1453 name = dsc->disposition;
1454 dsc->disposition = ipc_object_copyin_type(name);
1455
1456 if (!MACH_PORT_VALID((mach_port_name_t)dsc->name)) {
1457 complex = TRUE;
1458 break;
1459 }
1460 kr = ipc_object_copyin(space, (mach_port_name_t)dsc->name, name, &object);
1461 if (kr != KERN_SUCCESS) {
1462 ipc_kmsg_clean_partial(kmsg, i, paddr, space_needed);
1463 return MACH_SEND_INVALID_RIGHT;
1464 }
1465 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
1466 ipc_port_check_circularity((ipc_port_t) object,
1467 (ipc_port_t) dest)) {
1468 kmsg->ikm_header.msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
1469 }
1470 dsc->name = (ipc_port_t) object;
1471 complex = TRUE;
1472 break;
1473 }
1474 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
1475 case MACH_MSG_OOL_DESCRIPTOR: {
1476 vm_size_t length;
1477 boolean_t dealloc;
1478 vm_offset_t addr;
1479 vm_offset_t kaddr;
1480 mach_msg_ool_descriptor_t *dsc;
1481
1482 dsc = &sstart->out_of_line;
1483 dealloc = dsc->deallocate;
1484 addr = (vm_offset_t) dsc->address;
1485
1486 length = dsc->size;
1487
1488 if (length == 0) {
1489 dsc->address = 0;
1490 } else if ((length >= MSG_OOL_SIZE_SMALL) &&
1491 (dsc->copy == MACH_MSG_PHYSICAL_COPY) && !dealloc) {
1492
1493 /*
1494 * If the request is a physical copy and the source
1495 * is not being deallocated, then allocate space
1496 * in the kernel's pageable ipc copy map and copy
1497 * the data in. The semantics guarantee that the
1498 * data will have been physically copied before
1499 * the send operation terminates. Thus if the data
1500 * is not being deallocated, we must be prepared
1501 * to page if the region is sufficiently large.
1502 */
1503 if (copyin((const char *) addr, (char *) paddr,
1504 length)) {
1505 ipc_kmsg_clean_partial(kmsg, i, paddr,
1506 space_needed);
1507 return MACH_SEND_INVALID_MEMORY;
1508 }
1509
1510 /*
1511 * The kernel ipc copy map is marked no_zero_fill.
1512 * If the transfer is not a page multiple, we need
1513 * to zero fill the balance.
1514 */
1515 if (!page_aligned(length)) {
1516 (void) memset((void *) (paddr + length), 0,
1517 round_page_32(length) - length);
1518 }
1519 if (vm_map_copyin(ipc_kernel_copy_map, paddr, length,
1520 TRUE, &copy) != KERN_SUCCESS) {
1521 ipc_kmsg_clean_partial(kmsg, i, paddr,
1522 space_needed);
1523 return MACH_MSG_VM_KERNEL;
1524 }
1525 dsc->address = (void *) copy;
1526 paddr += round_page_32(length);
1527 space_needed -= round_page_32(length);
1528 } else {
1529
1530 /*
1531 * Make a vm_map_copy_t of the of the data. If the
1532 * data is small, this will do an optimized physical
1533 * copy. Otherwise, it will do a virtual copy.
1534 *
1535 * NOTE: A virtual copy is OK if the original is being
1536 * deallocted, even if a physical copy was requested.
1537 */
1538 kr = vm_map_copyin(map, addr, length, dealloc, &copy);
1539 if (kr != KERN_SUCCESS) {
1540 ipc_kmsg_clean_partial(kmsg,i,paddr,space_needed);
1541 return (kr == KERN_RESOURCE_SHORTAGE) ?
1542 MACH_MSG_VM_KERNEL :
1543 MACH_SEND_INVALID_MEMORY;
1544 }
1545 dsc->address = (void *) copy;
1546 }
1547 complex = TRUE;
1548 break;
1549 }
1550 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
1551 vm_size_t length;
1552 vm_offset_t data;
1553 vm_offset_t addr;
1554 ipc_object_t *objects;
1555 int j;
1556 mach_msg_type_name_t name;
1557 mach_msg_ool_ports_descriptor_t *dsc;
1558
1559 dsc = &sstart->ool_ports;
1560 addr = (vm_offset_t) dsc->address;
1561
1562 /* calculate length of data in bytes, rounding up */
1563 length = dsc->count * sizeof(mach_port_name_t);
1564
1565 if (length == 0) {
1566 complex = TRUE;
1567 dsc->address = (void *) 0;
1568 break;
1569 }
1570
1571 data = kalloc(length);
1572
1573 if (data == 0) {
1574 ipc_kmsg_clean_partial(kmsg, i, paddr, space_needed);
1575 return MACH_SEND_NO_BUFFER;
1576 }
1577
1578 if (copyinmap(map, addr, data, length)) {
1579 kfree(data, length);
1580 ipc_kmsg_clean_partial(kmsg, i, paddr, space_needed);
1581 return MACH_SEND_INVALID_MEMORY;
1582 }
1583
1584 if (dsc->deallocate) {
1585 (void) vm_deallocate(map, addr, length);
1586 }
1587
1588 dsc->address = (void *) data;
1589
1590 /* this is really the type SEND, SEND_ONCE, etc. */
1591 name = dsc->disposition;
1592 dsc->disposition = ipc_object_copyin_type(name);
1593
1594 objects = (ipc_object_t *) data;
1595
1596 for ( j = 0; j < dsc->count; j++) {
1597 mach_port_name_t port = (mach_port_name_t) objects[j];
1598 ipc_object_t object;
1599
1600 if (!MACH_PORT_VALID(port))
1601 continue;
1602
1603 kr = ipc_object_copyin(space, port, name, &object);
1604
1605 if (kr != KERN_SUCCESS) {
1606 int k;
1607
1608 for(k = 0; k < j; k++) {
1609 object = objects[k];
1610 if (IPC_OBJECT_VALID(object))
1611 ipc_object_destroy(object, dsc->disposition);
1612 }
1613 kfree(data, length);
1614 ipc_kmsg_clean_partial(kmsg, i, paddr, space_needed);
1615 return MACH_SEND_INVALID_RIGHT;
1616 }
1617
1618 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
1619 ipc_port_check_circularity(
1620 (ipc_port_t) object,
1621 (ipc_port_t) dest))
1622 kmsg->ikm_header.msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
1623
1624 objects[j] = object;
1625 }
1626
1627 complex = TRUE;
1628 break;
1629 }
1630 default: {
1631 /*
1632 * Invalid descriptor
1633 */
1634 ipc_kmsg_clean_partial(kmsg, i, paddr, space_needed);
1635 return MACH_SEND_INVALID_TYPE;
1636 }
1637 }
1638 i++ ;
1639 }
1640
1641 if (!complex)
1642 kmsg->ikm_header.msgh_bits &= ~MACH_MSGH_BITS_COMPLEX;
1643 return MACH_MSG_SUCCESS;
1644 }
1645
1646
1647 /*
1648 * Routine: ipc_kmsg_copyin
1649 * Purpose:
1650 * "Copy-in" port rights and out-of-line memory
1651 * in the message.
1652 *
1653 * In all failure cases, the message is left holding
1654 * no rights or memory. However, the message buffer
1655 * is not deallocated. If successful, the message
1656 * contains a valid destination port.
1657 * Conditions:
1658 * Nothing locked.
1659 * Returns:
1660 * MACH_MSG_SUCCESS Successful copyin.
1661 * MACH_SEND_INVALID_HEADER
1662 * Illegal value in the message header bits.
1663 * MACH_SEND_INVALID_NOTIFY Bad notify port.
1664 * MACH_SEND_INVALID_DEST Can't copyin destination port.
1665 * MACH_SEND_INVALID_REPLY Can't copyin reply port.
1666 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory.
1667 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body.
1668 * MACH_SEND_INVALID_TYPE Bad type specification.
1669 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data.
1670 */
1671
1672 mach_msg_return_t
1673 ipc_kmsg_copyin(
1674 ipc_kmsg_t kmsg,
1675 ipc_space_t space,
1676 vm_map_t map,
1677 mach_port_name_t notify)
1678 {
1679 mach_msg_return_t mr;
1680
1681 mr = ipc_kmsg_copyin_header(&kmsg->ikm_header, space, notify);
1682 if (mr != MACH_MSG_SUCCESS)
1683 return mr;
1684
1685 if ((kmsg->ikm_header.msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0)
1686 return MACH_MSG_SUCCESS;
1687
1688 return( ipc_kmsg_copyin_body( kmsg, space, map) );
1689 }
1690
1691 /*
1692 * Routine: ipc_kmsg_copyin_from_kernel
1693 * Purpose:
1694 * "Copy-in" port rights and out-of-line memory
1695 * in a message sent from the kernel.
1696 *
1697 * Because the message comes from the kernel,
1698 * the implementation assumes there are no errors
1699 * or peculiarities in the message.
1700 *
1701 * Returns TRUE if queueing the message
1702 * would result in a circularity.
1703 * Conditions:
1704 * Nothing locked.
1705 */
1706
1707 void
1708 ipc_kmsg_copyin_from_kernel(
1709 ipc_kmsg_t kmsg)
1710 {
1711 mach_msg_bits_t bits = kmsg->ikm_header.msgh_bits;
1712 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits);
1713 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits);
1714 ipc_object_t remote = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
1715 ipc_object_t local = (ipc_object_t) kmsg->ikm_header.msgh_local_port;
1716
1717 /* translate the destination and reply ports */
1718
1719 ipc_object_copyin_from_kernel(remote, rname);
1720 if (IO_VALID(local))
1721 ipc_object_copyin_from_kernel(local, lname);
1722
1723 /*
1724 * The common case is a complex message with no reply port,
1725 * because that is what the memory_object interface uses.
1726 */
1727
1728 if (bits == (MACH_MSGH_BITS_COMPLEX |
1729 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) {
1730 bits = (MACH_MSGH_BITS_COMPLEX |
1731 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0));
1732
1733 kmsg->ikm_header.msgh_bits = bits;
1734 } else {
1735 bits = (MACH_MSGH_BITS_OTHER(bits) |
1736 MACH_MSGH_BITS(ipc_object_copyin_type(rname),
1737 ipc_object_copyin_type(lname)));
1738
1739 kmsg->ikm_header.msgh_bits = bits;
1740 if ((bits & MACH_MSGH_BITS_COMPLEX) == 0)
1741 return;
1742 }
1743 {
1744 mach_msg_descriptor_t *saddr, *eaddr;
1745 mach_msg_body_t *body;
1746
1747 body = (mach_msg_body_t *) (&kmsg->ikm_header + 1);
1748 saddr = (mach_msg_descriptor_t *) (body + 1);
1749 eaddr = (mach_msg_descriptor_t *) saddr + body->msgh_descriptor_count;
1750
1751 for ( ; saddr < eaddr; saddr++) {
1752
1753 switch (saddr->type.type) {
1754
1755 case MACH_MSG_PORT_DESCRIPTOR: {
1756 mach_msg_type_name_t name;
1757 ipc_object_t object;
1758 mach_msg_port_descriptor_t *dsc;
1759
1760 dsc = &saddr->port;
1761
1762 /* this is really the type SEND, SEND_ONCE, etc. */
1763 name = dsc->disposition;
1764 object = (ipc_object_t) dsc->name;
1765 dsc->disposition = ipc_object_copyin_type(name);
1766
1767 if (!IO_VALID(object)) {
1768 break;
1769 }
1770
1771 ipc_object_copyin_from_kernel(object, name);
1772
1773 /* CDY avoid circularity when the destination is also */
1774 /* the kernel. This check should be changed into an */
1775 /* assert when the new kobject model is in place since*/
1776 /* ports will not be used in kernel to kernel chats */
1777
1778 if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) {
1779 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
1780 ipc_port_check_circularity((ipc_port_t) object,
1781 (ipc_port_t) remote)) {
1782 kmsg->ikm_header.msgh_bits |=
1783 MACH_MSGH_BITS_CIRCULAR;
1784 }
1785 }
1786 break;
1787 }
1788 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
1789 case MACH_MSG_OOL_DESCRIPTOR: {
1790 /*
1791 * The sender should supply ready-made memory, i.e.
1792 * a vm_map_copy_t, so we don't need to do anything.
1793 */
1794 break;
1795 }
1796 case MACH_MSG_OOL_PORTS_DESCRIPTOR: {
1797 ipc_object_t *objects;
1798 int j;
1799 mach_msg_type_name_t name;
1800 mach_msg_ool_ports_descriptor_t *dsc;
1801
1802 dsc = &saddr->ool_ports;
1803
1804 /* this is really the type SEND, SEND_ONCE, etc. */
1805 name = dsc->disposition;
1806 dsc->disposition = ipc_object_copyin_type(name);
1807
1808 objects = (ipc_object_t *) dsc->address;
1809
1810 for ( j = 0; j < dsc->count; j++) {
1811 ipc_object_t object = objects[j];
1812
1813 if (!IO_VALID(object))
1814 continue;
1815
1816 ipc_object_copyin_from_kernel(object, name);
1817
1818 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) &&
1819 ipc_port_check_circularity(
1820 (ipc_port_t) object,
1821 (ipc_port_t) remote))
1822 kmsg->ikm_header.msgh_bits |= MACH_MSGH_BITS_CIRCULAR;
1823 }
1824 break;
1825 }
1826 default: {
1827 #if MACH_ASSERT
1828 panic("ipc_kmsg_copyin_from_kernel: bad descriptor");
1829 #endif /* MACH_ASSERT */
1830 }
1831 }
1832 }
1833 }
1834 }
1835
1836 /*
1837 * Routine: ipc_kmsg_copyout_header
1838 * Purpose:
1839 * "Copy-out" port rights in the header of a message.
1840 * Operates atomically; if it doesn't succeed the
1841 * message header and the space are left untouched.
1842 * If it does succeed the remote/local port fields
1843 * contain port names instead of object pointers,
1844 * and the bits field is updated.
1845 *
1846 * The notify argument implements the MACH_RCV_NOTIFY option.
1847 * If it is not MACH_PORT_NULL, it should name a receive right.
1848 * If the process of receiving the reply port creates a
1849 * new right in the receiving task, then the new right is
1850 * automatically registered for a dead-name notification,
1851 * with the notify port supplying the send-once right.
1852 * Conditions:
1853 * Nothing locked.
1854 * Returns:
1855 * MACH_MSG_SUCCESS Copied out port rights.
1856 * MACH_RCV_INVALID_NOTIFY
1857 * Notify is non-null and doesn't name a receive right.
1858 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.)
1859 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
1860 * The space is dead.
1861 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE
1862 * No room in space for another name.
1863 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
1864 * Couldn't allocate memory for the reply port.
1865 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL
1866 * Couldn't allocate memory for the dead-name request.
1867 */
1868
1869 mach_msg_return_t
1870 ipc_kmsg_copyout_header(
1871 mach_msg_header_t *msg,
1872 ipc_space_t space,
1873 mach_port_name_t notify)
1874 {
1875 mach_msg_bits_t mbits = msg->msgh_bits;
1876 ipc_port_t dest = (ipc_port_t) msg->msgh_remote_port;
1877
1878 assert(IP_VALID(dest));
1879
1880 {
1881 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
1882 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
1883 ipc_port_t reply = (ipc_port_t) msg->msgh_local_port;
1884 mach_port_name_t dest_name, reply_name;
1885
1886 if (IP_VALID(reply)) {
1887 ipc_port_t notify_port;
1888 ipc_entry_t entry;
1889 kern_return_t kr;
1890
1891 /*
1892 * Handling notify (for MACH_RCV_NOTIFY) is tricky.
1893 * The problem is atomically making a send-once right
1894 * from the notify port and installing it for a
1895 * dead-name request in the new entry, because this
1896 * requires two port locks (on the notify port and
1897 * the reply port). However, we can safely make
1898 * and consume send-once rights for the notify port
1899 * as long as we hold the space locked. This isn't
1900 * an atomicity problem, because the only way
1901 * to detect that a send-once right has been created
1902 * and then consumed if it wasn't needed is by getting
1903 * at the receive right to look at ip_sorights, and
1904 * because the space is write-locked status calls can't
1905 * lookup the notify port receive right. When we make
1906 * the send-once right, we lock the notify port,
1907 * so any status calls in progress will be done.
1908 */
1909
1910 is_write_lock(space);
1911
1912 for (;;) {
1913 ipc_port_request_index_t request;
1914
1915 if (!space->is_active) {
1916 is_write_unlock(space);
1917 return (MACH_RCV_HEADER_ERROR|
1918 MACH_MSG_IPC_SPACE);
1919 }
1920
1921 if (notify != MACH_PORT_NULL) {
1922 notify_port = ipc_port_lookup_notify(space,
1923 notify);
1924 if (notify_port == IP_NULL) {
1925 is_write_unlock(space);
1926 return MACH_RCV_INVALID_NOTIFY;
1927 }
1928 } else
1929 notify_port = IP_NULL;
1930
1931 if ((reply_type != MACH_MSG_TYPE_PORT_SEND_ONCE) &&
1932 ipc_right_reverse(space, (ipc_object_t) reply,
1933 &reply_name, &entry)) {
1934 /* reply port is locked and active */
1935
1936 /*
1937 * We don't need the notify_port
1938 * send-once right, but we can't release
1939 * it here because reply port is locked.
1940 * Wait until after the copyout to
1941 * release the notify port right.
1942 */
1943
1944 assert(entry->ie_bits &
1945 MACH_PORT_TYPE_SEND_RECEIVE);
1946 break;
1947 }
1948
1949 ip_lock(reply);
1950 if (!ip_active(reply)) {
1951 ip_release(reply);
1952 ip_check_unlock(reply);
1953
1954 if (notify_port != IP_NULL)
1955 ipc_port_release_sonce(notify_port);
1956
1957 ip_lock(dest);
1958 is_write_unlock(space);
1959
1960 reply = IP_DEAD;
1961 reply_name = MACH_PORT_DEAD;
1962 goto copyout_dest;
1963 }
1964
1965 reply_name = (mach_port_name_t)reply;
1966 kr = ipc_entry_get(space, &reply_name, &entry);
1967 if (kr != KERN_SUCCESS) {
1968 ip_unlock(reply);
1969
1970 if (notify_port != IP_NULL)
1971 ipc_port_release_sonce(notify_port);
1972
1973 /* space is locked */
1974 kr = ipc_entry_grow_table(space,
1975 ITS_SIZE_NONE);
1976 if (kr != KERN_SUCCESS) {
1977 /* space is unlocked */
1978
1979 if (kr == KERN_RESOURCE_SHORTAGE)
1980 return (MACH_RCV_HEADER_ERROR|
1981 MACH_MSG_IPC_KERNEL);
1982 else
1983 return (MACH_RCV_HEADER_ERROR|
1984 MACH_MSG_IPC_SPACE);
1985 }
1986 /* space is locked again; start over */
1987
1988 continue;
1989 }
1990 assert(IE_BITS_TYPE(entry->ie_bits) ==
1991 MACH_PORT_TYPE_NONE);
1992 assert(entry->ie_object == IO_NULL);
1993
1994 if (notify_port == IP_NULL) {
1995 /* not making a dead-name request */
1996
1997 entry->ie_object = (ipc_object_t) reply;
1998 break;
1999 }
2000
2001 kr = ipc_port_dnrequest(reply, reply_name,
2002 notify_port, &request);
2003 if (kr != KERN_SUCCESS) {
2004 ip_unlock(reply);
2005
2006 ipc_port_release_sonce(notify_port);
2007
2008 ipc_entry_dealloc(space, reply_name, entry);
2009 is_write_unlock(space);
2010
2011 ip_lock(reply);
2012 if (!ip_active(reply)) {
2013 /* will fail next time around loop */
2014
2015 ip_unlock(reply);
2016 is_write_lock(space);
2017 continue;
2018 }
2019
2020 kr = ipc_port_dngrow(reply, ITS_SIZE_NONE);
2021 /* port is unlocked */
2022 if (kr != KERN_SUCCESS)
2023 return (MACH_RCV_HEADER_ERROR|
2024 MACH_MSG_IPC_KERNEL);
2025
2026 is_write_lock(space);
2027 continue;
2028 }
2029
2030 notify_port = IP_NULL; /* don't release right below */
2031
2032 entry->ie_object = (ipc_object_t) reply;
2033 entry->ie_request = request;
2034 break;
2035 }
2036
2037 /* space and reply port are locked and active */
2038
2039 ip_reference(reply); /* hold onto the reply port */
2040
2041 kr = ipc_right_copyout(space, reply_name, entry,
2042 reply_type, TRUE, (ipc_object_t) reply);
2043 /* reply port is unlocked */
2044 assert(kr == KERN_SUCCESS);
2045
2046 if (notify_port != IP_NULL)
2047 ipc_port_release_sonce(notify_port);
2048
2049 ip_lock(dest);
2050 is_write_unlock(space);
2051 } else {
2052 /*
2053 * No reply port! This is an easy case.
2054 * We only need to have the space locked
2055 * when checking notify and when locking
2056 * the destination (to ensure atomicity).
2057 */
2058
2059 is_read_lock(space);
2060 if (!space->is_active) {
2061 is_read_unlock(space);
2062 return MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE;
2063 }
2064
2065 if (notify != MACH_PORT_NULL) {
2066 ipc_entry_t entry;
2067
2068 /* must check notify even though it won't be used */
2069
2070 if ((entry = ipc_entry_lookup(space, notify)) == IE_NULL) {
2071 is_read_unlock(space);
2072 return MACH_RCV_INVALID_NOTIFY;
2073 }
2074
2075 if ((entry->ie_bits & MACH_PORT_TYPE_RECEIVE) == 0) {
2076 is_read_unlock(space);
2077 return MACH_RCV_INVALID_NOTIFY;
2078 }
2079 }
2080
2081 ip_lock(dest);
2082 is_read_unlock(space);
2083
2084 reply_name = (mach_port_name_t) reply;
2085 }
2086
2087 /*
2088 * At this point, the space is unlocked and the destination
2089 * port is locked. (Lock taken while space was locked.)
2090 * reply_name is taken care of; we still need dest_name.
2091 * We still hold a ref for reply (if it is valid).
2092 *
2093 * If the space holds receive rights for the destination,
2094 * we return its name for the right. Otherwise the task
2095 * managed to destroy or give away the receive right between
2096 * receiving the message and this copyout. If the destination
2097 * is dead, return MACH_PORT_DEAD, and if the receive right
2098 * exists somewhere else (another space, in transit)
2099 * return MACH_PORT_NULL.
2100 *
2101 * Making this copyout operation atomic with the previous
2102 * copyout of the reply port is a bit tricky. If there was
2103 * no real reply port (it wasn't IP_VALID) then this isn't
2104 * an issue. If the reply port was dead at copyout time,
2105 * then we are OK, because if dest is dead we serialize
2106 * after the death of both ports and if dest is alive
2107 * we serialize after reply died but before dest's (later) death.
2108 * So assume reply was alive when we copied it out. If dest
2109 * is alive, then we are OK because we serialize before
2110 * the ports' deaths. So assume dest is dead when we look at it.
2111 * If reply dies/died after dest, then we are OK because
2112 * we serialize after dest died but before reply dies.
2113 * So the hard case is when reply is alive at copyout,
2114 * dest is dead at copyout, and reply died before dest died.
2115 * In this case pretend that dest is still alive, so
2116 * we serialize while both ports are alive.
2117 *
2118 * Because the space lock is held across the copyout of reply
2119 * and locking dest, the receive right for dest can't move
2120 * in or out of the space while the copyouts happen, so
2121 * that isn't an atomicity problem. In the last hard case
2122 * above, this implies that when dest is dead that the
2123 * space couldn't have had receive rights for dest at
2124 * the time reply was copied-out, so when we pretend
2125 * that dest is still alive, we can return MACH_PORT_NULL.
2126 *
2127 * If dest == reply, then we have to make it look like
2128 * either both copyouts happened before the port died,
2129 * or both happened after the port died. This special
2130 * case works naturally if the timestamp comparison
2131 * is done correctly.
2132 */
2133
2134 copyout_dest:
2135
2136 if (ip_active(dest)) {
2137 ipc_object_copyout_dest(space, (ipc_object_t) dest,
2138 dest_type, &dest_name);
2139 /* dest is unlocked */
2140 } else {
2141 ipc_port_timestamp_t timestamp;
2142
2143 timestamp = dest->ip_timestamp;
2144 ip_release(dest);
2145 ip_check_unlock(dest);
2146
2147 if (IP_VALID(reply)) {
2148 ip_lock(reply);
2149 if (ip_active(reply) ||
2150 IP_TIMESTAMP_ORDER(timestamp,
2151 reply->ip_timestamp))
2152 dest_name = MACH_PORT_DEAD;
2153 else
2154 dest_name = MACH_PORT_NULL;
2155 ip_unlock(reply);
2156 } else
2157 dest_name = MACH_PORT_DEAD;
2158 }
2159
2160 if (IP_VALID(reply))
2161 ipc_port_release(reply);
2162
2163 msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
2164 MACH_MSGH_BITS(reply_type, dest_type));
2165 msg->msgh_local_port = (ipc_port_t)dest_name;
2166 msg->msgh_remote_port = (ipc_port_t)reply_name;
2167 }
2168
2169 return MACH_MSG_SUCCESS;
2170 }
2171
2172 /*
2173 * Routine: ipc_kmsg_copyout_object
2174 * Purpose:
2175 * Copy-out a port right. Always returns a name,
2176 * even for unsuccessful return codes. Always
2177 * consumes the supplied object.
2178 * Conditions:
2179 * Nothing locked.
2180 * Returns:
2181 * MACH_MSG_SUCCESS The space acquired the right
2182 * (name is valid) or the object is dead (MACH_PORT_DEAD).
2183 * MACH_MSG_IPC_SPACE No room in space for the right,
2184 * or the space is dead. (Name is MACH_PORT_NULL.)
2185 * MACH_MSG_IPC_KERNEL Kernel resource shortage.
2186 * (Name is MACH_PORT_NULL.)
2187 */
2188
2189 mach_msg_return_t
2190 ipc_kmsg_copyout_object(
2191 ipc_space_t space,
2192 ipc_object_t object,
2193 mach_msg_type_name_t msgt_name,
2194 mach_port_name_t *namep)
2195 {
2196 kern_return_t kr;
2197
2198 if (!IO_VALID(object)) {
2199 *namep = (mach_port_name_t) object;
2200 return MACH_MSG_SUCCESS;
2201 }
2202
2203 kr = ipc_object_copyout(space, object, msgt_name, TRUE, namep);
2204 if (kr != KERN_SUCCESS) {
2205 ipc_object_destroy(object, msgt_name);
2206
2207 if (kr == KERN_INVALID_CAPABILITY)
2208 *namep = MACH_PORT_DEAD;
2209 else {
2210 *namep = MACH_PORT_NULL;
2211
2212 if (kr == KERN_RESOURCE_SHORTAGE)
2213 return MACH_MSG_IPC_KERNEL;
2214 else
2215 return MACH_MSG_IPC_SPACE;
2216 }
2217 }
2218
2219 return MACH_MSG_SUCCESS;
2220 }
2221
2222 /*
2223 * Routine: ipc_kmsg_copyout_body
2224 * Purpose:
2225 * "Copy-out" port rights and out-of-line memory
2226 * in the body of a message.
2227 *
2228 * The error codes are a combination of special bits.
2229 * The copyout proceeds despite errors.
2230 * Conditions:
2231 * Nothing locked.
2232 * Returns:
2233 * MACH_MSG_SUCCESS Successful copyout.
2234 * MACH_MSG_IPC_SPACE No room for port right in name space.
2235 * MACH_MSG_VM_SPACE No room for memory in address space.
2236 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2237 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2238 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT
2239 */
2240
2241 mach_msg_return_t
2242 ipc_kmsg_copyout_body(
2243 ipc_kmsg_t kmsg,
2244 ipc_space_t space,
2245 vm_map_t map,
2246 mach_msg_body_t *slist)
2247 {
2248 mach_msg_body_t *body;
2249 mach_msg_descriptor_t *saddr, *eaddr;
2250 mach_msg_return_t mr = MACH_MSG_SUCCESS;
2251 kern_return_t kr;
2252 vm_offset_t data;
2253 mach_msg_descriptor_t *sstart, *send;
2254
2255 body = (mach_msg_body_t *) (&kmsg->ikm_header + 1);
2256 saddr = (mach_msg_descriptor_t *) (body + 1);
2257 eaddr = saddr + body->msgh_descriptor_count;
2258
2259 /*
2260 * Do scatter list setup
2261 */
2262 if (slist != MACH_MSG_BODY_NULL) {
2263 sstart = (mach_msg_descriptor_t *) (slist + 1);
2264 send = sstart + slist->msgh_descriptor_count;
2265 }
2266 else {
2267 sstart = MACH_MSG_DESCRIPTOR_NULL;
2268 }
2269
2270 for ( ; saddr < eaddr; saddr++ ) {
2271
2272 switch (saddr->type.type) {
2273
2274 case MACH_MSG_PORT_DESCRIPTOR: {
2275 mach_msg_port_descriptor_t *dsc;
2276
2277 /*
2278 * Copyout port right carried in the message
2279 */
2280 dsc = &saddr->port;
2281 mr |= ipc_kmsg_copyout_object(space,
2282 (ipc_object_t) dsc->name,
2283 dsc->disposition,
2284 (mach_port_name_t *) &dsc->name);
2285
2286 break;
2287 }
2288 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
2289 case MACH_MSG_OOL_DESCRIPTOR : {
2290 vm_offset_t rcv_addr;
2291 vm_offset_t snd_addr;
2292 mach_msg_ool_descriptor_t *dsc;
2293 mach_msg_copy_options_t copy_option;
2294
2295 SKIP_PORT_DESCRIPTORS(sstart, send);
2296
2297 dsc = &saddr->out_of_line;
2298
2299 assert(dsc->copy != MACH_MSG_KALLOC_COPY_T);
2300
2301 copy_option = dsc->copy;
2302
2303 if ((snd_addr = (vm_offset_t) dsc->address) != 0) {
2304 if (sstart != MACH_MSG_DESCRIPTOR_NULL &&
2305 sstart->out_of_line.copy == MACH_MSG_OVERWRITE) {
2306
2307 /*
2308 * There is an overwrite descriptor specified in the
2309 * scatter list for this ool data. The descriptor
2310 * has already been verified
2311 */
2312 rcv_addr = (vm_offset_t) sstart->out_of_line.address;
2313 dsc->copy = MACH_MSG_OVERWRITE;
2314 } else {
2315 dsc->copy = MACH_MSG_ALLOCATE;
2316 }
2317
2318 /*
2319 * Whether the data was virtually or physically
2320 * copied we have a vm_map_copy_t for it.
2321 * If there's an overwrite region specified
2322 * overwrite it, otherwise do a virtual copy out.
2323 */
2324 if (dsc->copy == MACH_MSG_OVERWRITE) {
2325 kr = vm_map_copy_overwrite(map, rcv_addr,
2326 (vm_map_copy_t) dsc->address, TRUE);
2327 } else {
2328 kr = vm_map_copyout(map, &rcv_addr,
2329 (vm_map_copy_t) dsc->address);
2330 }
2331 if (kr != KERN_SUCCESS) {
2332 if (kr == KERN_RESOURCE_SHORTAGE)
2333 mr |= MACH_MSG_VM_KERNEL;
2334 else
2335 mr |= MACH_MSG_VM_SPACE;
2336 vm_map_copy_discard((vm_map_copy_t) dsc->address);
2337 dsc->address = 0;
2338 INCREMENT_SCATTER(sstart);
2339 break;
2340 }
2341 dsc->address = (void *) rcv_addr;
2342 }
2343 INCREMENT_SCATTER(sstart);
2344 break;
2345 }
2346 case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
2347 vm_offset_t addr;
2348 mach_port_name_t *objects;
2349 mach_msg_type_number_t j;
2350 vm_size_t length;
2351 mach_msg_ool_ports_descriptor_t *dsc;
2352
2353 SKIP_PORT_DESCRIPTORS(sstart, send);
2354
2355 dsc = &saddr->ool_ports;
2356
2357 length = dsc->count * sizeof(mach_port_name_t);
2358
2359 if (length != 0) {
2360 if (sstart != MACH_MSG_DESCRIPTOR_NULL &&
2361 sstart->ool_ports.copy == MACH_MSG_OVERWRITE) {
2362
2363 /*
2364 * There is an overwrite descriptor specified in the
2365 * scatter list for this ool data. The descriptor
2366 * has already been verified
2367 */
2368 addr = (vm_offset_t) sstart->out_of_line.address;
2369 dsc->copy = MACH_MSG_OVERWRITE;
2370 }
2371 else {
2372
2373 /*
2374 * Dynamically allocate the region
2375 */
2376 int anywhere = VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|
2377 VM_FLAGS_ANYWHERE;
2378
2379 dsc->copy = MACH_MSG_ALLOCATE;
2380 if ((kr = vm_allocate(map, &addr, length,
2381 anywhere)) != KERN_SUCCESS) {
2382 ipc_kmsg_clean_body(kmsg,
2383 body->msgh_descriptor_count);
2384 dsc->address = 0;
2385
2386 if (kr == KERN_RESOURCE_SHORTAGE){
2387 mr |= MACH_MSG_VM_KERNEL;
2388 } else {
2389 mr |= MACH_MSG_VM_SPACE;
2390 }
2391 INCREMENT_SCATTER(sstart);
2392 break;
2393 }
2394 }
2395 } else {
2396 INCREMENT_SCATTER(sstart);
2397 break;
2398 }
2399
2400
2401 objects = (mach_port_name_t *) dsc->address ;
2402
2403 /* copyout port rights carried in the message */
2404
2405 for ( j = 0; j < dsc->count ; j++) {
2406 ipc_object_t object =
2407 (ipc_object_t) objects[j];
2408
2409 mr |= ipc_kmsg_copyout_object(space, object,
2410 dsc->disposition, &objects[j]);
2411 }
2412
2413 /* copyout to memory allocated above */
2414
2415 data = (vm_offset_t) dsc->address;
2416 (void) copyoutmap(map, data, addr, length);
2417 kfree(data, length);
2418
2419 dsc->address = (void *) addr;
2420 INCREMENT_SCATTER(sstart);
2421 break;
2422 }
2423 default : {
2424 panic("untyped IPC copyout body: invalid message descriptor");
2425 }
2426 }
2427 }
2428 return mr;
2429 }
2430
2431 /*
2432 * Routine: ipc_kmsg_copyout
2433 * Purpose:
2434 * "Copy-out" port rights and out-of-line memory
2435 * in the message.
2436 * Conditions:
2437 * Nothing locked.
2438 * Returns:
2439 * MACH_MSG_SUCCESS Copied out all rights and memory.
2440 * MACH_RCV_INVALID_NOTIFY Bad notify port.
2441 * Rights and memory in the message are intact.
2442 * MACH_RCV_HEADER_ERROR + special bits
2443 * Rights and memory in the message are intact.
2444 * MACH_RCV_BODY_ERROR + special bits
2445 * The message header was successfully copied out.
2446 * As much of the body was handled as possible.
2447 */
2448
2449 mach_msg_return_t
2450 ipc_kmsg_copyout(
2451 ipc_kmsg_t kmsg,
2452 ipc_space_t space,
2453 vm_map_t map,
2454 mach_port_name_t notify,
2455 mach_msg_body_t *slist)
2456 {
2457 mach_msg_return_t mr;
2458
2459 mr = ipc_kmsg_copyout_header(&kmsg->ikm_header, space, notify);
2460 if (mr != MACH_MSG_SUCCESS)
2461 return mr;
2462
2463 if (kmsg->ikm_header.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
2464 mr = ipc_kmsg_copyout_body(kmsg, space, map, slist);
2465
2466 if (mr != MACH_MSG_SUCCESS)
2467 mr |= MACH_RCV_BODY_ERROR;
2468 }
2469
2470 return mr;
2471 }
2472
2473 /*
2474 * Routine: ipc_kmsg_copyout_pseudo
2475 * Purpose:
2476 * Does a pseudo-copyout of the message.
2477 * This is like a regular copyout, except
2478 * that the ports in the header are handled
2479 * as if they are in the body. They aren't reversed.
2480 *
2481 * The error codes are a combination of special bits.
2482 * The copyout proceeds despite errors.
2483 * Conditions:
2484 * Nothing locked.
2485 * Returns:
2486 * MACH_MSG_SUCCESS Successful copyout.
2487 * MACH_MSG_IPC_SPACE No room for port right in name space.
2488 * MACH_MSG_VM_SPACE No room for memory in address space.
2489 * MACH_MSG_IPC_KERNEL Resource shortage handling port right.
2490 * MACH_MSG_VM_KERNEL Resource shortage handling memory.
2491 */
2492
2493 mach_msg_return_t
2494 ipc_kmsg_copyout_pseudo(
2495 ipc_kmsg_t kmsg,
2496 ipc_space_t space,
2497 vm_map_t map,
2498 mach_msg_body_t *slist)
2499 {
2500 mach_msg_bits_t mbits = kmsg->ikm_header.msgh_bits;
2501 ipc_object_t dest = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
2502 ipc_object_t reply = (ipc_object_t) kmsg->ikm_header.msgh_local_port;
2503 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits);
2504 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits);
2505 mach_port_name_t dest_name, reply_name;
2506 mach_msg_return_t mr;
2507
2508 assert(IO_VALID(dest));
2509
2510 mr = (ipc_kmsg_copyout_object(space, dest, dest_type, &dest_name) |
2511 ipc_kmsg_copyout_object(space, reply, reply_type, &reply_name));
2512
2513 kmsg->ikm_header.msgh_bits = mbits &~ MACH_MSGH_BITS_CIRCULAR;
2514 kmsg->ikm_header.msgh_remote_port = (ipc_port_t)dest_name;
2515 kmsg->ikm_header.msgh_local_port = (ipc_port_t)reply_name;
2516
2517 if (mbits & MACH_MSGH_BITS_COMPLEX) {
2518 mr |= ipc_kmsg_copyout_body(kmsg, space, map, slist);
2519 }
2520
2521 return mr;
2522 }
2523
2524 /*
2525 * Routine: ipc_kmsg_copyout_dest
2526 * Purpose:
2527 * Copies out the destination port in the message.
2528 * Destroys all other rights and memory in the message.
2529 * Conditions:
2530 * Nothing locked.
2531 */
2532
2533 void
2534 ipc_kmsg_copyout_dest(
2535 ipc_kmsg_t kmsg,
2536 ipc_space_t space)
2537 {
2538 mach_msg_bits_t mbits;
2539 ipc_object_t dest;
2540 ipc_object_t reply;
2541 mach_msg_type_name_t dest_type;
2542 mach_msg_type_name_t reply_type;
2543 mach_port_name_t dest_name, reply_name;
2544
2545 mbits = kmsg->ikm_header.msgh_bits;
2546 dest = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
2547 reply = (ipc_object_t) kmsg->ikm_header.msgh_local_port;
2548 dest_type = MACH_MSGH_BITS_REMOTE(mbits);
2549 reply_type = MACH_MSGH_BITS_LOCAL(mbits);
2550
2551 assert(IO_VALID(dest));
2552
2553 io_lock(dest);
2554 if (io_active(dest)) {
2555 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
2556 /* dest is unlocked */
2557 } else {
2558 io_release(dest);
2559 io_check_unlock(dest);
2560 dest_name = MACH_PORT_DEAD;
2561 }
2562
2563 if (IO_VALID(reply)) {
2564 ipc_object_destroy(reply, reply_type);
2565 reply_name = MACH_PORT_NULL;
2566 } else
2567 reply_name = (mach_port_name_t) reply;
2568
2569 kmsg->ikm_header.msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) |
2570 MACH_MSGH_BITS(reply_type, dest_type));
2571 kmsg->ikm_header.msgh_local_port = (ipc_port_t)dest_name;
2572 kmsg->ikm_header.msgh_remote_port = (ipc_port_t)reply_name;
2573
2574 if (mbits & MACH_MSGH_BITS_COMPLEX) {
2575 mach_msg_body_t *body;
2576
2577 body = (mach_msg_body_t *) (&kmsg->ikm_header + 1);
2578 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count);
2579 }
2580 }
2581 /*
2582 * Routine: ipc_kmsg_copyin_scatter
2583 * Purpose:
2584 * allocate and copyin a scatter list
2585 * Algorithm:
2586 * The gather (kmsg) is valid since it has been copied in.
2587 * Gather list descriptors are sequentially paired with scatter
2588 * list descriptors, with port descriptors in either list ignored.
2589 * Descriptors are consistent if the type fileds match and size
2590 * of the scatter descriptor is less than or equal to the
2591 * size of the gather descriptor. A MACH_MSG_ALLOCATE copy
2592 * strategy in a scatter descriptor matches any size in the
2593 * corresponding gather descriptor assuming they are the same type.
2594 * Either list may be larger than the other. During the
2595 * subsequent copy out, excess scatter descriptors are ignored
2596 * and excess gather descriptors default to dynamic allocation.
2597 *
2598 * In the case of a size error, the scatter list is released.
2599 * Conditions:
2600 * Nothing locked.
2601 * Returns:
2602 * the allocated message body containing the scatter list.
2603 */
2604
2605 mach_msg_body_t *
2606 ipc_kmsg_copyin_scatter(
2607 mach_msg_header_t *msg,
2608 mach_msg_size_t slist_size,
2609 ipc_kmsg_t kmsg)
2610 {
2611 mach_msg_body_t *slist;
2612 mach_msg_body_t *body;
2613 mach_msg_descriptor_t *gstart, *gend;
2614 mach_msg_descriptor_t *sstart, *send;
2615
2616
2617 if (slist_size < sizeof(mach_msg_base_t))
2618 return MACH_MSG_BODY_NULL;
2619
2620 slist_size -= sizeof(mach_msg_header_t);
2621 slist = (mach_msg_body_t *)kalloc(slist_size);
2622 if (slist == MACH_MSG_BODY_NULL)
2623 return slist;
2624
2625 if (copyin((char *) (msg + 1), (char *)slist, slist_size)) {
2626 kfree((vm_offset_t)slist, slist_size);
2627 return MACH_MSG_BODY_NULL;
2628 }
2629
2630 if ((slist->msgh_descriptor_count* sizeof(mach_msg_descriptor_t)
2631 + sizeof(mach_msg_size_t)) > slist_size) {
2632 kfree((vm_offset_t)slist, slist_size);
2633 return MACH_MSG_BODY_NULL;
2634 }
2635
2636 body = (mach_msg_body_t *) (&kmsg->ikm_header + 1);
2637 gstart = (mach_msg_descriptor_t *) (body + 1);
2638 gend = gstart + body->msgh_descriptor_count;
2639
2640 sstart = (mach_msg_descriptor_t *) (slist + 1);
2641 send = sstart + slist->msgh_descriptor_count;
2642
2643 while (gstart < gend) {
2644 mach_msg_descriptor_type_t g_type;
2645
2646 /*
2647 * Skip port descriptors in gather list.
2648 */
2649 g_type = gstart->type.type;
2650
2651 if (g_type != MACH_MSG_PORT_DESCRIPTOR) {
2652
2653 /*
2654 * A scatter list with a 0 descriptor count is treated as an
2655 * automatic size mismatch.
2656 */
2657 if (slist->msgh_descriptor_count == 0) {
2658 kfree((vm_offset_t)slist, slist_size);
2659 return MACH_MSG_BODY_NULL;
2660 }
2661
2662 /*
2663 * Skip port descriptors in scatter list.
2664 */
2665 while (sstart < send) {
2666 if (sstart->type.type != MACH_MSG_PORT_DESCRIPTOR)
2667 break;
2668 sstart++;
2669 }
2670
2671 /*
2672 * No more scatter descriptors, we're done
2673 */
2674 if (sstart >= send) {
2675 break;
2676 }
2677
2678 /*
2679 * Check type, copy and size fields
2680 */
2681 if (g_type == MACH_MSG_OOL_DESCRIPTOR ||
2682 g_type == MACH_MSG_OOL_VOLATILE_DESCRIPTOR) {
2683 if (sstart->type.type != MACH_MSG_OOL_DESCRIPTOR &&
2684 sstart->type.type != MACH_MSG_OOL_VOLATILE_DESCRIPTOR) {
2685 kfree((vm_offset_t)slist, slist_size);
2686 return MACH_MSG_BODY_NULL;
2687 }
2688 if (sstart->out_of_line.copy == MACH_MSG_OVERWRITE &&
2689 gstart->out_of_line.size > sstart->out_of_line.size) {
2690 kfree((vm_offset_t)slist, slist_size);
2691 return MACH_MSG_BODY_NULL;
2692 }
2693 }
2694 else {
2695 if (sstart->type.type != MACH_MSG_OOL_PORTS_DESCRIPTOR) {
2696 kfree((vm_offset_t)slist, slist_size);
2697 return MACH_MSG_BODY_NULL;
2698 }
2699 if (sstart->ool_ports.copy == MACH_MSG_OVERWRITE &&
2700 gstart->ool_ports.count > sstart->ool_ports.count) {
2701 kfree((vm_offset_t)slist, slist_size);
2702 return MACH_MSG_BODY_NULL;
2703 }
2704 }
2705 sstart++;
2706 }
2707 gstart++;
2708 }
2709 return slist;
2710 }
2711
2712
2713 /*
2714 * Routine: ipc_kmsg_free_scatter
2715 * Purpose:
2716 * Deallocate a scatter list. Since we actually allocated
2717 * a body without a header, and since the header was originally
2718 * accounted for in slist_size, we have to ajust it down
2719 * before freeing the scatter list.
2720 */
2721 void
2722 ipc_kmsg_free_scatter(
2723 mach_msg_body_t *slist,
2724 mach_msg_size_t slist_size)
2725 {
2726 slist_size -= sizeof(mach_msg_header_t);
2727 kfree((vm_offset_t)slist, slist_size);
2728 }
2729
2730
2731 /*
2732 * Routine: ipc_kmsg_copyout_to_kernel
2733 * Purpose:
2734 * Copies out the destination and reply ports in the message.
2735 * Leaves all other rights and memory in the message alone.
2736 * Conditions:
2737 * Nothing locked.
2738 *
2739 * Derived from ipc_kmsg_copyout_dest.
2740 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest).
2741 * We really do want to save rights and memory.
2742 */
2743
2744 void
2745 ipc_kmsg_copyout_to_kernel(
2746 ipc_kmsg_t kmsg,
2747 ipc_space_t space)
2748 {
2749 ipc_object_t dest;
2750 ipc_object_t reply;
2751 mach_msg_type_name_t dest_type;
2752 mach_msg_type_name_t reply_type;
2753 mach_port_name_t dest_name, reply_name;
2754
2755 dest = (ipc_object_t) kmsg->ikm_header.msgh_remote_port;
2756 reply = (ipc_object_t) kmsg->ikm_header.msgh_local_port;
2757 dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header.msgh_bits);
2758 reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header.msgh_bits);
2759
2760 assert(IO_VALID(dest));
2761
2762 io_lock(dest);
2763 if (io_active(dest)) {
2764 ipc_object_copyout_dest(space, dest, dest_type, &dest_name);
2765 /* dest is unlocked */
2766 } else {
2767 io_release(dest);
2768 io_check_unlock(dest);
2769 dest_name = MACH_PORT_DEAD;
2770 }
2771
2772 reply_name = (mach_port_name_t) reply;
2773
2774 kmsg->ikm_header.msgh_bits =
2775 (MACH_MSGH_BITS_OTHER(kmsg->ikm_header.msgh_bits) |
2776 MACH_MSGH_BITS(reply_type, dest_type));
2777 kmsg->ikm_header.msgh_local_port = (ipc_port_t)dest_name;
2778 kmsg->ikm_header.msgh_remote_port = (ipc_port_t)reply_name;
2779 }
2780
2781 #include <mach_kdb.h>
2782 #if MACH_KDB
2783
2784 #include <ddb/db_output.h>
2785 #include <ipc/ipc_print.h>
2786 /*
2787 * Forward declarations
2788 */
2789 void ipc_msg_print_untyped(
2790 mach_msg_body_t *body);
2791
2792 char * ipc_type_name(
2793 int type_name,
2794 boolean_t received);
2795
2796 void ipc_print_type_name(
2797 int type_name);
2798
2799 char *
2800 msgh_bit_decode(
2801 mach_msg_bits_t bit);
2802
2803 char *
2804 mm_copy_options_string(
2805 mach_msg_copy_options_t option);
2806
2807 void db_print_msg_uid(mach_msg_header_t *);
2808
2809
2810 char *
2811 ipc_type_name(
2812 int type_name,
2813 boolean_t received)
2814 {
2815 switch (type_name) {
2816 case MACH_MSG_TYPE_PORT_NAME:
2817 return "port_name";
2818
2819 case MACH_MSG_TYPE_MOVE_RECEIVE:
2820 if (received) {
2821 return "port_receive";
2822 } else {
2823 return "move_receive";
2824 }
2825
2826 case MACH_MSG_TYPE_MOVE_SEND:
2827 if (received) {
2828 return "port_send";
2829 } else {
2830 return "move_send";
2831 }
2832
2833 case MACH_MSG_TYPE_MOVE_SEND_ONCE:
2834 if (received) {
2835 return "port_send_once";
2836 } else {
2837 return "move_send_once";
2838 }
2839
2840 case MACH_MSG_TYPE_COPY_SEND:
2841 return "copy_send";
2842
2843 case MACH_MSG_TYPE_MAKE_SEND:
2844 return "make_send";
2845
2846 case MACH_MSG_TYPE_MAKE_SEND_ONCE:
2847 return "make_send_once";
2848
2849 default:
2850 return (char *) 0;
2851 }
2852 }
2853
2854 void
2855 ipc_print_type_name(
2856 int type_name)
2857 {
2858 char *name = ipc_type_name(type_name, TRUE);
2859 if (name) {
2860 printf("%s", name);
2861 } else {
2862 printf("type%d", type_name);
2863 }
2864 }
2865
2866 /*
2867 * ipc_kmsg_print [ debug ]
2868 */
2869 void
2870 ipc_kmsg_print(
2871 ipc_kmsg_t kmsg)
2872 {
2873 iprintf("kmsg=0x%x\n", kmsg);
2874 iprintf("ikm_next=0x%x, prev=0x%x, size=%d",
2875 kmsg->ikm_next,
2876 kmsg->ikm_prev,
2877 kmsg->ikm_size);
2878 printf("\n");
2879 ipc_msg_print(&kmsg->ikm_header);
2880 }
2881
2882 char *
2883 msgh_bit_decode(
2884 mach_msg_bits_t bit)
2885 {
2886 switch (bit) {
2887 case MACH_MSGH_BITS_COMPLEX: return "complex";
2888 case MACH_MSGH_BITS_CIRCULAR: return "circular";
2889 default: return (char *) 0;
2890 }
2891 }
2892
2893 /*
2894 * ipc_msg_print [ debug ]
2895 */
2896 void
2897 ipc_msg_print(
2898 mach_msg_header_t *msgh)
2899 {
2900 mach_msg_bits_t mbits;
2901 unsigned int bit, i;
2902 char *bit_name;
2903 int needs_comma;
2904
2905 mbits = msgh->msgh_bits;
2906 iprintf("msgh_bits=0x%x: l=0x%x,r=0x%x\n",
2907 mbits,
2908 MACH_MSGH_BITS_LOCAL(msgh->msgh_bits),
2909 MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
2910
2911 mbits = MACH_MSGH_BITS_OTHER(mbits) & MACH_MSGH_BITS_USED;
2912 db_indent += 2;
2913 if (mbits)
2914 iprintf("decoded bits: ");
2915 needs_comma = 0;
2916 for (i = 0, bit = 1; i < sizeof(mbits) * 8; ++i, bit <<= 1) {
2917 if ((mbits & bit) == 0)
2918 continue;
2919 bit_name = msgh_bit_decode((mach_msg_bits_t)bit);
2920 if (bit_name)
2921 printf("%s%s", needs_comma ? "," : "", bit_name);
2922 else
2923 printf("%sunknown(0x%x),", needs_comma ? "," : "", bit);
2924 ++needs_comma;
2925 }
2926 if (msgh->msgh_bits & ~MACH_MSGH_BITS_USED) {
2927 printf("%sunused=0x%x,", needs_comma ? "," : "",
2928 msgh->msgh_bits & ~MACH_MSGH_BITS_USED);
2929 }
2930 printf("\n");
2931 db_indent -= 2;
2932
2933 needs_comma = 1;
2934 if (msgh->msgh_remote_port) {
2935 iprintf("remote=0x%x(", msgh->msgh_remote_port);
2936 ipc_print_type_name(MACH_MSGH_BITS_REMOTE(msgh->msgh_bits));
2937 printf(")");
2938 } else {
2939 iprintf("remote=null");
2940 }
2941
2942 if (msgh->msgh_local_port) {
2943 printf("%slocal=0x%x(", needs_comma ? "," : "",
2944 msgh->msgh_local_port);
2945 ipc_print_type_name(MACH_MSGH_BITS_LOCAL(msgh->msgh_bits));
2946 printf(")\n");
2947 } else {
2948 printf("local=null\n");
2949 }
2950
2951 iprintf("msgh_id=%d, size=%d\n",
2952 msgh->msgh_id,
2953 msgh->msgh_size);
2954
2955 if (mbits & MACH_MSGH_BITS_COMPLEX) {
2956 ipc_msg_print_untyped((mach_msg_body_t *) (msgh + 1));
2957 }
2958 }
2959
2960
2961 char *
2962 mm_copy_options_string(
2963 mach_msg_copy_options_t option)
2964 {
2965 char *name;
2966
2967 switch (option) {
2968 case MACH_MSG_PHYSICAL_COPY:
2969 name = "PHYSICAL";
2970 break;
2971 case MACH_MSG_VIRTUAL_COPY:
2972 name = "VIRTUAL";
2973 break;
2974 case MACH_MSG_OVERWRITE:
2975 name = "OVERWRITE";
2976 break;
2977 case MACH_MSG_ALLOCATE:
2978 name = "ALLOCATE";
2979 break;
2980 case MACH_MSG_KALLOC_COPY_T:
2981 name = "KALLOC_COPY_T";
2982 break;
2983 default:
2984 name = "unknown";
2985 break;
2986 }
2987 return name;
2988 }
2989
2990 void
2991 ipc_msg_print_untyped(
2992 mach_msg_body_t *body)
2993 {
2994 mach_msg_descriptor_t *saddr, *send;
2995 mach_msg_descriptor_type_t type;
2996
2997 iprintf("%d descriptors %d: \n", body->msgh_descriptor_count);
2998
2999 saddr = (mach_msg_descriptor_t *) (body + 1);
3000 send = saddr + body->msgh_descriptor_count;
3001
3002 for ( ; saddr < send; saddr++ ) {
3003
3004 type = saddr->type.type;
3005
3006 switch (type) {
3007
3008 case MACH_MSG_PORT_DESCRIPTOR: {
3009 mach_msg_port_descriptor_t *dsc;
3010
3011 dsc = &saddr->port;
3012 iprintf("-- PORT name = 0x%x disp = ", dsc->name);
3013 ipc_print_type_name(dsc->disposition);
3014 printf("\n");
3015 break;
3016 }
3017 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3018 case MACH_MSG_OOL_DESCRIPTOR: {
3019 mach_msg_ool_descriptor_t *dsc;
3020
3021 dsc = &saddr->out_of_line;
3022 iprintf("-- OOL%s addr = 0x%x size = 0x%x copy = %s %s\n",
3023 type == MACH_MSG_OOL_DESCRIPTOR ? "" : " VOLATILE",
3024 dsc->address, dsc->size,
3025 mm_copy_options_string(dsc->copy),
3026 dsc->deallocate ? "DEALLOC" : "");
3027 break;
3028 }
3029 case MACH_MSG_OOL_PORTS_DESCRIPTOR : {
3030 mach_msg_ool_ports_descriptor_t *dsc;
3031
3032 dsc = &saddr->ool_ports;
3033
3034 iprintf("-- OOL_PORTS addr = 0x%x count = 0x%x ",
3035 dsc->address, dsc->count);
3036 printf("disp = ");
3037 ipc_print_type_name(dsc->disposition);
3038 printf(" copy = %s %s\n",
3039 mm_copy_options_string(dsc->copy),
3040 dsc->deallocate ? "DEALLOC" : "");
3041 break;
3042 }
3043
3044 default: {
3045 iprintf("-- UNKNOWN DESCRIPTOR 0x%x\n", type);
3046 break;
3047 }
3048 }
3049 }
3050 }
3051 #endif /* MACH_KDB */