1/* 2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31/* 32 * Mach Operating System 33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56/* 57 * NOTICE: This file was modified by McAfee Research in 2004 to introduce 58 * support for mandatory and extensible security protections. This notice 59 * is included in support of clause 2.2 (b) of the Apple Public License, 60 * Version 2.0. 61 * Copyright (c) 2005 SPARTA, Inc. 62 */ 63/* 64 */ 65/* 66 * File: ipc/ipc_kmsg.c 67 * Author: Rich Draves 68 * Date: 1989 69 * 70 * Operations on kernel messages. 71 */ 72 73 74#include <mach/mach_types.h> 75#include <mach/boolean.h> 76#include <mach/kern_return.h> 77#include <mach/message.h> 78#include <mach/port.h> 79#include <mach/vm_map.h> 80#include <mach/mach_vm.h> 81#include <mach/vm_statistics.h> 82 83#include <kern/kern_types.h> 84#include <kern/assert.h> 85#include <kern/debug.h> 86#include <kern/ipc_kobject.h> 87#include <kern/kalloc.h> 88#include <kern/zalloc.h> 89#include <kern/processor.h> 90#include <kern/thread.h> 91#include <kern/sched_prim.h> 92#include <kern/spl.h> 93#include <kern/misc_protos.h> 94#include <kern/counters.h> 95#include <kern/cpu_data.h> 96 97#include <machine/machlimits.h> 98 99#include <vm/vm_map.h> 100#include <vm/vm_object.h> 101#include <vm/vm_kern.h> 102 103#include <ipc/port.h> 104#include <ipc/ipc_types.h> 105#include <ipc/ipc_entry.h> 106#include <ipc/ipc_kmsg.h> 107#include <ipc/ipc_notify.h> 108#include <ipc/ipc_object.h> 109#include <ipc/ipc_space.h> 110#include <ipc/ipc_port.h> 111#include <ipc/ipc_right.h> 112#include <ipc/ipc_hash.h> 113#include <ipc/ipc_table.h> 114 115#include <security/mac_mach_internal.h> 116 117#include <string.h> 118 119#ifdef ppc 120#include <ppc/Firmware.h> 121#include <ppc/low_trace.h> 122#endif 123 124#if DEBUG 125#define DEBUG_MSGS_K64 1 126#endif 127 128#include <sys/kdebug.h> 129#include <libkern/OSAtomic.h> 130 131#pragma pack(4) 132 133typedef struct 134{ 135 mach_msg_bits_t msgh_bits; 136 mach_msg_size_t msgh_size; 137 uint32_t msgh_remote_port; 138 uint32_t msgh_local_port; 139 mach_msg_size_t msgh_reserved; 140 mach_msg_id_t msgh_id; 141} mach_msg_legacy_header_t; 142 143typedef struct 144{ 145 mach_msg_legacy_header_t header; 146 mach_msg_body_t body; 147} mach_msg_legacy_base_t; 148 149typedef struct 150{ 151 mach_port_name_t name; 152 mach_msg_size_t pad1; 153 uint32_t pad2 : 16; 154 mach_msg_type_name_t disposition : 8; 155 mach_msg_descriptor_type_t type : 8; 156} mach_msg_legacy_port_descriptor_t; 157 158 159typedef union 160{ 161 mach_msg_legacy_port_descriptor_t port; 162 mach_msg_ool_descriptor32_t out_of_line32; 163 mach_msg_ool_ports_descriptor32_t ool_ports32; 164 mach_msg_type_descriptor_t type; 165} mach_msg_legacy_descriptor_t; 166 167#pragma pack() 168 169#define LEGACY_HEADER_SIZE_DELTA ((mach_msg_size_t)(sizeof(mach_msg_header_t) - sizeof(mach_msg_legacy_header_t))) 170// END LP64 fixes 171 172 173#if DEBUG_MSGS_K64 174extern void ipc_pset_print64( 175 ipc_pset_t pset); 176 177extern void ipc_kmsg_print64( 178 ipc_kmsg_t kmsg, 179 const char *str); 180 181extern void ipc_msg_print64( 182 mach_msg_header_t *msgh); 183 184extern ipc_port_t ipc_name_to_data64( 185 task_t task, 186 mach_port_name_t name); 187 188/* 189 * Forward declarations 190 */ 191void ipc_msg_print_untyped64( 192 mach_msg_body_t *body); 193 194const char * ipc_type_name64( 195 int type_name, 196 boolean_t received); 197 198void ipc_print_type_name64( 199 int type_name); 200 201const char * 202msgh_bit_decode64( 203 mach_msg_bits_t bit); 204 205const char * 206mm_copy_options_string64( 207 mach_msg_copy_options_t option); 208 209void db_print_msg_uid64(mach_msg_header_t *); 210 211static void 212ipc_msg_body_print64(void *body, int size) 213{ 214 uint32_t *word = (uint32_t *) body; 215 uint32_t *end = (uint32_t *)(((uintptr_t) body) + size 216 - sizeof(mach_msg_header_t)); 217 int i; 218 219 kprintf(" body(%p-%p):\n %p: ", body, end, word); 220 for (;;) { 221 for (i = 0; i < 8; i++, word++) { 222 if (word >= end) { 223 kprintf("\n"); 224 return; 225 } 226 kprintf("%08x ", *word); 227 } 228 kprintf("\n %p: ", word); 229 } 230} 231 232 233const char * 234ipc_type_name64( 235 int type_name, 236 boolean_t received) 237{ 238 switch (type_name) { 239 case MACH_MSG_TYPE_PORT_NAME: 240 return "port_name"; 241 242 case MACH_MSG_TYPE_MOVE_RECEIVE: 243 if (received) { 244 return "port_receive"; 245 } else { 246 return "move_receive"; 247 } 248 249 case MACH_MSG_TYPE_MOVE_SEND: 250 if (received) { 251 return "port_send"; 252 } else { 253 return "move_send"; 254 } 255 256 case MACH_MSG_TYPE_MOVE_SEND_ONCE: 257 if (received) { 258 return "port_send_once"; 259 } else { 260 return "move_send_once"; 261 } 262 263 case MACH_MSG_TYPE_COPY_SEND: 264 return "copy_send"; 265 266 case MACH_MSG_TYPE_MAKE_SEND: 267 return "make_send"; 268 269 case MACH_MSG_TYPE_MAKE_SEND_ONCE: 270 return "make_send_once"; 271 272 default: 273 return (char *) 0; 274 } 275} 276 277void 278ipc_print_type_name64( 279 int type_name) 280{ 281 const char *name = ipc_type_name64(type_name, TRUE); 282 if (name) { 283 kprintf("%s", name); 284 } else { 285 kprintf("type%d", type_name); 286 } 287} 288 289/* 290 * ipc_kmsg_print64 [ debug ] 291 */ 292void 293ipc_kmsg_print64( 294 ipc_kmsg_t kmsg, 295 const char *str) 296{ 297 kprintf("%s kmsg=%p:\n", str, kmsg); 298 kprintf(" next=%p, prev=%p, size=%d", 299 kmsg->ikm_next, 300 kmsg->ikm_prev, 301 kmsg->ikm_size); 302 kprintf("\n"); 303 ipc_msg_print64(kmsg->ikm_header); 304} 305 306const char * 307msgh_bit_decode64( 308 mach_msg_bits_t bit) 309{ 310 switch (bit) { 311 case MACH_MSGH_BITS_COMPLEX: return "complex"; 312 case MACH_MSGH_BITS_CIRCULAR: return "circular"; 313 default: return (char *) 0; 314 } 315} 316 317/* 318 * ipc_msg_print64 [ debug ] 319 */ 320void 321ipc_msg_print64( 322 mach_msg_header_t *msgh) 323{ 324 mach_msg_bits_t mbits; 325 unsigned int bit, i; 326 const char *bit_name; 327 int needs_comma; 328 329 mbits = msgh->msgh_bits; 330 kprintf(" msgh_bits=0x%x: l=0x%x,r=0x%x\n", 331 mbits, 332 MACH_MSGH_BITS_LOCAL(msgh->msgh_bits), 333 MACH_MSGH_BITS_REMOTE(msgh->msgh_bits)); 334 335 mbits = MACH_MSGH_BITS_OTHER(mbits) & MACH_MSGH_BITS_USED; 336 kprintf(" decoded bits: "); 337 needs_comma = 0; 338 for (i = 0, bit = 1; i < sizeof(mbits) * 8; ++i, bit <<= 1) { 339 if ((mbits & bit) == 0) 340 continue; 341 bit_name = msgh_bit_decode64((mach_msg_bits_t)bit); 342 if (bit_name) 343 kprintf("%s%s", needs_comma ? "," : "", bit_name); 344 else 345 kprintf("%sunknown(0x%x),", needs_comma ? "," : "", bit); 346 ++needs_comma; 347 } 348 if (msgh->msgh_bits & ~MACH_MSGH_BITS_USED) { 349 kprintf("%sunused=0x%x,", needs_comma ? "," : "", 350 msgh->msgh_bits & ~MACH_MSGH_BITS_USED); 351 } 352 kprintf("\n"); 353 354 needs_comma = 1; 355 if (msgh->msgh_remote_port) { 356 kprintf(" remote=%p(", msgh->msgh_remote_port); 357 ipc_print_type_name64(MACH_MSGH_BITS_REMOTE(msgh->msgh_bits)); 358 kprintf(")"); 359 } else { 360 kprintf(" remote=null"); 361 } 362 363 if (msgh->msgh_local_port) { 364 kprintf("%slocal=%p(", needs_comma ? "," : "", 365 msgh->msgh_local_port); 366 ipc_print_type_name64(MACH_MSGH_BITS_LOCAL(msgh->msgh_bits)); 367 kprintf(")\n"); 368 } else { 369 kprintf("local=null\n"); 370 } 371 372 kprintf(" msgh_id=%d, size=%d\n", 373 msgh->msgh_id, 374 msgh->msgh_size); 375 376 if (mbits & MACH_MSGH_BITS_COMPLEX) { 377 ipc_msg_print_untyped64((mach_msg_body_t *) (msgh + 1)); 378 } 379 380 ipc_msg_body_print64((void *)(msgh + 1), msgh->msgh_size); 381} 382 383 384const char * 385mm_copy_options_string64( 386 mach_msg_copy_options_t option) 387{ 388 const char *name; 389 390 switch (option) { 391 case MACH_MSG_PHYSICAL_COPY: 392 name = "PHYSICAL"; 393 break; 394 case MACH_MSG_VIRTUAL_COPY: 395 name = "VIRTUAL"; 396 break; 397 case MACH_MSG_OVERWRITE: 398 name = "OVERWRITE"; 399 break; 400 case MACH_MSG_ALLOCATE: 401 name = "ALLOCATE"; 402 break; 403 case MACH_MSG_KALLOC_COPY_T: 404 name = "KALLOC_COPY_T"; 405 break; 406 default: 407 name = "unknown"; 408 break; 409 } 410 return name; 411} 412 413void 414ipc_msg_print_untyped64( 415 mach_msg_body_t *body) 416{ 417 mach_msg_descriptor_t *saddr, *send; 418 mach_msg_descriptor_type_t type; 419 420 kprintf(" %d descriptors: \n", body->msgh_descriptor_count); 421 422 saddr = (mach_msg_descriptor_t *) (body + 1); 423 send = saddr + body->msgh_descriptor_count; 424 425 for ( ; saddr < send; saddr++ ) { 426 427 type = saddr->type.type; 428 429 switch (type) { 430 431 case MACH_MSG_PORT_DESCRIPTOR: { 432 mach_msg_port_descriptor_t *dsc; 433 434 dsc = &saddr->port; 435 kprintf(" PORT name = %p disp = ", dsc->name); 436 ipc_print_type_name64(dsc->disposition); 437 kprintf("\n"); 438 break; 439 } 440 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 441 case MACH_MSG_OOL_DESCRIPTOR: { 442 mach_msg_ool_descriptor_t *dsc; 443 444 dsc = (mach_msg_ool_descriptor_t *) &saddr->out_of_line; 445 kprintf(" OOL%s addr = %p size = 0x%x copy = %s %s\n", 446 type == MACH_MSG_OOL_DESCRIPTOR ? "" : " VOLATILE", 447 dsc->address, dsc->size, 448 mm_copy_options_string64(dsc->copy), 449 dsc->deallocate ? "DEALLOC" : ""); 450 break; 451 } 452 case MACH_MSG_OOL_PORTS_DESCRIPTOR : { 453 mach_msg_ool_ports_descriptor_t *dsc; 454 455 dsc = (mach_msg_ool_ports_descriptor_t *) &saddr->ool_ports; 456 457 kprintf(" OOL_PORTS addr = %p count = 0x%x ", 458 dsc->address, dsc->count); 459 kprintf("disp = "); 460 ipc_print_type_name64(dsc->disposition); 461 kprintf(" copy = %s %s\n", 462 mm_copy_options_string64(dsc->copy), 463 dsc->deallocate ? "DEALLOC" : ""); 464 break; 465 } 466 467 default: { 468 kprintf(" UNKNOWN DESCRIPTOR 0x%x\n", type); 469 break; 470 } 471 } 472 } 473} 474 475#define DEBUG_IPC_KMSG_PRINT(kmsg,string) \ 476 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \ 477 ipc_kmsg_print64(kmsg, string); \ 478 } 479#define DEBUG_IPC_MSG_BODY_PRINT(body,size) \ 480 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { \ 481 ipc_msg_body_print64(body,size);\ 482 } 483#else /* !DEBUG_MSGS_K64 */ 484#define DEBUG_IPC_KMSG_PRINT(kmsg,string) 485#define DEBUG_IPC_MSG_BODY_PRINT(body,size) 486#endif /* !DEBUG_MSGS_K64 */ 487 488extern vm_map_t ipc_kernel_copy_map; 489extern vm_size_t ipc_kmsg_max_space; 490extern vm_size_t ipc_kmsg_max_vm_space; 491extern vm_size_t ipc_kmsg_max_body_space; 492extern vm_size_t msg_ool_size_small; 493 494#define MSG_OOL_SIZE_SMALL msg_ool_size_small 495 496#if defined(__LP64__) 497#define MAP_SIZE_DIFFERS(map) (map->max_offset < MACH_VM_MAX_ADDRESS) 498#define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor32_t 499#define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor32_t 500#else 501#define MAP_SIZE_DIFFERS(map) (map->max_offset > VM_MAX_ADDRESS) 502#define OTHER_OOL_DESCRIPTOR mach_msg_ool_descriptor64_t 503#define OTHER_OOL_PORTS_DESCRIPTOR mach_msg_ool_ports_descriptor64_t 504#endif 505 506#define DESC_SIZE_ADJUSTMENT ((mach_msg_size_t)(sizeof(mach_msg_ool_descriptor64_t) - \ 507 sizeof(mach_msg_ool_descriptor32_t))) 508 509/* scatter list macros */ 510 511#define SKIP_PORT_DESCRIPTORS(s, c) \ 512MACRO_BEGIN \ 513 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \ 514 while ((c) > 0) { \ 515 if ((s)->type.type != MACH_MSG_PORT_DESCRIPTOR) \ 516 break; \ 517 (s)++; (c)--; \ 518 } \ 519 if (c == 0) \ 520 (s) = MACH_MSG_DESCRIPTOR_NULL; \ 521 } \ 522MACRO_END 523 524#define INCREMENT_SCATTER(s, c, d) \ 525MACRO_BEGIN \ 526 if ((s) != MACH_MSG_DESCRIPTOR_NULL) { \ 527 s = (d) ? (mach_msg_descriptor_t *) \ 528 ((OTHER_OOL_DESCRIPTOR *)(s) + 1) : \ 529 (s + 1); \ 530 (c)--; \ 531 } \ 532MACRO_END 533 534/* zone for cached ipc_kmsg_t structures */ 535zone_t ipc_kmsg_zone; 536 537/* 538 * Forward declarations 539 */ 540 541void ipc_kmsg_clean( 542 ipc_kmsg_t kmsg); 543 544void ipc_kmsg_clean_body( 545 ipc_kmsg_t kmsg, 546 mach_msg_type_number_t number, 547 mach_msg_descriptor_t *desc); 548 549void ipc_kmsg_clean_partial( 550 ipc_kmsg_t kmsg, 551 mach_msg_type_number_t number, 552 mach_msg_descriptor_t *desc, 553 vm_offset_t paddr, 554 vm_size_t length); 555 556mach_msg_return_t ipc_kmsg_copyin_body( 557 ipc_kmsg_t kmsg, 558 ipc_space_t space, 559 vm_map_t map); 560 561/* 562 * We keep a per-processor cache of kernel message buffers. 563 * The cache saves the overhead/locking of using kalloc/kfree. 564 * The per-processor cache seems to miss less than a per-thread cache, 565 * and it also uses less memory. Access to the cache doesn't 566 * require locking. 567 */ 568 569/* 570 * Routine: ipc_kmsg_alloc 571 * Purpose: 572 * Allocate a kernel message structure. If we can get one from 573 * the cache, that is best. Otherwise, allocate a new one. 574 * Conditions: 575 * Nothing locked. 576 */ 577ipc_kmsg_t 578ipc_kmsg_alloc( 579 mach_msg_size_t msg_and_trailer_size) 580{ 581 mach_msg_size_t max_expanded_size; 582 ipc_kmsg_t kmsg; 583 584 /* 585 * LP64support - 586 * Pad the allocation in case we need to expand the 587 * message descrptors for user spaces with pointers larger than 588 * the kernel's own, or vice versa. We don't know how many descriptors 589 * there are yet, so just assume the whole body could be 590 * descriptors (if there could be any at all). 591 * 592 * The expansion space is left in front of the header, 593 * because it is easier to pull the header and descriptors 594 * forward as we process them than it is to push all the 595 * data backwards. 596 */ 597 mach_msg_size_t size = msg_and_trailer_size - MAX_TRAILER_SIZE; 598 599 /* compare against implementation upper limit for the body */ 600 if (size > ipc_kmsg_max_body_space) 601 return IKM_NULL; 602 603 if (size > sizeof(mach_msg_base_t)) { 604 mach_msg_size_t max_desc = (mach_msg_size_t)(((size - sizeof(mach_msg_base_t)) / 605 sizeof(mach_msg_ool_descriptor32_t)) * 606 DESC_SIZE_ADJUSTMENT); 607 608 /* make sure expansion won't cause wrap */ 609 if (msg_and_trailer_size > MACH_MSG_SIZE_MAX - max_desc) 610 return IKM_NULL; 611 612 max_expanded_size = msg_and_trailer_size + max_desc; 613 } else 614 max_expanded_size = msg_and_trailer_size; 615 616 if (max_expanded_size < IKM_SAVED_MSG_SIZE) 617 max_expanded_size = IKM_SAVED_MSG_SIZE; /* round up for ikm_cache */ 618 619 if (max_expanded_size == IKM_SAVED_MSG_SIZE) { 620 struct ikm_cache *cache; 621 unsigned int i; 622 623 disable_preemption(); 624 cache = &PROCESSOR_DATA(current_processor(), ikm_cache); 625 if ((i = cache->avail) > 0) { 626 assert(i <= IKM_STASH); 627 kmsg = cache->entries[--i]; 628 cache->avail = i; 629 enable_preemption(); 630 ikm_check_init(kmsg, max_expanded_size); 631 ikm_set_header(kmsg, msg_and_trailer_size); 632 return (kmsg); 633 } 634 enable_preemption(); 635 kmsg = (ipc_kmsg_t)zalloc(ipc_kmsg_zone); 636 } else { 637 kmsg = (ipc_kmsg_t)kalloc(ikm_plus_overhead(max_expanded_size)); 638 } 639 640 if (kmsg != IKM_NULL) { 641 ikm_init(kmsg, max_expanded_size); 642 ikm_set_header(kmsg, msg_and_trailer_size); 643 } 644 645 return(kmsg); 646} 647 648/* 649 * Routine: ipc_kmsg_free 650 * Purpose: 651 * Free a kernel message buffer. If the kms is preallocated 652 * to a port, just "put it back (marked unused)." We have to 653 * do this with the port locked. The port may have its hold 654 * on our message released. In that case, we have to just 655 * revert the message to a traditional one and free it normally. 656 * Conditions: 657 * Nothing locked. 658 */ 659 660void 661ipc_kmsg_free( 662 ipc_kmsg_t kmsg) 663{ 664 mach_msg_size_t size = kmsg->ikm_size; 665 ipc_port_t port; 666 667#if CONFIG_MACF_MACH 668 if (kmsg->ikm_sender != NULL) { 669 task_deallocate(kmsg->ikm_sender); 670 kmsg->ikm_sender = NULL; 671 } 672#endif 673 674 /* 675 * Check to see if the message is bound to the port. If so, 676 * mark it not in use. If the port isn't already dead, then 677 * leave the message associated with it. Otherwise, free it. 678 */ 679 port = ikm_prealloc_inuse_port(kmsg); 680 if (port != IP_NULL) { 681 ip_lock(port); 682 ikm_prealloc_clear_inuse(kmsg, port); 683 if (ip_active(port) && (port->ip_premsg == kmsg)) { 684 assert(IP_PREALLOC(port)); 685 ip_unlock(port); 686 ip_release(port); 687 return; 688 } 689 ip_unlock(port); 690 ip_release(port); /* May be last reference */ 691 } 692 693 /* 694 * Peek and see if it has to go back in the cache. 695 */ 696 if (kmsg->ikm_size == IKM_SAVED_MSG_SIZE) { 697 struct ikm_cache *cache; 698 unsigned int i; 699 700 disable_preemption(); 701 cache = &PROCESSOR_DATA(current_processor(), ikm_cache); 702 if ((i = cache->avail) < IKM_STASH) { 703 cache->entries[i] = kmsg; 704 cache->avail = i + 1; 705 enable_preemption(); 706 return; 707 } 708 enable_preemption(); 709 zfree(ipc_kmsg_zone, kmsg); 710 return; 711 } 712 kfree(kmsg, ikm_plus_overhead(size)); 713} 714 715 716/* 717 * Routine: ipc_kmsg_enqueue 718 * Purpose: 719 * Enqueue a kmsg. 720 */ 721 722void 723ipc_kmsg_enqueue( 724 ipc_kmsg_queue_t queue, 725 ipc_kmsg_t kmsg) 726{ 727 ipc_kmsg_enqueue_macro(queue, kmsg); 728} 729 730/* 731 * Routine: ipc_kmsg_dequeue 732 * Purpose: 733 * Dequeue and return a kmsg. 734 */ 735 736ipc_kmsg_t 737ipc_kmsg_dequeue( 738 ipc_kmsg_queue_t queue) 739{ 740 ipc_kmsg_t first; 741 742 first = ipc_kmsg_queue_first(queue); 743 744 if (first != IKM_NULL) 745 ipc_kmsg_rmqueue_first_macro(queue, first); 746 747 return first; 748} 749 750/* 751 * Routine: ipc_kmsg_rmqueue 752 * Purpose: 753 * Pull a kmsg out of a queue. 754 */ 755 756void 757ipc_kmsg_rmqueue( 758 ipc_kmsg_queue_t queue, 759 ipc_kmsg_t kmsg) 760{ 761 ipc_kmsg_t next, prev; 762 763 assert(queue->ikmq_base != IKM_NULL); 764 765 next = kmsg->ikm_next; 766 prev = kmsg->ikm_prev; 767 768 if (next == kmsg) { 769 assert(prev == kmsg); 770 assert(queue->ikmq_base == kmsg); 771 772 queue->ikmq_base = IKM_NULL; 773 } else { 774 if (queue->ikmq_base == kmsg) 775 queue->ikmq_base = next; 776 777 next->ikm_prev = prev; 778 prev->ikm_next = next; 779 } 780 /* XXX Temporary debug logic */ 781 assert((kmsg->ikm_next = IKM_BOGUS) == IKM_BOGUS); 782 assert((kmsg->ikm_prev = IKM_BOGUS) == IKM_BOGUS); 783} 784 785/* 786 * Routine: ipc_kmsg_queue_next 787 * Purpose: 788 * Return the kmsg following the given kmsg. 789 * (Or IKM_NULL if it is the last one in the queue.) 790 */ 791 792ipc_kmsg_t 793ipc_kmsg_queue_next( 794 ipc_kmsg_queue_t queue, 795 ipc_kmsg_t kmsg) 796{ 797 ipc_kmsg_t next; 798 799 assert(queue->ikmq_base != IKM_NULL); 800 801 next = kmsg->ikm_next; 802 if (queue->ikmq_base == next) 803 next = IKM_NULL; 804 805 return next; 806} 807 808/* 809 * Routine: ipc_kmsg_destroy 810 * Purpose: 811 * Destroys a kernel message. Releases all rights, 812 * references, and memory held by the message. 813 * Frees the message. 814 * Conditions: 815 * No locks held. 816 */ 817 818void 819ipc_kmsg_destroy( 820 ipc_kmsg_t kmsg) 821{ 822 /* 823 * Destroying a message can cause more messages to be destroyed. 824 * Curtail recursion by putting messages on the deferred 825 * destruction queue. If this was the first message on the 826 * queue, this instance must process the full queue. 827 */ 828 if (ipc_kmsg_delayed_destroy(kmsg)) 829 ipc_kmsg_reap_delayed(); 830} 831 832/* 833 * Routine: ipc_kmsg_delayed_destroy 834 * Purpose: 835 * Enqueues a kernel message for deferred destruction. 836 * Returns: 837 * Boolean indicator that the caller is responsible to reap 838 * deferred messages. 839 */ 840 841boolean_t ipc_kmsg_delayed_destroy( 842 ipc_kmsg_t kmsg) 843{ 844 ipc_kmsg_queue_t queue = &(current_thread()->ith_messages); 845 boolean_t first = ipc_kmsg_queue_empty(queue); 846 847 ipc_kmsg_enqueue(queue, kmsg); 848 return first; 849} 850 851/* 852 * Routine: ipc_kmsg_destroy_queue 853 * Purpose: 854 * Destroys messages from the per-thread 855 * deferred reaping queue. 856 * Conditions: 857 * No locks held. 858 */ 859 860void 861ipc_kmsg_reap_delayed(void) 862{ 863 ipc_kmsg_queue_t queue = &(current_thread()->ith_messages); 864 ipc_kmsg_t kmsg; 865 866 /* 867 * must leave kmsg in queue while cleaning it to assure 868 * no nested calls recurse into here. 869 */ 870 while ((kmsg = ipc_kmsg_queue_first(queue)) != IKM_NULL) { 871 ipc_kmsg_clean(kmsg); 872 ipc_kmsg_rmqueue(queue, kmsg); 873 ipc_kmsg_free(kmsg); 874 } 875} 876 877/* 878 * Routine: ipc_kmsg_clean_body 879 * Purpose: 880 * Cleans the body of a kernel message. 881 * Releases all rights, references, and memory. 882 * 883 * Conditions: 884 * No locks held. 885 */ 886static unsigned int _ipc_kmsg_clean_invalid_desc = 0; 887void 888ipc_kmsg_clean_body( 889 __unused ipc_kmsg_t kmsg, 890 mach_msg_type_number_t number, 891 mach_msg_descriptor_t *saddr) 892{ 893 mach_msg_type_number_t i; 894 895 if ( number == 0 ) 896 return; 897 898 for (i = 0 ; i < number; i++, saddr++ ) { 899 900 switch (saddr->type.type) { 901 902 case MACH_MSG_PORT_DESCRIPTOR: { 903 mach_msg_port_descriptor_t *dsc; 904 905 dsc = &saddr->port; 906 907 /* 908 * Destroy port rights carried in the message 909 */ 910 if (!IO_VALID((ipc_object_t) dsc->name)) 911 continue; 912 ipc_object_destroy((ipc_object_t) dsc->name, dsc->disposition); 913 break; 914 } 915 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 916 case MACH_MSG_OOL_DESCRIPTOR : { 917 mach_msg_ool_descriptor_t *dsc; 918 919 dsc = (mach_msg_ool_descriptor_t *)&saddr->out_of_line; 920 921 /* 922 * Destroy memory carried in the message 923 */ 924 if (dsc->size == 0) { 925 assert(dsc->address == (void *) 0); 926 } else { 927 vm_map_copy_discard((vm_map_copy_t) dsc->address); 928 } 929 break; 930 } 931 case MACH_MSG_OOL_PORTS_DESCRIPTOR : { 932 ipc_object_t *objects; 933 mach_msg_type_number_t j; 934 mach_msg_ool_ports_descriptor_t *dsc; 935 936 dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports; 937 objects = (ipc_object_t *) dsc->address; 938 939 if (dsc->count == 0) { 940 break; 941 } 942 943 assert(objects != (ipc_object_t *) 0); 944 945 /* destroy port rights carried in the message */ 946 947 for (j = 0; j < dsc->count; j++) { 948 ipc_object_t object = objects[j]; 949 950 if (!IO_VALID(object)) 951 continue; 952 953 ipc_object_destroy(object, dsc->disposition); 954 } 955 956 /* destroy memory carried in the message */ 957 958 assert(dsc->count != 0); 959 960 kfree(dsc->address, 961 (vm_size_t) dsc->count * sizeof(mach_port_t)); 962 break; 963 } 964 default : { 965 _ipc_kmsg_clean_invalid_desc++; /* don't understand this type of descriptor */ 966 } 967 } 968 } 969} 970 971/* 972 * Routine: ipc_kmsg_clean_partial 973 * Purpose: 974 * Cleans a partially-acquired kernel message. 975 * number is the index of the type descriptor 976 * in the body of the message that contained the error. 977 * If dolast, the memory and port rights in this last 978 * type spec are also cleaned. In that case, number 979 * specifies the number of port rights to clean. 980 * Conditions: 981 * Nothing locked. 982 */ 983 984void 985ipc_kmsg_clean_partial( 986 ipc_kmsg_t kmsg, 987 mach_msg_type_number_t number, 988 mach_msg_descriptor_t *desc, 989 vm_offset_t paddr, 990 vm_size_t length) 991{ 992 ipc_object_t object; 993 mach_msg_bits_t mbits = kmsg->ikm_header->msgh_bits; 994 995 object = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 996 assert(IO_VALID(object)); 997 ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits)); 998 999 object = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 1000 if (IO_VALID(object)) 1001 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits)); 1002 1003 if (paddr) { 1004 (void) vm_deallocate(ipc_kernel_copy_map, paddr, length); 1005 } 1006 1007 ipc_kmsg_clean_body(kmsg, number, desc); 1008} 1009 1010/* 1011 * Routine: ipc_kmsg_clean 1012 * Purpose: 1013 * Cleans a kernel message. Releases all rights, 1014 * references, and memory held by the message. 1015 * Conditions: 1016 * No locks held. 1017 */ 1018 1019void 1020ipc_kmsg_clean( 1021 ipc_kmsg_t kmsg) 1022{ 1023 ipc_object_t object; 1024 mach_msg_bits_t mbits; 1025 1026 mbits = kmsg->ikm_header->msgh_bits; 1027 object = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 1028 if (IO_VALID(object)) 1029 ipc_object_destroy_dest(object, MACH_MSGH_BITS_REMOTE(mbits)); 1030 1031 object = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 1032 if (IO_VALID(object)) 1033 ipc_object_destroy(object, MACH_MSGH_BITS_LOCAL(mbits)); 1034 1035 if (mbits & MACH_MSGH_BITS_COMPLEX) { 1036 mach_msg_body_t *body; 1037 1038 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 1039 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count, 1040 (mach_msg_descriptor_t *)(body + 1)); 1041 } 1042 1043#if CONFIG_MACF_MACH 1044 if (kmsg->ikm_sender != NULL) { 1045 task_deallocate(kmsg->ikm_sender); 1046 kmsg->ikm_sender = NULL; 1047 } 1048#endif 1049} 1050 1051/* 1052 * Routine: ipc_kmsg_set_prealloc 1053 * Purpose: 1054 * Assign a kmsg as a preallocated message buffer to a port. 1055 * Conditions: 1056 * port locked. 1057 */ 1058 1059void 1060ipc_kmsg_set_prealloc( 1061 ipc_kmsg_t kmsg, 1062 ipc_port_t port) 1063{ 1064 assert(kmsg->ikm_prealloc == IP_NULL); 1065 1066 kmsg->ikm_prealloc = IP_NULL; 1067 IP_SET_PREALLOC(port, kmsg); 1068} 1069 1070/* 1071 * Routine: ipc_kmsg_clear_prealloc 1072 * Purpose: 1073 * Release the Assignment of a preallocated message buffer from a port. 1074 * Conditions: 1075 * port locked. 1076 */ 1077void 1078ipc_kmsg_clear_prealloc( 1079 ipc_kmsg_t kmsg, 1080 ipc_port_t port) 1081{ 1082 assert(kmsg->ikm_prealloc == port); 1083 1084 kmsg->ikm_prealloc = IP_NULL; 1085 IP_CLEAR_PREALLOC(port, kmsg); 1086} 1087 1088/* 1089 * Routine: ipc_kmsg_prealloc 1090 * Purpose: 1091 * Wraper to ipc_kmsg_alloc() to account for 1092 * header expansion requirements. 1093 */ 1094ipc_kmsg_t 1095ipc_kmsg_prealloc(mach_msg_size_t size) 1096{ 1097#if defined(__LP64__) 1098 if (size > MACH_MSG_SIZE_MAX - LEGACY_HEADER_SIZE_DELTA) 1099 return IKM_NULL; 1100 1101 size += LEGACY_HEADER_SIZE_DELTA; 1102#endif 1103 return ipc_kmsg_alloc(size); 1104} 1105 1106 1107/* 1108 * Routine: ipc_kmsg_get 1109 * Purpose: 1110 * Allocates a kernel message buffer. 1111 * Copies a user message to the message buffer. 1112 * Conditions: 1113 * Nothing locked. 1114 * Returns: 1115 * MACH_MSG_SUCCESS Acquired a message buffer. 1116 * MACH_SEND_MSG_TOO_SMALL Message smaller than a header. 1117 * MACH_SEND_MSG_TOO_SMALL Message size not long-word multiple. 1118 * MACH_SEND_TOO_LARGE Message too large to ever be sent. 1119 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer. 1120 * MACH_SEND_INVALID_DATA Couldn't copy message data. 1121 */ 1122 1123mach_msg_return_t 1124ipc_kmsg_get( 1125 mach_vm_address_t msg_addr, 1126 mach_msg_size_t size, 1127 ipc_kmsg_t *kmsgp) 1128{ 1129 mach_msg_size_t msg_and_trailer_size; 1130 ipc_kmsg_t kmsg; 1131 mach_msg_max_trailer_t *trailer; 1132 mach_msg_legacy_base_t legacy_base; 1133 mach_msg_size_t len_copied; 1134 legacy_base.body.msgh_descriptor_count = 0; 1135 1136 if ((size < sizeof(mach_msg_legacy_header_t)) || (size & 3)) 1137 return MACH_SEND_MSG_TOO_SMALL; 1138 1139 if (size > ipc_kmsg_max_body_space) 1140 return MACH_SEND_TOO_LARGE; 1141 1142 if(size == sizeof(mach_msg_legacy_header_t)) 1143 len_copied = sizeof(mach_msg_legacy_header_t); 1144 else 1145 len_copied = sizeof(mach_msg_legacy_base_t); 1146 1147 if (copyinmsg(msg_addr, (char *)&legacy_base, len_copied)) 1148 return MACH_SEND_INVALID_DATA; 1149 1150 msg_addr += sizeof(legacy_base.header); 1151#if defined(__LP64__) 1152 size += LEGACY_HEADER_SIZE_DELTA; 1153#endif 1154 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { 1155 unsigned int j; 1156 for (j=0; j<sizeof(legacy_base.header); j++) { 1157 kprintf("%02x\n", ((unsigned char*)&legacy_base.header)[j]); 1158 } 1159 } 1160 1161 msg_and_trailer_size = size + MAX_TRAILER_SIZE; 1162 kmsg = ipc_kmsg_alloc(msg_and_trailer_size); 1163 if (kmsg == IKM_NULL) 1164 return MACH_SEND_NO_BUFFER; 1165 1166 kmsg->ikm_header->msgh_size = size; 1167 kmsg->ikm_header->msgh_bits = legacy_base.header.msgh_bits; 1168 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(legacy_base.header.msgh_remote_port); 1169 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(legacy_base.header.msgh_local_port); 1170 kmsg->ikm_header->msgh_reserved = legacy_base.header.msgh_reserved; 1171 kmsg->ikm_header->msgh_id = legacy_base.header.msgh_id; 1172 1173 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_get header:\n" 1174 " size: 0x%.8x\n" 1175 " bits: 0x%.8x\n" 1176 " remote_port: %p\n" 1177 " local_port: %p\n" 1178 " reserved: 0x%.8x\n" 1179 " id: %.8d\n", 1180 kmsg->ikm_header->msgh_size, 1181 kmsg->ikm_header->msgh_bits, 1182 kmsg->ikm_header->msgh_remote_port, 1183 kmsg->ikm_header->msgh_local_port, 1184 kmsg->ikm_header->msgh_reserved, 1185 kmsg->ikm_header->msgh_id); 1186 1187 if (copyinmsg(msg_addr, (char *)(kmsg->ikm_header + 1), size - (mach_msg_size_t)sizeof(mach_msg_header_t))) { 1188 ipc_kmsg_free(kmsg); 1189 return MACH_SEND_INVALID_DATA; 1190 } 1191 1192 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) 1193 { 1194 kprintf("body: size: %lu\n", (size - sizeof(mach_msg_header_t))); 1195 uint32_t i; 1196 for(i=0;i*4 < (size - sizeof(mach_msg_header_t));i++) 1197 { 1198 kprintf("%.4x\n",((uint32_t *)(kmsg->ikm_header + 1))[i]); 1199 } 1200 } 1201 DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_get()"); 1202 1203 /* 1204 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE) 1205 * However, the internal size field of the trailer (msgh_trailer_size) 1206 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to optimize 1207 * the cases where no implicit data is requested. 1208 */ 1209 trailer = (mach_msg_max_trailer_t *) ((vm_offset_t)kmsg->ikm_header + size); 1210 trailer->msgh_sender = current_thread()->task->sec_token; 1211 trailer->msgh_audit = current_thread()->task->audit_token; 1212 trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0; 1213 trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE; 1214 1215#ifdef ppc 1216 if(trcWork.traceMask) dbgTrace(0x1100, (unsigned int)kmsg->ikm_header->msgh_id, 1217 (unsigned int)kmsg->ikm_header->msgh_remote_port, 1218 (unsigned int)kmsg->ikm_header->msgh_local_port, 0); 1219#endif 1220 1221#if CONFIG_MACF_MACH 1222 /* XXX - why do we zero sender labels here instead of in mach_msg()? */ 1223 task_t cur = current_task(); 1224 if (cur) { 1225 task_reference(cur); 1226 kmsg->ikm_sender = cur; 1227 } else 1228 trailer->msgh_labels.sender = 0; 1229#else 1230 trailer->msgh_labels.sender = 0; 1231#endif 1232 1233 *kmsgp = kmsg; 1234 return MACH_MSG_SUCCESS; 1235} 1236 1237/* 1238 * Routine: ipc_kmsg_get_from_kernel 1239 * Purpose: 1240 * First checks for a preallocated message 1241 * reserved for kernel clients. If not found - 1242 * allocates a new kernel message buffer. 1243 * Copies a kernel message to the message buffer. 1244 * Only resource errors are allowed. 1245 * Conditions: 1246 * Nothing locked. 1247 * Ports in header are ipc_port_t. 1248 * Returns: 1249 * MACH_MSG_SUCCESS Acquired a message buffer. 1250 * MACH_SEND_NO_BUFFER Couldn't allocate a message buffer. 1251 */ 1252 1253mach_msg_return_t 1254ipc_kmsg_get_from_kernel( 1255 mach_msg_header_t *msg, 1256 mach_msg_size_t size, 1257 ipc_kmsg_t *kmsgp) 1258{ 1259 ipc_kmsg_t kmsg; 1260 mach_msg_size_t msg_and_trailer_size; 1261 mach_msg_max_trailer_t *trailer; 1262 ipc_port_t dest_port; 1263 1264 assert(size >= sizeof(mach_msg_header_t)); 1265 assert((size & 3) == 0); 1266 1267 dest_port = (ipc_port_t)msg->msgh_remote_port; 1268 1269 msg_and_trailer_size = size + MAX_TRAILER_SIZE; 1270 1271 /* 1272 * See if the port has a pre-allocated kmsg for kernel 1273 * clients. These are set up for those kernel clients 1274 * which cannot afford to wait. 1275 */ 1276 if (IP_VALID(dest_port) && IP_PREALLOC(dest_port)) { 1277 mach_msg_size_t max_desc = 0; 1278 1279 ip_lock(dest_port); 1280 if (!ip_active(dest_port)) { 1281 ip_unlock(dest_port); 1282 return MACH_SEND_NO_BUFFER; 1283 } 1284 assert(IP_PREALLOC(dest_port)); 1285 kmsg = dest_port->ip_premsg; 1286 if (ikm_prealloc_inuse(kmsg)) { 1287 ip_unlock(dest_port); 1288 return MACH_SEND_NO_BUFFER; 1289 } 1290#if !defined(__LP64__) 1291 if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) { 1292 assert(size > sizeof(mach_msg_base_t)); 1293 max_desc = ((mach_msg_base_t *)msg)->body.msgh_descriptor_count * 1294 DESC_SIZE_ADJUSTMENT; 1295 } 1296#endif 1297 if (msg_and_trailer_size > kmsg->ikm_size - max_desc) { 1298 ip_unlock(dest_port); 1299 return MACH_SEND_TOO_LARGE; 1300 } 1301 ikm_prealloc_set_inuse(kmsg, dest_port); 1302 ikm_set_header(kmsg, msg_and_trailer_size); 1303 ip_unlock(dest_port); 1304 } 1305 else 1306 { 1307 kmsg = ipc_kmsg_alloc(msg_and_trailer_size); 1308 if (kmsg == IKM_NULL) 1309 return MACH_SEND_NO_BUFFER; 1310 } 1311 1312 (void) memcpy((void *) kmsg->ikm_header, (const void *) msg, size); 1313 1314 kmsg->ikm_header->msgh_size = size; 1315 1316 /* 1317 * I reserve for the trailer the largest space (MAX_TRAILER_SIZE) 1318 * However, the internal size field of the trailer (msgh_trailer_size) 1319 * is initialized to the minimum (sizeof(mach_msg_trailer_t)), to 1320 * optimize the cases where no implicit data is requested. 1321 */ 1322 trailer = (mach_msg_max_trailer_t *) 1323 ((vm_offset_t)kmsg->ikm_header + size); 1324 trailer->msgh_sender = KERNEL_SECURITY_TOKEN; 1325 trailer->msgh_audit = KERNEL_AUDIT_TOKEN; 1326 trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0; 1327 trailer->msgh_trailer_size = MACH_MSG_TRAILER_MINIMUM_SIZE; 1328 1329 trailer->msgh_labels.sender = 0; 1330 1331#if CONFIG_MACF_MACH 1332 kmsg->ikm_sender = NULL; 1333#endif 1334 *kmsgp = kmsg; 1335 return MACH_MSG_SUCCESS; 1336} 1337 1338/* 1339 * Routine: ipc_kmsg_send 1340 * Purpose: 1341 * Send a message. The message holds a reference 1342 * for the destination port in the msgh_remote_port field. 1343 * 1344 * If unsuccessful, the caller still has possession of 1345 * the message and must do something with it. If successful, 1346 * the message is queued, given to a receiver, destroyed, 1347 * or handled directly by the kernel via mach_msg. 1348 * Conditions: 1349 * Nothing locked. 1350 * Returns: 1351 * MACH_MSG_SUCCESS The message was accepted. 1352 * MACH_SEND_TIMED_OUT Caller still has message. 1353 * MACH_SEND_INTERRUPTED Caller still has message. 1354 * MACH_SEND_INVALID_DEST Caller still has message. 1355 */ 1356 1357 1358mach_msg_return_t 1359ipc_kmsg_send( 1360 ipc_kmsg_t kmsg, 1361 mach_msg_option_t option, 1362 mach_msg_timeout_t send_timeout) 1363{ 1364 ipc_port_t port; 1365 mach_msg_return_t error = MACH_MSG_SUCCESS; 1366 spl_t s; 1367 1368#if IMPORTANCE_INHERITANCE 1369 boolean_t did_importance = FALSE; 1370#if IMPORTANCE_DEBUG 1371 mach_msg_id_t imp_msgh_id = -1; 1372 int sender_pid = -1; 1373#endif /* IMPORTANCE_DEBUG */ 1374#endif /* IMPORTANCE_INHERITANCE */ 1375 1376 /* don't allow the creation of a circular loop */ 1377 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_CIRCULAR) { 1378 ipc_kmsg_destroy(kmsg); 1379 return MACH_MSG_SUCCESS; 1380 } 1381 1382 port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port; 1383 assert(IP_VALID(port)); 1384 ip_lock(port); 1385 1386 if (port->ip_receiver == ipc_space_kernel) { 1387 1388 /* 1389 * We can check ip_receiver == ipc_space_kernel 1390 * before checking that the port is active because 1391 * ipc_port_dealloc_kernel clears ip_receiver 1392 * before destroying a kernel port. 1393 */ 1394 assert(ip_active(port)); 1395 port->ip_messages.imq_seqno++; 1396 ip_unlock(port); 1397 1398 current_task()->messages_sent++; 1399 1400 /* 1401 * Call the server routine, and get the reply message to send. 1402 */ 1403 kmsg = ipc_kobject_server(kmsg); 1404 if (kmsg == IKM_NULL) 1405 return MACH_MSG_SUCCESS; 1406 1407 port = (ipc_port_t) kmsg->ikm_header->msgh_remote_port; 1408 assert(IP_VALID(port)); 1409 ip_lock(port); 1410 /* fall thru with reply - same options */ 1411 } 1412 1413#if IMPORTANCE_INHERITANCE 1414 retry: 1415#endif /* IMPORTANCE_INHERITANCE */ 1416 1417 /* 1418 * Can't deliver to a dead port. 1419 * However, we can pretend it got sent 1420 * and was then immediately destroyed. 1421 */ 1422 if (!ip_active(port)) { 1423 /* 1424 * We can't let ipc_kmsg_destroy deallocate 1425 * the port right, because we might end up 1426 * in an infinite loop trying to deliver 1427 * a send-once notification. 1428 */ 1429 ip_unlock(port); 1430 ip_release(port); 1431 kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL; 1432 ipc_kmsg_destroy(kmsg); 1433 return MACH_MSG_SUCCESS; 1434 } 1435 1436#if IMPORTANCE_INHERITANCE 1437 /* 1438 * Need to see if this message needs importance donation and/or 1439 * propagation. That routine can drop the port lock. If it does 1440 * we'll have to revalidate the destination. 1441 */ 1442 if ((did_importance == FALSE) && 1443 (port->ip_impdonation != 0) && 1444 ((option & MACH_SEND_NOIMPORTANCE) == 0) && 1445 (((option & MACH_SEND_IMPORTANCE) != 0) || 1446 (task_is_importance_donor(current_task())))) { 1447 1448 did_importance = TRUE; 1449 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_RAISEIMP; 1450 1451#if IMPORTANCE_DEBUG 1452 if (kdebug_enable) { 1453 mach_msg_max_trailer_t *dbgtrailer = (mach_msg_max_trailer_t *) 1454 ((vm_offset_t)kmsg->ikm_header + round_msg(kmsg->ikm_header->msgh_size)); 1455 sender_pid = dbgtrailer->msgh_audit.val[5]; 1456 imp_msgh_id = kmsg->ikm_header->msgh_id; 1457 1458 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, (IMPORTANCE_CODE(IMP_MSG, IMP_MSG_SEND)) | DBG_FUNC_START, 1459 audit_token_pid_from_task(current_task()), sender_pid, imp_msgh_id, 0, 0); 1460 } 1461#endif /* IMPORTANCE_DEBUG */ 1462 1463 if (ipc_port_importance_delta(port, 1) == TRUE) { 1464 ip_lock(port); 1465 goto retry; 1466 } 1467 } 1468#endif /* IMPORTANCE_INHERITANCE */ 1469 1470 /* 1471 * We have a valid message and a valid reference on the port. 1472 * we can unlock the port and call mqueue_send() on its message 1473 * queue. Lock message queue while port is locked. 1474 */ 1475 s = splsched(); 1476 imq_lock(&port->ip_messages); 1477 ip_unlock(port); 1478 1479 error = ipc_mqueue_send(&port->ip_messages, kmsg, option, 1480 send_timeout, s); 1481 1482#if IMPORTANCE_INHERITANCE 1483 if (did_importance == TRUE) { 1484 __unused int importance_cleared = 0; 1485 switch (error) { 1486 case MACH_SEND_TIMED_OUT: 1487 case MACH_SEND_NO_BUFFER: 1488 case MACH_SEND_INTERRUPTED: 1489 /* 1490 * We still have the kmsg and its 1491 * reference on the port. But we 1492 * have to back out the importance 1493 * boost. 1494 * 1495 * The port could have changed hands, 1496 * be inflight to another destination, 1497 * etc... But in those cases our 1498 * back-out will find the new owner 1499 * (and all the operations that 1500 * transferred the right should have 1501 * applied their own boost adjustments 1502 * to the old owner(s)). 1503 */ 1504 importance_cleared = 1; 1505 ip_lock(port); 1506 if (ipc_port_importance_delta(port, -1) == FALSE) 1507 ip_unlock(port); 1508 break; 1509 1510 case MACH_SEND_INVALID_DEST: 1511 /* 1512 * In the case that the receive right has 1513 * gone away, the assertion count for the 1514 * message we were trying to enqueue was 1515 * already subtracted from the destination 1516 * task (as part of port destruction). 1517 */ 1518 break; 1519 1520 case MACH_MSG_SUCCESS: 1521 default: 1522 break; 1523 } 1524#if IMPORTANCE_DEBUG 1525 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, (IMPORTANCE_CODE(IMP_MSG, IMP_MSG_SEND)) | DBG_FUNC_END, 1526 audit_token_pid_from_task(current_task()), sender_pid, imp_msgh_id, importance_cleared, 0); 1527#endif /* IMPORTANCE_DEBUG */ 1528 } 1529#endif /* IMPORTANCE_INHERITANCE */ 1530 1531 /* 1532 * If the port has been destroyed while we wait, treat the message 1533 * as a successful delivery (like we do for an inactive port). 1534 */ 1535 if (error == MACH_SEND_INVALID_DEST) { 1536 kmsg->ikm_header->msgh_remote_port = MACH_PORT_NULL; 1537 ipc_kmsg_destroy(kmsg); 1538 return MACH_MSG_SUCCESS; 1539 } 1540 return error; 1541} 1542 1543/* 1544 * Routine: ipc_kmsg_put 1545 * Purpose: 1546 * Copies a message buffer to a user message. 1547 * Copies only the specified number of bytes. 1548 * Frees the message buffer. 1549 * Conditions: 1550 * Nothing locked. The message buffer must have clean 1551 * header fields. 1552 * Returns: 1553 * MACH_MSG_SUCCESS Copied data out of message buffer. 1554 * MACH_RCV_INVALID_DATA Couldn't copy to user message. 1555 */ 1556 1557mach_msg_return_t 1558ipc_kmsg_put( 1559 mach_vm_address_t msg_addr, 1560 ipc_kmsg_t kmsg, 1561 mach_msg_size_t size) 1562{ 1563 mach_msg_return_t mr; 1564 1565 DEBUG_IPC_KMSG_PRINT(kmsg, "ipc_kmsg_put()"); 1566 1567 1568 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_put header:\n" 1569 " size: 0x%.8x\n" 1570 " bits: 0x%.8x\n" 1571 " remote_port: %p\n" 1572 " local_port: %p\n" 1573 " reserved: 0x%.8x\n" 1574 " id: %.8d\n", 1575 kmsg->ikm_header->msgh_size, 1576 kmsg->ikm_header->msgh_bits, 1577 kmsg->ikm_header->msgh_remote_port, 1578 kmsg->ikm_header->msgh_local_port, 1579 kmsg->ikm_header->msgh_reserved, 1580 kmsg->ikm_header->msgh_id); 1581 1582#if defined(__LP64__) 1583 if (current_task() != kernel_task) { /* don't if receiver expects fully-cooked in-kernel msg; ux_exception */ 1584 mach_msg_legacy_header_t *legacy_header = 1585 (mach_msg_legacy_header_t *)((vm_offset_t)(kmsg->ikm_header) + LEGACY_HEADER_SIZE_DELTA); 1586 1587 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits; 1588 mach_msg_size_t msg_size = kmsg->ikm_header->msgh_size; 1589 mach_port_name_t remote_port = CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_remote_port); 1590 mach_port_name_t local_port = CAST_MACH_PORT_TO_NAME(kmsg->ikm_header->msgh_local_port); 1591 mach_msg_size_t reserved = kmsg->ikm_header->msgh_reserved; 1592 mach_msg_id_t id = kmsg->ikm_header->msgh_id; 1593 1594 legacy_header->msgh_id = id; 1595 legacy_header->msgh_reserved = reserved; 1596 legacy_header->msgh_local_port = local_port; 1597 legacy_header->msgh_remote_port = remote_port; 1598 legacy_header->msgh_size = msg_size - LEGACY_HEADER_SIZE_DELTA; 1599 legacy_header->msgh_bits = bits; 1600 1601 size -= LEGACY_HEADER_SIZE_DELTA; 1602 kmsg->ikm_header = (mach_msg_header_t *)legacy_header; 1603 } 1604#endif 1605 1606 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) { 1607 kprintf("ipc_kmsg_put header+body: %d\n", (size)); 1608 uint32_t i; 1609 for(i=0;i*4 < size;i++) 1610 { 1611 kprintf("%.4x\n",((uint32_t *)kmsg->ikm_header)[i]); 1612 } 1613 kprintf("type: %d\n", ((mach_msg_type_descriptor_t *)(((mach_msg_base_t *)kmsg->ikm_header)+1))->type); 1614 } 1615 if (copyoutmsg((const char *) kmsg->ikm_header, msg_addr, size)) 1616 mr = MACH_RCV_INVALID_DATA; 1617 else 1618 mr = MACH_MSG_SUCCESS; 1619 1620 ipc_kmsg_free(kmsg); 1621 return mr; 1622} 1623 1624/* 1625 * Routine: ipc_kmsg_put_to_kernel 1626 * Purpose: 1627 * Copies a message buffer to a kernel message. 1628 * Frees the message buffer. 1629 * No errors allowed. 1630 * Conditions: 1631 * Nothing locked. 1632 */ 1633 1634void 1635ipc_kmsg_put_to_kernel( 1636 mach_msg_header_t *msg, 1637 ipc_kmsg_t kmsg, 1638 mach_msg_size_t size) 1639{ 1640 (void) memcpy((void *) msg, (const void *) kmsg->ikm_header, size); 1641 1642 ipc_kmsg_free(kmsg); 1643} 1644 1645/* 1646 * Routine: ipc_kmsg_copyin_header 1647 * Purpose: 1648 * "Copy-in" port rights in the header of a message. 1649 * Operates atomically; if it doesn't succeed the 1650 * message header and the space are left untouched. 1651 * If it does succeed the remote/local port fields 1652 * contain object pointers instead of port names, 1653 * and the bits field is updated. The destination port 1654 * will be a valid port pointer. 1655 * 1656 * Conditions: 1657 * Nothing locked. 1658 * Returns: 1659 * MACH_MSG_SUCCESS Successful copyin. 1660 * MACH_SEND_INVALID_HEADER 1661 * Illegal value in the message header bits. 1662 * MACH_SEND_INVALID_DEST The space is dead. 1663 * MACH_SEND_INVALID_DEST Can't copyin destination port. 1664 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.) 1665 * MACH_SEND_INVALID_REPLY Can't copyin reply port. 1666 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.) 1667 */ 1668 1669mach_msg_return_t 1670ipc_kmsg_copyin_header( 1671 mach_msg_header_t *msg, 1672 ipc_space_t space, 1673 mach_msg_option_t *optionp) 1674{ 1675 mach_msg_bits_t mbits = msg->msgh_bits & MACH_MSGH_BITS_USER; 1676 mach_port_name_t dest_name = CAST_MACH_PORT_TO_NAME(msg->msgh_remote_port); 1677 mach_port_name_t reply_name = CAST_MACH_PORT_TO_NAME(msg->msgh_local_port); 1678 kern_return_t kr; 1679 1680 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits); 1681 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits); 1682 ipc_object_t dest_port, reply_port; 1683 ipc_entry_t dest_entry, reply_entry; 1684 ipc_port_t dest_soright, reply_soright; 1685 ipc_port_t release_port = IP_NULL; 1686 1687#if IMPORTANCE_INHERITANCE 1688 int assertcnt = 0; 1689 boolean_t needboost = FALSE; 1690#endif /* IMPORTANCE_INHERITANCE */ 1691 1692 queue_head_t links_data; 1693 queue_t links = &links_data; 1694 wait_queue_link_t wql; 1695 1696 queue_init(links); 1697 1698 if ((mbits != msg->msgh_bits) || 1699 (!MACH_MSG_TYPE_PORT_ANY_SEND(dest_type)) || 1700 ((reply_type == 0) ? 1701 (reply_name != MACH_PORT_NULL) : 1702 !MACH_MSG_TYPE_PORT_ANY_SEND(reply_type))) 1703 return MACH_SEND_INVALID_HEADER; 1704 1705 reply_soright = IP_NULL; /* in case we go to invalid dest early */ 1706 1707 is_write_lock(space); 1708 if (!is_active(space)) 1709 goto invalid_dest; 1710 1711 if (!MACH_PORT_VALID(dest_name)) 1712 goto invalid_dest; 1713 1714#if CONFIG_MACF_MACH 1715 /* 1716 * We do the port send check here instead of in ipc_kmsg_send() 1717 * because copying the header involves copying the port rights too 1718 * and we need to do the send check before anything is actually copied. 1719 */ 1720 dest_entry = ipc_entry_lookup(space, dest_name); 1721 if (dest_entry != IE_NULL) { 1722 int error = 0; 1723 ipc_port_t port = (ipc_port_t) dest_entry->ie_object; 1724 if (port == IP_NULL) 1725 goto invalid_dest; 1726 ip_lock(port); 1727 if (ip_active(port)) { 1728 task_t self = current_task(); 1729 tasklabel_lock(self); 1730 error = mac_port_check_send(&self->maclabel, 1731 &port->ip_label); 1732 tasklabel_unlock(self); 1733 } 1734 ip_unlock(port); 1735 if (error != 0) 1736 goto invalid_dest; 1737 } 1738#endif 1739 1740 if (dest_name == reply_name) { 1741 mach_port_name_t name = dest_name; 1742 1743 /* 1744 * Destination and reply ports are the same! 1745 * This is a little tedious to make atomic, because 1746 * there are 25 combinations of dest_type/reply_type. 1747 * However, most are easy. If either is move-sonce, 1748 * then there must be an error. If either are 1749 * make-send or make-sonce, then we must be looking 1750 * at a receive right so the port can't die. 1751 * The hard cases are the combinations of 1752 * copy-send and make-send. 1753 */ 1754 1755 dest_entry = ipc_entry_lookup(space, name); 1756 if (dest_entry == IE_NULL) 1757 goto invalid_dest; 1758 1759 reply_entry = dest_entry; 1760 assert(reply_type != 0); /* because name not null */ 1761 1762 if (!ipc_right_copyin_check(space, name, reply_entry, reply_type)) 1763 goto invalid_reply; 1764 1765 if ((dest_type == MACH_MSG_TYPE_MOVE_SEND_ONCE) || 1766 (reply_type == MACH_MSG_TYPE_MOVE_SEND_ONCE)) { 1767 /* 1768 * Why must there be an error? To get a valid 1769 * destination, this entry must name a live 1770 * port (not a dead name or dead port). However 1771 * a successful move-sonce will destroy a 1772 * live entry. Therefore the other copyin, 1773 * whatever it is, would fail. We've already 1774 * checked for reply port errors above, 1775 * so report a destination error. 1776 */ 1777 1778 goto invalid_dest; 1779 } else if ((dest_type == MACH_MSG_TYPE_MAKE_SEND) || 1780 (dest_type == MACH_MSG_TYPE_MAKE_SEND_ONCE) || 1781 (reply_type == MACH_MSG_TYPE_MAKE_SEND) || 1782 (reply_type == MACH_MSG_TYPE_MAKE_SEND_ONCE)) { 1783 1784#if IMPORTANCE_INHERITANCE 1785 kr = ipc_right_copyin(space, name, dest_entry, 1786 dest_type, FALSE, 1787 &dest_port, &dest_soright, 1788 &release_port, 1789 &assertcnt, 1790 links); 1791 assert(assertcnt == 0); 1792#else 1793 kr = ipc_right_copyin(space, name, dest_entry, 1794 dest_type, FALSE, 1795 &dest_port, &dest_soright, 1796 &release_port, 1797 links); 1798#endif /* IMPORTANCE_INHERITANCE */ 1799 1800 if (kr != KERN_SUCCESS) 1801 goto invalid_dest; 1802 1803 /* 1804 * Either dest or reply needs a receive right. 1805 * We know the receive right is there, because 1806 * of the copyin_check and copyin calls. Hence 1807 * the port is not in danger of dying. If dest 1808 * used the receive right, then the right needed 1809 * by reply (and verified by copyin_check) will 1810 * still be there. 1811 */ 1812 1813 assert(IO_VALID(dest_port)); 1814 assert(dest_soright == IP_NULL); 1815 1816#if IMPORTANCE_INHERITANCE 1817 kr = ipc_right_copyin(space, name, reply_entry, 1818 reply_type, TRUE, 1819 &reply_port, &reply_soright, 1820 &release_port, 1821 &assertcnt, 1822 links); 1823 assert(assertcnt == 0); 1824#else 1825 kr = ipc_right_copyin(space, name, reply_entry, 1826 reply_type, TRUE, 1827 &reply_port, &reply_soright, 1828 &release_port, 1829 links); 1830#endif /* IMPORTANCE_INHERITANCE */ 1831 1832 assert(kr == KERN_SUCCESS); 1833 assert(reply_port == dest_port); 1834 assert(reply_entry->ie_bits & MACH_PORT_TYPE_RECEIVE); 1835 assert(reply_soright == IP_NULL); 1836 } else if ((dest_type == MACH_MSG_TYPE_COPY_SEND) && 1837 (reply_type == MACH_MSG_TYPE_COPY_SEND)) { 1838 /* 1839 * To make this atomic, just do one copy-send, 1840 * and dup the send right we get out. 1841 */ 1842 1843#if IMPORTANCE_INHERITANCE 1844 kr = ipc_right_copyin(space, name, dest_entry, 1845 dest_type, FALSE, 1846 &dest_port, &dest_soright, 1847 &release_port, 1848 &assertcnt, 1849 links); 1850 assert(assertcnt == 0); 1851#else 1852 kr = ipc_right_copyin(space, name, dest_entry, 1853 dest_type, FALSE, 1854 &dest_port, &dest_soright, 1855 &release_port, 1856 links); 1857#endif /* IMPORTANCE_INHERITANCE */ 1858 1859 if (kr != KERN_SUCCESS) 1860 goto invalid_dest; 1861 1862 assert(dest_entry->ie_bits & MACH_PORT_TYPE_SEND); 1863 assert(dest_soright == IP_NULL); 1864 1865 /* 1866 * It's OK if the port we got is dead now, 1867 * so reply_port is IP_DEAD, because the msg 1868 * won't go anywhere anyway. 1869 */ 1870 1871 reply_port = (ipc_object_t) 1872 ipc_port_copy_send((ipc_port_t) dest_port); 1873 reply_soright = IP_NULL; 1874 } else if ((dest_type == MACH_MSG_TYPE_MOVE_SEND) && 1875 (reply_type == MACH_MSG_TYPE_MOVE_SEND)) { 1876 /* 1877 * This is an easy case. Just use our 1878 * handy-dandy special-purpose copyin call 1879 * to get two send rights for the price of one. 1880 */ 1881 1882 kr = ipc_right_copyin_two(space, name, dest_entry, 1883 &dest_port, &dest_soright, 1884 &release_port); 1885 if (kr != KERN_SUCCESS) 1886 goto invalid_dest; 1887 1888 /* the entry might need to be deallocated */ 1889 if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) { 1890 ipc_entry_dealloc(space, name, dest_entry); 1891 dest_entry = IE_NULL; 1892 } 1893 1894 reply_port = dest_port; 1895 reply_soright = IP_NULL; 1896 } else { 1897 ipc_port_t soright; 1898 1899 assert(((dest_type == MACH_MSG_TYPE_COPY_SEND) && 1900 (reply_type == MACH_MSG_TYPE_MOVE_SEND)) || 1901 ((dest_type == MACH_MSG_TYPE_MOVE_SEND) && 1902 (reply_type == MACH_MSG_TYPE_COPY_SEND))); 1903 1904 /* 1905 * To make this atomic, just do a move-send, 1906 * and dup the send right we get out. 1907 */ 1908 1909#if IMPORTANCE_INHERITANCE 1910 kr = ipc_right_copyin(space, name, dest_entry, 1911 MACH_MSG_TYPE_MOVE_SEND, FALSE, 1912 &dest_port, &soright, 1913 &release_port, 1914 &assertcnt, 1915 links); 1916 assert(assertcnt == 0); 1917#else 1918 kr = ipc_right_copyin(space, name, dest_entry, 1919 MACH_MSG_TYPE_MOVE_SEND, FALSE, 1920 &dest_port, &soright, 1921 &release_port, 1922 links); 1923#endif /* IMPORTANCE_INHERITANCE */ 1924 1925 if (kr != KERN_SUCCESS) 1926 goto invalid_dest; 1927 1928 /* the entry might need to be deallocated */ 1929 1930 if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) { 1931 ipc_entry_dealloc(space, name, dest_entry); 1932 dest_entry = IE_NULL; 1933 } 1934 1935 /* 1936 * It's OK if the port we got is dead now, 1937 * so reply_port is IP_DEAD, because the msg 1938 * won't go anywhere anyway. 1939 */ 1940 1941 reply_port = (ipc_object_t) 1942 ipc_port_copy_send((ipc_port_t) dest_port); 1943 1944 if (dest_type == MACH_MSG_TYPE_MOVE_SEND) { 1945 dest_soright = soright; 1946 reply_soright = IP_NULL; 1947 } else { 1948 dest_soright = IP_NULL; 1949 reply_soright = soright; 1950 } 1951 } 1952 } else if (!MACH_PORT_VALID(reply_name)) { 1953 /* 1954 * No reply port! This is an easy case 1955 * to make atomic. Just copyin the destination. 1956 */ 1957 1958 dest_entry = ipc_entry_lookup(space, dest_name); 1959 if (dest_entry == IE_NULL) 1960 goto invalid_dest; 1961 1962#if IMPORTANCE_INHERITANCE 1963 kr = ipc_right_copyin(space, dest_name, dest_entry, 1964 dest_type, FALSE, 1965 &dest_port, &dest_soright, 1966 &release_port, 1967 &assertcnt, 1968 links); 1969 assert(assertcnt == 0); 1970#else 1971 kr = ipc_right_copyin(space, dest_name, dest_entry, 1972 dest_type, FALSE, 1973 &dest_port, &dest_soright, 1974 &release_port, 1975 links); 1976#endif /* IMPORTANCE_INHERITANCE */ 1977 1978 if (kr != KERN_SUCCESS) 1979 goto invalid_dest; 1980 1981 /* the entry might need to be deallocated */ 1982 if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) { 1983 ipc_entry_dealloc(space, dest_name, dest_entry); 1984 dest_entry = IE_NULL; 1985 } 1986 1987 reply_port = (ipc_object_t)CAST_MACH_NAME_TO_PORT(reply_name); 1988 reply_soright = IP_NULL; 1989 } else { 1990 /* 1991 * This is the tough case to make atomic. 1992 * The difficult problem is serializing with port death. 1993 * At the time we copyin dest_port, it must be alive. 1994 * If reply_port is alive when we copyin it, then 1995 * we are OK, because we serialize before the death 1996 * of both ports. Assume reply_port is dead at copyin. 1997 * Then if dest_port dies/died after reply_port died, 1998 * we are OK, because we serialize between the death 1999 * of the two ports. So the bad case is when dest_port 2000 * dies after its copyin, reply_port dies before its 2001 * copyin, and dest_port dies before reply_port. Then 2002 * the copyins operated as if dest_port was alive 2003 * and reply_port was dead, which shouldn't have happened 2004 * because they died in the other order. 2005 * 2006 * Note that it is easy for a user task to tell if 2007 * a copyin happened before or after a port died. 2008 * For example, suppose both dest and reply are 2009 * send-once rights (types are both move-sonce) and 2010 * both rights have dead-name requests registered. 2011 * If a port dies before copyin, a dead-name notification 2012 * is generated and the dead name's urefs are incremented, 2013 * and if the copyin happens first, a port-deleted 2014 * notification is generated. 2015 * 2016 * Note that although the entries are different, 2017 * dest_port and reply_port might still be the same. 2018 * 2019 * JMM - The code to handle this was too expensive and, anyway, 2020 * we intend to separate the dest lookup from the reply copyin 2021 * by a wide margin, so the user will have to learn to deal! 2022 * I will be making the change soon in rdar://problem/6275821. 2023 */ 2024 2025 dest_entry = ipc_entry_lookup(space, dest_name); 2026 if (dest_entry == IE_NULL) 2027 goto invalid_dest; 2028 2029 reply_entry = ipc_entry_lookup(space, reply_name); 2030 if (reply_entry == IE_NULL) 2031 goto invalid_reply; 2032 2033 assert(dest_entry != reply_entry); /* names are not equal */ 2034 assert(reply_type != 0); /* because reply_name not null */ 2035 2036 if (!ipc_right_copyin_check(space, reply_name, reply_entry, 2037 reply_type)) 2038 goto invalid_reply; 2039 2040#if IMPORTANCE_INHERITANCE 2041 kr = ipc_right_copyin(space, dest_name, dest_entry, 2042 dest_type, FALSE, 2043 &dest_port, &dest_soright, 2044 &release_port, 2045 &assertcnt, 2046 links); 2047 assert(assertcnt == 0); 2048#else 2049 kr = ipc_right_copyin(space, dest_name, dest_entry, 2050 dest_type, FALSE, 2051 &dest_port, &dest_soright, 2052 &release_port, 2053 links); 2054#endif /* IMPORTANCE_INHERITANCE */ 2055 2056 if (kr != KERN_SUCCESS) 2057 goto invalid_dest; 2058 2059 assert(IO_VALID(dest_port)); 2060 2061#if IMPORTANCE_INHERITANCE 2062 kr = ipc_right_copyin(space, reply_name, reply_entry, 2063 reply_type, TRUE, 2064 &reply_port, &reply_soright, 2065 &release_port, 2066 &assertcnt, 2067 links); 2068 assert(assertcnt == 0); 2069#else 2070 kr = ipc_right_copyin(space, reply_name, reply_entry, 2071 reply_type, TRUE, 2072 &reply_port, &reply_soright, 2073 &release_port, 2074 links); 2075#endif /* IMPORTANCE_INHERITANCE */ 2076 2077 assert(kr == KERN_SUCCESS); 2078 2079 /* the entries might need to be deallocated */ 2080 2081 if (IE_BITS_TYPE(reply_entry->ie_bits) == MACH_PORT_TYPE_NONE) { 2082 ipc_entry_dealloc(space, reply_name, reply_entry); 2083 reply_entry = IE_NULL; 2084 } 2085 2086 if (IE_BITS_TYPE(dest_entry->ie_bits) == MACH_PORT_TYPE_NONE) { 2087 ipc_entry_dealloc(space, dest_name, dest_entry); 2088 dest_entry = IE_NULL; 2089 } 2090 } 2091 2092 dest_type = ipc_object_copyin_type(dest_type); 2093 reply_type = ipc_object_copyin_type(reply_type); 2094 2095 /* 2096 * JMM - Without rdar://problem/6275821, this is the last place we can 2097 * re-arm the send-possible notifications. It may trigger unexpectedly 2098 * early (send may NOT have failed), but better than missing. We assure 2099 * we won't miss by forcing MACH_SEND_ALWAYS if we got past arming. 2100 */ 2101 if (((*optionp & MACH_SEND_NOTIFY) != 0) && 2102 dest_type != MACH_MSG_TYPE_PORT_SEND_ONCE && 2103 dest_entry != IE_NULL && dest_entry->ie_request != IE_REQ_NONE) { 2104 ipc_port_t dport = (ipc_port_t)dest_port; 2105 2106 assert(dport != IP_NULL); 2107 ip_lock(dport); 2108 if (ip_active(dport) && dport->ip_receiver != ipc_space_kernel) { 2109 if (ip_full(dport)) { 2110#if IMPORTANCE_INHERITANCE 2111 needboost = ipc_port_request_sparm(dport, dest_name, 2112 dest_entry->ie_request, 2113 (*optionp & MACH_SEND_NOIMPORTANCE)); 2114 if (needboost == FALSE) 2115 ip_unlock(dport); 2116#else 2117 2118 ipc_port_request_sparm(dport, dest_name, dest_entry->ie_request); 2119 ip_unlock(dport); 2120#endif /* IMPORTANCE_INHERITANCE */ 2121 } else { 2122 *optionp |= MACH_SEND_ALWAYS; 2123 ip_unlock(dport); 2124 } 2125 } else { 2126 ip_unlock(dport); 2127 } 2128 } 2129 2130 is_write_unlock(space); 2131 2132#if IMPORTANCE_INHERITANCE 2133 /* 2134 * If our request is the first boosting send-possible 2135 * notification this cycle, push the boost down the 2136 * destination port. 2137 */ 2138 if (needboost == TRUE) { 2139 ipc_port_t dport = (ipc_port_t)dest_port; 2140 2141 /* dport still locked from above */ 2142 if (ipc_port_importance_delta(dport, 1) == FALSE) 2143 ip_unlock(dport); 2144 } 2145#endif /* IMPORTANCE_INHERITANCE */ 2146 2147 if (dest_soright != IP_NULL) 2148 ipc_notify_port_deleted(dest_soright, dest_name); 2149 2150 if (reply_soright != IP_NULL) 2151 ipc_notify_port_deleted(reply_soright, reply_name); 2152 2153 msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | 2154 MACH_MSGH_BITS(dest_type, reply_type)); 2155 msg->msgh_remote_port = (ipc_port_t)dest_port; 2156 msg->msgh_local_port = (ipc_port_t)reply_port; 2157 2158 while(!queue_empty(links)) { 2159 wql = (wait_queue_link_t) dequeue(links); 2160 wait_queue_link_free(wql); 2161 } 2162 2163 if (release_port != IP_NULL) 2164 ip_release(release_port); 2165 2166 2167 return MACH_MSG_SUCCESS; 2168 2169invalid_reply: 2170 is_write_unlock(space); 2171 2172 while(!queue_empty(links)) { 2173 wql = (wait_queue_link_t) dequeue(links); 2174 wait_queue_link_free(wql); 2175 } 2176 2177 if (release_port != IP_NULL) 2178 ip_release(release_port); 2179 2180 return MACH_SEND_INVALID_REPLY; 2181 2182invalid_dest: 2183 is_write_unlock(space); 2184 2185 while(!queue_empty(links)) { 2186 wql = (wait_queue_link_t) dequeue(links); 2187 wait_queue_link_free(wql); 2188 } 2189 2190 if (release_port != IP_NULL) 2191 ip_release(release_port); 2192 2193 if (reply_soright != IP_NULL) 2194 ipc_notify_port_deleted(reply_soright, reply_name); 2195 2196 return MACH_SEND_INVALID_DEST; 2197} 2198 2199mach_msg_descriptor_t *ipc_kmsg_copyin_port_descriptor( 2200 volatile mach_msg_port_descriptor_t *dsc, 2201 mach_msg_legacy_port_descriptor_t *user_dsc, 2202 ipc_space_t space, 2203 ipc_object_t dest, 2204 ipc_kmsg_t kmsg, 2205 mach_msg_return_t *mr); 2206 2207void ipc_print_type_name( 2208 int type_name); 2209mach_msg_descriptor_t * 2210ipc_kmsg_copyin_port_descriptor( 2211 volatile mach_msg_port_descriptor_t *dsc, 2212 mach_msg_legacy_port_descriptor_t *user_dsc_in, 2213 ipc_space_t space, 2214 ipc_object_t dest, 2215 ipc_kmsg_t kmsg, 2216 mach_msg_return_t *mr) 2217{ 2218 volatile mach_msg_legacy_port_descriptor_t *user_dsc = user_dsc_in; 2219 mach_msg_type_name_t user_disp; 2220 mach_msg_type_name_t result_disp; 2221 mach_port_name_t name; 2222 ipc_object_t object; 2223 2224 user_disp = user_dsc->disposition; 2225 result_disp = ipc_object_copyin_type(user_disp); 2226 2227 name = (mach_port_name_t)user_dsc->name; 2228 if (MACH_PORT_VALID(name)) { 2229 2230 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object); 2231 if (kr != KERN_SUCCESS) { 2232 *mr = MACH_SEND_INVALID_RIGHT; 2233 return NULL; 2234 } 2235 2236 if ((result_disp == MACH_MSG_TYPE_PORT_RECEIVE) && 2237 ipc_port_check_circularity((ipc_port_t) object, 2238 (ipc_port_t) dest)) { 2239 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR; 2240 } 2241 dsc->name = (ipc_port_t) object; 2242 } else { 2243 dsc->name = CAST_MACH_NAME_TO_PORT(name); 2244 } 2245 dsc->disposition = result_disp; 2246 dsc->type = MACH_MSG_PORT_DESCRIPTOR; 2247 2248 dsc->pad_end = 0; // debug, unnecessary 2249 2250 return (mach_msg_descriptor_t *)(user_dsc_in+1); 2251} 2252 2253mach_msg_descriptor_t * ipc_kmsg_copyin_ool_descriptor( 2254 mach_msg_ool_descriptor_t *dsc, 2255 mach_msg_descriptor_t *user_dsc, 2256 int is_64bit, 2257 vm_offset_t *paddr, 2258 vm_map_copy_t *copy, 2259 vm_size_t *space_needed, 2260 vm_map_t map, 2261 mach_msg_return_t *mr); 2262mach_msg_descriptor_t * 2263ipc_kmsg_copyin_ool_descriptor( 2264 mach_msg_ool_descriptor_t *dsc, 2265 mach_msg_descriptor_t *user_dsc, 2266 int is_64bit, 2267 vm_offset_t *paddr, 2268 vm_map_copy_t *copy, 2269 vm_size_t *space_needed, 2270 vm_map_t map, 2271 mach_msg_return_t *mr) 2272{ 2273 vm_size_t length; 2274 boolean_t dealloc; 2275 mach_msg_copy_options_t copy_options; 2276 mach_vm_offset_t addr; 2277 mach_msg_descriptor_type_t dsc_type; 2278 2279 if (is_64bit) { 2280 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 2281 2282 addr = (mach_vm_offset_t) user_ool_dsc->address; 2283 length = user_ool_dsc->size; 2284 dealloc = user_ool_dsc->deallocate; 2285 copy_options = user_ool_dsc->copy; 2286 dsc_type = user_ool_dsc->type; 2287 2288 user_dsc = (typeof(user_dsc))(user_ool_dsc+1); 2289 } else { 2290 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 2291 2292 addr = CAST_USER_ADDR_T(user_ool_dsc->address); 2293 dealloc = user_ool_dsc->deallocate; 2294 copy_options = user_ool_dsc->copy; 2295 dsc_type = user_ool_dsc->type; 2296 length = user_ool_dsc->size; 2297 2298 user_dsc = (typeof(user_dsc))(user_ool_dsc+1); 2299 } 2300 2301 dsc->size = (mach_msg_size_t)length; 2302 dsc->deallocate = dealloc; 2303 dsc->copy = copy_options; 2304 dsc->type = dsc_type; 2305 2306 if (length == 0) { 2307 dsc->address = NULL; 2308 } else if ((length >= MSG_OOL_SIZE_SMALL) && 2309 (copy_options == MACH_MSG_PHYSICAL_COPY) && !dealloc) { 2310 2311 /* 2312 * If the request is a physical copy and the source 2313 * is not being deallocated, then allocate space 2314 * in the kernel's pageable ipc copy map and copy 2315 * the data in. The semantics guarantee that the 2316 * data will have been physically copied before 2317 * the send operation terminates. Thus if the data 2318 * is not being deallocated, we must be prepared 2319 * to page if the region is sufficiently large. 2320 */ 2321 if (copyin(addr, (char *)*paddr, length)) { 2322 *mr = MACH_SEND_INVALID_MEMORY; 2323 return NULL; 2324 } 2325 2326 /* 2327 * The kernel ipc copy map is marked no_zero_fill. 2328 * If the transfer is not a page multiple, we need 2329 * to zero fill the balance. 2330 */ 2331 if (!page_aligned(length)) { 2332 (void) memset((void *) (*paddr + length), 0, 2333 round_page(length) - length); 2334 } 2335 if (vm_map_copyin(ipc_kernel_copy_map, (vm_map_address_t)*paddr, 2336 (vm_map_size_t)length, TRUE, copy) != KERN_SUCCESS) { 2337 *mr = MACH_MSG_VM_KERNEL; 2338 return NULL; 2339 } 2340 dsc->address = (void *)*copy; 2341 *paddr += round_page(length); 2342 *space_needed -= round_page(length); 2343 } else { 2344 2345 /* 2346 * Make a vm_map_copy_t of the of the data. If the 2347 * data is small, this will do an optimized physical 2348 * copy. Otherwise, it will do a virtual copy. 2349 * 2350 * NOTE: A virtual copy is OK if the original is being 2351 * deallocted, even if a physical copy was requested. 2352 */ 2353 kern_return_t kr = vm_map_copyin(map, addr, 2354 (vm_map_size_t)length, dealloc, copy); 2355 if (kr != KERN_SUCCESS) { 2356 *mr = (kr == KERN_RESOURCE_SHORTAGE) ? 2357 MACH_MSG_VM_KERNEL : 2358 MACH_SEND_INVALID_MEMORY; 2359 return NULL; 2360 } 2361 dsc->address = (void *)*copy; 2362 } 2363 return user_dsc; 2364} 2365 2366mach_msg_descriptor_t * ipc_kmsg_copyin_ool_ports_descriptor( 2367 mach_msg_ool_ports_descriptor_t *dsc, 2368 mach_msg_descriptor_t *user_dsc, 2369 int is_64bit, 2370 vm_map_t map, 2371 ipc_space_t space, 2372 ipc_object_t dest, 2373 ipc_kmsg_t kmsg, 2374 mach_msg_return_t *mr); 2375mach_msg_descriptor_t * 2376ipc_kmsg_copyin_ool_ports_descriptor( 2377 mach_msg_ool_ports_descriptor_t *dsc, 2378 mach_msg_descriptor_t *user_dsc, 2379 int is_64bit, 2380 vm_map_t map, 2381 ipc_space_t space, 2382 ipc_object_t dest, 2383 ipc_kmsg_t kmsg, 2384 mach_msg_return_t *mr) 2385{ 2386 void *data; 2387 ipc_object_t *objects; 2388 unsigned int i; 2389 mach_vm_offset_t addr; 2390 mach_msg_type_name_t user_disp; 2391 mach_msg_type_name_t result_disp; 2392 mach_msg_type_number_t count; 2393 mach_msg_copy_options_t copy_option; 2394 boolean_t deallocate; 2395 mach_msg_descriptor_type_t type; 2396 vm_size_t ports_length, names_length; 2397 2398 if (is_64bit) { 2399 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 2400 2401 addr = (mach_vm_offset_t)user_ool_dsc->address; 2402 count = user_ool_dsc->count; 2403 deallocate = user_ool_dsc->deallocate; 2404 copy_option = user_ool_dsc->copy; 2405 user_disp = user_ool_dsc->disposition; 2406 type = user_ool_dsc->type; 2407 2408 user_dsc = (typeof(user_dsc))(user_ool_dsc+1); 2409 } else { 2410 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 2411 2412 addr = CAST_USER_ADDR_T(user_ool_dsc->address); 2413 count = user_ool_dsc->count; 2414 deallocate = user_ool_dsc->deallocate; 2415 copy_option = user_ool_dsc->copy; 2416 user_disp = user_ool_dsc->disposition; 2417 type = user_ool_dsc->type; 2418 2419 user_dsc = (typeof(user_dsc))(user_ool_dsc+1); 2420 } 2421 2422 dsc->deallocate = deallocate; 2423 dsc->copy = copy_option; 2424 dsc->type = type; 2425 dsc->count = count; 2426 dsc->address = NULL; /* for now */ 2427 2428 result_disp = ipc_object_copyin_type(user_disp); 2429 dsc->disposition = result_disp; 2430 2431 if (count > (INT_MAX / sizeof(mach_port_t))) { 2432 *mr = MACH_SEND_TOO_LARGE; 2433 return NULL; 2434 } 2435 2436 /* calculate length of data in bytes, rounding up */ 2437 ports_length = count * sizeof(mach_port_t); 2438 names_length = count * sizeof(mach_port_name_t); 2439 2440 if (ports_length == 0) { 2441 return user_dsc; 2442 } 2443 2444 data = kalloc(ports_length); 2445 2446 if (data == NULL) { 2447 *mr = MACH_SEND_NO_BUFFER; 2448 return NULL; 2449 } 2450 2451#ifdef __LP64__ 2452 mach_port_name_t *names = &((mach_port_name_t *)data)[count]; 2453#else 2454 mach_port_name_t *names = ((mach_port_name_t *)data); 2455#endif 2456 2457 if (copyinmap(map, addr, names, names_length) != KERN_SUCCESS) { 2458 kfree(data, ports_length); 2459 *mr = MACH_SEND_INVALID_MEMORY; 2460 return NULL; 2461 } 2462 2463 if (deallocate) { 2464 (void) mach_vm_deallocate(map, addr, (mach_vm_size_t)ports_length); 2465 } 2466 2467 objects = (ipc_object_t *) data; 2468 dsc->address = data; 2469 2470 for ( i = 0; i < count; i++) { 2471 mach_port_name_t name = names[i]; 2472 ipc_object_t object; 2473 2474 if (!MACH_PORT_VALID(name)) { 2475 objects[i] = (ipc_object_t)CAST_MACH_NAME_TO_PORT(name); 2476 continue; 2477 } 2478 2479 kern_return_t kr = ipc_object_copyin(space, name, user_disp, &object); 2480 2481 if (kr != KERN_SUCCESS) { 2482 unsigned int j; 2483 2484 for(j = 0; j < i; j++) { 2485 object = objects[j]; 2486 if (IPC_OBJECT_VALID(object)) 2487 ipc_object_destroy(object, result_disp); 2488 } 2489 kfree(data, ports_length); 2490 dsc->address = NULL; 2491 *mr = MACH_SEND_INVALID_RIGHT; 2492 return NULL; 2493 } 2494 2495 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) && 2496 ipc_port_check_circularity( 2497 (ipc_port_t) object, 2498 (ipc_port_t) dest)) 2499 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR; 2500 2501 objects[i] = object; 2502 } 2503 2504 return user_dsc; 2505} 2506 2507/* 2508 * Routine: ipc_kmsg_copyin_body 2509 * Purpose: 2510 * "Copy-in" port rights and out-of-line memory 2511 * in the message body. 2512 * 2513 * In all failure cases, the message is left holding 2514 * no rights or memory. However, the message buffer 2515 * is not deallocated. If successful, the message 2516 * contains a valid destination port. 2517 * Conditions: 2518 * Nothing locked. 2519 * Returns: 2520 * MACH_MSG_SUCCESS Successful copyin. 2521 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory. 2522 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body. 2523 * MACH_SEND_INVALID_TYPE Bad type specification. 2524 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data. 2525 * MACH_SEND_INVALID_RT_OOL_SIZE OOL Buffer too large for RT 2526 * MACH_MSG_INVALID_RT_DESCRIPTOR Dealloc and RT are incompatible 2527 */ 2528 2529mach_msg_return_t 2530ipc_kmsg_copyin_body( 2531 ipc_kmsg_t kmsg, 2532 ipc_space_t space, 2533 vm_map_t map) 2534{ 2535 ipc_object_t dest; 2536 mach_msg_body_t *body; 2537 mach_msg_descriptor_t *daddr, *naddr; 2538 mach_msg_descriptor_t *user_addr, *kern_addr; 2539 mach_msg_type_number_t dsc_count; 2540 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS); 2541 boolean_t complex = FALSE; 2542 vm_size_t space_needed = 0; 2543 vm_offset_t paddr = 0; 2544 vm_map_copy_t copy = VM_MAP_COPY_NULL; 2545 mach_msg_type_number_t i; 2546 mach_msg_return_t mr = MACH_MSG_SUCCESS; 2547 2548 vm_size_t descriptor_size = 0; 2549 2550 /* 2551 * Determine if the target is a kernel port. 2552 */ 2553 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 2554 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 2555 naddr = (mach_msg_descriptor_t *) (body + 1); 2556 2557 dsc_count = body->msgh_descriptor_count; 2558 if (dsc_count == 0) 2559 return MACH_MSG_SUCCESS; 2560 2561 /* 2562 * Make an initial pass to determine kernal VM space requirements for 2563 * physical copies and possible contraction of the descriptors from 2564 * processes with pointers larger than the kernel's. 2565 */ 2566 daddr = NULL; 2567 for (i = 0; i < dsc_count; i++) { 2568 daddr = naddr; 2569 2570 /* make sure the descriptor fits in the message */ 2571 if (is_task_64bit) { 2572 switch (daddr->type.type) { 2573 case MACH_MSG_OOL_DESCRIPTOR: 2574 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 2575 case MACH_MSG_OOL_PORTS_DESCRIPTOR: 2576 descriptor_size += 16; 2577 naddr = (typeof(naddr))((vm_offset_t)daddr + 16); 2578 break; 2579 default: 2580 descriptor_size += 12; 2581 naddr = (typeof(naddr))((vm_offset_t)daddr + 12); 2582 break; 2583 } 2584 } else { 2585 descriptor_size += 12; 2586 naddr = (typeof(naddr))((vm_offset_t)daddr + 12); 2587 } 2588 2589 if (naddr > (mach_msg_descriptor_t *) 2590 ((vm_offset_t)kmsg->ikm_header + kmsg->ikm_header->msgh_size)) { 2591 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0); 2592 mr = MACH_SEND_MSG_TOO_SMALL; 2593 goto out; 2594 } 2595 2596 switch (daddr->type.type) { 2597 mach_msg_size_t size; 2598 2599 case MACH_MSG_OOL_DESCRIPTOR: 2600 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 2601 size = (is_task_64bit) ? 2602 ((mach_msg_ool_descriptor64_t *)daddr)->size : 2603 daddr->out_of_line.size; 2604 2605 if (daddr->out_of_line.copy != MACH_MSG_PHYSICAL_COPY && 2606 daddr->out_of_line.copy != MACH_MSG_VIRTUAL_COPY) { 2607 /* 2608 * Invalid copy option 2609 */ 2610 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0); 2611 mr = MACH_SEND_INVALID_TYPE; 2612 goto out; 2613 } 2614 2615 if ((size >= MSG_OOL_SIZE_SMALL) && 2616 (daddr->out_of_line.copy == MACH_MSG_PHYSICAL_COPY) && 2617 !(daddr->out_of_line.deallocate)) { 2618 2619 /* 2620 * Out-of-line memory descriptor, accumulate kernel 2621 * memory requirements 2622 */ 2623 if (space_needed + round_page(size) <= space_needed) { 2624 /* Overflow dectected */ 2625 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0); 2626 mr = MACH_MSG_VM_KERNEL; 2627 goto out; 2628 } 2629 2630 space_needed += round_page(size); 2631 if (space_needed > ipc_kmsg_max_vm_space) { 2632 2633 /* 2634 * Per message kernel memory limit exceeded 2635 */ 2636 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0); 2637 mr = MACH_MSG_VM_KERNEL; 2638 goto out; 2639 } 2640 } 2641 } 2642 } 2643 2644 /* 2645 * Allocate space in the pageable kernel ipc copy map for all the 2646 * ool data that is to be physically copied. Map is marked wait for 2647 * space. 2648 */ 2649 if (space_needed) { 2650 if (vm_allocate(ipc_kernel_copy_map, &paddr, space_needed, 2651 VM_FLAGS_ANYWHERE) != KERN_SUCCESS) { 2652 ipc_kmsg_clean_partial(kmsg, 0, NULL, 0, 0); 2653 mr = MACH_MSG_VM_KERNEL; 2654 goto out; 2655 } 2656 } 2657 2658 /* user_addr = just after base as it was copied in */ 2659 user_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t)); 2660 /* Shift the mach_msg_base_t down to make for dsc_count*16bytes of descriptors */ 2661 if(descriptor_size != 16*dsc_count) { 2662 vm_offset_t dsc_adjust = 16*dsc_count - descriptor_size; 2663 memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t)); 2664 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust); 2665 /* Update the message size for the larger in-kernel representation */ 2666 kmsg->ikm_header->msgh_size += (mach_msg_size_t)dsc_adjust; 2667 } 2668 2669 2670 /* kern_addr = just after base after it has been (conditionally) moved */ 2671 kern_addr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t)); 2672 2673 /* handle the OOL regions and port descriptors. */ 2674 for(i=0;i<dsc_count;i++) { 2675 switch (user_addr->type.type) { 2676 case MACH_MSG_PORT_DESCRIPTOR: 2677 user_addr = ipc_kmsg_copyin_port_descriptor((mach_msg_port_descriptor_t *)kern_addr, 2678 (mach_msg_legacy_port_descriptor_t *)user_addr, space, dest, kmsg, &mr); 2679 kern_addr++; 2680 complex = TRUE; 2681 break; 2682 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 2683 case MACH_MSG_OOL_DESCRIPTOR: 2684 user_addr = ipc_kmsg_copyin_ool_descriptor((mach_msg_ool_descriptor_t *)kern_addr, 2685 user_addr, is_task_64bit, &paddr, ©, &space_needed, map, &mr); 2686 kern_addr++; 2687 complex = TRUE; 2688 break; 2689 case MACH_MSG_OOL_PORTS_DESCRIPTOR: 2690 user_addr = ipc_kmsg_copyin_ool_ports_descriptor((mach_msg_ool_ports_descriptor_t *)kern_addr, 2691 user_addr, is_task_64bit, map, space, dest, kmsg, &mr); 2692 kern_addr++; 2693 complex = TRUE; 2694 break; 2695 default: 2696 /* Invalid descriptor */ 2697 mr = MACH_SEND_INVALID_TYPE; 2698 break; 2699 } 2700 2701 if (MACH_MSG_SUCCESS != mr) { 2702 /* clean from start of message descriptors to i */ 2703 ipc_kmsg_clean_partial(kmsg, i, 2704 (mach_msg_descriptor_t *)((mach_msg_base_t *)kmsg->ikm_header + 1), 2705 paddr, space_needed); 2706 goto out; 2707 } 2708 } /* End of loop */ 2709 2710 if (!complex) { 2711 kmsg->ikm_header->msgh_bits &= ~MACH_MSGH_BITS_COMPLEX; 2712 } 2713 out: 2714 return mr; 2715} 2716 2717 2718/* 2719 * Routine: ipc_kmsg_copyin 2720 * Purpose: 2721 * "Copy-in" port rights and out-of-line memory 2722 * in the message. 2723 * 2724 * In all failure cases, the message is left holding 2725 * no rights or memory. However, the message buffer 2726 * is not deallocated. If successful, the message 2727 * contains a valid destination port. 2728 * Conditions: 2729 * Nothing locked. 2730 * Returns: 2731 * MACH_MSG_SUCCESS Successful copyin. 2732 * MACH_SEND_INVALID_HEADER 2733 * Illegal value in the message header bits. 2734 * MACH_SEND_INVALID_DEST Can't copyin destination port. 2735 * MACH_SEND_INVALID_REPLY Can't copyin reply port. 2736 * MACH_SEND_INVALID_MEMORY Can't grab out-of-line memory. 2737 * MACH_SEND_INVALID_RIGHT Can't copyin port right in body. 2738 * MACH_SEND_INVALID_TYPE Bad type specification. 2739 * MACH_SEND_MSG_TOO_SMALL Body is too small for types/data. 2740 */ 2741 2742mach_msg_return_t 2743ipc_kmsg_copyin( 2744 ipc_kmsg_t kmsg, 2745 ipc_space_t space, 2746 vm_map_t map, 2747 mach_msg_option_t *optionp) 2748{ 2749 mach_msg_return_t mr; 2750 2751 kmsg->ikm_header->msgh_bits &= MACH_MSGH_BITS_USER; 2752 2753 mr = ipc_kmsg_copyin_header(kmsg->ikm_header, space, optionp); 2754 2755 if (mr != MACH_MSG_SUCCESS) 2756 return mr; 2757 2758 DEBUG_KPRINT_SYSCALL_IPC("ipc_kmsg_copyin header:\n%.8x\n%.8x\n%p\n%p\n%.8x\n%.8x\n", 2759 kmsg->ikm_header->msgh_size, 2760 kmsg->ikm_header->msgh_bits, 2761 kmsg->ikm_header->msgh_remote_port, 2762 kmsg->ikm_header->msgh_local_port, 2763 kmsg->ikm_header->msgh_reserved, 2764 kmsg->ikm_header->msgh_id); 2765 2766 if ((kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0) 2767 return MACH_MSG_SUCCESS; 2768 2769 mr = ipc_kmsg_copyin_body( kmsg, space, map); 2770 2771 if (DEBUG_KPRINT_SYSCALL_PREDICATE(DEBUG_KPRINT_SYSCALL_IPC_MASK)) 2772 { 2773 kprintf("body:\n"); 2774 uint32_t i; 2775 for(i=0;i*4 < (kmsg->ikm_header->msgh_size - sizeof(mach_msg_header_t));i++) 2776 { 2777 kprintf("%.4x\n",((uint32_t *)(kmsg->ikm_header + 1))[i]); 2778 } 2779 } 2780 2781 return mr; 2782} 2783 2784/* 2785 * Routine: ipc_kmsg_copyin_from_kernel 2786 * Purpose: 2787 * "Copy-in" port rights and out-of-line memory 2788 * in a message sent from the kernel. 2789 * 2790 * Because the message comes from the kernel, 2791 * the implementation assumes there are no errors 2792 * or peculiarities in the message. 2793 * Conditions: 2794 * Nothing locked. 2795 */ 2796 2797mach_msg_return_t 2798ipc_kmsg_copyin_from_kernel( 2799 ipc_kmsg_t kmsg) 2800{ 2801 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits; 2802 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits); 2803 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits); 2804 ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 2805 ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 2806 2807 /* translate the destination and reply ports */ 2808 if (!IO_VALID(remote)) 2809 return MACH_SEND_INVALID_DEST; 2810 2811 ipc_object_copyin_from_kernel(remote, rname); 2812 if (IO_VALID(local)) 2813 ipc_object_copyin_from_kernel(local, lname); 2814 2815 /* 2816 * The common case is a complex message with no reply port, 2817 * because that is what the memory_object interface uses. 2818 */ 2819 2820 if (bits == (MACH_MSGH_BITS_COMPLEX | 2821 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) { 2822 bits = (MACH_MSGH_BITS_COMPLEX | 2823 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0)); 2824 2825 kmsg->ikm_header->msgh_bits = bits; 2826 } else { 2827 bits = (MACH_MSGH_BITS_OTHER(bits) | 2828 MACH_MSGH_BITS(ipc_object_copyin_type(rname), 2829 ipc_object_copyin_type(lname))); 2830 2831 kmsg->ikm_header->msgh_bits = bits; 2832 if ((bits & MACH_MSGH_BITS_COMPLEX) == 0) 2833 return MACH_MSG_SUCCESS; 2834 } 2835 { 2836 mach_msg_descriptor_t *saddr; 2837 mach_msg_body_t *body; 2838 mach_msg_type_number_t i, count; 2839 2840 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 2841 saddr = (mach_msg_descriptor_t *) (body + 1); 2842 count = body->msgh_descriptor_count; 2843 2844 for (i = 0; i < count; i++, saddr++) { 2845 2846 switch (saddr->type.type) { 2847 2848 case MACH_MSG_PORT_DESCRIPTOR: { 2849 mach_msg_type_name_t name; 2850 ipc_object_t object; 2851 mach_msg_port_descriptor_t *dsc; 2852 2853 dsc = &saddr->port; 2854 2855 /* this is really the type SEND, SEND_ONCE, etc. */ 2856 name = dsc->disposition; 2857 object = (ipc_object_t) dsc->name; 2858 dsc->disposition = ipc_object_copyin_type(name); 2859 2860 if (!IO_VALID(object)) { 2861 break; 2862 } 2863 2864 ipc_object_copyin_from_kernel(object, name); 2865 2866 /* CDY avoid circularity when the destination is also */ 2867 /* the kernel. This check should be changed into an */ 2868 /* assert when the new kobject model is in place since*/ 2869 /* ports will not be used in kernel to kernel chats */ 2870 2871 if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) { 2872 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) && 2873 ipc_port_check_circularity((ipc_port_t) object, 2874 (ipc_port_t) remote)) { 2875 kmsg->ikm_header->msgh_bits |= 2876 MACH_MSGH_BITS_CIRCULAR; 2877 } 2878 } 2879 break; 2880 } 2881 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 2882 case MACH_MSG_OOL_DESCRIPTOR: { 2883 /* 2884 * The sender should supply ready-made memory, i.e. 2885 * a vm_map_copy_t, so we don't need to do anything. 2886 */ 2887 break; 2888 } 2889 case MACH_MSG_OOL_PORTS_DESCRIPTOR: { 2890 ipc_object_t *objects; 2891 unsigned int j; 2892 mach_msg_type_name_t name; 2893 mach_msg_ool_ports_descriptor_t *dsc; 2894 2895 dsc = (mach_msg_ool_ports_descriptor_t *)&saddr->ool_ports; 2896 2897 /* this is really the type SEND, SEND_ONCE, etc. */ 2898 name = dsc->disposition; 2899 dsc->disposition = ipc_object_copyin_type(name); 2900 2901 objects = (ipc_object_t *) dsc->address; 2902 2903 for ( j = 0; j < dsc->count; j++) { 2904 ipc_object_t object = objects[j]; 2905 2906 if (!IO_VALID(object)) 2907 continue; 2908 2909 ipc_object_copyin_from_kernel(object, name); 2910 2911 if ((dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) && 2912 ipc_port_check_circularity( 2913 (ipc_port_t) object, 2914 (ipc_port_t) remote)) 2915 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR; 2916 } 2917 break; 2918 } 2919 default: { 2920#if MACH_ASSERT 2921 panic("ipc_kmsg_copyin_from_kernel: bad descriptor"); 2922#endif /* MACH_ASSERT */ 2923 } 2924 } 2925 } 2926 } 2927 return MACH_MSG_SUCCESS; 2928} 2929 2930#if IKM_SUPPORT_LEGACY 2931mach_msg_return_t 2932ipc_kmsg_copyin_from_kernel_legacy( 2933 ipc_kmsg_t kmsg) 2934{ 2935 mach_msg_bits_t bits = kmsg->ikm_header->msgh_bits; 2936 mach_msg_type_name_t rname = MACH_MSGH_BITS_REMOTE(bits); 2937 mach_msg_type_name_t lname = MACH_MSGH_BITS_LOCAL(bits); 2938 ipc_object_t remote = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 2939 ipc_object_t local = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 2940 2941 /* translate the destination and reply ports */ 2942 if (!IO_VALID(remote)) 2943 return MACH_SEND_INVALID_DEST; 2944 2945 ipc_object_copyin_from_kernel(remote, rname); 2946 if (IO_VALID(local)) 2947 ipc_object_copyin_from_kernel(local, lname); 2948 2949 /* 2950 * The common case is a complex message with no reply port, 2951 * because that is what the memory_object interface uses. 2952 */ 2953 2954 if (bits == (MACH_MSGH_BITS_COMPLEX | 2955 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0))) { 2956 bits = (MACH_MSGH_BITS_COMPLEX | 2957 MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0)); 2958 2959 kmsg->ikm_header->msgh_bits = bits; 2960 } else { 2961 bits = (MACH_MSGH_BITS_OTHER(bits) | 2962 MACH_MSGH_BITS(ipc_object_copyin_type(rname), 2963 ipc_object_copyin_type(lname))); 2964 2965 kmsg->ikm_header->msgh_bits = bits; 2966 if ((bits & MACH_MSGH_BITS_COMPLEX) == 0) 2967 return MACH_MSG_SUCCESS; 2968 } 2969 { 2970 mach_msg_legacy_descriptor_t *saddr; 2971 mach_msg_descriptor_t *daddr; 2972 mach_msg_body_t *body; 2973 mach_msg_type_number_t i, count; 2974 2975 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 2976 saddr = (typeof(saddr)) (body + 1); 2977 count = body->msgh_descriptor_count; 2978 2979 if(count) { 2980 vm_offset_t dsc_adjust = 4*count; 2981 memmove((char *)(((vm_offset_t)kmsg->ikm_header) - dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t)); 2982 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header - dsc_adjust); 2983 /* Update the message size for the larger in-kernel representation */ 2984 kmsg->ikm_header->msgh_size += dsc_adjust; 2985 } 2986 daddr = (mach_msg_descriptor_t *)((vm_offset_t)kmsg->ikm_header + sizeof(mach_msg_base_t)); 2987 2988 for (i = 0; i < count; i++, saddr++, daddr++) { 2989 switch (saddr->type.type) { 2990 2991 case MACH_MSG_PORT_DESCRIPTOR: { 2992 mach_msg_type_name_t name; 2993 ipc_object_t object; 2994 mach_msg_legacy_port_descriptor_t *dsc; 2995 mach_msg_port_descriptor_t *dest_dsc; 2996 2997 dsc = (typeof(dsc))&saddr->port; 2998 dest_dsc = &daddr->port; 2999 3000 /* this is really the type SEND, SEND_ONCE, etc. */ 3001 name = dsc->disposition; 3002 object = (ipc_object_t) CAST_MACH_NAME_TO_PORT(dsc->name); 3003 dest_dsc->disposition = ipc_object_copyin_type(name); 3004 dest_dsc->name = (mach_port_t)object; 3005 dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR; 3006 3007 if (!IO_VALID(object)) { 3008 break; 3009 } 3010 3011 ipc_object_copyin_from_kernel(object, name); 3012 3013 /* CDY avoid circularity when the destination is also */ 3014 /* the kernel. This check should be changed into an */ 3015 /* assert when the new kobject model is in place since*/ 3016 /* ports will not be used in kernel to kernel chats */ 3017 3018 if (((ipc_port_t)remote)->ip_receiver != ipc_space_kernel) { 3019 if ((dest_dsc->disposition == MACH_MSG_TYPE_PORT_RECEIVE) && 3020 ipc_port_check_circularity((ipc_port_t) object, 3021 (ipc_port_t) remote)) { 3022 kmsg->ikm_header->msgh_bits |= 3023 MACH_MSGH_BITS_CIRCULAR; 3024 } 3025 } 3026 break; 3027 } 3028 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 3029 case MACH_MSG_OOL_DESCRIPTOR: { 3030 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t 3031 * so we don't need to do anything special. */ 3032 3033 mach_msg_ool_descriptor32_t *source_dsc = &saddr->out_of_line32; 3034 mach_msg_ool_descriptor_t *dest_dsc = (typeof(dest_dsc))&daddr->out_of_line; 3035 3036 vm_offset_t address = source_dsc->address; 3037 vm_size_t size = source_dsc->size; 3038 boolean_t deallocate = source_dsc->deallocate; 3039 mach_msg_copy_options_t copy = source_dsc->copy; 3040 mach_msg_descriptor_type_t type = source_dsc->type; 3041 3042 dest_dsc->address = (void *)address; 3043 dest_dsc->size = size; 3044 dest_dsc->deallocate = deallocate; 3045 dest_dsc->copy = copy; 3046 dest_dsc->type = type; 3047 break; 3048 } 3049 case MACH_MSG_OOL_PORTS_DESCRIPTOR: { 3050 ipc_object_t *objects; 3051 unsigned int j; 3052 mach_msg_type_name_t name; 3053 mach_msg_ool_ports_descriptor_t *dest_dsc; 3054 3055 mach_msg_ool_ports_descriptor32_t *source_dsc = &saddr->ool_ports32; 3056 dest_dsc = (typeof(dest_dsc))&daddr->ool_ports; 3057 3058 boolean_t deallocate = source_dsc->deallocate; 3059 mach_msg_copy_options_t copy = source_dsc->copy; 3060 mach_msg_size_t port_count = source_dsc->count; 3061 mach_msg_type_name_t disposition = source_dsc->disposition; 3062 3063 /* this is really the type SEND, SEND_ONCE, etc. */ 3064 name = disposition; 3065 disposition = ipc_object_copyin_type(name); 3066 3067 objects = (ipc_object_t *) (uintptr_t)source_dsc->address; 3068 3069 for ( j = 0; j < port_count; j++) { 3070 ipc_object_t object = objects[j]; 3071 3072 if (!IO_VALID(object)) 3073 continue; 3074 3075 ipc_object_copyin_from_kernel(object, name); 3076 3077 if ((disposition == MACH_MSG_TYPE_PORT_RECEIVE) && 3078 ipc_port_check_circularity( 3079 (ipc_port_t) object, 3080 (ipc_port_t) remote)) 3081 kmsg->ikm_header->msgh_bits |= MACH_MSGH_BITS_CIRCULAR; 3082 } 3083 3084 dest_dsc->address = objects; 3085 dest_dsc->deallocate = deallocate; 3086 dest_dsc->copy = copy; 3087 dest_dsc->disposition = disposition; 3088 dest_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR; 3089 dest_dsc->count = port_count; 3090 break; 3091 } 3092 default: { 3093#if MACH_ASSERT 3094 panic("ipc_kmsg_copyin_from_kernel: bad descriptor"); 3095#endif /* MACH_ASSERT */ 3096 } 3097 } 3098 } 3099 } 3100 return MACH_MSG_SUCCESS; 3101} 3102#endif /* IKM_SUPPORT_LEGACY */ 3103 3104/* 3105 * Routine: ipc_kmsg_copyout_header 3106 * Purpose: 3107 * "Copy-out" port rights in the header of a message. 3108 * Operates atomically; if it doesn't succeed the 3109 * message header and the space are left untouched. 3110 * If it does succeed the remote/local port fields 3111 * contain port names instead of object pointers, 3112 * and the bits field is updated. 3113 * Conditions: 3114 * Nothing locked. 3115 * Returns: 3116 * MACH_MSG_SUCCESS Copied out port rights. 3117 * MACH_RCV_INVALID_NOTIFY 3118 * Notify is non-null and doesn't name a receive right. 3119 * (Either KERN_INVALID_NAME or KERN_INVALID_RIGHT.) 3120 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE 3121 * The space is dead. 3122 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE 3123 * No room in space for another name. 3124 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL 3125 * Couldn't allocate memory for the reply port. 3126 * MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_KERNEL 3127 * Couldn't allocate memory for the dead-name request. 3128 */ 3129 3130mach_msg_return_t 3131ipc_kmsg_copyout_header( 3132 mach_msg_header_t *msg, 3133 ipc_space_t space) 3134{ 3135 mach_msg_bits_t mbits = msg->msgh_bits; 3136 ipc_port_t dest = (ipc_port_t) msg->msgh_remote_port; 3137 3138 assert(IP_VALID(dest)); 3139 3140 /* 3141 * While we still hold a reference on the received-from port, 3142 * process all send-possible notfications we received along with 3143 * the message. 3144 */ 3145 ipc_port_spnotify(dest); 3146 3147 { 3148 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits); 3149 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits); 3150 ipc_port_t reply = (ipc_port_t) msg->msgh_local_port; 3151 ipc_port_t release_port = IP_NULL; 3152 mach_port_name_t dest_name, reply_name; 3153 3154 if (IP_VALID(reply)) { 3155 ipc_entry_t entry; 3156 kern_return_t kr; 3157 3158 /* 3159 * Get reply port entry (if none, skip to dest port 3160 * copyout). This may require growing the space. 3161 */ 3162 3163 is_write_lock(space); 3164 3165 for (;;) { 3166 if (!is_active(space)) { 3167 is_write_unlock(space); 3168 return (MACH_RCV_HEADER_ERROR| 3169 MACH_MSG_IPC_SPACE); 3170 } 3171 3172 if ((reply_type != MACH_MSG_TYPE_PORT_SEND_ONCE) && 3173 ipc_right_reverse(space, (ipc_object_t) reply, 3174 &reply_name, &entry)) { 3175 /* reply port is locked and active */ 3176 assert(entry->ie_bits & 3177 MACH_PORT_TYPE_SEND_RECEIVE); 3178 break; 3179 } 3180 3181 ip_lock(reply); 3182 if (!ip_active(reply)) { 3183 ip_unlock(reply); 3184 ip_lock(dest); 3185 is_write_unlock(space); 3186 3187 release_port = reply; 3188 reply = IP_DEAD; 3189 reply_name = MACH_PORT_DEAD; 3190 goto copyout_dest; 3191 } 3192 3193 reply_name = CAST_MACH_PORT_TO_NAME(reply); 3194 kr = ipc_entry_get(space, &reply_name, &entry); 3195 if (kr != KERN_SUCCESS) { 3196 ip_unlock(reply); 3197 3198 /* space is locked */ 3199 kr = ipc_entry_grow_table(space, 3200 ITS_SIZE_NONE); 3201 if (kr != KERN_SUCCESS) { 3202 return (MACH_RCV_HEADER_ERROR| 3203 MACH_MSG_IPC_SPACE); 3204 } 3205 /* space is locked again; start over */ 3206 3207 continue; 3208 } 3209 assert(IE_BITS_TYPE(entry->ie_bits) == 3210 MACH_PORT_TYPE_NONE); 3211 assert(entry->ie_object == IO_NULL); 3212 3213 entry->ie_object = (ipc_object_t) reply; 3214 break; 3215 } 3216 3217 /* space and reply port are locked and active */ 3218 3219 ip_reference(reply); /* hold onto the reply port */ 3220 3221 kr = ipc_right_copyout(space, reply_name, entry, 3222 reply_type, TRUE, (ipc_object_t) reply); 3223 3224 /* reply port is unlocked */ 3225 assert(kr == KERN_SUCCESS); 3226 3227 ip_lock(dest); 3228 is_write_unlock(space); 3229 3230 } else { 3231 /* 3232 * No reply port! This is an easy case. 3233 * We only need to have the space locked 3234 * when locking the destination. 3235 */ 3236 3237 is_read_lock(space); 3238 if (!is_active(space)) { 3239 is_read_unlock(space); 3240 return MACH_RCV_HEADER_ERROR|MACH_MSG_IPC_SPACE; 3241 } 3242 3243 ip_lock(dest); 3244 is_read_unlock(space); 3245 3246 reply_name = CAST_MACH_PORT_TO_NAME(reply); 3247 } 3248 3249 /* 3250 * At this point, the space is unlocked and the destination 3251 * port is locked. (Lock taken while space was locked.) 3252 * reply_name is taken care of; we still need dest_name. 3253 * We still hold a ref for reply (if it is valid). 3254 * 3255 * If the space holds receive rights for the destination, 3256 * we return its name for the right. Otherwise the task 3257 * managed to destroy or give away the receive right between 3258 * receiving the message and this copyout. If the destination 3259 * is dead, return MACH_PORT_DEAD, and if the receive right 3260 * exists somewhere else (another space, in transit) 3261 * return MACH_PORT_NULL. 3262 * 3263 * Making this copyout operation atomic with the previous 3264 * copyout of the reply port is a bit tricky. If there was 3265 * no real reply port (it wasn't IP_VALID) then this isn't 3266 * an issue. If the reply port was dead at copyout time, 3267 * then we are OK, because if dest is dead we serialize 3268 * after the death of both ports and if dest is alive 3269 * we serialize after reply died but before dest's (later) death. 3270 * So assume reply was alive when we copied it out. If dest 3271 * is alive, then we are OK because we serialize before 3272 * the ports' deaths. So assume dest is dead when we look at it. 3273 * If reply dies/died after dest, then we are OK because 3274 * we serialize after dest died but before reply dies. 3275 * So the hard case is when reply is alive at copyout, 3276 * dest is dead at copyout, and reply died before dest died. 3277 * In this case pretend that dest is still alive, so 3278 * we serialize while both ports are alive. 3279 * 3280 * Because the space lock is held across the copyout of reply 3281 * and locking dest, the receive right for dest can't move 3282 * in or out of the space while the copyouts happen, so 3283 * that isn't an atomicity problem. In the last hard case 3284 * above, this implies that when dest is dead that the 3285 * space couldn't have had receive rights for dest at 3286 * the time reply was copied-out, so when we pretend 3287 * that dest is still alive, we can return MACH_PORT_NULL. 3288 * 3289 * If dest == reply, then we have to make it look like 3290 * either both copyouts happened before the port died, 3291 * or both happened after the port died. This special 3292 * case works naturally if the timestamp comparison 3293 * is done correctly. 3294 */ 3295 3296 copyout_dest: 3297 3298 if (ip_active(dest)) { 3299 ipc_object_copyout_dest(space, (ipc_object_t) dest, 3300 dest_type, &dest_name); 3301 /* dest is unlocked */ 3302 3303 } else { 3304 ipc_port_timestamp_t timestamp; 3305 3306 timestamp = dest->ip_timestamp; 3307 ip_unlock(dest); 3308 ip_release(dest); 3309 3310 if (IP_VALID(reply)) { 3311 ip_lock(reply); 3312 if (ip_active(reply) || 3313 IP_TIMESTAMP_ORDER(timestamp, 3314 reply->ip_timestamp)) 3315 dest_name = MACH_PORT_DEAD; 3316 else 3317 dest_name = MACH_PORT_NULL; 3318 ip_unlock(reply); 3319 } else 3320 dest_name = MACH_PORT_DEAD; 3321 } 3322 3323 if (IP_VALID(reply)) 3324 ip_release(reply); 3325 3326 if (IP_VALID(release_port)) 3327 ip_release(release_port); 3328 3329 msg->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | 3330 MACH_MSGH_BITS(reply_type, dest_type)); 3331 msg->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name); 3332 msg->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name); 3333 } 3334 3335 return MACH_MSG_SUCCESS; 3336} 3337 3338/* 3339 * Routine: ipc_kmsg_copyout_object 3340 * Purpose: 3341 * Copy-out a port right. Always returns a name, 3342 * even for unsuccessful return codes. Always 3343 * consumes the supplied object. 3344 * Conditions: 3345 * Nothing locked. 3346 * Returns: 3347 * MACH_MSG_SUCCESS The space acquired the right 3348 * (name is valid) or the object is dead (MACH_PORT_DEAD). 3349 * MACH_MSG_IPC_SPACE No room in space for the right, 3350 * or the space is dead. (Name is MACH_PORT_NULL.) 3351 * MACH_MSG_IPC_KERNEL Kernel resource shortage. 3352 * (Name is MACH_PORT_NULL.) 3353 */ 3354 3355mach_msg_return_t 3356ipc_kmsg_copyout_object( 3357 ipc_space_t space, 3358 ipc_object_t object, 3359 mach_msg_type_name_t msgt_name, 3360 mach_port_name_t *namep) 3361{ 3362 kern_return_t kr; 3363 3364 if (!IO_VALID(object)) { 3365 *namep = CAST_MACH_PORT_TO_NAME(object); 3366 return MACH_MSG_SUCCESS; 3367 } 3368 3369 kr = ipc_object_copyout(space, object, msgt_name, TRUE, namep); 3370 if (kr != KERN_SUCCESS) { 3371 ipc_object_destroy(object, msgt_name); 3372 3373 if (kr == KERN_INVALID_CAPABILITY) 3374 *namep = MACH_PORT_DEAD; 3375 else { 3376 *namep = MACH_PORT_NULL; 3377 3378 if (kr == KERN_RESOURCE_SHORTAGE) 3379 return MACH_MSG_IPC_KERNEL; 3380 else 3381 return MACH_MSG_IPC_SPACE; 3382 } 3383 } 3384 3385 return MACH_MSG_SUCCESS; 3386} 3387 3388mach_msg_descriptor_t * 3389ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc, 3390 mach_msg_descriptor_t *user_dsc, 3391 ipc_space_t space, 3392 kern_return_t *mr); 3393mach_msg_descriptor_t * 3394ipc_kmsg_copyout_port_descriptor(mach_msg_descriptor_t *dsc, 3395 mach_msg_descriptor_t *dest_dsc, 3396 ipc_space_t space, 3397 kern_return_t *mr) 3398{ 3399 mach_port_t port; 3400 mach_port_name_t name; 3401 mach_msg_type_name_t disp; 3402 3403 3404 /* Copyout port right carried in the message */ 3405 port = dsc->port.name; 3406 disp = dsc->port.disposition; 3407 *mr |= ipc_kmsg_copyout_object(space, 3408 (ipc_object_t)port, 3409 disp, 3410 &name); 3411 3412 if(current_task() == kernel_task) 3413 { 3414 mach_msg_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc; 3415 user_dsc--; // point to the start of this port descriptor 3416 user_dsc->name = CAST_MACH_NAME_TO_PORT(name); 3417 user_dsc->disposition = disp; 3418 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR; 3419 dest_dsc = (typeof(dest_dsc))user_dsc; 3420 } else { 3421 mach_msg_legacy_port_descriptor_t *user_dsc = (typeof(user_dsc))dest_dsc; 3422 user_dsc--; // point to the start of this port descriptor 3423 user_dsc->name = CAST_MACH_PORT_TO_NAME(name); 3424 user_dsc->disposition = disp; 3425 user_dsc->type = MACH_MSG_PORT_DESCRIPTOR; 3426 dest_dsc = (typeof(dest_dsc))user_dsc; 3427 } 3428 3429 return (mach_msg_descriptor_t *)dest_dsc; 3430} 3431 3432mach_msg_descriptor_t * 3433ipc_kmsg_copyout_ool_descriptor(mach_msg_ool_descriptor_t *dsc, mach_msg_descriptor_t *user_dsc, int is_64bit, vm_map_t map, mach_msg_return_t *mr); 3434mach_msg_descriptor_t * 3435ipc_kmsg_copyout_ool_descriptor(mach_msg_ool_descriptor_t *dsc, mach_msg_descriptor_t *user_dsc, int is_64bit, vm_map_t map, mach_msg_return_t *mr) 3436{ 3437 vm_map_copy_t copy; 3438 vm_map_address_t rcv_addr; 3439 mach_msg_copy_options_t copy_options; 3440 mach_msg_size_t size; 3441 mach_msg_descriptor_type_t dsc_type; 3442 3443 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count); 3444 3445 copy = (vm_map_copy_t) dsc->address; 3446 size = dsc->size; 3447 copy_options = dsc->copy; 3448 assert(copy_options != MACH_MSG_KALLOC_COPY_T); 3449 dsc_type = dsc->type; 3450 rcv_addr = 0; 3451 3452 if (copy != VM_MAP_COPY_NULL) { 3453 /* 3454 * Check to see if there is an overwrite descriptor 3455 * specified in the scatter list for this ool data. 3456 * The descriptor has already been verified. 3457 */ 3458#if 0 3459 if (saddr != MACH_MSG_DESCRIPTOR_NULL) { 3460 if (differs) { 3461 OTHER_OOL_DESCRIPTOR *scatter_dsc; 3462 3463 scatter_dsc = (OTHER_OOL_DESCRIPTOR *)saddr; 3464 if (scatter_dsc->copy == MACH_MSG_OVERWRITE) { 3465 rcv_addr = (mach_vm_offset_t) scatter_dsc->address; 3466 copy_options = MACH_MSG_OVERWRITE; 3467 } else { 3468 copy_options = MACH_MSG_VIRTUAL_COPY; 3469 } 3470 } else { 3471 mach_msg_ool_descriptor_t *scatter_dsc; 3472 3473 scatter_dsc = &saddr->out_of_line; 3474 if (scatter_dsc->copy == MACH_MSG_OVERWRITE) { 3475 rcv_addr = CAST_USER_ADDR_T(scatter_dsc->address); 3476 copy_options = MACH_MSG_OVERWRITE; 3477 } else { 3478 copy_options = MACH_MSG_VIRTUAL_COPY; 3479 } 3480 } 3481 INCREMENT_SCATTER(saddr, sdsc_count, differs); 3482 } 3483#endif 3484 3485 3486 /* 3487 * Whether the data was virtually or physically 3488 * copied we have a vm_map_copy_t for it. 3489 * If there's an overwrite region specified 3490 * overwrite it, otherwise do a virtual copy out. 3491 */ 3492 kern_return_t kr; 3493 if (copy_options == MACH_MSG_OVERWRITE && rcv_addr != 0) { 3494 kr = vm_map_copy_overwrite(map, rcv_addr, 3495 copy, TRUE); 3496 } else { 3497 kr = vm_map_copyout(map, &rcv_addr, copy); 3498 } 3499 if (kr != KERN_SUCCESS) { 3500 if (kr == KERN_RESOURCE_SHORTAGE) 3501 *mr |= MACH_MSG_VM_KERNEL; 3502 else 3503 *mr |= MACH_MSG_VM_SPACE; 3504 vm_map_copy_discard(copy); 3505 rcv_addr = 0; 3506 size = 0; 3507 } 3508 } else { 3509 rcv_addr = 0; 3510 size = 0; 3511 } 3512 3513 /* 3514 * Now update the descriptor as the user would see it. 3515 * This may require expanding the descriptor to the user 3516 * visible size. There is already space allocated for 3517 * this in what naddr points to. 3518 */ 3519 if(current_task() == kernel_task) 3520 { 3521 mach_msg_ool_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 3522 user_ool_dsc--; 3523 3524 user_ool_dsc->address = (void *)(uintptr_t)rcv_addr; 3525 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ? 3526 TRUE : FALSE; 3527 user_ool_dsc->copy = copy_options; 3528 user_ool_dsc->type = dsc_type; 3529 user_ool_dsc->size = size; 3530 3531 user_dsc = (typeof(user_dsc))user_ool_dsc; 3532 } else if (is_64bit) { 3533 mach_msg_ool_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 3534 user_ool_dsc--; 3535 3536 user_ool_dsc->address = rcv_addr; 3537 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ? 3538 TRUE : FALSE; 3539 user_ool_dsc->copy = copy_options; 3540 user_ool_dsc->type = dsc_type; 3541 user_ool_dsc->size = size; 3542 3543 user_dsc = (typeof(user_dsc))user_ool_dsc; 3544 } else { 3545 mach_msg_ool_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 3546 user_ool_dsc--; 3547 3548 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr); 3549 user_ool_dsc->size = size; 3550 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ? 3551 TRUE : FALSE; 3552 user_ool_dsc->copy = copy_options; 3553 user_ool_dsc->type = dsc_type; 3554 3555 user_dsc = (typeof(user_dsc))user_ool_dsc; 3556 } 3557 return user_dsc; 3558} 3559 3560mach_msg_descriptor_t * 3561ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc, 3562 mach_msg_descriptor_t *user_dsc, 3563 int is_64bit, 3564 vm_map_t map, 3565 ipc_space_t space, 3566 ipc_kmsg_t kmsg, 3567 mach_msg_return_t *mr); 3568mach_msg_descriptor_t * 3569ipc_kmsg_copyout_ool_ports_descriptor(mach_msg_ool_ports_descriptor_t *dsc, 3570 mach_msg_descriptor_t *user_dsc, 3571 int is_64bit, 3572 vm_map_t map, 3573 ipc_space_t space, 3574 ipc_kmsg_t kmsg, 3575 mach_msg_return_t *mr) 3576{ 3577 mach_vm_offset_t rcv_addr = 0; 3578 mach_msg_type_name_t disp; 3579 mach_msg_type_number_t count, i; 3580 vm_size_t ports_length, names_length; 3581 3582 mach_msg_copy_options_t copy_options = MACH_MSG_VIRTUAL_COPY; 3583 3584 //SKIP_PORT_DESCRIPTORS(saddr, sdsc_count); 3585 3586 count = dsc->count; 3587 disp = dsc->disposition; 3588 ports_length = count * sizeof(mach_port_t); 3589 names_length = count * sizeof(mach_port_name_t); 3590 3591 if (ports_length != 0 && dsc->address != 0) { 3592 3593 /* 3594 * Check to see if there is an overwrite descriptor 3595 * specified in the scatter list for this ool data. 3596 * The descriptor has already been verified. 3597 */ 3598#if 0 3599 if (saddr != MACH_MSG_DESCRIPTOR_NULL) { 3600 if (differs) { 3601 OTHER_OOL_DESCRIPTOR *scatter_dsc; 3602 3603 scatter_dsc = (OTHER_OOL_DESCRIPTOR *)saddr; 3604 rcv_addr = (mach_vm_offset_t) scatter_dsc->address; 3605 copy_options = scatter_dsc->copy; 3606 } else { 3607 mach_msg_ool_descriptor_t *scatter_dsc; 3608 3609 scatter_dsc = &saddr->out_of_line; 3610 rcv_addr = CAST_USER_ADDR_T(scatter_dsc->address); 3611 copy_options = scatter_dsc->copy; 3612 } 3613 INCREMENT_SCATTER(saddr, sdsc_count, differs); 3614 } 3615#endif 3616 3617 if (copy_options == MACH_MSG_VIRTUAL_COPY) { 3618 /* 3619 * Dynamically allocate the region 3620 */ 3621 int anywhere = VM_MAKE_TAG(VM_MEMORY_MACH_MSG)| 3622 VM_FLAGS_ANYWHERE; 3623 3624 kern_return_t kr; 3625 if ((kr = mach_vm_allocate(map, &rcv_addr, 3626 (mach_vm_size_t)names_length, 3627 anywhere)) != KERN_SUCCESS) { 3628 ipc_kmsg_clean_body(kmsg, 1, (mach_msg_descriptor_t *)dsc); 3629 rcv_addr = 0; 3630 3631 if (kr == KERN_RESOURCE_SHORTAGE){ 3632 *mr |= MACH_MSG_VM_KERNEL; 3633 } else { 3634 *mr |= MACH_MSG_VM_SPACE; 3635 } 3636 } 3637 } 3638 3639 /* 3640 * Handle the port rights and copy out the names 3641 * for those rights out to user-space. 3642 */ 3643 if (rcv_addr != 0) { 3644 mach_port_t *objects = (mach_port_t *) dsc->address; 3645 mach_port_name_t *names = (mach_port_name_t *) dsc->address; 3646 3647 /* copyout port rights carried in the message */ 3648 3649 for ( i = 0; i < count ; i++) { 3650 ipc_object_t object = (ipc_object_t)objects[i]; 3651 3652 *mr |= ipc_kmsg_copyout_object(space, object, 3653 disp, &names[i]); 3654 } 3655 3656 /* copyout to memory allocated above */ 3657 void *data = dsc->address; 3658 if (copyoutmap(map, data, rcv_addr, names_length) != KERN_SUCCESS) 3659 *mr |= MACH_MSG_VM_SPACE; 3660 kfree(data, ports_length); 3661 } 3662 } else { 3663 rcv_addr = 0; 3664 } 3665 3666 /* 3667 * Now update the descriptor based on the information 3668 * calculated above. 3669 */ 3670 if(current_task() == kernel_task) { 3671 mach_msg_ool_ports_descriptor_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 3672 user_ool_dsc--; 3673 3674 user_ool_dsc->address = (void *)(uintptr_t)rcv_addr; 3675 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ? 3676 TRUE : FALSE; 3677 user_ool_dsc->copy = copy_options; 3678 user_ool_dsc->disposition = disp; 3679 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR; 3680 user_ool_dsc->count = count; 3681 3682 user_dsc = (typeof(user_dsc))user_ool_dsc; 3683 } if (is_64bit) { 3684 mach_msg_ool_ports_descriptor64_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 3685 user_ool_dsc--; 3686 3687 user_ool_dsc->address = rcv_addr; 3688 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ? 3689 TRUE : FALSE; 3690 user_ool_dsc->copy = copy_options; 3691 user_ool_dsc->disposition = disp; 3692 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR; 3693 user_ool_dsc->count = count; 3694 3695 user_dsc = (typeof(user_dsc))user_ool_dsc; 3696 } else { 3697 mach_msg_ool_ports_descriptor32_t *user_ool_dsc = (typeof(user_ool_dsc))user_dsc; 3698 user_ool_dsc--; 3699 3700 user_ool_dsc->address = CAST_DOWN_EXPLICIT(uint32_t, rcv_addr); 3701 user_ool_dsc->count = count; 3702 user_ool_dsc->deallocate = (copy_options == MACH_MSG_VIRTUAL_COPY) ? 3703 TRUE : FALSE; 3704 user_ool_dsc->copy = copy_options; 3705 user_ool_dsc->disposition = disp; 3706 user_ool_dsc->type = MACH_MSG_OOL_PORTS_DESCRIPTOR; 3707 3708 user_dsc = (typeof(user_dsc))user_ool_dsc; 3709 } 3710 return user_dsc; 3711} 3712 3713/* 3714 * Routine: ipc_kmsg_copyout_body 3715 * Purpose: 3716 * "Copy-out" port rights and out-of-line memory 3717 * in the body of a message. 3718 * 3719 * The error codes are a combination of special bits. 3720 * The copyout proceeds despite errors. 3721 * Conditions: 3722 * Nothing locked. 3723 * Returns: 3724 * MACH_MSG_SUCCESS Successful copyout. 3725 * MACH_MSG_IPC_SPACE No room for port right in name space. 3726 * MACH_MSG_VM_SPACE No room for memory in address space. 3727 * MACH_MSG_IPC_KERNEL Resource shortage handling port right. 3728 * MACH_MSG_VM_KERNEL Resource shortage handling memory. 3729 * MACH_MSG_INVALID_RT_DESCRIPTOR Descriptor incompatible with RT 3730 */ 3731 3732mach_msg_return_t 3733ipc_kmsg_copyout_body( 3734 ipc_kmsg_t kmsg, 3735 ipc_space_t space, 3736 vm_map_t map, 3737 mach_msg_body_t *slist) 3738{ 3739 mach_msg_body_t *body; 3740 mach_msg_descriptor_t *kern_dsc, *user_dsc; 3741 mach_msg_descriptor_t *saddr; 3742 mach_msg_type_number_t dsc_count, sdsc_count; 3743 int i; 3744 mach_msg_return_t mr = MACH_MSG_SUCCESS; 3745 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS); 3746 3747 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 3748 dsc_count = body->msgh_descriptor_count; 3749 kern_dsc = (mach_msg_descriptor_t *) (body + 1); 3750 /* Point user_dsc just after the end of all the descriptors */ 3751 user_dsc = &kern_dsc[dsc_count]; 3752 3753 /* Do scatter list setup */ 3754 if (slist != MACH_MSG_BODY_NULL) { 3755 panic("Scatter lists disabled"); 3756 saddr = (mach_msg_descriptor_t *) (slist + 1); 3757 sdsc_count = slist->msgh_descriptor_count; 3758 } 3759 else { 3760 saddr = MACH_MSG_DESCRIPTOR_NULL; 3761 sdsc_count = 0; 3762 } 3763 3764 /* Now process the descriptors */ 3765 for (i = dsc_count-1; i >= 0; i--) { 3766 switch (kern_dsc[i].type.type) { 3767 3768 case MACH_MSG_PORT_DESCRIPTOR: 3769 user_dsc = ipc_kmsg_copyout_port_descriptor(&kern_dsc[i], user_dsc, space, &mr); 3770 break; 3771 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 3772 case MACH_MSG_OOL_DESCRIPTOR : 3773 user_dsc = ipc_kmsg_copyout_ool_descriptor( 3774 (mach_msg_ool_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, &mr); 3775 break; 3776 case MACH_MSG_OOL_PORTS_DESCRIPTOR : 3777 user_dsc = ipc_kmsg_copyout_ool_ports_descriptor( 3778 (mach_msg_ool_ports_descriptor_t *)&kern_dsc[i], user_dsc, is_task_64bit, map, space, kmsg, &mr); 3779 break; 3780 default : { 3781 panic("untyped IPC copyout body: invalid message descriptor"); 3782 } 3783 } 3784 } 3785 3786 if(user_dsc != kern_dsc) { 3787 vm_offset_t dsc_adjust = (vm_offset_t)user_dsc - (vm_offset_t)kern_dsc; 3788 memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t)); 3789 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust); 3790 /* Update the message size for the smaller user representation */ 3791 kmsg->ikm_header->msgh_size -= (mach_msg_size_t)dsc_adjust; 3792 } 3793 3794 return mr; 3795} 3796 3797/* 3798 * Routine: ipc_kmsg_copyout_size 3799 * Purpose: 3800 * Compute the size of the message as copied out to the given 3801 * map. If the destination map's pointers are a different size 3802 * than the kernel's, we have to allow for expansion/ 3803 * contraction of the descriptors as appropriate. 3804 * Conditions: 3805 * Nothing locked. 3806 * Returns: 3807 * size of the message as it would be received. 3808 */ 3809 3810mach_msg_size_t 3811ipc_kmsg_copyout_size( 3812 ipc_kmsg_t kmsg, 3813 vm_map_t map) 3814{ 3815 mach_msg_size_t send_size; 3816 3817 send_size = kmsg->ikm_header->msgh_size; 3818 3819 boolean_t is_task_64bit = (map->max_offset > VM_MAX_ADDRESS); 3820 3821#if defined(__LP64__) 3822 send_size -= LEGACY_HEADER_SIZE_DELTA; 3823#endif 3824 3825 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) { 3826 3827 mach_msg_body_t *body; 3828 mach_msg_descriptor_t *saddr, *eaddr; 3829 3830 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 3831 saddr = (mach_msg_descriptor_t *) (body + 1); 3832 eaddr = saddr + body->msgh_descriptor_count; 3833 3834 for ( ; saddr < eaddr; saddr++ ) { 3835 switch (saddr->type.type) { 3836 case MACH_MSG_OOL_DESCRIPTOR: 3837 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 3838 case MACH_MSG_OOL_PORTS_DESCRIPTOR: 3839 if(!is_task_64bit) 3840 send_size -= DESC_SIZE_ADJUSTMENT; 3841 break; 3842 case MACH_MSG_PORT_DESCRIPTOR: 3843 send_size -= DESC_SIZE_ADJUSTMENT; 3844 break; 3845 default: 3846 break; 3847 } 3848 } 3849 } 3850 return send_size; 3851} 3852 3853/* 3854 * Routine: ipc_kmsg_copyout 3855 * Purpose: 3856 * "Copy-out" port rights and out-of-line memory 3857 * in the message. 3858 * Conditions: 3859 * Nothing locked. 3860 * Returns: 3861 * MACH_MSG_SUCCESS Copied out all rights and memory. 3862 * MACH_RCV_HEADER_ERROR + special bits 3863 * Rights and memory in the message are intact. 3864 * MACH_RCV_BODY_ERROR + special bits 3865 * The message header was successfully copied out. 3866 * As much of the body was handled as possible. 3867 */ 3868 3869mach_msg_return_t 3870ipc_kmsg_copyout( 3871 ipc_kmsg_t kmsg, 3872 ipc_space_t space, 3873 vm_map_t map, 3874 mach_msg_body_t *slist) 3875{ 3876 mach_msg_return_t mr; 3877 3878 mr = ipc_kmsg_copyout_header(kmsg->ikm_header, space); 3879 if (mr != MACH_MSG_SUCCESS) { 3880 return mr; 3881 } 3882 3883 if (kmsg->ikm_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) { 3884 mr = ipc_kmsg_copyout_body(kmsg, space, map, slist); 3885 3886 if (mr != MACH_MSG_SUCCESS) 3887 mr |= MACH_RCV_BODY_ERROR; 3888 } 3889 3890 return mr; 3891} 3892 3893/* 3894 * Routine: ipc_kmsg_copyout_pseudo 3895 * Purpose: 3896 * Does a pseudo-copyout of the message. 3897 * This is like a regular copyout, except 3898 * that the ports in the header are handled 3899 * as if they are in the body. They aren't reversed. 3900 * 3901 * The error codes are a combination of special bits. 3902 * The copyout proceeds despite errors. 3903 * Conditions: 3904 * Nothing locked. 3905 * Returns: 3906 * MACH_MSG_SUCCESS Successful copyout. 3907 * MACH_MSG_IPC_SPACE No room for port right in name space. 3908 * MACH_MSG_VM_SPACE No room for memory in address space. 3909 * MACH_MSG_IPC_KERNEL Resource shortage handling port right. 3910 * MACH_MSG_VM_KERNEL Resource shortage handling memory. 3911 */ 3912 3913mach_msg_return_t 3914ipc_kmsg_copyout_pseudo( 3915 ipc_kmsg_t kmsg, 3916 ipc_space_t space, 3917 vm_map_t map, 3918 mach_msg_body_t *slist) 3919{ 3920 mach_msg_bits_t mbits = kmsg->ikm_header->msgh_bits; 3921 ipc_object_t dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 3922 ipc_object_t reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 3923 mach_msg_type_name_t dest_type = MACH_MSGH_BITS_REMOTE(mbits); 3924 mach_msg_type_name_t reply_type = MACH_MSGH_BITS_LOCAL(mbits); 3925 mach_port_name_t dest_name, reply_name; 3926 mach_msg_return_t mr; 3927 3928 assert(IO_VALID(dest)); 3929 3930 mr = (ipc_kmsg_copyout_object(space, dest, dest_type, &dest_name) | 3931 ipc_kmsg_copyout_object(space, reply, reply_type, &reply_name)); 3932 3933 kmsg->ikm_header->msgh_bits = mbits & MACH_MSGH_BITS_USER; 3934 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(dest_name); 3935 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(reply_name); 3936 3937 if (mbits & MACH_MSGH_BITS_COMPLEX) { 3938 mr |= ipc_kmsg_copyout_body(kmsg, space, map, slist); 3939 } 3940 3941 return mr; 3942} 3943 3944/* 3945 * Routine: ipc_kmsg_copyout_dest 3946 * Purpose: 3947 * Copies out the destination port in the message. 3948 * Destroys all other rights and memory in the message. 3949 * Conditions: 3950 * Nothing locked. 3951 */ 3952 3953void 3954ipc_kmsg_copyout_dest( 3955 ipc_kmsg_t kmsg, 3956 ipc_space_t space) 3957{ 3958 mach_msg_bits_t mbits; 3959 ipc_object_t dest; 3960 ipc_object_t reply; 3961 mach_msg_type_name_t dest_type; 3962 mach_msg_type_name_t reply_type; 3963 mach_port_name_t dest_name, reply_name; 3964 3965 mbits = kmsg->ikm_header->msgh_bits; 3966 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 3967 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 3968 dest_type = MACH_MSGH_BITS_REMOTE(mbits); 3969 reply_type = MACH_MSGH_BITS_LOCAL(mbits); 3970 3971 assert(IO_VALID(dest)); 3972 3973 io_lock(dest); 3974 if (io_active(dest)) { 3975 ipc_object_copyout_dest(space, dest, dest_type, &dest_name); 3976 /* dest is unlocked */ 3977 } else { 3978 io_unlock(dest); 3979 io_release(dest); 3980 dest_name = MACH_PORT_DEAD; 3981 } 3982 3983 if (IO_VALID(reply)) { 3984 ipc_object_destroy(reply, reply_type); 3985 reply_name = MACH_PORT_NULL; 3986 } else 3987 reply_name = CAST_MACH_PORT_TO_NAME(reply); 3988 3989 kmsg->ikm_header->msgh_bits = (MACH_MSGH_BITS_OTHER(mbits) | 3990 MACH_MSGH_BITS(reply_type, dest_type)); 3991 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name); 3992 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name); 3993 3994 if (mbits & MACH_MSGH_BITS_COMPLEX) { 3995 mach_msg_body_t *body; 3996 3997 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 3998 ipc_kmsg_clean_body(kmsg, body->msgh_descriptor_count, 3999 (mach_msg_descriptor_t *)(body + 1)); 4000 } 4001} 4002 4003/* 4004 * Routine: ipc_kmsg_copyin_scatter 4005 * Purpose: 4006 * allocate and copyin a scatter list 4007 * Algorithm: 4008 * The gather (kmsg) is valid since it has been copied in. 4009 * Gather list descriptors are sequentially paired with scatter 4010 * list descriptors, with port descriptors in either list ignored. 4011 * Descriptors are consistent if the type fileds match and size 4012 * of the scatter descriptor is less than or equal to the 4013 * size of the gather descriptor. A MACH_MSG_ALLOCATE copy 4014 * strategy in a scatter descriptor matches any size in the 4015 * corresponding gather descriptor assuming they are the same type. 4016 * Either list may be larger than the other. During the 4017 * subsequent copy out, excess scatter descriptors are ignored 4018 * and excess gather descriptors default to dynamic allocation. 4019 * 4020 * In the case of a size error, the scatter list is released. 4021 * Conditions: 4022 * Nothing locked. 4023 * Returns: 4024 * the allocated message body containing the scatter list. 4025 */ 4026 4027mach_msg_body_t * 4028ipc_kmsg_get_scatter( 4029 mach_vm_address_t msg_addr, 4030 mach_msg_size_t slist_size, 4031 ipc_kmsg_t kmsg) 4032{ 4033 mach_msg_body_t *slist; 4034 mach_msg_body_t *body; 4035 mach_msg_descriptor_t *gstart, *gend; 4036 mach_msg_descriptor_t *sstart, *send; 4037 4038#if defined(__LP64__) 4039 panic("ipc_kmsg_get_scatter called!"); 4040#endif 4041 4042 if (slist_size < sizeof(mach_msg_base_t)) 4043 return MACH_MSG_BODY_NULL; 4044 4045 slist_size -= (mach_msg_size_t)sizeof(mach_msg_header_t); 4046 slist = (mach_msg_body_t *)kalloc(slist_size); 4047 if (slist == MACH_MSG_BODY_NULL) 4048 return slist; 4049 4050 if (copyin(msg_addr + sizeof(mach_msg_header_t), (char *)slist, slist_size)) { 4051 kfree(slist, slist_size); 4052 return MACH_MSG_BODY_NULL; 4053 } 4054 4055 if ((slist->msgh_descriptor_count* sizeof(mach_msg_descriptor_t) 4056 + sizeof(mach_msg_size_t)) > slist_size) { 4057 kfree(slist, slist_size); 4058 return MACH_MSG_BODY_NULL; 4059 } 4060 4061 body = (mach_msg_body_t *) (kmsg->ikm_header + 1); 4062 gstart = (mach_msg_descriptor_t *) (body + 1); 4063 gend = gstart + body->msgh_descriptor_count; 4064 4065 sstart = (mach_msg_descriptor_t *) (slist + 1); 4066 send = sstart + slist->msgh_descriptor_count; 4067 4068 while (gstart < gend) { 4069 mach_msg_descriptor_type_t g_type; 4070 4071 /* 4072 * Skip port descriptors in gather list. 4073 */ 4074 g_type = gstart->type.type; 4075 4076 if (g_type != MACH_MSG_PORT_DESCRIPTOR) { 4077 4078 /* 4079 * A scatter list with a 0 descriptor count is treated as an 4080 * automatic size mismatch. 4081 */ 4082 if (slist->msgh_descriptor_count == 0) { 4083 kfree(slist, slist_size); 4084 return MACH_MSG_BODY_NULL; 4085 } 4086 4087 /* 4088 * Skip port descriptors in scatter list. 4089 */ 4090 while (sstart < send) { 4091 if (sstart->type.type != MACH_MSG_PORT_DESCRIPTOR) 4092 break; 4093 sstart++; 4094 } 4095 4096 /* 4097 * No more scatter descriptors, we're done 4098 */ 4099 if (sstart >= send) { 4100 break; 4101 } 4102 4103 /* 4104 * Check type, copy and size fields 4105 */ 4106 if (g_type == MACH_MSG_OOL_DESCRIPTOR || 4107 g_type == MACH_MSG_OOL_VOLATILE_DESCRIPTOR) { 4108 if (sstart->type.type != MACH_MSG_OOL_DESCRIPTOR && 4109 sstart->type.type != MACH_MSG_OOL_VOLATILE_DESCRIPTOR) { 4110 kfree(slist, slist_size); 4111 return MACH_MSG_BODY_NULL; 4112 } 4113 if (sstart->out_of_line.copy == MACH_MSG_OVERWRITE && 4114 gstart->out_of_line.size > sstart->out_of_line.size) { 4115 kfree(slist, slist_size); 4116 return MACH_MSG_BODY_NULL; 4117 } 4118 } 4119 else { 4120 if (sstart->type.type != MACH_MSG_OOL_PORTS_DESCRIPTOR) { 4121 kfree(slist, slist_size); 4122 return MACH_MSG_BODY_NULL; 4123 } 4124 if (sstart->ool_ports.copy == MACH_MSG_OVERWRITE && 4125 gstart->ool_ports.count > sstart->ool_ports.count) { 4126 kfree(slist, slist_size); 4127 return MACH_MSG_BODY_NULL; 4128 } 4129 } 4130 sstart++; 4131 } 4132 gstart++; 4133 } 4134 return slist; 4135} 4136 4137 4138/* 4139 * Routine: ipc_kmsg_free_scatter 4140 * Purpose: 4141 * Deallocate a scatter list. Since we actually allocated 4142 * a body without a header, and since the header was originally 4143 * accounted for in slist_size, we have to ajust it down 4144 * before freeing the scatter list. 4145 */ 4146void 4147ipc_kmsg_free_scatter( 4148 mach_msg_body_t *slist, 4149 mach_msg_size_t slist_size) 4150{ 4151#if defined(__LP64__) 4152 panic("%s called; halting!", __func__); 4153#endif 4154 4155 slist_size -= (mach_msg_size_t)sizeof(mach_msg_header_t); 4156 kfree(slist, slist_size); 4157} 4158 4159 4160/* 4161 * Routine: ipc_kmsg_copyout_to_kernel 4162 * Purpose: 4163 * Copies out the destination and reply ports in the message. 4164 * Leaves all other rights and memory in the message alone. 4165 * Conditions: 4166 * Nothing locked. 4167 * 4168 * Derived from ipc_kmsg_copyout_dest. 4169 * Use by mach_msg_rpc_from_kernel (which used to use copyout_dest). 4170 * We really do want to save rights and memory. 4171 */ 4172 4173void 4174ipc_kmsg_copyout_to_kernel( 4175 ipc_kmsg_t kmsg, 4176 ipc_space_t space) 4177{ 4178 ipc_object_t dest; 4179 ipc_object_t reply; 4180 mach_msg_type_name_t dest_type; 4181 mach_msg_type_name_t reply_type; 4182 mach_port_name_t dest_name, reply_name; 4183 4184 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 4185 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 4186 dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits); 4187 reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits); 4188 4189 assert(IO_VALID(dest)); 4190 4191 io_lock(dest); 4192 if (io_active(dest)) { 4193 ipc_object_copyout_dest(space, dest, dest_type, &dest_name); 4194 /* dest is unlocked */ 4195 } else { 4196 io_unlock(dest); 4197 io_release(dest); 4198 dest_name = MACH_PORT_DEAD; 4199 } 4200 4201 reply_name = CAST_MACH_PORT_TO_NAME(reply); 4202 4203 kmsg->ikm_header->msgh_bits = 4204 (MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) | 4205 MACH_MSGH_BITS(reply_type, dest_type)); 4206 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name); 4207 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name); 4208} 4209 4210#if IKM_SUPPORT_LEGACY 4211void 4212ipc_kmsg_copyout_to_kernel_legacy( 4213 ipc_kmsg_t kmsg, 4214 ipc_space_t space) 4215{ 4216 ipc_object_t dest; 4217 ipc_object_t reply; 4218 mach_msg_type_name_t dest_type; 4219 mach_msg_type_name_t reply_type; 4220 mach_port_name_t dest_name, reply_name; 4221 4222 dest = (ipc_object_t) kmsg->ikm_header->msgh_remote_port; 4223 reply = (ipc_object_t) kmsg->ikm_header->msgh_local_port; 4224 dest_type = MACH_MSGH_BITS_REMOTE(kmsg->ikm_header->msgh_bits); 4225 reply_type = MACH_MSGH_BITS_LOCAL(kmsg->ikm_header->msgh_bits); 4226 4227 assert(IO_VALID(dest)); 4228 4229 io_lock(dest); 4230 if (io_active(dest)) { 4231 ipc_object_copyout_dest(space, dest, dest_type, &dest_name); 4232 /* dest is unlocked */ 4233 } else { 4234 io_unlock(dest); 4235 io_release(dest); 4236 dest_name = MACH_PORT_DEAD; 4237 } 4238 4239 reply_name = CAST_MACH_PORT_TO_NAME(reply); 4240 4241 kmsg->ikm_header->msgh_bits = 4242 (MACH_MSGH_BITS_OTHER(kmsg->ikm_header->msgh_bits) | 4243 MACH_MSGH_BITS(reply_type, dest_type)); 4244 kmsg->ikm_header->msgh_local_port = CAST_MACH_NAME_TO_PORT(dest_name); 4245 kmsg->ikm_header->msgh_remote_port = CAST_MACH_NAME_TO_PORT(reply_name); 4246 4247 mach_msg_descriptor_t *saddr; 4248 mach_msg_legacy_descriptor_t *daddr; 4249 mach_msg_type_number_t i, count = ((mach_msg_base_t *)kmsg->ikm_header)->body.msgh_descriptor_count; 4250 saddr = (mach_msg_descriptor_t *) (((mach_msg_base_t *)kmsg->ikm_header) + 1); 4251 saddr = &saddr[count-1]; 4252 daddr = (mach_msg_legacy_descriptor_t *)&saddr[count]; 4253 daddr--; 4254 4255 vm_offset_t dsc_adjust = 0; 4256 4257 for (i = 0; i < count; i++, saddr--, daddr--) { 4258 switch (saddr->type.type) { 4259 case MACH_MSG_PORT_DESCRIPTOR: { 4260 mach_msg_port_descriptor_t *dsc = &saddr->port; 4261 mach_msg_legacy_port_descriptor_t *dest_dsc = &daddr->port; 4262 4263 mach_port_t name = dsc->name; 4264 mach_msg_type_name_t disposition = dsc->disposition; 4265 4266 dest_dsc->name = CAST_MACH_PORT_TO_NAME(name); 4267 dest_dsc->disposition = disposition; 4268 dest_dsc->type = MACH_MSG_PORT_DESCRIPTOR; 4269 break; 4270 } 4271 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 4272 case MACH_MSG_OOL_DESCRIPTOR: { 4273 /* The sender should supply ready-made memory, i.e. a vm_map_copy_t 4274 * so we don't need to do anything special. */ 4275 4276 mach_msg_ool_descriptor_t *source_dsc = (typeof(source_dsc))&saddr->out_of_line; 4277 4278 mach_msg_ool_descriptor32_t *dest_dsc = &daddr->out_of_line32; 4279 4280 vm_offset_t address = (vm_offset_t)source_dsc->address; 4281 vm_size_t size = source_dsc->size; 4282 boolean_t deallocate = source_dsc->deallocate; 4283 mach_msg_copy_options_t copy = source_dsc->copy; 4284 mach_msg_descriptor_type_t type = source_dsc->type; 4285 4286 dest_dsc->address = address; 4287 dest_dsc->size = size; 4288 dest_dsc->deallocate = deallocate; 4289 dest_dsc->copy = copy; 4290 dest_dsc->type = type; 4291 break; 4292 } 4293 case MACH_MSG_OOL_PORTS_DESCRIPTOR: { 4294 mach_msg_ool_ports_descriptor_t *source_dsc = (typeof(source_dsc))&saddr->ool_ports; 4295 4296 mach_msg_ool_ports_descriptor32_t *dest_dsc = &daddr->ool_ports32; 4297 4298 vm_offset_t address = (vm_offset_t)source_dsc->address; 4299 vm_size_t port_count = source_dsc->count; 4300 boolean_t deallocate = source_dsc->deallocate; 4301 mach_msg_copy_options_t copy = source_dsc->copy; 4302 mach_msg_descriptor_type_t type = source_dsc->type; 4303 4304 dest_dsc->address = address; 4305 dest_dsc->count = port_count; 4306 dest_dsc->deallocate = deallocate; 4307 dest_dsc->copy = copy; 4308 dest_dsc->type = type; 4309 break; 4310 } 4311 default: { 4312#if MACH_ASSERT 4313 panic("ipc_kmsg_copyin_from_kernel: bad descriptor"); 4314#endif /* MACH_ASSERT */ 4315 } 4316 } 4317 } 4318 4319 if(count) { 4320 dsc_adjust = 4*count; 4321 memmove((char *)((vm_offset_t)kmsg->ikm_header + dsc_adjust), kmsg->ikm_header, sizeof(mach_msg_base_t)); 4322 kmsg->ikm_header = (mach_msg_header_t *)((vm_offset_t)kmsg->ikm_header + dsc_adjust); 4323 /* Update the message size for the smaller user representation */ 4324 kmsg->ikm_header->msgh_size -= dsc_adjust; 4325 } 4326} 4327#endif /* IKM_SUPPORT_LEGACY */ 4328 4329mach_msg_trailer_size_t 4330ipc_kmsg_add_trailer(ipc_kmsg_t kmsg, ipc_space_t space, 4331 mach_msg_option_t option, thread_t thread, 4332 mach_port_seqno_t seqno, boolean_t minimal_trailer, 4333 mach_vm_offset_t context) 4334{ 4335 mach_msg_max_trailer_t *trailer; 4336 4337 (void)thread; 4338 trailer = (mach_msg_max_trailer_t *) 4339 ((vm_offset_t)kmsg->ikm_header + 4340 round_msg(kmsg->ikm_header->msgh_size)); 4341 4342 if (!(option & MACH_RCV_TRAILER_MASK)) { 4343 return trailer->msgh_trailer_size; 4344 } 4345 4346 trailer->msgh_seqno = seqno; 4347 trailer->msgh_context = context; 4348 trailer->msgh_trailer_size = REQUESTED_TRAILER_SIZE(thread_is_64bit(thread), option); 4349 4350 if (minimal_trailer) { 4351 goto done; 4352 } 4353 4354 if (MACH_RCV_TRAILER_ELEMENTS(option) >= 4355 MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV)){ 4356#if CONFIG_MACF_MACH 4357 if (kmsg->ikm_sender != NULL && 4358 IP_VALID(kmsg->ikm_header->msgh_remote_port) && 4359 mac_port_check_method(kmsg->ikm_sender, 4360 &kmsg->ikm_sender->maclabel, 4361 &kmsg->ikm_header->msgh_remote_port->ip_label, 4362 kmsg->ikm_header->msgh_id) == 0) 4363 trailer->msgh_ad = 1; 4364 else 4365#endif 4366 trailer->msgh_ad = 0; 4367 } 4368 4369 /* 4370 * The ipc_kmsg_t holds a reference to the label of a label 4371 * handle, not the port. We must get a reference to the port 4372 * and a send right to copyout to the receiver. 4373 */ 4374 4375 if (option & MACH_RCV_TRAILER_ELEMENTS (MACH_RCV_TRAILER_LABELS)) { 4376#if CONFIG_MACF_MACH 4377 if (kmsg->ikm_sender != NULL) { 4378 ipc_labelh_t lh = kmsg->ikm_sender->label; 4379 kern_return_t kr; 4380 4381 ip_lock(lh->lh_port); 4382 lh->lh_port->ip_mscount++; 4383 lh->lh_port->ip_srights++; 4384 ip_reference(lh->lh_port); 4385 ip_unlock(lh->lh_port); 4386 4387 kr = ipc_object_copyout(space, (ipc_object_t)lh->lh_port, 4388 MACH_MSG_TYPE_PORT_SEND, 0, 4389 &trailer->msgh_labels.sender); 4390 if (kr != KERN_SUCCESS) { 4391 ip_release(lh->lh_port); 4392 trailer->msgh_labels.sender = 0; 4393 } 4394 } else { 4395 trailer->msgh_labels.sender = 0; 4396 } 4397#else 4398 (void)space; 4399 trailer->msgh_labels.sender = 0; 4400#endif 4401 } 4402 4403 4404done: 4405 4406 return trailer->msgh_trailer_size; 4407} 4408