X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8ad349bb6ed4a0be06e34c92be0d98b92e078db4..6d2010ae8f7a6078e10b361c6962983bab233e0f:/osfmk/ipc/ipc_port.h diff --git a/osfmk/ipc/ipc_port.h b/osfmk/ipc/ipc_port.h index 5df916d98..34aab79d8 100644 --- a/osfmk/ipc/ipc_port.h +++ b/osfmk/ipc/ipc_port.h @@ -1,31 +1,29 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2008 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the - * License may not be used to create, or enable the creation or - * redistribution of, unlawful or unlicensed copies of an Apple operating - * system, or to circumvent, violate, or enable the circumvention or - * violation of, any terms of an Apple operating system software license - * agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and * limitations under the License. - * - * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -55,6 +53,12 @@ * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ /* */ /* @@ -68,6 +72,8 @@ #ifndef _IPC_IPC_PORT_H_ #define _IPC_IPC_PORT_H_ +#if MACH_KERNEL_PRIVATE + #include #include #include @@ -85,6 +91,8 @@ #include #include +#include + /* * A receive right (port) can be in four states: * 1) dead (not active, ip_timestamp has death time) @@ -105,10 +113,12 @@ typedef unsigned int ipc_port_timestamp_t; struct ipc_port { /* - * Initial sub-structure in common with ipc_pset and rpc_port - * First element is an ipc_object + * Initial sub-structure in common with ipc_pset + * First element is an ipc_object second is a + * message queue */ struct ipc_object ip_object; + struct ipc_mqueue ip_messages; union { struct ipc_space *receiver; @@ -117,17 +127,19 @@ struct ipc_port { } data; ipc_kobject_t ip_kobject; + mach_port_mscount_t ip_mscount; mach_port_rights_t ip_srights; mach_port_rights_t ip_sorights; struct ipc_port *ip_nsrequest; struct ipc_port *ip_pdrequest; - struct ipc_port_request *ip_dnrequests; + struct ipc_port_request *ip_requests; + boolean_t ip_sprequests; unsigned int ip_pset_count; - struct ipc_mqueue ip_messages; struct ipc_kmsg *ip_premsg; + mach_vm_address_t ip_context; #if NORMA_VM /* @@ -140,26 +152,31 @@ struct ipc_port { #endif #if MACH_ASSERT -#define IP_NSPARES 10 -#define IP_CALLSTACK_MAX 10 +#define IP_NSPARES 4 +#define IP_CALLSTACK_MAX 16 queue_chain_t ip_port_links; /* all allocated ports */ thread_t ip_thread; /* who made me? thread context */ unsigned long ip_timetrack; /* give an idea of "when" created */ natural_t ip_callstack[IP_CALLSTACK_MAX]; /* stack trace */ unsigned long ip_spares[IP_NSPARES]; /* for debugging */ #endif /* MACH_ASSERT */ - int alias; + uintptr_t alias; + +#if CONFIG_MACF_MACH + struct label ip_label; +#endif }; #define ip_references ip_object.io_references #define ip_bits ip_object.io_bits -#define ip_receiver_name ip_object.io_receiver_name #define ip_receiver data.receiver #define ip_destination data.destination #define ip_timestamp data.timestamp +#define ip_receiver_name ip_messages.imq_receiver_name + #define IP_NULL IPC_PORT_NULL #define IP_DEAD IPC_PORT_DEAD #define IP_VALID(port) IPC_PORT_VALID(port) @@ -176,6 +193,9 @@ struct ipc_port { #define ip_kotype(port) io_kotype(&(port)->ip_object) +#define ip_full_kernel(port) imq_full_kernel(&(port)->ip_messages) +#define ip_full(port) imq_full(&(port)->ip_messages) + /* * JMM - Preallocation flag * This flag indicates that there is a message buffer preallocated for this @@ -200,7 +220,7 @@ MACRO_BEGIN \ (port)->ip_premsg = IKM_NULL; \ MACRO_END - +/* JMM - address alignment/packing for LP64 */ struct ipc_port_request { union { struct ipc_port *port; @@ -219,22 +239,37 @@ struct ipc_port_request { #define ipr_soright notify.port #define ipr_name name.name +/* + * Use the low bits in the ipr_soright to specify the request type + */ +#define IPR_SOR_SPARM_MASK 1 /* send-possible armed */ +#define IPR_SOR_SPREQ_MASK 2 /* send-possible requested */ +#define IPR_SOR_SPBIT_MASK 3 /* combo */ +#define IPR_SOR_SPARMED(sor) (((uintptr_t)(sor) & IPR_SOR_SPARM_MASK) != 0) +#define IPR_SOR_SPREQ(sor) (((uintptr_t)(sor) & IPR_SOR_SPREQ_MASK) != 0) +#define IPR_SOR_PORT(sor) ((ipc_port_t)((uintptr_t)(sor) & ~IPR_SOR_SPBIT_MASK)) +#define IPR_SOR_MAKE(p,m) ((ipc_port_t)((uintptr_t)(p) | (m))) + +extern lck_grp_t ipc_lck_grp; +extern lck_attr_t ipc_lck_attr; + /* * Taking the ipc_port_multiple lock grants the privilege * to lock multiple ports at once. No ports must locked * when it is taken. */ -decl_mutex_data(extern,ipc_port_multiple_lock_data) +decl_lck_mtx_data(extern,ipc_port_multiple_lock_data) +extern lck_mtx_ext_t ipc_port_multiple_lock_data_ext; #define ipc_port_multiple_lock_init() \ - mutex_init(&ipc_port_multiple_lock_data, 0) + lck_mtx_init_ext(&ipc_port_multiple_lock_data, &ipc_port_multiple_lock_data_ext, &ipc_lck_grp, &ipc_lck_attr) #define ipc_port_multiple_lock() \ - mutex_lock(&ipc_port_multiple_lock_data) + lck_mtx_lock(&ipc_port_multiple_lock_data) #define ipc_port_multiple_unlock() \ - mutex_unlock(&ipc_port_multiple_lock_data) + lck_mtx_unlock(&ipc_port_multiple_lock_data) /* * The port timestamp facility provides timestamps @@ -242,17 +277,19 @@ decl_mutex_data(extern,ipc_port_multiple_lock_data) * mach_port_names with port death. */ -decl_mutex_data(extern,ipc_port_timestamp_lock_data) +decl_lck_mtx_data(extern,ipc_port_timestamp_lock_data) +extern lck_mtx_ext_t ipc_port_timestamp_lock_data_ext; + extern ipc_port_timestamp_t ipc_port_timestamp_data; #define ipc_port_timestamp_lock_init() \ - mutex_init(&ipc_port_timestamp_lock_data, 0) + lck_mtx_init_ext(&ipc_port_timestamp_lock_data, &ipc_port_timestamp_lock_data_ext, &ipc_lck_grp, &ipc_lck_attr) #define ipc_port_timestamp_lock() \ - mutex_lock(&ipc_port_timestamp_lock_data) + lck_mtx_lock(&ipc_port_timestamp_lock_data) #define ipc_port_timestamp_unlock() \ - mutex_unlock(&ipc_port_timestamp_lock_data) + lck_mtx_unlock(&ipc_port_timestamp_lock_data) /* Retrieve a port timestamp value */ extern ipc_port_timestamp_t ipc_port_timestamp(void); @@ -276,32 +313,47 @@ extern ipc_port_timestamp_t ipc_port_timestamp(void); MACH_PORT_RIGHT_SEND, \ (ipc_object_t *) (portp)) -/* Allocate a dead-name request slot */ +/* Allocate a notification request slot */ extern kern_return_t -ipc_port_dnrequest( +ipc_port_request_alloc( ipc_port_t port, mach_port_name_t name, ipc_port_t soright, + boolean_t send_possible, + boolean_t immediate, ipc_port_request_index_t *indexp); -/* Grow a port's table of dead-name requests */ -extern kern_return_t ipc_port_dngrow( +/* Grow one of a port's tables of notifcation requests */ +extern kern_return_t ipc_port_request_grow( ipc_port_t port, ipc_table_elems_t target_size); -/* Cancel a dead-name request and return the send-once right */ -extern ipc_port_t ipc_port_dncancel( +/* Return the type(s) of notification requests outstanding */ +extern mach_port_type_t ipc_port_request_type( + ipc_port_t port, + mach_port_name_t name, + ipc_port_request_index_t index); + +/* Cancel a notification request and return the send-once right */ +extern ipc_port_t ipc_port_request_cancel( ipc_port_t port, mach_port_name_t name, ipc_port_request_index_t index); -#define ipc_port_dnrename(port, index, oname, nname) \ +/* Arm any delayed send-possible notification */ +extern void ipc_port_request_sparm( + ipc_port_t port, + mach_port_name_t name, + ipc_port_request_index_t index); + +/* Macros for manipulating a port's dead name notificaiton requests */ +#define ipc_port_request_rename(port, index, oname, nname) \ MACRO_BEGIN \ ipc_port_request_t ipr, table; \ \ assert(ip_active(port)); \ \ - table = port->ip_dnrequests; \ + table = port->ip_requests; \ assert(table != IPR_NULL); \ \ ipr = &table[index]; \ @@ -310,6 +362,7 @@ MACRO_BEGIN \ ipr->ipr_name = nname; \ MACRO_END + /* Make a port-deleted request */ extern void ipc_port_pdrequest( ipc_port_t port, @@ -354,8 +407,11 @@ extern kern_return_t ipc_port_alloc_name( /* Generate dead name notifications */ extern void ipc_port_dnnotify( - ipc_port_t port, - ipc_port_request_t dnrequests); + ipc_port_t port); + +/* Generate send-possible notifications */ +extern void ipc_port_spnotify( + ipc_port_t port); /* Destroy a port */ extern void ipc_port_destroy( @@ -390,10 +446,18 @@ extern mach_port_name_t ipc_port_copyout_send( ipc_port_t sright, ipc_space_t space); +#endif /* MACH_KERNEL_PRIVATE */ + +#if KERNEL_PRIVATE + /* Release a (valid) naked send right */ extern void ipc_port_release_send( ipc_port_t port); +#endif /* KERNEL_PRIVATE */ + +#if MACH_KERNEL_PRIVATE + /* Make a naked send-once right from a receive right */ extern ipc_port_t ipc_port_make_sonce( ipc_port_t port); @@ -406,6 +470,10 @@ extern void ipc_port_release_sonce( extern void ipc_port_release_receive( ipc_port_t port); +/* finalize the destruction of a port before it gets freed */ +extern void ipc_port_finalize( + ipc_port_t port); + /* Allocate a port in a special space */ extern ipc_port_t ipc_port_alloc_special( ipc_space_t space); @@ -440,4 +508,6 @@ extern void ipc_port_debug_init(void); #define ipc_port_release(port) \ ipc_object_release(&(port)->ip_object) +#endif /* MACH_KERNEL_PRIVATE */ + #endif /* _IPC_IPC_PORT_H_ */