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