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