xref: /xnu-10063.141.1/osfmk/mach/message.h (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
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