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