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