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 */ 62/* 63 */ 64/* 65 * File: ipc/ipc_object.h 66 * Author: Rich Draves 67 * Date: 1989 68 * 69 * Definitions for IPC objects, for which tasks have capabilities. 70 */ 71 72#ifndef _IPC_IPC_OBJECT_H_ 73#define _IPC_IPC_OBJECT_H_ 74 75#include <mach_rt.h> 76 77#include <mach/kern_return.h> 78#include <mach/message.h> 79#include <kern/locks.h> 80#include <kern/macro_help.h> 81#include <kern/assert.h> 82#include <kern/zalloc.h> 83#include <ipc/ipc_types.h> 84#include <libkern/OSAtomic.h> 85 86typedef natural_t ipc_object_refs_t; /* for ipc/ipc_object.h */ 87typedef natural_t ipc_object_bits_t; 88typedef natural_t ipc_object_type_t; 89 90/* 91 * The ipc_object is used to both tag and reference count these two data 92 * structures, and (Noto Bene!) pointers to either of these or the 93 * ipc_object at the head of these are freely cast back and forth; hence 94 * the ipc_object MUST BE FIRST in the ipc_common_data. 95 * 96 * If the RPC implementation enabled user-mode code to use kernel-level 97 * data structures (as ours used to), this peculiar structuring would 98 * avoid having anything in user code depend on the kernel configuration 99 * (with which lock size varies). 100 */ 101struct ipc_object { 102 ipc_object_bits_t io_bits; 103 ipc_object_refs_t io_references; 104 lck_spin_t io_lock_data; 105}; 106 107/* 108 * If another object type needs to participate in io_kotype()-based 109 * dispatching, it must include a stub structure as the first 110 * element 111 */ 112struct ipc_object_header { 113 ipc_object_bits_t io_bits; 114#ifdef __LP64__ 115 natural_t io_padding; /* pad to natural boundary */ 116#endif 117}; 118 119/* 120 * Legacy defines. Should use IPC_OBJECT_NULL, etc... 121 */ 122#define IO_NULL ((ipc_object_t) 0) 123#define IO_DEAD ((ipc_object_t) ~0UL) 124#define IO_VALID(io) (((io) != IO_NULL) && ((io) != IO_DEAD)) 125 126/* 127 * IPC steals the high-order bits from the kotype to use 128 * for its own purposes. This allows IPC to record facts 129 * about ports that aren't otherwise obvious from the 130 * existing port fields. In particular, IPC can optionally 131 * mark a port for no more senders detection. Any change 132 * to IO_BITS_PORT_INFO must be coordinated with bitfield 133 * definitions in ipc_port.h. 134 */ 135#define IO_BITS_PORT_INFO 0x0000f000 /* stupid port tricks */ 136#define IO_BITS_KOTYPE 0x00000fff /* used by the object */ 137#define IO_BITS_OTYPE 0x7fff0000 /* determines a zone */ 138#define IO_BITS_ACTIVE 0x80000000 /* is object alive? */ 139 140#define io_active(io) (((io)->io_bits & IO_BITS_ACTIVE) != 0) 141 142#define io_otype(io) (((io)->io_bits & IO_BITS_OTYPE) >> 16) 143#define io_kotype(io) ((io)->io_bits & IO_BITS_KOTYPE) 144 145#define io_makebits(active, otype, kotype) \ 146 (((active) ? IO_BITS_ACTIVE : 0) | ((otype) << 16) | (kotype)) 147 148/* 149 * Object types: ports, port sets, kernel-loaded ports 150 */ 151#define IOT_PORT 0 152#define IOT_PORT_SET 1 153#define IOT_NUMBER 2 /* number of types used */ 154 155extern zone_t ipc_object_zones[IOT_NUMBER]; 156 157#define io_alloc(otype) \ 158 ((ipc_object_t) zalloc(ipc_object_zones[(otype)])) 159 160extern void io_free( 161 unsigned int otype, 162 ipc_object_t object); 163 164/* 165 * Here we depend on the ipc_object being first within the kernel struct 166 * (ipc_port and ipc_pset). 167 */ 168#define io_lock_init(io) \ 169 lck_spin_init(&(io)->io_lock_data, &ipc_lck_grp, &ipc_lck_attr) 170#define io_lock_destroy(io) \ 171 lck_spin_destroy(&(io)->io_lock_data, &ipc_lck_grp) 172#define io_lock(io) \ 173 lck_spin_lock(&(io)->io_lock_data) 174#define io_lock_try(io) \ 175 lck_spin_try_lock(&(io)->io_lock_data) 176#define io_unlock(io) \ 177 lck_spin_unlock(&(io)->io_lock_data) 178 179#define _VOLATILE_ volatile 180 181/* Sanity check the ref count. If it is 0, we may be doubly zfreeing. 182 * If it is larger than max int, it has been corrupted, probably by being 183 * modified into an address (this is architecture dependent, but it's 184 * safe to assume there cannot really be max int references). 185 * 186 * NOTE: The 0 test alone will not catch double zfreeing of ipc_port 187 * structs, because the io_references field is the first word of the struct, 188 * and zfree modifies that to point to the next free zone element. 189 */ 190#define IO_MAX_REFERENCES \ 191 (unsigned)(~0 ^ (1 << (sizeof(int)*BYTE_SIZE - 1))) 192 193static inline void 194io_reference(ipc_object_t io) { 195 assert((io)->io_references > 0 && 196 (io)->io_references < IO_MAX_REFERENCES); 197 OSIncrementAtomic(&((io)->io_references)); 198} 199 200 201static inline void 202io_release(ipc_object_t io) { 203 assert((io)->io_references > 0 && 204 (io)->io_references < IO_MAX_REFERENCES); 205 /* If we just removed the last reference count */ 206 if ( 1 == OSDecrementAtomic(&((io)->io_references))) { 207 /* Free the object */ 208 io_free(io_otype((io)), (io)); 209 } 210} 211 212/* 213 * Retrieve a label for use in a kernel call that takes a security 214 * label as a parameter. If necessary, io_getlabel acquires internal 215 * (not io_lock) locks, and io_unlocklabel releases them. 216 */ 217 218struct label; 219extern struct label *io_getlabel (ipc_object_t obj); 220#define io_unlocklabel(obj) 221 222/* 223 * Exported interfaces 224 */ 225 226/* Take a reference to an object */ 227extern void ipc_object_reference( 228 ipc_object_t object); 229 230/* Release a reference to an object */ 231extern void ipc_object_release( 232 ipc_object_t object); 233 234/* Look up an object in a space */ 235extern kern_return_t ipc_object_translate( 236 ipc_space_t space, 237 mach_port_name_t name, 238 mach_port_right_t right, 239 ipc_object_t *objectp); 240 241/* Look up two objects in a space, locking them in the order described */ 242extern kern_return_t ipc_object_translate_two( 243 ipc_space_t space, 244 mach_port_name_t name1, 245 mach_port_right_t right1, 246 ipc_object_t *objectp1, 247 mach_port_name_t name2, 248 mach_port_right_t right2, 249 ipc_object_t *objectp2); 250 251/* Allocate a dead-name entry */ 252extern kern_return_t 253ipc_object_alloc_dead( 254 ipc_space_t space, 255 mach_port_name_t *namep); 256 257/* Allocate a dead-name entry, with a specific name */ 258extern kern_return_t ipc_object_alloc_dead_name( 259 ipc_space_t space, 260 mach_port_name_t name); 261 262/* Allocate an object */ 263extern kern_return_t ipc_object_alloc( 264 ipc_space_t space, 265 ipc_object_type_t otype, 266 mach_port_type_t type, 267 mach_port_urefs_t urefs, 268 mach_port_name_t *namep, 269 ipc_object_t *objectp); 270 271/* Allocate an object, with a specific name */ 272extern kern_return_t ipc_object_alloc_name( 273 ipc_space_t space, 274 ipc_object_type_t otype, 275 mach_port_type_t type, 276 mach_port_urefs_t urefs, 277 mach_port_name_t name, 278 ipc_object_t *objectp); 279 280/* Convert a send type name to a received type name */ 281extern mach_msg_type_name_t ipc_object_copyin_type( 282 mach_msg_type_name_t msgt_name); 283 284/* Copyin a capability from a space */ 285extern kern_return_t ipc_object_copyin( 286 ipc_space_t space, 287 mach_port_name_t name, 288 mach_msg_type_name_t msgt_name, 289 ipc_object_t *objectp); 290 291/* Copyin a naked capability from the kernel */ 292extern void ipc_object_copyin_from_kernel( 293 ipc_object_t object, 294 mach_msg_type_name_t msgt_name); 295 296/* Destroy a naked capability */ 297extern void ipc_object_destroy( 298 ipc_object_t object, 299 mach_msg_type_name_t msgt_name); 300 301/* Destroy a naked destination capability */ 302extern void ipc_object_destroy_dest( 303 ipc_object_t object, 304 mach_msg_type_name_t msgt_name); 305 306/* Copyout a capability, placing it into a space */ 307extern kern_return_t ipc_object_copyout( 308 ipc_space_t space, 309 ipc_object_t object, 310 mach_msg_type_name_t msgt_name, 311 boolean_t overflow, 312 mach_port_name_t *namep); 313 314/* Copyout a capability with a name, placing it into a space */ 315extern kern_return_t ipc_object_copyout_name( 316 ipc_space_t space, 317 ipc_object_t object, 318 mach_msg_type_name_t msgt_name, 319 boolean_t overflow, 320 mach_port_name_t name); 321 322/* Translate/consume the destination right of a message */ 323extern void ipc_object_copyout_dest( 324 ipc_space_t space, 325 ipc_object_t object, 326 mach_msg_type_name_t msgt_name, 327 mach_port_name_t *namep); 328 329/* Rename an entry in a space */ 330extern kern_return_t ipc_object_rename( 331 ipc_space_t space, 332 mach_port_name_t oname, 333 mach_port_name_t nname); 334 335#endif /* _IPC_IPC_OBJECT_H_ */ 336