1 /* 2 * Copyright (c) 2000-2004 Apple Computer, 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 [email protected] 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.h 67 * Author: Rich Draves 68 * Date: 1989 69 * 70 * Definitions for kernel messages. 71 */ 72 73 #ifndef _IPC_IPC_KMSG_H_ 74 #define _IPC_IPC_KMSG_H_ 75 76 #include <mach/vm_types.h> 77 #include <mach/message.h> 78 #include <kern/kern_types.h> 79 #include <kern/assert.h> 80 #include <kern/macro_help.h> 81 #include <ipc/ipc_types.h> 82 #include <ipc/ipc_object.h> 83 #include <sys/kdebug.h> 84 85 #if (DEVELOPMENT || DEBUG) 86 /* Turn on to keep partial message signatures for better debug */ 87 #define IKM_PARTIAL_SIG 0 88 #endif 89 90 /* 91 * This structure is only the header for a kmsg buffer; 92 * the actual buffer is normally larger. The rest of the buffer 93 * holds the body of the message. 94 * 95 * In a kmsg, the port fields hold pointers to ports instead 96 * of port names. These pointers hold references. 97 * 98 * The ikm_header.msgh_remote_port field is the destination 99 * of the message. 100 * 101 * sync_qos and special_port_qos stores the qos for prealloced 102 * port, this fields could be deleted once we remove ip_prealloc. 103 */ 104 105 struct ipc_kmsg { 106 struct ipc_kmsg *ikm_next; /* next message on port/discard queue */ 107 struct ipc_kmsg *ikm_prev; /* prev message on port/discard queue */ 108 union { 109 ipc_port_t XNU_PTRAUTH_SIGNED_PTR("kmsg.ikm_prealloc") ikm_prealloc; /* port we were preallocated from */ 110 void *XNU_PTRAUTH_SIGNED_PTR("kmsg.ikm_data") ikm_data; 111 }; 112 mach_msg_header_t *XNU_PTRAUTH_SIGNED_PTR("kmsg.ikm_header") ikm_header; 113 ipc_port_t XNU_PTRAUTH_SIGNED_PTR("kmsg.ikm_voucher_port") ikm_voucher_port; /* voucher port carried */ 114 struct ipc_importance_elem *ikm_importance; /* inherited from */ 115 queue_chain_t ikm_inheritance; /* inherited from link */ 116 struct turnstile *ikm_turnstile; /* send turnstile for ikm_prealloc port */ 117 #if MACH_FLIPC 118 struct mach_node *ikm_node; /* Originating node - needed for ack */ 119 #endif 120 mach_msg_size_t ikm_size; 121 uint32_t ikm_ppriority; /* pthread priority of this kmsg */ 122 #if IKM_PARTIAL_SIG 123 uintptr_t ikm_header_sig; /* sig for just the header */ 124 uintptr_t ikm_headtrail_sig;/* sif for header and trailer */ 125 #endif 126 uintptr_t ikm_signature; /* sig for all kernel-processed data */ 127 ipc_object_copyin_flags_t ikm_flags; 128 mach_msg_qos_t ikm_qos_override; /* qos override on this kmsg */ 129 mach_msg_type_name_t ikm_voucher_type : 8; /* disposition type the voucher came in with */ 130 131 uint8_t ikm_inline_data[] __attribute__((aligned(4))); 132 }; 133 134 /* 135 * XXX For debugging. 136 */ 137 #define IKM_BOGUS ((ipc_kmsg_t) 0xffffff10) 138 139 /* 140 * The size of the kernel message buffers that will be cached. 141 * IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't. 142 */ 143 extern zone_t ipc_kmsg_zone; 144 #define IKM_SAVED_KMSG_SIZE 256 145 #define IKM_SAVED_MSG_SIZE (IKM_SAVED_KMSG_SIZE - sizeof(struct ipc_kmsg)) 146 147 #define ikm_prealloc_inuse_port(kmsg) \ 148 ((kmsg)->ikm_prealloc) 149 150 #define ikm_prealloc_inuse(kmsg) \ 151 ((kmsg)->ikm_prealloc != IP_NULL) 152 153 #define ikm_prealloc_set_inuse(kmsg, port) \ 154 MACRO_BEGIN \ 155 assert((port) != IP_NULL); \ 156 (kmsg)->ikm_prealloc = (port); \ 157 ip_reference(port); \ 158 MACRO_END 159 160 #define ikm_prealloc_clear_inuse(kmsg, port) \ 161 MACRO_BEGIN \ 162 (kmsg)->ikm_prealloc = IP_NULL; \ 163 MACRO_END 164 165 struct ipc_kmsg_queue { 166 struct ipc_kmsg *ikmq_base; 167 }; 168 169 typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t; 170 171 #define IKMQ_NULL ((ipc_kmsg_queue_t) 0) 172 173 174 /* 175 * Exported interfaces 176 */ 177 178 #define ipc_kmsg_queue_init(queue) \ 179 MACRO_BEGIN \ 180 (queue)->ikmq_base = IKM_NULL; \ 181 MACRO_END 182 183 #define ipc_kmsg_queue_empty(queue) ((queue)->ikmq_base == IKM_NULL) 184 185 /* Enqueue a kmsg */ 186 extern void ipc_kmsg_enqueue( 187 ipc_kmsg_queue_t queue, 188 ipc_kmsg_t kmsg); 189 190 extern boolean_t ipc_kmsg_enqueue_qos( 191 ipc_kmsg_queue_t queue, 192 ipc_kmsg_t kmsg); 193 194 extern boolean_t ipc_kmsg_override_qos( 195 ipc_kmsg_queue_t queue, 196 ipc_kmsg_t kmsg, 197 mach_msg_qos_t qos_ovr); 198 199 /* Dequeue and return a kmsg */ 200 extern ipc_kmsg_t ipc_kmsg_dequeue( 201 ipc_kmsg_queue_t queue); 202 203 /* Pull a kmsg out of a queue */ 204 extern void ipc_kmsg_rmqueue( 205 ipc_kmsg_queue_t queue, 206 ipc_kmsg_t kmsg); 207 208 /* Pull the (given) first kmsg out of a queue */ 209 extern void ipc_kmsg_rmqueue_first( 210 ipc_kmsg_queue_t queue, 211 ipc_kmsg_t kmsg); 212 213 #define ipc_kmsg_queue_first(queue) ((queue)->ikmq_base) 214 215 /* Return the kmsg following the given kmsg */ 216 extern ipc_kmsg_t ipc_kmsg_queue_next( 217 ipc_kmsg_queue_t queue, 218 ipc_kmsg_t kmsg); 219 220 __options_decl(ipc_kmsg_alloc_flags_t, uint32_t, { 221 IPC_KMSG_ALLOC_USER = 0x0000, 222 IPC_KMSG_ALLOC_KERNEL = 0x0001, 223 IPC_KMSG_ALLOC_ZERO = 0x0002, 224 IPC_KMSG_ALLOC_SAVED = 0x0004, 225 IPC_KMSG_ALLOC_NOFAIL = 0x0008, 226 }); 227 228 /* Allocate a kernel message */ 229 extern ipc_kmsg_t ipc_kmsg_alloc( 230 mach_msg_size_t size, 231 mach_msg_size_t user_descriptors, 232 ipc_kmsg_alloc_flags_t flags); 233 234 /* Free a kernel message buffer */ 235 extern void ipc_kmsg_free( 236 ipc_kmsg_t kmsg); 237 238 /* Destroy kernel message */ 239 extern void ipc_kmsg_destroy( 240 ipc_kmsg_t kmsg); 241 242 /* Enqueue kernel message for deferred destruction */ 243 extern boolean_t ipc_kmsg_delayed_destroy( 244 ipc_kmsg_t kmsg); 245 246 /* Enqueue queue of kernel messages for deferred destruction */ 247 extern boolean_t ipc_kmsg_delayed_destroy_queue( 248 ipc_kmsg_queue_t queue); 249 250 /* Process all the delayed message destroys */ 251 extern void ipc_kmsg_reap_delayed(void); 252 253 /* bind a preallocated message buffer to a port */ 254 extern void ipc_kmsg_set_prealloc( 255 ipc_kmsg_t kmsg, 256 ipc_port_t port); 257 258 /* Allocate a kernel message buffer and copy a user message to the buffer */ 259 extern mach_msg_return_t ipc_kmsg_get_from_user( 260 mach_vm_address_t msg_addr, 261 mach_msg_size_t size, 262 ipc_kmsg_t *kmsgp); 263 264 /* Allocate a kernel message buffer and copy a kernel message to the buffer */ 265 extern mach_msg_return_t ipc_kmsg_get_from_kernel( 266 mach_msg_header_t *msg, 267 mach_msg_size_t size, 268 ipc_kmsg_t *kmsgp); 269 270 /* Send a message to a port */ 271 extern mach_msg_return_t ipc_kmsg_send( 272 ipc_kmsg_t kmsg, 273 mach_msg_option_t option, 274 mach_msg_timeout_t timeout_val); 275 276 /* Copy a kernel message buffer to a user message */ 277 extern mach_msg_return_t ipc_kmsg_put_to_user( 278 ipc_kmsg_t kmsg, 279 mach_msg_option_t option, 280 mach_vm_address_t rcv_addr, 281 mach_msg_size_t rcv_size, 282 mach_msg_size_t trailer_size, 283 mach_msg_size_t *size); 284 285 /* Copy a kernel message buffer to a kernel message */ 286 extern void ipc_kmsg_put_to_kernel( 287 mach_msg_header_t *msg, 288 ipc_kmsg_t kmsg, 289 mach_msg_size_t size); 290 291 /* Copyin port rights and out-of-line memory from a user message */ 292 extern mach_msg_return_t ipc_kmsg_copyin_from_user( 293 ipc_kmsg_t kmsg, 294 ipc_space_t space, 295 vm_map_t map, 296 mach_msg_priority_t priority, 297 mach_msg_option_t *optionp, 298 bool filter_nonfatal); 299 300 /* Copyin port rights and out-of-line memory from a kernel message */ 301 extern mach_msg_return_t ipc_kmsg_copyin_from_kernel( 302 ipc_kmsg_t kmsg); 303 304 /* Copyout the header and body to a user message */ 305 extern mach_msg_return_t ipc_kmsg_copyout( 306 ipc_kmsg_t kmsg, 307 ipc_space_t space, 308 vm_map_t map, 309 mach_msg_body_t *slist, 310 mach_msg_option_t option); 311 312 /* Copyout port rights and out-of-line memory to a user message, 313 * not reversing the ports in the header */ 314 extern mach_msg_return_t ipc_kmsg_copyout_pseudo( 315 ipc_kmsg_t kmsg, 316 ipc_space_t space, 317 vm_map_t map, 318 mach_msg_body_t *slist); 319 320 /* Compute size of message as copied out to the specified space/map */ 321 extern mach_msg_size_t ipc_kmsg_copyout_size( 322 ipc_kmsg_t kmsg, 323 vm_map_t map); 324 325 /* Copyout the destination port in the message */ 326 extern void ipc_kmsg_copyout_dest_to_user( 327 ipc_kmsg_t kmsg, 328 ipc_space_t space); 329 330 /* kernel's version of ipc_kmsg_copyout_dest_to_user */ 331 extern void ipc_kmsg_copyout_dest_to_kernel( 332 ipc_kmsg_t kmsg, 333 ipc_space_t space); 334 335 /* Returns a pointer to a thread group in the kmsg if any. Caller has a 336 * reference to the kmsg */ 337 extern struct thread_group *ipc_kmsg_get_thread_group( 338 ipc_kmsg_t kmsg); 339 340 extern mach_msg_trailer_size_t ipc_kmsg_trailer_size( 341 mach_msg_option_t option, 342 thread_t thread); 343 344 extern void ipc_kmsg_init_trailer( 345 ipc_kmsg_t kmsg, 346 mach_msg_size_t msg_size, 347 task_t sender); 348 349 extern void ipc_kmsg_add_trailer( 350 ipc_kmsg_t kmsg, 351 ipc_space_t space, 352 mach_msg_option_t option, 353 thread_t thread, 354 mach_port_seqno_t seqno, 355 boolean_t minimal_trailer, 356 mach_vm_offset_t context); 357 358 extern void ipc_kmsg_set_voucher_port( 359 ipc_kmsg_t kmsg, 360 ipc_port_t voucher, 361 mach_msg_type_name_t type); 362 363 extern ipc_port_t ipc_kmsg_get_voucher_port( 364 ipc_kmsg_t kmsg); 365 366 extern void ipc_kmsg_clear_voucher_port( 367 ipc_kmsg_t kmsg); 368 369 #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) 370 extern void ipc_kmsg_trace_send( 371 ipc_kmsg_t kmsg, 372 mach_msg_option_t option); 373 #else 374 #define ipc_kmsg_trace_send(a, b) do { } while (0) 375 #endif 376 377 extern mach_msg_header_t * 378 ipc_kmsg_msg_header(ipc_kmsg_t); 379 380 #endif /* _IPC_IPC_KMSG_H_ */ 381