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