1 /*
2 * Copyright (c) 2000-2006 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 SPARTA, Inc. in 2005 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: kern/ipc_kobject.h
66 * Author: Rich Draves
67 * Date: 1989
68 *
69 * Declarations for letting a port represent a kernel object.
70 */
71
72 #ifdef MACH_KERNEL_PRIVATE
73 #include <ipc/ipc_kmsg.h>
74 #include <ipc/ipc_port.h>
75 #include <kern/startup.h>
76 #endif /* MACH_KERNEL_PRIVATE */
77
78 #ifndef _KERN_IPC_KOBJECT_H_
79 #define _KERN_IPC_KOBJECT_H_
80
81 __BEGIN_DECLS
82
83 #ifdef KERNEL_PRIVATE
84 /*
85 * This is the legacy in-kernel ipc-object mechanism. Over the next
86 * several months, this will be phased out in favor of a mechanism that
87 * is less Mach IPC specific, and common across in-mach, in-kernel-component,
88 * and user-level-component (Plugin) models.
89 */
90 #include <mach/machine/vm_types.h>
91 #include <mach/mach_types.h>
92
93 __enum_decl(ipc_kotype_t, natural_t, {
94 IKOT_NONE = 0,
95 IKOT_THREAD_CONTROL = 1,
96 IKOT_TASK_CONTROL = 2,
97 IKOT_HOST = 3,
98 IKOT_HOST_PRIV = 4,
99 IKOT_PROCESSOR = 5,
100 IKOT_PSET = 6,
101 IKOT_PSET_NAME = 7,
102 IKOT_TIMER = 8,
103 IKOT_PORT_SUBST_ONCE = 9,
104 // IKOT_MIG = 10,
105 IKOT_MEMORY_OBJECT = 11,
106 // IKOT_XMM_PAGER = 12,
107 // IKOT_XMM_KERNEL = 13,
108 // IKOT_XMM_REPLY = 14,
109 IKOT_UND_REPLY = 15,
110 IKOT_HOST_NOTIFY = 16,
111 // IKOT_HOST_SECURITY = 17,
112 // IKOT_LEDGER = 18,
113 IKOT_MASTER_DEVICE = 19,
114 IKOT_TASK_NAME = 20,
115 // IKOT_SUBSYSTEM = 21,
116 // IKOT_IO_DONE_QUEUE = 22,
117 IKOT_SEMAPHORE = 23,
118 // IKOT_LOCK_SET = 24,
119 IKOT_CLOCK = 25,
120 IKOT_CLOCK_CTRL = 26,
121 IKOT_IOKIT_IDENT = 27,
122 IKOT_NAMED_ENTRY = 28,
123 IKOT_IOKIT_CONNECT = 29,
124 IKOT_IOKIT_OBJECT = 30,
125 // IKOT_UPL = 31,
126 IKOT_MEM_OBJ_CONTROL = 32,
127 #if CONFIG_AUDIT
128 IKOT_AU_SESSIONPORT = 33,
129 #endif
130 IKOT_FILEPORT = 34,
131 // IKOT_LABELH = 35,
132 IKOT_TASK_RESUME = 36,
133 IKOT_VOUCHER = 37,
134 IKOT_VOUCHER_ATTR_CONTROL = 38,
135 IKOT_WORK_INTERVAL = 39,
136 IKOT_UX_HANDLER = 40,
137 IKOT_UEXT_OBJECT = 41,
138 IKOT_ARCADE_REG = 42,
139 IKOT_EVENTLINK = 43,
140 IKOT_TASK_INSPECT = 44,
141 IKOT_TASK_READ = 45,
142 IKOT_THREAD_INSPECT = 46,
143 IKOT_THREAD_READ = 47,
144 // IKOT_SUID_CRED = 48,
145 #if HYPERVISOR
146 IKOT_HYPERVISOR = 49,
147 #endif
148 IKOT_TASK_ID_TOKEN = 50,
149 #if CONFIG_PROC_RESOURCE_LIMITS
150 IKOT_TASK_FATAL = 51,
151 #endif
152 /* magic catch-all; should be the last entry */
153 IKOT_UNKNOWN,
154 });
155
156 #define IKOT_MAX_TYPE (IKOT_UNKNOWN+1) /* # of IKOT_ types */
157
158 #ifdef __cplusplus
159 /* preserve legacy ABI for c++ */
160 typedef natural_t ipc_kobject_type_t;
161 #else
162 typedef ipc_kotype_t ipc_kobject_type_t;
163 #endif
164
165 /* set the bitstring index for kobject */
166 extern kern_return_t ipc_kobject_set_kobjidx(
167 int msgid,
168 int index);
169
170 #endif /* KERNEL_PRIVATE */
171 #ifdef MACH_KERNEL_PRIVATE
172 #pragma GCC visibility push(hidden)
173
174 /*!
175 * @typedef ipc_kobject_ops_t
176 *
177 * @brief
178 * Describes the operations for a given kobject.
179 *
180 * @field iko_ko_type
181 * An @c IKOT_* value.
182 *
183 * @field iko_op_allow_upgrade
184 * Whether this kobject type is made (upgraded) rather than born.
185 *
186 * @field iko_op_stable
187 * The kobject/port association is stable:
188 * - ipc_kobject_dealloc_port() cannot be called
189 * while there are outstanding send rights,
190 * - ipc_kobject_enable() is never called.
191 * - ipc_kobject_disable() is never called.
192 *
193 * @field iko_op_permanent
194 * The port is never destroyed.
195 * This doesn't necessarily imply iko_op_stable.
196 *
197 * @field iko_op_no_senders
198 * A callback to run when a NO_SENDERS notification fires.
199 *
200 * Kobjects that destroy their port on no senders only are guaranteed
201 * to be called with an active port only.
202 *
203 * However kobject ports that can be destroyed concurrently need
204 * to be prepared for no senders to fail to acquire the kobject port.
205 *
206 * @field iko_op_destroy
207 * A callback to run as part of destroying the kobject port.
208 *
209 * When this callback is set, @c ipc_kobject_dealloc_port()
210 * will not implicitly call @c ipc_kobject_disable().
211 *
212 * The callback runs after the port has been marked inactive,
213 * hence @c ipc_kobject_get_raw() needs to be used to get to the port.
214 */
215 typedef const struct ipc_kobject_ops {
216 ipc_kobject_type_t iko_op_type;
217 unsigned long
218 iko_op_allow_upgrade : 1,
219 iko_op_stable : 1,
220 iko_op_permanent : 1;
221 const char *iko_op_name;
222 void (*iko_op_no_senders)(ipc_port_t port, mach_port_mscount_t mscount);
223 void (*iko_op_destroy)(ipc_port_t port);
224 } *ipc_kobject_ops_t;
225
226 #define IPC_KOBJECT_DEFINE(type, ...) \
227 __startup_data \
228 static struct ipc_kobject_ops ipc_kobject_ops_##type = { \
229 .iko_op_type = type, \
230 .iko_op_name = #type, \
231 __VA_ARGS__ \
232 }; \
233 STARTUP_ARG(MACH_IPC, STARTUP_RANK_FIRST, ipc_kobject_register_startup, \
234 &ipc_kobject_ops_##type)
235
236 struct ipc_kobject_label {
237 ipc_label_t ikol_label; /* [private] mandatory access label */
238 ipc_port_t XNU_PTRAUTH_SIGNED_PTR("ipc_kobject_label.ikol_alt_port") ikol_alt_port;
239 };
240
241 __options_decl(ipc_kobject_alloc_options_t, uint32_t, {
242 /* Just make the naked port */
243 IPC_KOBJECT_ALLOC_NONE = 0x00000000,
244 /* Make a send right */
245 IPC_KOBJECT_ALLOC_MAKE_SEND = 0x00000001,
246 /* Register for no-more-senders */
247 IPC_KOBJECT_ALLOC_NSREQUEST = 0x00000002,
248 /* Make it no grant port */
249 IPC_KOBJECT_ALLOC_NO_GRANT = 0x00000004,
250 /* Mark the port as immovable send right */
251 IPC_KOBJECT_ALLOC_IMMOVABLE_SEND = 0x00000008,
252 /* Add a label structure to the port */
253 IPC_KOBJECT_ALLOC_LABEL = 0x00000010,
254 /* Mark the port as pinned (non dealloc-able) in an ipc space */
255 IPC_KOBJECT_ALLOC_PINNED = 0x00000020,
256 /* Use ptrauth_discriminator in ipc_kobject_make_send_lazy_alloc_port */
257 IPC_KOBJECT_PTRAUTH_STORE = 0x00000040,
258 });
259
260 /* Allocates a kobject port, never fails */
261 extern ipc_port_t ipc_kobject_alloc_port(
262 ipc_kobject_t kobject,
263 ipc_kobject_type_t type,
264 ipc_kobject_alloc_options_t options);
265
266 /* Allocates a kobject port, never fails */
267 extern ipc_port_t ipc_kobject_alloc_labeled_port(
268 ipc_kobject_t kobject,
269 ipc_kobject_type_t type,
270 ipc_label_t label,
271 ipc_kobject_alloc_options_t options);
272
273 extern ipc_port_t ipc_kobject_alloc_subst_once(
274 ipc_port_t target);
275
276 /* Makes a send right, lazily allocating a kobject port, arming for no-senders, never fails */
277 extern boolean_t ipc_kobject_make_send_lazy_alloc_port(
278 ipc_port_t *port_store,
279 ipc_kobject_t kobject,
280 ipc_kobject_type_t type,
281 ipc_kobject_alloc_options_t alloc_opts,
282 uint64_t ptrauth_discriminator) __result_use_check;
283
284 /* Makes a send right, lazily allocating a kobject port, arming for no-senders, never fails */
285 extern boolean_t ipc_kobject_make_send_lazy_alloc_labeled_port(
286 ipc_port_t *port_store,
287 ipc_kobject_t kobject,
288 ipc_kobject_type_t type,
289 ipc_label_t label) __result_use_check;
290
291 extern kern_return_t ipc_kobject_nsrequest(
292 ipc_port_t port,
293 mach_port_mscount_t sync,
294 mach_port_mscount_t *mscount) __result_use_check;
295
296 /* Makes a send right, and arms no-senders */
297 extern kern_return_t ipc_kobject_make_send_nsrequest(
298 ipc_port_t port) __result_use_check;
299
300 extern ipc_kobject_t ipc_kobject_dealloc_port_and_unlock(
301 ipc_port_t port,
302 mach_port_mscount_t mscount,
303 ipc_kobject_type_t type);
304
305 extern ipc_kobject_t ipc_kobject_dealloc_port(
306 ipc_port_t port,
307 mach_port_mscount_t mscount,
308 ipc_kobject_type_t type);
309
310 extern void ipc_kobject_enable(
311 ipc_port_t port,
312 ipc_kobject_t kobject,
313 ipc_kobject_type_t type);
314
315 extern ipc_kobject_t ipc_kobject_get_raw(
316 ipc_port_t port,
317 ipc_kobject_type_t type);
318
319 extern ipc_kobject_t ipc_kobject_get_locked(
320 ipc_port_t port,
321 ipc_kobject_type_t type);
322
323 extern ipc_kobject_t ipc_kobject_get_stable(
324 ipc_port_t port,
325 ipc_kobject_type_t type);
326
327 extern ipc_kobject_t ipc_kobject_disable_locked(
328 ipc_port_t port,
329 ipc_kobject_type_t type);
330
331 extern ipc_kobject_t ipc_kobject_disable(
332 ipc_port_t port,
333 ipc_kobject_type_t type);
334
335 extern void ipc_kobject_upgrade_locked(
336 ipc_port_t port,
337 ipc_kobject_t kobject,
338 ipc_kobject_type_t type);
339
340 extern kern_return_t ipc_kobject_upgrade(
341 ipc_port_t port,
342 ipc_kobject_t kobject,
343 ipc_kobject_type_t type) __result_use_check;
344
345 extern ipc_kobject_t ipc_kobject_downgrade_host_notify(
346 ipc_port_t port);
347
348 /* Check if a kobject can be copied out to a given space */
349 extern bool ipc_kobject_label_check(
350 ipc_space_t space,
351 ipc_port_t port,
352 mach_msg_type_name_t msgt_name,
353 ipc_object_copyout_flags_t *flags,
354 ipc_port_t *subst_portp) __result_use_check;
355
356 __result_use_check
357 static inline bool
ip_label_check(ipc_space_t space,ipc_port_t port,mach_msg_type_name_t msgt_name,ipc_object_copyout_flags_t * flags,ipc_port_t * subst_portp)358 ip_label_check(
359 ipc_space_t space,
360 ipc_port_t port,
361 mach_msg_type_name_t msgt_name,
362 ipc_object_copyout_flags_t *flags,
363 ipc_port_t *subst_portp)
364 {
365 if (!ip_is_kolabeled(port)) {
366 *subst_portp = IP_NULL;
367 return true;
368 }
369 return ipc_kobject_label_check(space, port, msgt_name, flags, subst_portp);
370 }
371
372 /* implementation details */
373
374 __startup_func
375 extern void ipc_kobject_register_startup(
376 ipc_kobject_ops_t ops);
377
378 /* initialization of kobject subsystem */
379 extern void ipc_kobject_init(void);
380
381 /* Dispatch a kernel server function */
382 extern ipc_kmsg_t ipc_kobject_server(
383 ipc_port_t receiver,
384 ipc_kmsg_t request,
385 mach_msg_option_t option);
386
387 /* Release any kernel object resources associated with a port */
388 extern void ipc_kobject_destroy(
389 ipc_port_t port);
390
391 #define null_conversion(port) (port)
392
393 extern void ipc_kobject_notify_no_senders(
394 ipc_port_t port,
395 mach_port_mscount_t mscount);
396
397 extern void ipc_kobject_notify_send_once_and_unlock(
398 ipc_port_t port);
399
400 extern kern_return_t uext_server(
401 ipc_port_t receiver,
402 ipc_kmsg_t request,
403 ipc_kmsg_t *reply);
404
405 #pragma GCC visibility pop
406 #endif /* MACH_KERNEL_PRIVATE */
407
408 __END_DECLS
409
410 #endif /* _KERN_IPC_KOBJECT_H_ */
411