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