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