1 /*
2 * Copyright (c) 2000-2005 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,1988,1987 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: mach/message.h
67 *
68 * Mach IPC message and primitive function definitions.
69 */
70
71 #ifndef _MACH_MESSAGE_H_
72 #define _MACH_MESSAGE_H_
73
74 #include <stddef.h>
75 #include <stdint.h>
76 #include <machine/limits.h>
77 #include <machine/types.h> /* user_addr_t */
78 #include <mach/port.h>
79 #include <mach/boolean.h>
80 #include <mach/kern_return.h>
81 #include <mach/machine/vm_types.h>
82
83 #include <sys/cdefs.h>
84 #include <sys/appleapiopts.h>
85 #include <Availability.h>
86 #if !KERNEL && PRIVATE
87 #include <TargetConditionals.h>
88 #endif
89 #if __has_feature(ptrauth_calls)
90 #include <ptrauth.h>
91 #endif
92
93 /*
94 * The timeout mechanism uses mach_msg_timeout_t values,
95 * passed by value. The timeout units are milliseconds.
96 * It is controlled with the MACH_SEND_TIMEOUT
97 * and MACH_RCV_TIMEOUT options.
98 */
99
100 typedef natural_t mach_msg_timeout_t;
101
102 /*
103 * The value to be used when there is no timeout.
104 * (No MACH_SEND_TIMEOUT/MACH_RCV_TIMEOUT option.)
105 */
106
107 #define MACH_MSG_TIMEOUT_NONE ((mach_msg_timeout_t) 0)
108
109 /*
110 * The kernel uses MACH_MSGH_BITS_COMPLEX as a hint. If it isn't on, it
111 * assumes the body of the message doesn't contain port rights or OOL
112 * data. The field is set in received messages. A user task must
113 * use caution in interpreting the body of a message if the bit isn't
114 * on, because the mach_msg_type's in the body might "lie" about the
115 * contents. If the bit isn't on, but the mach_msg_types
116 * in the body specify rights or OOL data, the behavior is undefined.
117 * (Ie, an error may or may not be produced.)
118 *
119 * The value of MACH_MSGH_BITS_REMOTE determines the interpretation
120 * of the msgh_remote_port field. It is handled like a msgt_name,
121 * but must result in a send or send-once type right.
122 *
123 * The value of MACH_MSGH_BITS_LOCAL determines the interpretation
124 * of the msgh_local_port field. It is handled like a msgt_name,
125 * and also must result in a send or send-once type right.
126 *
127 * The value of MACH_MSGH_BITS_VOUCHER determines the interpretation
128 * of the msgh_voucher_port field. It is handled like a msgt_name,
129 * but must result in a send right (and the msgh_voucher_port field
130 * must be the name of a send right to a Mach voucher kernel object.
131 *
132 * MACH_MSGH_BITS() combines two MACH_MSG_TYPE_* values, for the remote
133 * and local fields, into a single value suitable for msgh_bits.
134 *
135 * MACH_MSGH_BITS_CIRCULAR should be zero; is is used internally.
136 *
137 * The unused bits should be zero and are reserved for the kernel
138 * or for future interface expansion.
139 */
140
141 #define MACH_MSGH_BITS_ZERO 0x00000000
142
143 #define MACH_MSGH_BITS_REMOTE_MASK 0x0000001f
144 #define MACH_MSGH_BITS_LOCAL_MASK 0x00001f00
145 #define MACH_MSGH_BITS_VOUCHER_MASK 0x001f0000
146
147 #define MACH_MSGH_BITS_PORTS_MASK \
148 (MACH_MSGH_BITS_REMOTE_MASK | \
149 MACH_MSGH_BITS_LOCAL_MASK | \
150 MACH_MSGH_BITS_VOUCHER_MASK)
151
152 #define MACH_MSGH_BITS_COMPLEX 0x80000000U /* message is complex */
153
154 #define MACH_MSGH_BITS_USER 0x801f1f1fU /* allowed bits user->kernel */
155
156 #define MACH_MSGH_BITS_RAISEIMP 0x20000000U /* importance raised due to msg */
157 #define MACH_MSGH_BITS_DENAP MACH_MSGH_BITS_RAISEIMP
158
159 #define MACH_MSGH_BITS_IMPHOLDASRT 0x10000000U /* assertion help, userland private */
160 #define MACH_MSGH_BITS_DENAPHOLDASRT MACH_MSGH_BITS_IMPHOLDASRT
161
162 #define MACH_MSGH_BITS_CIRCULAR 0x10000000U /* message circular, kernel private */
163
164 #define MACH_MSGH_BITS_USED 0xb01f1f1fU
165
166 /* setter macros for the bits */
167 #define MACH_MSGH_BITS(remote, local) /* legacy */ \
168 ((remote) | ((local) << 8))
169 #define MACH_MSGH_BITS_SET_PORTS(remote, local, voucher) \
170 (((remote) & MACH_MSGH_BITS_REMOTE_MASK) | \
171 (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) | \
172 (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK))
173 #define MACH_MSGH_BITS_SET(remote, local, voucher, other) \
174 (MACH_MSGH_BITS_SET_PORTS((remote), (local), (voucher)) \
175 | ((other) &~ MACH_MSGH_BITS_PORTS_MASK))
176
177 /* getter macros for pulling values out of the bits field */
178 #define MACH_MSGH_BITS_REMOTE(bits) \
179 ((bits) & MACH_MSGH_BITS_REMOTE_MASK)
180 #define MACH_MSGH_BITS_LOCAL(bits) \
181 (((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8)
182 #define MACH_MSGH_BITS_VOUCHER(bits) \
183 (((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16)
184 #define MACH_MSGH_BITS_PORTS(bits) \
185 ((bits) & MACH_MSGH_BITS_PORTS_MASK)
186 #define MACH_MSGH_BITS_OTHER(bits) \
187 ((bits) &~ MACH_MSGH_BITS_PORTS_MASK)
188
189 /* checking macros */
190 #define MACH_MSGH_BITS_HAS_REMOTE(bits) \
191 (MACH_MSGH_BITS_REMOTE(bits) != MACH_MSGH_BITS_ZERO)
192 #define MACH_MSGH_BITS_HAS_LOCAL(bits) \
193 (MACH_MSGH_BITS_LOCAL(bits) != MACH_MSGH_BITS_ZERO)
194 #define MACH_MSGH_BITS_HAS_VOUCHER(bits) \
195 (MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO)
196 #define MACH_MSGH_BITS_IS_COMPLEX(bits) \
197 (((bits) & MACH_MSGH_BITS_COMPLEX) != MACH_MSGH_BITS_ZERO)
198
199 /* importance checking macros */
200 #define MACH_MSGH_BITS_RAISED_IMPORTANCE(bits) \
201 (((bits) & MACH_MSGH_BITS_RAISEIMP) != MACH_MSGH_BITS_ZERO)
202 #define MACH_MSGH_BITS_HOLDS_IMPORTANCE_ASSERTION(bits) \
203 (((bits) & MACH_MSGH_BITS_IMPHOLDASRT) != MACH_MSGH_BITS_ZERO)
204
205 /*
206 * Every message starts with a message header.
207 * Following the message header, if the message is complex, are a count
208 * of type descriptors and the type descriptors themselves
209 * (mach_msg_descriptor_t). The size of the message must be specified in
210 * bytes, and includes the message header, descriptor count, descriptors,
211 * and inline data.
212 *
213 * The msgh_remote_port field specifies the destination of the message.
214 * It must specify a valid send or send-once right for a port.
215 *
216 * The msgh_local_port field specifies a "reply port". Normally,
217 * This field carries a send-once right that the receiver will use
218 * to reply to the message. It may carry the values MACH_PORT_NULL,
219 * MACH_PORT_DEAD, a send-once right, or a send right.
220 *
221 * The msgh_voucher_port field specifies a Mach voucher port. Only
222 * send rights to kernel-implemented Mach Voucher kernel objects in
223 * addition to MACH_PORT_NULL or MACH_PORT_DEAD may be passed.
224 *
225 * The msgh_id field is uninterpreted by the message primitives.
226 * It normally carries information specifying the format
227 * or meaning of the message.
228 */
229
230 typedef unsigned int mach_msg_bits_t;
231 typedef natural_t mach_msg_size_t;
232 typedef integer_t mach_msg_id_t;
233
234 #define MACH_MSG_SIZE_NULL (mach_msg_size_t *) 0
235
236 typedef unsigned int mach_msg_priority_t;
237
238 #define MACH_MSG_PRIORITY_UNSPECIFIED (mach_msg_priority_t) 0
239
240 #if PRIVATE
241 typedef uint8_t mach_msg_qos_t; // same as thread_qos_t
242 #define MACH_MSG_QOS_UNSPECIFIED 0
243 #define MACH_MSG_QOS_MAINTENANCE 1
244 #define MACH_MSG_QOS_BACKGROUND 2
245 #define MACH_MSG_QOS_UTILITY 3
246 #define MACH_MSG_QOS_DEFAULT 4
247 #define MACH_MSG_QOS_USER_INITIATED 5
248 #define MACH_MSG_QOS_USER_INTERACTIVE 6
249 #define MACH_MSG_QOS_LAST 6
250
251 extern int mach_msg_priority_is_pthread_priority(mach_msg_priority_t pri);
252 extern mach_msg_priority_t mach_msg_priority_encode(
253 mach_msg_qos_t override_qos,
254 mach_msg_qos_t qos,
255 int relpri);
256 extern mach_msg_qos_t mach_msg_priority_overide_qos(mach_msg_priority_t pri);
257 extern mach_msg_qos_t mach_msg_priority_qos(mach_msg_priority_t pri);
258 extern int mach_msg_priority_relpri(mach_msg_priority_t pri);
259
260 #if KERNEL || !TARGET_OS_SIMULATOR
261 static inline int
mach_msg_priority_is_pthread_priority_inline(mach_msg_priority_t pri)262 mach_msg_priority_is_pthread_priority_inline(mach_msg_priority_t pri)
263 {
264 return (pri & 0xff) == 0xff;
265 }
266
267 #define MACH_MSG_PRIORITY_RELPRI_SHIFT 8
268 #define MACH_MSG_PRIORITY_RELPRI_MASK (0xff << MACH_MSG_PRIORITY_RELPRI_SHIFT)
269 #define MACH_MSG_PRIORITY_QOS_SHIFT 16
270 #define MACH_MSG_PRIORITY_QOS_MASK (0xf << MACH_MSG_PRIORITY_QOS_SHIFT)
271 #define MACH_MSG_PRIORITY_OVERRIDE_SHIFT 20
272 #define MACH_MSG_PRIORITY_OVERRIDE_MASK (0xf << MACH_MSG_PRIORITY_OVERRIDE_SHIFT)
273
274 static inline mach_msg_priority_t
mach_msg_priority_encode_inline(mach_msg_qos_t override_qos,mach_msg_qos_t qos,int relpri)275 mach_msg_priority_encode_inline(mach_msg_qos_t override_qos, mach_msg_qos_t qos, int relpri)
276 {
277 mach_msg_priority_t pri = 0;
278 if (qos > 0 && qos <= MACH_MSG_QOS_LAST) {
279 pri |= (uint32_t)(qos << MACH_MSG_PRIORITY_QOS_SHIFT);
280 pri |= (uint32_t)((uint8_t)(relpri - 1) << MACH_MSG_PRIORITY_RELPRI_SHIFT);
281 }
282 if (override_qos > 0 && override_qos <= MACH_MSG_QOS_LAST) {
283 pri |= (uint32_t)(override_qos << MACH_MSG_PRIORITY_OVERRIDE_SHIFT);
284 }
285 return pri;
286 }
287
288 static inline mach_msg_qos_t
mach_msg_priority_overide_qos_inline(mach_msg_priority_t pri)289 mach_msg_priority_overide_qos_inline(mach_msg_priority_t pri)
290 {
291 pri &= MACH_MSG_PRIORITY_OVERRIDE_MASK;
292 pri >>= MACH_MSG_PRIORITY_OVERRIDE_SHIFT;
293 return (mach_msg_qos_t)(pri <= MACH_MSG_QOS_LAST ? pri : 0);
294 }
295
296 static inline mach_msg_qos_t
mach_msg_priority_qos_inline(mach_msg_priority_t pri)297 mach_msg_priority_qos_inline(mach_msg_priority_t pri)
298 {
299 pri &= MACH_MSG_PRIORITY_QOS_MASK;
300 pri >>= MACH_MSG_PRIORITY_QOS_SHIFT;
301 return (mach_msg_qos_t)(pri <= MACH_MSG_QOS_LAST ? pri : 0);
302 }
303
304 static inline int
mach_msg_priority_relpri_inline(mach_msg_priority_t pri)305 mach_msg_priority_relpri_inline(mach_msg_priority_t pri)
306 {
307 if (mach_msg_priority_qos_inline(pri)) {
308 return (int8_t)(pri >> MACH_MSG_PRIORITY_RELPRI_SHIFT) + 1;
309 }
310 return 0;
311 }
312
313 #define mach_msg_priority_is_pthread_priority(...) \
314 mach_msg_priority_is_pthread_priority_inline(__VA_ARGS__)
315 #define mach_msg_priority_encode(...) \
316 mach_msg_priority_encode_inline(__VA_ARGS__)
317 #define mach_msg_priority_overide_qos(...) \
318 mach_msg_priority_overide_qos_inline(__VA_ARGS__)
319 #define mach_msg_priority_qos(...) \
320 mach_msg_priority_qos_inline(__VA_ARGS__)
321 #define mach_msg_priority_relpri(...) \
322 mach_msg_priority_relpri_inline(__VA_ARGS__)
323 #endif
324
325 #endif // PRIVATE
326
327 typedef unsigned int mach_msg_type_name_t;
328
329 #define MACH_MSG_TYPE_MOVE_RECEIVE 16 /* Must hold receive right */
330 #define MACH_MSG_TYPE_MOVE_SEND 17 /* Must hold send right(s) */
331 #define MACH_MSG_TYPE_MOVE_SEND_ONCE 18 /* Must hold sendonce right */
332 #define MACH_MSG_TYPE_COPY_SEND 19 /* Must hold send right(s) */
333 #define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */
334 #define MACH_MSG_TYPE_MAKE_SEND_ONCE 21 /* Must hold receive right */
335 #define MACH_MSG_TYPE_COPY_RECEIVE 22 /* NOT VALID */
336 #define MACH_MSG_TYPE_DISPOSE_RECEIVE 24 /* must hold receive right */
337 #define MACH_MSG_TYPE_DISPOSE_SEND 25 /* must hold send right(s) */
338 #define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26 /* must hold sendonce right */
339
340 typedef unsigned int mach_msg_copy_options_t;
341
342 #define MACH_MSG_PHYSICAL_COPY 0
343 #define MACH_MSG_VIRTUAL_COPY 1
344 #define MACH_MSG_ALLOCATE 2
345 #define MACH_MSG_OVERWRITE 3 /* deprecated */
346 #ifdef MACH_KERNEL
347 #define MACH_MSG_KALLOC_COPY_T 4
348 #endif /* MACH_KERNEL */
349
350 #define MACH_MSG_GUARD_FLAGS_NONE 0x0000
351 #define MACH_MSG_GUARD_FLAGS_IMMOVABLE_RECEIVE 0x0001 /* Move the receive right and mark it as immovable */
352 #define MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND 0x0002 /* Verify that the port is unguarded */
353 #define MACH_MSG_GUARD_FLAGS_MASK 0x0003 /* Valid flag bits */
354 typedef unsigned int mach_msg_guard_flags_t;
355
356 /*
357 * In a complex mach message, the mach_msg_header_t is followed by
358 * a descriptor count, then an array of that number of descriptors
359 * (mach_msg_*_descriptor_t). The type field of mach_msg_type_descriptor_t
360 * (which any descriptor can be cast to) indicates the flavor of the
361 * descriptor.
362 *
363 * Note that in LP64, the various types of descriptors are no longer all
364 * the same size as mach_msg_descriptor_t, so the array cannot be indexed
365 * as expected.
366 */
367
368 typedef unsigned int mach_msg_descriptor_type_t;
369
370 #define MACH_MSG_PORT_DESCRIPTOR 0
371 #define MACH_MSG_OOL_DESCRIPTOR 1
372 #define MACH_MSG_OOL_PORTS_DESCRIPTOR 2
373 #define MACH_MSG_OOL_VOLATILE_DESCRIPTOR 3
374 #define MACH_MSG_GUARDED_PORT_DESCRIPTOR 4
375
376 #define MACH_MSG_DESCRIPTOR_MAX MACH_MSG_GUARDED_PORT_DESCRIPTOR
377
378 #if XNU_KERNEL_PRIVATE && __has_feature(ptrauth_calls)
379 #define __ipc_desc_sign(d) \
380 __ptrauth(ptrauth_key_process_independent_data, \
381 1, ptrauth_string_discriminator("ipc_desc." d))
382 #else
383 #define __ipc_desc_sign(d)
384 #endif /* KERNEL */
385
386 #pragma pack(push, 4)
387
388 typedef struct {
389 natural_t pad1;
390 mach_msg_size_t pad2;
391 unsigned int pad3 : 24;
392 mach_msg_descriptor_type_t type : 8;
393 } mach_msg_type_descriptor_t;
394
395 typedef struct {
396 #if KERNEL
397 union {
398 mach_port_t __ipc_desc_sign("port") name;
399 mach_port_t kext_name;
400 mach_port_t u_name;
401 };
402 #else
403 mach_port_t name;
404 mach_msg_size_t pad1;
405 #endif
406 unsigned int pad2 : 16;
407 mach_msg_type_name_t disposition : 8;
408 mach_msg_descriptor_type_t type : 8;
409 #if defined(KERNEL)
410 uint32_t pad_end;
411 #endif
412 } mach_msg_port_descriptor_t;
413
414 #if MACH_KERNEL_PRIVATE
415 typedef struct {
416 mach_port_name_t name;
417 mach_msg_size_t pad1;
418 uint32_t pad2 : 16;
419 mach_msg_type_name_t disposition : 8;
420 mach_msg_descriptor_type_t type : 8;
421 } mach_msg_user_port_descriptor_t;
422 #endif /* MACH_KERNEL_PRIVATE */
423
424 typedef struct {
425 uint32_t address;
426 mach_msg_size_t size;
427 boolean_t deallocate: 8;
428 mach_msg_copy_options_t copy: 8;
429 unsigned int pad1: 8;
430 mach_msg_descriptor_type_t type: 8;
431 } mach_msg_ool_descriptor32_t;
432
433 typedef struct {
434 uint64_t address;
435 boolean_t deallocate: 8;
436 mach_msg_copy_options_t copy: 8;
437 unsigned int pad1: 8;
438 mach_msg_descriptor_type_t type: 8;
439 mach_msg_size_t size;
440 } mach_msg_ool_descriptor64_t;
441
442 typedef struct {
443 #if KERNEL
444 union {
445 void *__ipc_desc_sign("address") address;
446 void *kext_address;
447 user_addr_t u_address;
448 };
449 #else
450 void *address;
451 #endif
452 #if !defined(__LP64__)
453 mach_msg_size_t size;
454 #endif
455 boolean_t deallocate: 8;
456 mach_msg_copy_options_t copy: 8;
457 unsigned int pad1: 8;
458 mach_msg_descriptor_type_t type: 8;
459 #if defined(__LP64__)
460 mach_msg_size_t size;
461 #endif
462 #if defined(KERNEL) && !defined(__LP64__)
463 uint32_t pad_end;
464 #endif
465 } mach_msg_ool_descriptor_t;
466
467 typedef struct {
468 uint32_t address;
469 mach_msg_size_t count;
470 boolean_t deallocate: 8;
471 mach_msg_copy_options_t copy: 8;
472 mach_msg_type_name_t disposition : 8;
473 mach_msg_descriptor_type_t type : 8;
474 } mach_msg_ool_ports_descriptor32_t;
475
476 typedef struct {
477 uint64_t address;
478 boolean_t deallocate: 8;
479 mach_msg_copy_options_t copy: 8;
480 mach_msg_type_name_t disposition : 8;
481 mach_msg_descriptor_type_t type : 8;
482 mach_msg_size_t count;
483 } mach_msg_ool_ports_descriptor64_t;
484
485 typedef struct {
486 #if KERNEL
487 union {
488 void *__ipc_desc_sign("port_array") address;
489 void *kext_address;
490 user_addr_t u_address;
491 };
492 #else
493 void *address;
494 #endif
495 #if !defined(__LP64__)
496 mach_msg_size_t count;
497 #endif
498 boolean_t deallocate: 8;
499 mach_msg_copy_options_t copy: 8;
500 mach_msg_type_name_t disposition : 8;
501 mach_msg_descriptor_type_t type : 8;
502 #if defined(__LP64__)
503 mach_msg_size_t count;
504 #endif
505 #if defined(KERNEL) && !defined(__LP64__)
506 uint32_t pad_end;
507 #endif
508 } mach_msg_ool_ports_descriptor_t;
509
510 typedef struct {
511 uint32_t context;
512 mach_port_name_t name;
513 mach_msg_guard_flags_t flags : 16;
514 mach_msg_type_name_t disposition : 8;
515 mach_msg_descriptor_type_t type : 8;
516 } mach_msg_guarded_port_descriptor32_t;
517
518 typedef struct {
519 uint64_t context;
520 mach_msg_guard_flags_t flags : 16;
521 mach_msg_type_name_t disposition : 8;
522 mach_msg_descriptor_type_t type : 8;
523 mach_port_name_t name;
524 } mach_msg_guarded_port_descriptor64_t;
525
526 typedef struct {
527 #if defined(KERNEL)
528 union {
529 mach_port_t __ipc_desc_sign("guarded_port") name;
530 mach_port_t kext_name;
531 mach_port_context_t u_context;
532 };
533 mach_msg_guard_flags_t flags : 16;
534 mach_msg_type_name_t disposition : 8;
535 mach_msg_descriptor_type_t type : 8;
536 union {
537 uint32_t pad_end;
538 mach_port_name_t u_name;
539 };
540 #else
541 mach_port_context_t context;
542 #if !defined(__LP64__)
543 mach_port_name_t name;
544 #endif
545 mach_msg_guard_flags_t flags : 16;
546 mach_msg_type_name_t disposition : 8;
547 mach_msg_descriptor_type_t type : 8;
548 #if defined(__LP64__)
549 mach_port_name_t name;
550 #endif /* defined(__LP64__) */
551 #endif /* defined(KERNEL) */
552 } mach_msg_guarded_port_descriptor_t;
553
554 /*
555 * LP64support - This union definition is not really
556 * appropriate in LP64 mode because not all descriptors
557 * are of the same size in that environment.
558 */
559 #if defined(__LP64__) && defined(KERNEL)
560 typedef union {
561 mach_msg_port_descriptor_t port;
562 mach_msg_ool_descriptor32_t out_of_line;
563 mach_msg_ool_ports_descriptor32_t ool_ports;
564 mach_msg_type_descriptor_t type;
565 mach_msg_guarded_port_descriptor32_t guarded_port;
566 } mach_msg_descriptor_t;
567 #else
568 typedef union {
569 mach_msg_port_descriptor_t port;
570 mach_msg_ool_descriptor_t out_of_line;
571 mach_msg_ool_ports_descriptor_t ool_ports;
572 mach_msg_type_descriptor_t type;
573 mach_msg_guarded_port_descriptor_t guarded_port;
574 } mach_msg_descriptor_t;
575 #endif
576
577 typedef struct {
578 mach_msg_size_t msgh_descriptor_count;
579 } mach_msg_body_t;
580
581 #define MACH_MSG_BODY_NULL ((mach_msg_body_t *) 0)
582 #define MACH_MSG_DESCRIPTOR_NULL ((mach_msg_descriptor_t *) 0)
583
584 typedef struct {
585 mach_msg_bits_t msgh_bits;
586 mach_msg_size_t msgh_size;
587 mach_port_t msgh_remote_port;
588 mach_port_t msgh_local_port;
589 mach_port_name_t msgh_voucher_port;
590 mach_msg_id_t msgh_id;
591 } mach_msg_header_t;
592
593 #if PRIVATE
594
595 /* mach msg2 data vectors are positional */
596 __enum_decl(mach_msgv_index_t, uint32_t, {
597 MACH_MSGV_IDX_MSG = 0,
598 MACH_MSGV_IDX_AUX = 1,
599 });
600
601 #define MACH_MSGV_MAX_COUNT (MACH_MSGV_IDX_AUX + 1)
602 /* at least DISPATCH_MSGV_AUX_MAX_SIZE in libdispatch */
603 #define LIBSYSCALL_MSGV_AUX_MAX_SIZE 128
604
605 typedef struct {
606 /* a mach_msg_header_t* or mach_msg_aux_header_t* */
607 mach_vm_address_t msgv_data;
608 /* if msgv_rcv_addr is non-zero, use it as rcv address instead */
609 mach_vm_address_t msgv_rcv_addr;
610 mach_msg_size_t msgv_send_size;
611 mach_msg_size_t msgv_rcv_size;
612 } mach_msg_vector_t;
613
614 typedef struct {
615 mach_msg_size_t msgdh_size;
616 uint32_t msgdh_reserved; /* For future */
617 } mach_msg_aux_header_t;
618
619 #endif /* PRIVATE */
620
621 #define msgh_reserved msgh_voucher_port
622 #define MACH_MSG_NULL ((mach_msg_header_t *) 0)
623
624 typedef struct {
625 mach_msg_header_t header;
626 mach_msg_body_t body;
627 } mach_msg_base_t;
628
629 #if MACH_KERNEL_PRIVATE
630
631 typedef struct {
632 /* first two fields must align with mach_msg_header_t */
633 mach_msg_bits_t msgh_bits;
634 mach_msg_size_t msgh_size;
635 mach_port_name_t msgh_remote_port;
636 mach_port_name_t msgh_local_port;
637 mach_port_name_t msgh_voucher_port;
638 mach_msg_id_t msgh_id;
639 } mach_msg_user_header_t;
640
641 typedef struct {
642 mach_msg_user_header_t header;
643 mach_msg_body_t body;
644 } mach_msg_user_base_t;
645
646 typedef union {
647 mach_msg_type_descriptor_t kdesc_header;
648 mach_msg_port_descriptor_t kdesc_port;
649 mach_msg_ool_descriptor_t kdesc_memory;
650 mach_msg_ool_ports_descriptor_t kdesc_port_array;
651 mach_msg_guarded_port_descriptor_t kdesc_guarded_port;
652 } mach_msg_kdescriptor_t;
653
654 static inline mach_msg_descriptor_type_t
mach_msg_kdescriptor_type(const mach_msg_kdescriptor_t * kdesc)655 mach_msg_kdescriptor_type(const mach_msg_kdescriptor_t *kdesc)
656 {
657 return kdesc->kdesc_header.type;
658 }
659
660 typedef struct {
661 mach_msg_header_t msgb_header;
662 mach_msg_size_t msgb_dsc_count;
663 mach_msg_kdescriptor_t msgb_dsc_array[];
664 } mach_msg_kbase_t;
665
666 static inline mach_msg_kbase_t *
mach_msg_header_to_kbase(mach_msg_header_t * hdr)667 mach_msg_header_to_kbase(mach_msg_header_t *hdr)
668 {
669 return __container_of(hdr, mach_msg_kbase_t, msgb_header);
670 }
671
672 #define mach_port_array_alloc(count, flags) \
673 kalloc_type(mach_port_ool_t, count, flags)
674
675 #define mach_port_array_free(ptr, count) \
676 kfree_type(mach_port_ool_t, count, ptr)
677
678 #endif /* MACH_KERNEL_PRIVATE */
679
680 typedef unsigned int mach_msg_trailer_type_t;
681
682 #define MACH_MSG_TRAILER_FORMAT_0 0
683
684 typedef unsigned int mach_msg_trailer_size_t;
685 typedef char *mach_msg_trailer_info_t;
686
687 typedef struct {
688 mach_msg_trailer_type_t msgh_trailer_type;
689 mach_msg_trailer_size_t msgh_trailer_size;
690 } mach_msg_trailer_t;
691
692 /*
693 * The msgh_seqno field carries a sequence number
694 * associated with the received-from port. A port's
695 * sequence number is incremented every time a message
696 * is received from it and included in the received
697 * trailer to help put messages back in sequence if
698 * multiple threads receive and/or process received
699 * messages.
700 */
701 typedef struct {
702 mach_msg_trailer_type_t msgh_trailer_type;
703 mach_msg_trailer_size_t msgh_trailer_size;
704 mach_port_seqno_t msgh_seqno;
705 } mach_msg_seqno_trailer_t;
706
707 typedef struct {
708 unsigned int val[2];
709 } security_token_t;
710
711 typedef struct {
712 mach_msg_trailer_type_t msgh_trailer_type;
713 mach_msg_trailer_size_t msgh_trailer_size;
714 mach_port_seqno_t msgh_seqno;
715 security_token_t msgh_sender;
716 } mach_msg_security_trailer_t;
717
718 /*
719 * The audit token is an opaque token which identifies
720 * Mach tasks and senders of Mach messages as subjects
721 * to the BSM audit system. Only the appropriate BSM
722 * library routines should be used to interpret the
723 * contents of the audit token as the representation
724 * of the subject identity within the token may change
725 * over time.
726 */
727 typedef struct {
728 unsigned int val[8];
729 } audit_token_t;
730
731 /*
732 * Safe initializer for audit_token_t.
733 * Variables holding unset audit tokens should generally
734 * be initialized to INVALID_AUDIT_TOKEN_VALUE, to allow
735 * unset audit tokens be distinguished from the kernel's
736 * audit token, KERNEL_AUDIT_TOKEN_VALUE. It is `safe'
737 * in that it limits potential damage if such an unset
738 * audit token, or one of its fields, were ever to be
739 * interpreted as valid by mistake. Notably, the pid is
740 * outside of range of valid pids, and none of the
741 * fields correspond to privileged users or groups.
742 */
743 #define INVALID_AUDIT_TOKEN_VALUE {{ \
744 UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, \
745 UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX }}
746
747 typedef struct {
748 mach_msg_trailer_type_t msgh_trailer_type;
749 mach_msg_trailer_size_t msgh_trailer_size;
750 mach_port_seqno_t msgh_seqno;
751 security_token_t msgh_sender;
752 audit_token_t msgh_audit;
753 } mach_msg_audit_trailer_t;
754
755 typedef struct {
756 mach_msg_trailer_type_t msgh_trailer_type;
757 mach_msg_trailer_size_t msgh_trailer_size;
758 mach_port_seqno_t msgh_seqno;
759 security_token_t msgh_sender;
760 audit_token_t msgh_audit;
761 mach_port_context_t msgh_context;
762 } mach_msg_context_trailer_t;
763
764 #if defined(MACH_KERNEL_PRIVATE) && defined(__arm64__)
765 typedef struct {
766 mach_msg_trailer_type_t msgh_trailer_type;
767 mach_msg_trailer_size_t msgh_trailer_size;
768 mach_port_seqno_t msgh_seqno;
769 security_token_t msgh_sender;
770 audit_token_t msgh_audit;
771 mach_port_context32_t msgh_context;
772 } mach_msg_context_trailer32_t;
773
774 typedef struct {
775 mach_msg_trailer_type_t msgh_trailer_type;
776 mach_msg_trailer_size_t msgh_trailer_size;
777 mach_port_seqno_t msgh_seqno;
778 security_token_t msgh_sender;
779 audit_token_t msgh_audit;
780 mach_port_context64_t msgh_context;
781 } mach_msg_context_trailer64_t;
782 #endif
783
784
785 typedef struct {
786 mach_port_name_t sender;
787 } msg_labels_t;
788
789 typedef int mach_msg_filter_id;
790 #define MACH_MSG_FILTER_POLICY_ALLOW (mach_msg_filter_id)0
791
792 /*
793 * Trailer type to pass MAC policy label info as a mach message trailer.
794 *
795 */
796
797 typedef struct {
798 mach_msg_trailer_type_t msgh_trailer_type;
799 mach_msg_trailer_size_t msgh_trailer_size;
800 mach_port_seqno_t msgh_seqno;
801 security_token_t msgh_sender;
802 audit_token_t msgh_audit;
803 mach_port_context_t msgh_context;
804 mach_msg_filter_id msgh_ad;
805 msg_labels_t msgh_labels;
806 } mach_msg_mac_trailer_t;
807
808 #if defined(MACH_KERNEL_PRIVATE) && defined(__arm64__)
809 typedef struct {
810 mach_msg_trailer_type_t msgh_trailer_type;
811 mach_msg_trailer_size_t msgh_trailer_size;
812 mach_port_seqno_t msgh_seqno;
813 security_token_t msgh_sender;
814 audit_token_t msgh_audit;
815 mach_port_context32_t msgh_context;
816 mach_msg_filter_id msgh_ad;
817 msg_labels_t msgh_labels;
818 } mach_msg_mac_trailer32_t;
819
820 typedef struct {
821 mach_msg_trailer_type_t msgh_trailer_type;
822 mach_msg_trailer_size_t msgh_trailer_size;
823 mach_port_seqno_t msgh_seqno;
824 security_token_t msgh_sender;
825 audit_token_t msgh_audit;
826 mach_port_context64_t msgh_context;
827 mach_msg_filter_id msgh_ad;
828 msg_labels_t msgh_labels;
829 } mach_msg_mac_trailer64_t;
830
831 #endif
832
833 #define MACH_MSG_TRAILER_MINIMUM_SIZE sizeof(mach_msg_trailer_t)
834
835 /*
836 * These values can change from release to release - but clearly
837 * code cannot request additional trailer elements one was not
838 * compiled to understand. Therefore, it is safe to use this
839 * constant when the same module specified the receive options.
840 * Otherwise, you run the risk that the options requested by
841 * another module may exceed the local modules notion of
842 * MAX_TRAILER_SIZE.
843 */
844 #if defined(MACH_KERNEL_PRIVATE) && defined(__arm64__)
845 typedef mach_msg_mac_trailer64_t mach_msg_max_trailer64_t;
846 typedef mach_msg_mac_trailer32_t mach_msg_max_trailer32_t;
847 #endif
848
849 typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t;
850 #define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t))
851
852 /*
853 * Legacy requirements keep us from ever updating these defines (even
854 * when the format_0 trailers gain new option data fields in the future).
855 * Therefore, they shouldn't be used going forward. Instead, the sizes
856 * should be compared against the specific element size requested using
857 * REQUESTED_TRAILER_SIZE.
858 */
859 typedef mach_msg_security_trailer_t mach_msg_format_0_trailer_t;
860
861 /*typedef mach_msg_mac_trailer_t mach_msg_format_0_trailer_t;
862 */
863
864 #define MACH_MSG_TRAILER_FORMAT_0_SIZE sizeof(mach_msg_format_0_trailer_t)
865
866 #define KERNEL_SECURITY_TOKEN_VALUE { {0, 1} }
867 extern const security_token_t KERNEL_SECURITY_TOKEN;
868
869 #define KERNEL_AUDIT_TOKEN_VALUE { {0, 0, 0, 0, 0, 0, 0, 0} }
870 extern const audit_token_t KERNEL_AUDIT_TOKEN;
871
872 typedef integer_t mach_msg_options_t;
873
874 #define MACH_MSG_HEADER_EMPTY (mach_msg_header_t){ }
875
876 typedef struct {
877 mach_msg_header_t header;
878 } mach_msg_empty_send_t;
879
880 typedef struct {
881 mach_msg_header_t header;
882 mach_msg_trailer_t trailer;
883 } mach_msg_empty_rcv_t;
884
885 typedef union{
886 mach_msg_empty_send_t send;
887 mach_msg_empty_rcv_t rcv;
888 } mach_msg_empty_t;
889
890 #pragma pack(pop)
891
892 /* utility to round the message size - will become machine dependent */
893 #define round_msg(x) (((mach_msg_size_t)(x) + sizeof (natural_t) - 1) & \
894 ~(sizeof (natural_t) - 1))
895
896 #ifdef XNU_KERNEL_PRIVATE
897
898 #include <os/base.h>
899 #include <os/overflow.h>
900 #include <kern/debug.h>
901
902 #define round_msg_overflow(in, out) __os_warn_unused(({ \
903 bool __ovr = os_add_overflow(in, (__typeof__(*out))(sizeof(natural_t) - 1), out); \
904 *out &= ~((__typeof__(*out))(sizeof(natural_t) - 1)); \
905 __ovr; \
906 }))
907
908 static inline mach_msg_size_t
mach_round_msg(mach_msg_size_t x)909 mach_round_msg(mach_msg_size_t x)
910 {
911 if (round_msg_overflow(x, &x)) {
912 panic("round msg overflow");
913 }
914 return x;
915 }
916 #endif /* XNU_KERNEL_PRIVATE */
917
918 /*
919 * There is no fixed upper bound to the size of Mach messages.
920 */
921 #define MACH_MSG_SIZE_MAX ((mach_msg_size_t) ~0)
922
923 #if defined(__APPLE_API_PRIVATE)
924 /*
925 * But architectural limits of a given implementation, or
926 * temporal conditions may cause unpredictable send failures
927 * for messages larger than MACH_MSG_SIZE_RELIABLE.
928 *
929 * In either case, waiting for memory is [currently] outside
930 * the scope of send timeout values provided to IPC.
931 */
932 #define MACH_MSG_SIZE_RELIABLE ((mach_msg_size_t) 256 * 1024)
933 #endif
934 /*
935 * Compatibility definitions, for code written
936 * when there was a msgh_kind instead of msgh_seqno.
937 */
938 #define MACH_MSGH_KIND_NORMAL 0x00000000
939 #define MACH_MSGH_KIND_NOTIFICATION 0x00000001
940 #define msgh_kind msgh_seqno
941 #define mach_msg_kind_t mach_port_seqno_t
942
943 typedef natural_t mach_msg_type_size_t;
944 typedef natural_t mach_msg_type_number_t;
945
946 /*
947 * Values received/carried in messages. Tells the receiver what
948 * sort of port right he now has.
949 *
950 * MACH_MSG_TYPE_PORT_NAME is used to transfer a port name
951 * which should remain uninterpreted by the kernel. (Port rights
952 * are not transferred, just the port name.)
953 */
954
955 #define MACH_MSG_TYPE_PORT_NONE 0
956
957 #define MACH_MSG_TYPE_PORT_NAME 15
958 #define MACH_MSG_TYPE_PORT_RECEIVE MACH_MSG_TYPE_MOVE_RECEIVE
959 #define MACH_MSG_TYPE_PORT_SEND MACH_MSG_TYPE_MOVE_SEND
960 #define MACH_MSG_TYPE_PORT_SEND_ONCE MACH_MSG_TYPE_MOVE_SEND_ONCE
961
962 #define MACH_MSG_TYPE_LAST 22 /* Last assigned */
963
964 /*
965 * A dummy value. Mostly used to indicate that the actual value
966 * will be filled in later, dynamically.
967 */
968
969 #define MACH_MSG_TYPE_POLYMORPHIC ((mach_msg_type_name_t) -1)
970
971 /*
972 * Is a given item a port type?
973 */
974
975 #define MACH_MSG_TYPE_PORT_ANY(x) \
976 (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \
977 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))
978
979 #define MACH_MSG_TYPE_PORT_ANY_SEND(x) \
980 (((x) >= MACH_MSG_TYPE_MOVE_SEND) && \
981 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))
982
983 #define MACH_MSG_TYPE_PORT_ANY_RIGHT(x) \
984 (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \
985 ((x) <= MACH_MSG_TYPE_MOVE_SEND_ONCE))
986
987 typedef integer_t mach_msg_option_t;
988
989 #define MACH_MSG_OPTION_NONE 0x00000000
990
991 #define MACH_SEND_MSG 0x00000001
992 #define MACH_RCV_MSG 0x00000002
993
994 #define MACH_RCV_LARGE 0x00000004 /* report large message sizes */
995 #define MACH_RCV_LARGE_IDENTITY 0x00000008 /* identify source of large messages */
996
997 #define MACH_SEND_TIMEOUT 0x00000010 /* timeout value applies to send */
998 #define MACH_SEND_OVERRIDE 0x00000020 /* priority override for send */
999 #define MACH_SEND_INTERRUPT 0x00000040 /* don't restart interrupted sends */
1000 #define MACH_SEND_NOTIFY 0x00000080 /* arm send-possible notify */
1001 #define MACH_SEND_ALWAYS 0x00010000 /* ignore qlimits - kernel only */
1002 #define MACH_SEND_FILTER_NONFATAL 0x00010000 /* rejection by message filter should return failure - user only */
1003 #define MACH_SEND_TRAILER 0x00020000 /* sender-provided trailer */
1004 #define MACH_SEND_NOIMPORTANCE 0x00040000 /* msg won't carry importance */
1005 #define MACH_SEND_NODENAP MACH_SEND_NOIMPORTANCE
1006 #define MACH_SEND_IMPORTANCE 0x00080000 /* msg carries importance - kernel only */
1007 #define MACH_SEND_SYNC_OVERRIDE 0x00100000 /* msg should do sync IPC override (on legacy kernels) */
1008 #define MACH_SEND_PROPAGATE_QOS 0x00200000 /* IPC should propagate the caller's QoS */
1009 #define MACH_SEND_SYNC_USE_THRPRI MACH_SEND_PROPAGATE_QOS /* obsolete name */
1010 #define MACH_SEND_KERNEL 0x00400000 /* full send from kernel space - kernel only */
1011 #define MACH_SEND_SYNC_BOOTSTRAP_CHECKIN 0x00800000 /* special reply port should boost thread doing sync bootstrap checkin */
1012
1013 #define MACH_RCV_TIMEOUT 0x00000100 /* timeout value applies to receive */
1014 #define MACH_RCV_NOTIFY 0x00000000 /* legacy name (value was: 0x00000200) */
1015 #define MACH_RCV_INTERRUPT 0x00000400 /* don't restart interrupted receive */
1016 #define MACH_RCV_VOUCHER 0x00000800 /* willing to receive voucher port */
1017 #define MACH_RCV_OVERWRITE 0x00000000 /* scatter receive (deprecated) */
1018 #define MACH_RCV_GUARDED_DESC 0x00001000 /* Can receive new guarded descriptor */
1019 #define MACH_RCV_SYNC_WAIT 0x00004000 /* sync waiter waiting for rcv */
1020 #define MACH_RCV_SYNC_PEEK 0x00008000 /* sync waiter waiting to peek */
1021
1022 #define MACH_MSG_STRICT_REPLY 0x00000200 /* Enforce specific properties about the reply port, and
1023 * the context in which a thread replies to a message.
1024 * This flag must be passed on both the SEND and RCV */
1025
1026 #if PRIVATE
1027
1028 __options_decl(mach_msg_option64_t, uint64_t, {
1029 MACH64_MSG_OPTION_NONE = 0x0ull,
1030 /* share lower 32 bits with mach_msg_option_t */
1031 MACH64_SEND_MSG = MACH_SEND_MSG,
1032 MACH64_RCV_MSG = MACH_RCV_MSG,
1033
1034 MACH64_RCV_LARGE = MACH_RCV_LARGE,
1035 MACH64_RCV_LARGE_IDENTITY = MACH_RCV_LARGE_IDENTITY,
1036
1037 MACH64_SEND_TIMEOUT = MACH_SEND_TIMEOUT,
1038 MACH64_SEND_OVERRIDE = MACH_SEND_OVERRIDE,
1039 MACH64_SEND_INTERRUPT = MACH_SEND_INTERRUPT,
1040 MACH64_SEND_NOTIFY = MACH_SEND_NOTIFY,
1041 #if KERNEL
1042 MACH64_SEND_ALWAYS = MACH_SEND_ALWAYS,
1043 MACH64_SEND_IMPORTANCE = MACH_SEND_IMPORTANCE,
1044 MACH64_SEND_KERNEL = MACH_SEND_KERNEL,
1045 #endif
1046 MACH64_SEND_FILTER_NONFATAL = MACH_SEND_FILTER_NONFATAL,
1047 MACH64_SEND_TRAILER = MACH_SEND_TRAILER,
1048 MACH64_SEND_NOIMPORTANCE = MACH_SEND_NOIMPORTANCE,
1049 MACH64_SEND_NODENAP = MACH_SEND_NODENAP,
1050 MACH64_SEND_SYNC_OVERRIDE = MACH_SEND_SYNC_OVERRIDE,
1051 MACH64_SEND_PROPAGATE_QOS = MACH_SEND_PROPAGATE_QOS,
1052
1053 MACH64_SEND_SYNC_BOOTSTRAP_CHECKIN = MACH_SEND_SYNC_BOOTSTRAP_CHECKIN,
1054
1055 MACH64_RCV_TIMEOUT = MACH_RCV_TIMEOUT,
1056
1057 MACH64_RCV_INTERRUPT = MACH_RCV_INTERRUPT,
1058 MACH64_RCV_VOUCHER = MACH_RCV_VOUCHER,
1059
1060 MACH64_RCV_GUARDED_DESC = MACH_RCV_GUARDED_DESC,
1061 MACH64_RCV_SYNC_WAIT = MACH_RCV_SYNC_WAIT,
1062 MACH64_RCV_SYNC_PEEK = MACH_RCV_SYNC_PEEK,
1063
1064 MACH64_MSG_STRICT_REPLY = MACH_MSG_STRICT_REPLY,
1065 /* following options are 64 only */
1066
1067 /* Send and receive message as vectors */
1068 MACH64_MSG_VECTOR = 0x0000000100000000ull,
1069 /* The message is a kobject call */
1070 MACH64_SEND_KOBJECT_CALL = 0x0000000200000000ull,
1071 /* The message is sent to a message queue */
1072 MACH64_SEND_MQ_CALL = 0x0000000400000000ull,
1073 /* This message destination is unknown. Used by old simulators only. */
1074 MACH64_SEND_ANY = 0x0000000800000000ull,
1075 /* This message is a DriverKit call */
1076 MACH64_SEND_DK_CALL = 0x0000001000000000ull,
1077
1078 #ifdef XNU_KERNEL_PRIVATE
1079 /*
1080 * Policy for the mach_msg2_trap() call
1081 */
1082 MACH64_POLICY_KERNEL_EXTENSION = 0x0002000000000000ull,
1083 MACH64_POLICY_FILTER_NON_FATAL = 0x0004000000000000ull,
1084 MACH64_POLICY_FILTER_MSG = 0x0008000000000000ull,
1085 MACH64_POLICY_DEFAULT = 0x0010000000000000ull,
1086 #if XNU_TARGET_OS_OSX
1087 MACH64_POLICY_SIMULATED = 0x0020000000000000ull,
1088 #else
1089 MACH64_POLICY_SIMULATED = 0x0000000000000000ull,
1090 #endif
1091 #if CONFIG_ROSETTA
1092 MACH64_POLICY_TRANSLATED = 0x0040000000000000ull,
1093 #else
1094 MACH64_POLICY_TRANSLATED = 0x0000000000000000ull,
1095 #endif
1096 MACH64_POLICY_HARDENED = 0x0080000000000000ull,
1097 MACH64_POLICY_RIGID = 0x0100000000000000ull,
1098 MACH64_POLICY_PLATFORM = 0x0200000000000000ull,
1099 MACH64_POLICY_KERNEL = MACH64_SEND_KERNEL,
1100
1101 /* one of these bits must be set to have a valid policy */
1102 MACH64_POLICY_NEEDED_MASK = (
1103 MACH64_POLICY_SIMULATED |
1104 MACH64_POLICY_TRANSLATED |
1105 MACH64_POLICY_DEFAULT |
1106 MACH64_POLICY_HARDENED |
1107 MACH64_POLICY_RIGID |
1108 MACH64_POLICY_PLATFORM |
1109 MACH64_POLICY_KERNEL),
1110
1111 /* extra policy modifiers */
1112 MACH64_POLICY_MASK = (
1113 MACH64_POLICY_KERNEL_EXTENSION |
1114 MACH64_POLICY_FILTER_NON_FATAL |
1115 MACH64_POLICY_FILTER_MSG |
1116 MACH64_POLICY_NEEDED_MASK),
1117
1118 /*
1119 * If kmsg has auxiliary data, append it immediate after the message
1120 * and trailer.
1121 *
1122 * Must be used in conjunction with MACH64_MSG_VECTOR,
1123 * only used by kevent() from the kernel.
1124 */
1125 MACH64_RCV_LINEAR_VECTOR = 0x1000000000000000ull,
1126 /* Receive into highest addr of buffer */
1127 MACH64_RCV_STACK = 0x2000000000000000ull,
1128 #if MACH_FLIPC
1129 /*
1130 * This internal-only flag is intended for use by a single thread per-port/set!
1131 * If more than one thread attempts to MACH64_PEEK_MSG on a port or set, one of
1132 * the threads may miss messages (in fact, it may never wake up).
1133 */
1134 MACH64_PEEK_MSG = 0x4000000000000000ull,
1135 #endif /* MACH_FLIPC */
1136 /*
1137 * This is a mach_msg2() send/receive operation.
1138 */
1139 MACH64_MACH_MSG2 = 0x8000000000000000ull
1140 #endif
1141 });
1142
1143 /* old spelling */
1144 #define MACH64_SEND_USER_CALL MACH64_SEND_MQ_CALL
1145 #endif /* PRIVATE */
1146
1147 /*
1148 * NOTE: a 0x00------ RCV mask implies to ask for
1149 * a MACH_MSG_TRAILER_FORMAT_0 with 0 Elements,
1150 * which is equivalent to a mach_msg_trailer_t.
1151 *
1152 * XXXMAC: unlike the rest of the MACH_RCV_* flags, MACH_RCV_TRAILER_LABELS
1153 * needs its own private bit since we only calculate its fields when absolutely
1154 * required.
1155 */
1156 #define MACH_RCV_TRAILER_NULL 0
1157 #define MACH_RCV_TRAILER_SEQNO 1
1158 #define MACH_RCV_TRAILER_SENDER 2
1159 #define MACH_RCV_TRAILER_AUDIT 3
1160 #define MACH_RCV_TRAILER_CTX 4
1161 #define MACH_RCV_TRAILER_AV 7
1162 #define MACH_RCV_TRAILER_LABELS 8
1163
1164 #define MACH_RCV_TRAILER_TYPE(x) (((x) & 0xf) << 28)
1165 #define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24)
1166 #define MACH_RCV_TRAILER_MASK ((0xf << 24))
1167
1168 #define GET_RCV_ELEMENTS(y) (((y) >> 24) & 0xf)
1169
1170 #ifdef MACH_KERNEL_PRIVATE
1171 /*
1172 * The options that the kernel honors when passed from user space, not including
1173 * user-only options that alias kernel-only options.
1174 */
1175 #define MACH_SEND_USER (MACH_SEND_MSG | MACH_SEND_TIMEOUT | \
1176 MACH_SEND_NOTIFY | MACH_SEND_OVERRIDE | \
1177 MACH_SEND_TRAILER | MACH_SEND_NOIMPORTANCE | \
1178 MACH_SEND_SYNC_OVERRIDE | MACH_SEND_PROPAGATE_QOS | \
1179 MACH_SEND_FILTER_NONFATAL | \
1180 MACH_SEND_SYNC_BOOTSTRAP_CHECKIN | \
1181 MACH_MSG_STRICT_REPLY | MACH_RCV_GUARDED_DESC)
1182
1183 #define MACH_RCV_USER (MACH_RCV_MSG | MACH_RCV_TIMEOUT | \
1184 MACH_RCV_LARGE | MACH_RCV_LARGE_IDENTITY | \
1185 MACH_RCV_VOUCHER | MACH_RCV_TRAILER_MASK | \
1186 MACH_RCV_SYNC_WAIT | MACH_RCV_SYNC_PEEK | \
1187 MACH_RCV_GUARDED_DESC | MACH_MSG_STRICT_REPLY)
1188
1189 #define MACH64_MSG_OPTION_CFI_MASK (MACH64_SEND_KOBJECT_CALL | MACH64_SEND_MQ_CALL | \
1190 MACH64_SEND_ANY | MACH64_SEND_DK_CALL)
1191
1192 #define MACH64_RCV_USER (MACH_RCV_USER | MACH64_MSG_VECTOR)
1193
1194 #define MACH_MSG_OPTION_USER (MACH_SEND_USER | MACH_RCV_USER)
1195
1196 #define MACH64_MSG_OPTION_USER (MACH64_SEND_USER | MACH64_RCV_USER)
1197
1198 #define MACH64_SEND_USER (MACH_SEND_USER | MACH64_MSG_VECTOR | \
1199 MACH64_MSG_OPTION_CFI_MASK)
1200
1201 /* The options implemented by the library interface to mach_msg et. al. */
1202 #define MACH_MSG_OPTION_LIB (MACH_SEND_INTERRUPT | MACH_RCV_INTERRUPT)
1203
1204 #define MACH_SEND_WITH_STRICT_REPLY(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | MACH_SEND_MSG)) == \
1205 (MACH_MSG_STRICT_REPLY | MACH_SEND_MSG))
1206
1207 #define MACH_SEND_REPLY_IS_IMMOVABLE(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | \
1208 MACH_SEND_MSG | MACH_RCV_MSG | \
1209 MACH_RCV_GUARDED_DESC)) == \
1210 (MACH_MSG_STRICT_REPLY | MACH_SEND_MSG | MACH_RCV_GUARDED_DESC))
1211
1212 #define MACH_RCV_WITH_STRICT_REPLY(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | MACH_RCV_MSG)) == \
1213 (MACH_MSG_STRICT_REPLY | MACH_RCV_MSG))
1214
1215 #define MACH_RCV_WITH_IMMOVABLE_REPLY(_opts) (((_opts) & (MACH_MSG_STRICT_REPLY | \
1216 MACH_RCV_MSG | MACH_RCV_GUARDED_DESC)) == \
1217 (MACH_MSG_STRICT_REPLY | MACH_RCV_MSG | MACH_RCV_GUARDED_DESC))
1218
1219 #endif /* MACH_KERNEL_PRIVATE */
1220 #ifdef XNU_KERNEL_PRIVATE
1221
1222 /*
1223 * Default options to use when sending from the kernel.
1224 *
1225 * Until we are sure of its effects, we are disabling
1226 * importance donation from the kernel-side of user
1227 * threads in importance-donating tasks.
1228 * (11938665 & 23925818)
1229 */
1230 #define MACH_SEND_KERNEL_DEFAULT \
1231 (mach_msg_option64_t)(MACH_SEND_MSG | MACH_SEND_ALWAYS | MACH_SEND_NOIMPORTANCE)
1232
1233 #define MACH_SEND_KERNEL_IMPORTANCE \
1234 (mach_msg_option64_t)(MACH_SEND_MSG | MACH_SEND_ALWAYS | MACH_SEND_IMPORTANCE)
1235
1236 #endif /* XNU_KERNEL_PRIVATE */
1237
1238 /*
1239 * XXXMAC: note that in the case of MACH_RCV_TRAILER_LABELS,
1240 * we just fall through to mach_msg_max_trailer_t.
1241 * This is correct behavior since mach_msg_max_trailer_t is defined as
1242 * mac_msg_mac_trailer_t which is used for the LABELS trailer.
1243 * It also makes things work properly if MACH_RCV_TRAILER_LABELS is ORed
1244 * with one of the other options.
1245 */
1246
1247 #define REQUESTED_TRAILER_SIZE_NATIVE(y) \
1248 ((mach_msg_trailer_size_t) \
1249 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ? \
1250 sizeof(mach_msg_trailer_t) : \
1251 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ? \
1252 sizeof(mach_msg_seqno_trailer_t) : \
1253 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ? \
1254 sizeof(mach_msg_security_trailer_t) : \
1255 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ? \
1256 sizeof(mach_msg_audit_trailer_t) : \
1257 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ? \
1258 sizeof(mach_msg_context_trailer_t) : \
1259 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ? \
1260 sizeof(mach_msg_mac_trailer_t) : \
1261 sizeof(mach_msg_max_trailer_t))))))))
1262
1263
1264 #ifdef XNU_KERNEL_PRIVATE
1265
1266 #if defined(__arm64__)
1267 #define REQUESTED_TRAILER_SIZE(is64, y) \
1268 ((mach_msg_trailer_size_t) \
1269 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ? \
1270 sizeof(mach_msg_trailer_t) : \
1271 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ? \
1272 sizeof(mach_msg_seqno_trailer_t) : \
1273 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ? \
1274 sizeof(mach_msg_security_trailer_t) : \
1275 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ? \
1276 sizeof(mach_msg_audit_trailer_t) : \
1277 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ? \
1278 ((is64) ? sizeof(mach_msg_context_trailer64_t) : sizeof(mach_msg_context_trailer32_t)) : \
1279 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ? \
1280 ((is64) ? sizeof(mach_msg_mac_trailer64_t) : sizeof(mach_msg_mac_trailer32_t)) : \
1281 sizeof(mach_msg_max_trailer_t))))))))
1282 #else
1283 #define REQUESTED_TRAILER_SIZE(is64, y) REQUESTED_TRAILER_SIZE_NATIVE(y)
1284 #endif
1285
1286 #else /* XNU_KERNEL_PRIVATE */
1287 #define REQUESTED_TRAILER_SIZE(y) REQUESTED_TRAILER_SIZE_NATIVE(y)
1288 #endif /* XNU_KERNEL_PRIVATE */
1289
1290 /*
1291 * Much code assumes that mach_msg_return_t == kern_return_t.
1292 * This definition is useful for descriptive purposes.
1293 *
1294 * See <mach/error.h> for the format of error codes.
1295 * IPC errors are system 4. Send errors are subsystem 0;
1296 * receive errors are subsystem 1. The code field is always non-zero.
1297 * The high bits of the code field communicate extra information
1298 * for some error codes. MACH_MSG_MASK masks off these special bits.
1299 */
1300
1301 typedef kern_return_t mach_msg_return_t;
1302
1303 #define MACH_MSG_SUCCESS 0x00000000
1304
1305
1306 #define MACH_MSG_MASK 0x00003e00
1307 /* All special error code bits defined below. */
1308 #define MACH_MSG_IPC_SPACE 0x00002000
1309 /* No room in IPC name space for another capability name. */
1310 #define MACH_MSG_VM_SPACE 0x00001000
1311 /* No room in VM address space for out-of-line memory. */
1312 #define MACH_MSG_IPC_KERNEL 0x00000800
1313 /* Kernel resource shortage handling an IPC capability. */
1314 #define MACH_MSG_VM_KERNEL 0x00000400
1315 /* Kernel resource shortage handling out-of-line memory. */
1316
1317 #define MACH_SEND_IN_PROGRESS 0x10000001
1318 /* Thread is waiting to send. (Internal use only.) */
1319 #define MACH_SEND_INVALID_DATA 0x10000002
1320 /* Bogus in-line data. */
1321 #define MACH_SEND_INVALID_DEST 0x10000003
1322 /* Bogus destination port. */
1323 #define MACH_SEND_TIMED_OUT 0x10000004
1324 /* Message not sent before timeout expired. */
1325 #define MACH_SEND_INVALID_VOUCHER 0x10000005
1326 /* Bogus voucher port. */
1327 #define MACH_SEND_INTERRUPTED 0x10000007
1328 /* Software interrupt. */
1329 #define MACH_SEND_MSG_TOO_SMALL 0x10000008
1330 /* Data doesn't contain a complete message. */
1331 #define MACH_SEND_INVALID_REPLY 0x10000009
1332 /* Bogus reply port. */
1333 #define MACH_SEND_INVALID_RIGHT 0x1000000a
1334 /* Bogus port rights in the message body. */
1335 #define MACH_SEND_INVALID_NOTIFY 0x1000000b
1336 /* Bogus notify port argument. */
1337 #define MACH_SEND_INVALID_MEMORY 0x1000000c
1338 /* Invalid out-of-line memory pointer. */
1339 #define MACH_SEND_NO_BUFFER 0x1000000d
1340 /* No message buffer is available. */
1341 #define MACH_SEND_TOO_LARGE 0x1000000e
1342 /* Send is too large for port */
1343 #define MACH_SEND_INVALID_TYPE 0x1000000f
1344 /* Invalid msg-type specification. */
1345 #define MACH_SEND_INVALID_HEADER 0x10000010
1346 /* A field in the header had a bad value. */
1347 #define MACH_SEND_INVALID_TRAILER 0x10000011
1348 /* The trailer to be sent does not match kernel format. */
1349 #define MACH_SEND_INVALID_CONTEXT 0x10000012
1350 /* The sending thread context did not match the context on the dest port */
1351 #define MACH_SEND_INVALID_OPTIONS 0x10000013
1352 /* Send options are invalid. */
1353 #define MACH_SEND_INVALID_RT_OOL_SIZE 0x10000015
1354 /* compatibility: no longer a returned error */
1355 #define MACH_SEND_NO_GRANT_DEST 0x10000016
1356 /* The destination port doesn't accept ports in body */
1357 #define MACH_SEND_MSG_FILTERED 0x10000017
1358 /* Message send was rejected by message filter */
1359 #define MACH_SEND_AUX_TOO_SMALL 0x10000018
1360 /* Message auxiliary data is too small */
1361 #define MACH_SEND_AUX_TOO_LARGE 0x10000019
1362 /* Message auxiliary data is too large */
1363
1364 #define MACH_RCV_IN_PROGRESS 0x10004001
1365 /* Thread is waiting for receive. (Internal use only.) */
1366 #define MACH_RCV_INVALID_NAME 0x10004002
1367 /* Bogus name for receive port/port-set. */
1368 #define MACH_RCV_TIMED_OUT 0x10004003
1369 /* Didn't get a message within the timeout value. */
1370 #define MACH_RCV_TOO_LARGE 0x10004004
1371 /* Message buffer is not large enough for inline data. */
1372 #define MACH_RCV_INTERRUPTED 0x10004005
1373 /* Software interrupt. */
1374 #define MACH_RCV_PORT_CHANGED 0x10004006
1375 /* compatibility: no longer a returned error */
1376 #define MACH_RCV_INVALID_NOTIFY 0x10004007
1377 /* Bogus notify port argument. */
1378 #define MACH_RCV_INVALID_DATA 0x10004008
1379 /* Bogus message buffer for inline data. */
1380 #define MACH_RCV_PORT_DIED 0x10004009
1381 /* Port/set was sent away/died during receive. */
1382 #define MACH_RCV_IN_SET 0x1000400a
1383 /* compatibility: no longer a returned error */
1384 #define MACH_RCV_HEADER_ERROR 0x1000400b
1385 /* Error receiving message header. See special bits. */
1386 #define MACH_RCV_BODY_ERROR 0x1000400c
1387 /* Error receiving message body. See special bits. */
1388 #define MACH_RCV_INVALID_TYPE 0x1000400d
1389 /* Invalid msg-type specification in scatter list. */
1390 #define MACH_RCV_SCATTER_SMALL 0x1000400e
1391 /* Out-of-line overwrite region is not large enough */
1392 #define MACH_RCV_INVALID_TRAILER 0x1000400f
1393 /* trailer type or number of trailer elements not supported */
1394 #define MACH_RCV_IN_PROGRESS_TIMED 0x10004011
1395 /* Waiting for receive with timeout. (Internal use only.) */
1396 #define MACH_RCV_INVALID_REPLY 0x10004012
1397 /* invalid reply port used in a STRICT_REPLY message */
1398 #define MACH_RCV_INVALID_ARGUMENTS 0x10004013
1399 /* invalid receive arguments, receive has not started */
1400
1401 #ifdef XNU_KERNEL_PRIVATE
1402 #if MACH_FLIPC
1403 #define MACH_PEEK_IN_PROGRESS 0x10008001
1404 /* Waiting for a peek. (Internal use only.) */
1405 #define MACH_PEEK_READY 0x10008002
1406 /* Waiting for a peek. (Internal use only.) */
1407 #endif /* MACH_FLIPC */
1408 #endif
1409
1410
1411 __BEGIN_DECLS
1412
1413 /*
1414 * Routine: mach_msg_overwrite
1415 * Purpose:
1416 * Send and/or receive a message. If the message operation
1417 * is interrupted, and the user did not request an indication
1418 * of that fact, then restart the appropriate parts of the
1419 * operation silently (trap version does not restart).
1420 *
1421 * Distinct send and receive buffers may be specified. If
1422 * no separate receive buffer is specified, the msg parameter
1423 * will be used for both send and receive operations.
1424 *
1425 * In addition to a distinct receive buffer, that buffer may
1426 * already contain scatter control information to direct the
1427 * receiving of the message.
1428 */
1429 __WATCHOS_PROHIBITED __TVOS_PROHIBITED
1430 extern mach_msg_return_t mach_msg_overwrite(
1431 mach_msg_header_t *msg,
1432 mach_msg_option_t option,
1433 mach_msg_size_t send_size,
1434 mach_msg_size_t rcv_size,
1435 mach_port_name_t rcv_name,
1436 mach_msg_timeout_t timeout,
1437 mach_port_name_t notify,
1438 mach_msg_header_t *rcv_msg,
1439 mach_msg_size_t rcv_limit);
1440
1441 #ifndef KERNEL
1442
1443 /*
1444 * Routine: mach_msg
1445 * Purpose:
1446 * Send and/or receive a message. If the message operation
1447 * is interrupted, and the user did not request an indication
1448 * of that fact, then restart the appropriate parts of the
1449 * operation silently (trap version does not restart).
1450 */
1451 __WATCHOS_PROHIBITED __TVOS_PROHIBITED
1452 extern mach_msg_return_t mach_msg(
1453 mach_msg_header_t *msg,
1454 mach_msg_option_t option,
1455 mach_msg_size_t send_size,
1456 mach_msg_size_t rcv_size,
1457 mach_port_name_t rcv_name,
1458 mach_msg_timeout_t timeout,
1459 mach_port_name_t notify);
1460
1461 #if PRIVATE
1462 #if defined(__LP64__) || defined(__arm64__)
1463 __API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0))
1464 __IOS_PROHIBITED __WATCHOS_PROHIBITED __TVOS_PROHIBITED
1465 extern mach_msg_return_t mach_msg2_internal(
1466 void *data,
1467 mach_msg_option64_t option64,
1468 uint64_t msgh_bits_and_send_size,
1469 uint64_t msgh_remote_and_local_port,
1470 uint64_t msgh_voucher_and_id,
1471 uint64_t desc_count_and_rcv_name,
1472 uint64_t rcv_size_and_priority,
1473 uint64_t timeout);
1474
1475 __API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0))
1476 __IOS_PROHIBITED __WATCHOS_PROHIBITED __TVOS_PROHIBITED
1477 static inline mach_msg_return_t
mach_msg2(void * data,mach_msg_option64_t option64,mach_msg_header_t header,mach_msg_size_t send_size,mach_msg_size_t rcv_size,mach_port_t rcv_name,uint64_t timeout,uint32_t priority)1478 mach_msg2(
1479 void *data,
1480 mach_msg_option64_t option64,
1481 mach_msg_header_t header,
1482 mach_msg_size_t send_size,
1483 mach_msg_size_t rcv_size,
1484 mach_port_t rcv_name,
1485 uint64_t timeout,
1486 uint32_t priority)
1487 {
1488 mach_msg_base_t *base;
1489 mach_msg_size_t descriptors;
1490
1491 if (option64 & MACH64_MSG_VECTOR) {
1492 base = (mach_msg_base_t *)((mach_msg_vector_t *)data)->msgv_data;
1493 } else {
1494 base = (mach_msg_base_t *)data;
1495 }
1496
1497 if ((option64 & MACH64_SEND_MSG) &&
1498 (base->header.msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
1499 descriptors = base->body.msgh_descriptor_count;
1500 } else {
1501 descriptors = 0;
1502 }
1503
1504 #define MACH_MSG2_SHIFT_ARGS(lo, hi) ((uint64_t)hi << 32 | (uint32_t)lo)
1505 return mach_msg2_internal(data, option64,
1506 MACH_MSG2_SHIFT_ARGS(header.msgh_bits, send_size),
1507 MACH_MSG2_SHIFT_ARGS(header.msgh_remote_port, header.msgh_local_port),
1508 MACH_MSG2_SHIFT_ARGS(header.msgh_voucher_port, header.msgh_id),
1509 MACH_MSG2_SHIFT_ARGS(descriptors, rcv_name),
1510 MACH_MSG2_SHIFT_ARGS(rcv_size, priority), timeout);
1511 #undef MACH_MSG2_SHIFT_ARGS
1512 }
1513 #endif
1514 #endif /* PRIVATE */
1515
1516 /*
1517 * Routine: mach_voucher_deallocate
1518 * Purpose:
1519 * Deallocate a mach voucher created or received in a message. Drops
1520 * one (send right) reference to the voucher.
1521 */
1522 __WATCHOS_PROHIBITED __TVOS_PROHIBITED
1523 extern kern_return_t mach_voucher_deallocate(
1524 mach_port_name_t voucher);
1525
1526 #elif defined(MACH_KERNEL_PRIVATE)
1527
1528 /*!
1529 * @typedef mach_msg_send_uctx_t
1530 *
1531 * @brief
1532 * Data structure used for the send half of a @c mach_msg() call from userspace.
1533 *
1534 * @discussion
1535 * Callers must fill the @c send_header, @c send_dsc_count with the user header
1536 * being sent, as well as the parameters of user buffers used for send
1537 * (@c send_{msg,aux}_{addr,size}).
1538 *
1539 * @field send_header a copy of the user header being sent.
1540 * @field send_dsc_count the number of descriptors being sent.
1541 * must be 0 if the header doesn't have
1542 * the MACH_MSGH_BITS_COMPLEX bit set.
1543 * @field send_msg_addr the userspace address for the message being sent.
1544 * @field send_msg_size the size of the message being sent.
1545 * @field send_aux_addr the userspace address for the auxiliary data
1546 * being sent (will be 0 if not using a vector
1547 * operation)
1548 * @field send_aux_size the size for the auxiliary data being sent.
1549 *
1550 * @field send_dsc_mask internal field being used during right copyin
1551 * of descriptors.
1552 * @field send_dsc_usize the size (in bytes) of the user representation
1553 * of descriptors being sent.
1554 * @field send_dsc_port_count number of ports being sent in descriptors
1555 * (both in port or port array descriptors).
1556 * @field send_dsc_vm_size kernel wired memory (not counting port arrays)
1557 * needed to copyin this message.
1558 */
1559 typedef struct {
1560 /* send context/arguments */
1561 mach_msg_user_header_t send_header;
1562 mach_msg_size_t send_dsc_count;
1563
1564 mach_vm_address_t send_msg_addr;
1565 mach_vm_address_t send_aux_addr;
1566 mach_msg_size_t send_msg_size;
1567 mach_msg_size_t send_aux_size;
1568
1569 /* filled by copyin */
1570 uint64_t send_dsc_mask;
1571 mach_msg_size_t send_dsc_usize;
1572 mach_msg_size_t send_dsc_port_count;
1573 vm_size_t send_dsc_vm_size;
1574 } mach_msg_send_uctx_t;
1575
1576
1577 /*!
1578 * @typedef mach_msg_recv_bufs_t
1579 *
1580 * @brief
1581 * Data structure representing the buffers being used by userspace to receive
1582 * a message.
1583 *
1584 * @field recv_msg_addr the userspace address for the message
1585 * receive buffer.
1586 * @field recv_msg_size the size of the message receive buffer.
1587 *
1588 * @field recv_aux_addr the userspace address for the auxiliary data
1589 * receive buffer (will be 0 if not using a vector
1590 * operation)
1591 * @field recv_aux_size the size for the auxiliary data receive buffer.
1592 */
1593 typedef struct {
1594 mach_vm_address_t recv_msg_addr;
1595 mach_vm_address_t recv_aux_addr;
1596 mach_msg_size_t recv_msg_size;
1597 mach_msg_size_t recv_aux_size;
1598 } mach_msg_recv_bufs_t;
1599
1600
1601 /*!
1602 * @typedef mach_msg_recv_result_t
1603 *
1604 * @brief
1605 * Data structure representing the results of a receive operation,
1606 * in the context of the user task receiving that message.
1607 *
1608 * @field msgr_msg_size the user size of the message being copied out
1609 * (not including trailer or auxiliary data).
1610 * set for MACH_RCV_TOO_LARGE or MACH_MSG_SUCCESS,
1611 * 0 otherwise.
1612 *
1613 * @field msgr_trailer_size the trailer size of the message being copied out.
1614 * set MACH_MSG_SUCCESS, 0 otherwise.
1615 *
1616 * @field msgr_aux_size the auxiliary data size of the message being
1617 * copied out.
1618 * set for MACH_RCV_TOO_LARGE or MACH_MSG_SUCCESS,
1619 * 0 otherwise.
1620 *
1621 * @field msgr_recv_name the name of the port receiving the message.
1622 * Set for MACH_RCV_TOO_LARGE,
1623 * or to MSGR_PSEUDO_RECEIVE for pseudo-receive.
1624 *
1625 * @field msgr_seqno the sequence number for the message being
1626 * received.
1627 *
1628 * @field msgr_context the mach port context fort the port receiving
1629 * the message.
1630 *
1631 * @field msgr_priority the pthread priority of the message being
1632 * received.
1633 *
1634 * @field msgr_qos_ovrd the qos override for the message being received.
1635 */
1636 typedef struct {
1637 /* general info about the message being copied out */
1638 mach_msg_size_t msgr_msg_size;
1639 mach_msg_size_t msgr_trailer_size;
1640 mach_msg_size_t msgr_aux_size;
1641 #define MSGR_PSEUDO_RECEIVE (0xfffffffe)
1642 mach_port_name_t msgr_recv_name;
1643 mach_port_seqno_t msgr_seqno;
1644 mach_port_context_t msgr_context;
1645
1646 /* metadata for the sake of kevent only */
1647 uint32_t msgr_priority;
1648 mach_msg_qos_t msgr_qos_ovrd;
1649 } mach_msg_recv_result_t;
1650
1651 extern mach_msg_return_t mach_msg_receive_results(
1652 mach_msg_recv_result_t *msg); /* out only, can be NULL */
1653
1654 #endif /* KERNEL */
1655
1656 __END_DECLS
1657
1658 #endif /* _MACH_MESSAGE_H_ */
1659