zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

message.h (36112B) - Raw


      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  Software.Distribution@CS.CMU.EDU
     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 __has_feature(ptrauth_calls)
     87 #include <ptrauth.h>
     88 #endif
     89 
     90 /*
     91  *  The timeout mechanism uses mach_msg_timeout_t values,
     92  *  passed by value.  The timeout units are milliseconds.
     93  *  It is controlled with the MACH_SEND_TIMEOUT
     94  *  and MACH_RCV_TIMEOUT options.
     95  */
     96 
     97 typedef natural_t mach_msg_timeout_t;
     98 
     99 /*
    100  *  The value to be used when there is no timeout.
    101  *  (No MACH_SEND_TIMEOUT/MACH_RCV_TIMEOUT option.)
    102  */
    103 
    104 #define MACH_MSG_TIMEOUT_NONE           ((mach_msg_timeout_t) 0)
    105 
    106 /*
    107  *  The kernel uses MACH_MSGH_BITS_COMPLEX as a hint.  If it isn't on, it
    108  *  assumes the body of the message doesn't contain port rights or OOL
    109  *  data.  The field is set in received messages.  A user task must
    110  *  use caution in interpreting the body of a message if the bit isn't
    111  *  on, because the mach_msg_type's in the body might "lie" about the
    112  *  contents.  If the bit isn't on, but the mach_msg_types
    113  *  in the body specify rights or OOL data, the behavior is undefined.
    114  *  (Ie, an error may or may not be produced.)
    115  *
    116  *  The value of MACH_MSGH_BITS_REMOTE determines the interpretation
    117  *  of the msgh_remote_port field.  It is handled like a msgt_name,
    118  *  but must result in a send or send-once type right.
    119  *
    120  *  The value of MACH_MSGH_BITS_LOCAL determines the interpretation
    121  *  of the msgh_local_port field.  It is handled like a msgt_name,
    122  *  and also must result in a send or send-once type right.
    123  *
    124  *  The value of MACH_MSGH_BITS_VOUCHER determines the interpretation
    125  *  of the msgh_voucher_port field.  It is handled like a msgt_name,
    126  *  but must result in a send right (and the msgh_voucher_port field
    127  *  must be the name of a send right to a Mach voucher kernel object.
    128  *
    129  *  MACH_MSGH_BITS() combines two MACH_MSG_TYPE_* values, for the remote
    130  *  and local fields, into a single value suitable for msgh_bits.
    131  *
    132  *  MACH_MSGH_BITS_CIRCULAR should be zero; is is used internally.
    133  *
    134  *  The unused bits should be zero and are reserved for the kernel
    135  *  or for future interface expansion.
    136  */
    137 
    138 #define MACH_MSGH_BITS_ZERO             0x00000000
    139 
    140 #define MACH_MSGH_BITS_REMOTE_MASK      0x0000001f
    141 #define MACH_MSGH_BITS_LOCAL_MASK       0x00001f00
    142 #define MACH_MSGH_BITS_VOUCHER_MASK     0x001f0000
    143 
    144 #define MACH_MSGH_BITS_PORTS_MASK               \
    145 	        (MACH_MSGH_BITS_REMOTE_MASK |   \
    146 	         MACH_MSGH_BITS_LOCAL_MASK |    \
    147 	         MACH_MSGH_BITS_VOUCHER_MASK)
    148 
    149 #define MACH_MSGH_BITS_COMPLEX          0x80000000U     /* message is complex */
    150 
    151 #define MACH_MSGH_BITS_USER             0x801f1f1fU     /* allowed bits user->kernel */
    152 
    153 #define MACH_MSGH_BITS_RAISEIMP         0x20000000U     /* importance raised due to msg */
    154 #define MACH_MSGH_BITS_DENAP            MACH_MSGH_BITS_RAISEIMP
    155 
    156 #define MACH_MSGH_BITS_IMPHOLDASRT      0x10000000U     /* assertion help, userland private */
    157 #define MACH_MSGH_BITS_DENAPHOLDASRT    MACH_MSGH_BITS_IMPHOLDASRT
    158 
    159 #define MACH_MSGH_BITS_CIRCULAR         0x10000000U     /* message circular, kernel private */
    160 
    161 #define MACH_MSGH_BITS_USED             0xb01f1f1fU
    162 
    163 /* setter macros for the bits */
    164 #define MACH_MSGH_BITS(remote, local)  /* legacy */             \
    165 	        ((remote) | ((local) << 8))
    166 #define MACH_MSGH_BITS_SET_PORTS(remote, local, voucher)        \
    167 	(((remote) & MACH_MSGH_BITS_REMOTE_MASK) |              \
    168 	 (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) |         \
    169 	 (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK))
    170 #define MACH_MSGH_BITS_SET(remote, local, voucher, other)       \
    171 	(MACH_MSGH_BITS_SET_PORTS((remote), (local), (voucher)) \
    172 	 | ((other) &~ MACH_MSGH_BITS_PORTS_MASK))
    173 
    174 /* getter macros for pulling values out of the bits field */
    175 #define MACH_MSGH_BITS_REMOTE(bits)                             \
    176 	        ((bits) & MACH_MSGH_BITS_REMOTE_MASK)
    177 #define MACH_MSGH_BITS_LOCAL(bits)                              \
    178 	        (((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8)
    179 #define MACH_MSGH_BITS_VOUCHER(bits)                            \
    180 	        (((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16)
    181 #define MACH_MSGH_BITS_PORTS(bits)                              \
    182 	((bits) & MACH_MSGH_BITS_PORTS_MASK)
    183 #define MACH_MSGH_BITS_OTHER(bits)                              \
    184 	        ((bits) &~ MACH_MSGH_BITS_PORTS_MASK)
    185 
    186 /* checking macros */
    187 #define MACH_MSGH_BITS_HAS_REMOTE(bits)                         \
    188 	(MACH_MSGH_BITS_REMOTE(bits) != MACH_MSGH_BITS_ZERO)
    189 #define MACH_MSGH_BITS_HAS_LOCAL(bits)                          \
    190 	(MACH_MSGH_BITS_LOCAL(bits) != MACH_MSGH_BITS_ZERO)
    191 #define MACH_MSGH_BITS_HAS_VOUCHER(bits)                        \
    192 	(MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO)
    193 #define MACH_MSGH_BITS_IS_COMPLEX(bits)                         \
    194 	(((bits) & MACH_MSGH_BITS_COMPLEX) != MACH_MSGH_BITS_ZERO)
    195 
    196 /* importance checking macros */
    197 #define MACH_MSGH_BITS_RAISED_IMPORTANCE(bits)                  \
    198 	(((bits) & MACH_MSGH_BITS_RAISEIMP) != MACH_MSGH_BITS_ZERO)
    199 #define MACH_MSGH_BITS_HOLDS_IMPORTANCE_ASSERTION(bits)         \
    200 	(((bits) & MACH_MSGH_BITS_IMPHOLDASRT) != MACH_MSGH_BITS_ZERO)
    201 
    202 /*
    203  *  Every message starts with a message header.
    204  *  Following the message header, if the message is complex, are a count
    205  *  of type descriptors and the type descriptors themselves
    206  *  (mach_msg_descriptor_t). The size of the message must be specified in
    207  *  bytes, and includes the message header, descriptor count, descriptors,
    208  *  and inline data.
    209  *
    210  *  The msgh_remote_port field specifies the destination of the message.
    211  *  It must specify a valid send or send-once right for a port.
    212  *
    213  *  The msgh_local_port field specifies a "reply port".  Normally,
    214  *  This field carries a send-once right that the receiver will use
    215  *  to reply to the message.  It may carry the values MACH_PORT_NULL,
    216  *  MACH_PORT_DEAD, a send-once right, or a send right.
    217  *
    218  *  The msgh_voucher_port field specifies a Mach voucher port. Only
    219  *  send rights to kernel-implemented Mach Voucher kernel objects in
    220  *  addition to MACH_PORT_NULL or MACH_PORT_DEAD may be passed.
    221  *
    222  *  The msgh_id field is uninterpreted by the message primitives.
    223  *  It normally carries information specifying the format
    224  *  or meaning of the message.
    225  */
    226 
    227 typedef unsigned int mach_msg_bits_t;
    228 typedef natural_t mach_msg_size_t;
    229 typedef integer_t mach_msg_id_t;
    230 
    231 #define MACH_MSG_SIZE_NULL (mach_msg_size_t *) 0
    232 
    233 typedef unsigned int mach_msg_priority_t;
    234 
    235 #define MACH_MSG_PRIORITY_UNSPECIFIED (mach_msg_priority_t) 0
    236 
    237 
    238 typedef unsigned int mach_msg_type_name_t;
    239 
    240 #define MACH_MSG_TYPE_MOVE_RECEIVE      16      /* Must hold receive right */
    241 #define MACH_MSG_TYPE_MOVE_SEND         17      /* Must hold send right(s) */
    242 #define MACH_MSG_TYPE_MOVE_SEND_ONCE    18      /* Must hold sendonce right */
    243 #define MACH_MSG_TYPE_COPY_SEND         19      /* Must hold send right(s) */
    244 #define MACH_MSG_TYPE_MAKE_SEND         20      /* Must hold receive right */
    245 #define MACH_MSG_TYPE_MAKE_SEND_ONCE    21      /* Must hold receive right */
    246 #define MACH_MSG_TYPE_COPY_RECEIVE      22      /* NOT VALID */
    247 #define MACH_MSG_TYPE_DISPOSE_RECEIVE   24      /* must hold receive right */
    248 #define MACH_MSG_TYPE_DISPOSE_SEND      25      /* must hold send right(s) */
    249 #define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26      /* must hold sendonce right */
    250 
    251 typedef unsigned int mach_msg_copy_options_t;
    252 
    253 #define MACH_MSG_PHYSICAL_COPY          0
    254 #define MACH_MSG_VIRTUAL_COPY           1
    255 #define MACH_MSG_ALLOCATE               2
    256 #define MACH_MSG_OVERWRITE              3       /* deprecated */
    257 #ifdef  MACH_KERNEL
    258 #define MACH_MSG_KALLOC_COPY_T          4
    259 #endif  /* MACH_KERNEL */
    260 
    261 #define MACH_MSG_GUARD_FLAGS_NONE                   0x0000
    262 #define MACH_MSG_GUARD_FLAGS_IMMOVABLE_RECEIVE      0x0001    /* Move the receive right and mark it as immovable */
    263 #define MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND      0x0002    /* Verify that the port is unguarded */
    264 #define MACH_MSG_GUARD_FLAGS_MASK                   0x0003    /* Valid flag bits */
    265 typedef unsigned int mach_msg_guard_flags_t;
    266 
    267 /*
    268  * In a complex mach message, the mach_msg_header_t is followed by
    269  * a descriptor count, then an array of that number of descriptors
    270  * (mach_msg_*_descriptor_t). The type field of mach_msg_type_descriptor_t
    271  * (which any descriptor can be cast to) indicates the flavor of the
    272  * descriptor.
    273  *
    274  * Note that in LP64, the various types of descriptors are no longer all
    275  * the same size as mach_msg_descriptor_t, so the array cannot be indexed
    276  * as expected.
    277  */
    278 
    279 typedef unsigned int mach_msg_descriptor_type_t;
    280 
    281 #define MACH_MSG_PORT_DESCRIPTOR                0
    282 #define MACH_MSG_OOL_DESCRIPTOR                 1
    283 #define MACH_MSG_OOL_PORTS_DESCRIPTOR           2
    284 #define MACH_MSG_OOL_VOLATILE_DESCRIPTOR        3
    285 #define MACH_MSG_GUARDED_PORT_DESCRIPTOR        4
    286 
    287 #define MACH_MSG_DESCRIPTOR_MAX MACH_MSG_GUARDED_PORT_DESCRIPTOR
    288 
    289 #define __ipc_desc_sign(d)
    290 
    291 #pragma pack(push, 4)
    292 
    293 typedef struct {
    294 	natural_t                     pad1;
    295 	mach_msg_size_t               pad2;
    296 	unsigned int                  pad3 : 24;
    297 	mach_msg_descriptor_type_t    type : 8;
    298 } mach_msg_type_descriptor_t;
    299 
    300 typedef struct {
    301 	mach_port_t                   name;
    302 	mach_msg_size_t               pad1;
    303 	unsigned int                  pad2 : 16;
    304 	mach_msg_type_name_t          disposition : 8;
    305 	mach_msg_descriptor_type_t    type : 8;
    306 } mach_msg_port_descriptor_t;
    307 
    308 
    309 typedef struct {
    310 	uint32_t                      address;
    311 	mach_msg_size_t               size;
    312 	boolean_t                     deallocate: 8;
    313 	mach_msg_copy_options_t       copy: 8;
    314 	unsigned int                  pad1: 8;
    315 	mach_msg_descriptor_type_t    type: 8;
    316 } mach_msg_ool_descriptor32_t;
    317 
    318 typedef struct {
    319 	uint64_t                      address;
    320 	boolean_t                     deallocate: 8;
    321 	mach_msg_copy_options_t       copy: 8;
    322 	unsigned int                  pad1: 8;
    323 	mach_msg_descriptor_type_t    type: 8;
    324 	mach_msg_size_t               size;
    325 } mach_msg_ool_descriptor64_t;
    326 
    327 typedef struct {
    328 	void                         *address;
    329 #if !defined(__LP64__)
    330 	mach_msg_size_t               size;
    331 #endif
    332 	boolean_t                     deallocate: 8;
    333 	mach_msg_copy_options_t       copy: 8;
    334 	unsigned int                  pad1: 8;
    335 	mach_msg_descriptor_type_t    type: 8;
    336 #if defined(__LP64__)
    337 	mach_msg_size_t               size;
    338 #endif
    339 } mach_msg_ool_descriptor_t;
    340 
    341 typedef struct {
    342 	uint32_t                      address;
    343 	mach_msg_size_t               count;
    344 	boolean_t                     deallocate: 8;
    345 	mach_msg_copy_options_t       copy: 8;
    346 	mach_msg_type_name_t          disposition : 8;
    347 	mach_msg_descriptor_type_t    type : 8;
    348 } mach_msg_ool_ports_descriptor32_t;
    349 
    350 typedef struct {
    351 	uint64_t                      address;
    352 	boolean_t                     deallocate: 8;
    353 	mach_msg_copy_options_t       copy: 8;
    354 	mach_msg_type_name_t          disposition : 8;
    355 	mach_msg_descriptor_type_t    type : 8;
    356 	mach_msg_size_t               count;
    357 } mach_msg_ool_ports_descriptor64_t;
    358 
    359 typedef struct {
    360 	void                         *address;
    361 #if !defined(__LP64__)
    362 	mach_msg_size_t               count;
    363 #endif
    364 	boolean_t                     deallocate: 8;
    365 	mach_msg_copy_options_t       copy: 8;
    366 	mach_msg_type_name_t          disposition : 8;
    367 	mach_msg_descriptor_type_t    type : 8;
    368 #if defined(__LP64__)
    369 	mach_msg_size_t               count;
    370 #endif
    371 } mach_msg_ool_ports_descriptor_t;
    372 
    373 typedef struct {
    374 	uint32_t                      context;
    375 	mach_port_name_t              name;
    376 	mach_msg_guard_flags_t        flags : 16;
    377 	mach_msg_type_name_t          disposition : 8;
    378 	mach_msg_descriptor_type_t    type : 8;
    379 } mach_msg_guarded_port_descriptor32_t;
    380 
    381 typedef struct {
    382 	uint64_t                      context;
    383 	mach_msg_guard_flags_t        flags : 16;
    384 	mach_msg_type_name_t          disposition : 8;
    385 	mach_msg_descriptor_type_t    type : 8;
    386 	mach_port_name_t              name;
    387 } mach_msg_guarded_port_descriptor64_t;
    388 
    389 typedef struct {
    390 	mach_port_context_t           context;
    391 #if !defined(__LP64__)
    392 	mach_port_name_t              name;
    393 #endif
    394 	mach_msg_guard_flags_t        flags : 16;
    395 	mach_msg_type_name_t          disposition : 8;
    396 	mach_msg_descriptor_type_t    type : 8;
    397 #if defined(__LP64__)
    398 	mach_port_name_t              name;
    399 #endif /* defined(__LP64__) */
    400 } mach_msg_guarded_port_descriptor_t;
    401 
    402 /*
    403  * LP64support - This union definition is not really
    404  * appropriate in LP64 mode because not all descriptors
    405  * are of the same size in that environment.
    406  */
    407 typedef union {
    408 	mach_msg_port_descriptor_t            port;
    409 	mach_msg_ool_descriptor_t             out_of_line;
    410 	mach_msg_ool_ports_descriptor_t       ool_ports;
    411 	mach_msg_type_descriptor_t            type;
    412 	mach_msg_guarded_port_descriptor_t    guarded_port;
    413 } mach_msg_descriptor_t;
    414 
    415 typedef struct {
    416 	mach_msg_size_t msgh_descriptor_count;
    417 } mach_msg_body_t;
    418 
    419 #define MACH_MSG_BODY_NULL            ((mach_msg_body_t *) 0)
    420 #define MACH_MSG_DESCRIPTOR_NULL      ((mach_msg_descriptor_t *) 0)
    421 
    422 typedef struct {
    423 	mach_msg_bits_t               msgh_bits;
    424 	mach_msg_size_t               msgh_size;
    425 	mach_port_t                   msgh_remote_port;
    426 	mach_port_t                   msgh_local_port;
    427 	mach_port_name_t              msgh_voucher_port;
    428 	mach_msg_id_t                 msgh_id;
    429 } mach_msg_header_t;
    430 
    431 
    432 #define msgh_reserved                 msgh_voucher_port
    433 #define MACH_MSG_NULL                 ((mach_msg_header_t *) 0)
    434 
    435 typedef struct {
    436 	mach_msg_header_t             header;
    437 	mach_msg_body_t               body;
    438 } mach_msg_base_t;
    439 
    440 
    441 typedef unsigned int mach_msg_trailer_type_t;
    442 
    443 #define MACH_MSG_TRAILER_FORMAT_0       0
    444 
    445 typedef unsigned int mach_msg_trailer_size_t;
    446 typedef char *mach_msg_trailer_info_t;
    447 
    448 typedef struct {
    449 	mach_msg_trailer_type_t       msgh_trailer_type;
    450 	mach_msg_trailer_size_t       msgh_trailer_size;
    451 } mach_msg_trailer_t;
    452 
    453 /*
    454  *  The msgh_seqno field carries a sequence number
    455  *  associated with the received-from port.  A port's
    456  *  sequence number is incremented every time a message
    457  *  is received from it and included in the received
    458  *  trailer to help put messages back in sequence if
    459  *  multiple threads receive and/or process received
    460  *  messages.
    461  */
    462 typedef struct {
    463 	mach_msg_trailer_type_t       msgh_trailer_type;
    464 	mach_msg_trailer_size_t       msgh_trailer_size;
    465 	mach_port_seqno_t             msgh_seqno;
    466 } mach_msg_seqno_trailer_t;
    467 
    468 typedef struct {
    469 	unsigned int                  val[2];
    470 } security_token_t;
    471 
    472 typedef struct {
    473 	mach_msg_trailer_type_t       msgh_trailer_type;
    474 	mach_msg_trailer_size_t       msgh_trailer_size;
    475 	mach_port_seqno_t             msgh_seqno;
    476 	security_token_t              msgh_sender;
    477 } mach_msg_security_trailer_t;
    478 
    479 /*
    480  * The audit token is an opaque token which identifies
    481  * Mach tasks and senders of Mach messages as subjects
    482  * to the BSM audit system.  Only the appropriate BSM
    483  * library routines should be used to interpret the
    484  * contents of the audit token as the representation
    485  * of the subject identity within the token may change
    486  * over time.
    487  */
    488 typedef struct {
    489 	unsigned int                  val[8];
    490 } audit_token_t;
    491 
    492 /*
    493  * Safe initializer for audit_token_t.
    494  * Variables holding unset audit tokens should generally
    495  * be initialized to INVALID_AUDIT_TOKEN_VALUE, to allow
    496  * unset audit tokens be distinguished from the kernel's
    497  * audit token, KERNEL_AUDIT_TOKEN_VALUE.  It is `safe'
    498  * in that it limits potential damage if such an unset
    499  * audit token, or one of its fields, were ever to be
    500  * interpreted as valid by mistake.  Notably, the pid is
    501  * outside of range of valid pids, and none of the
    502  * fields correspond to privileged users or groups.
    503  */
    504 #define INVALID_AUDIT_TOKEN_VALUE     {{ \
    505 	UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, \
    506 	UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX }}
    507 
    508 typedef struct {
    509 	mach_msg_trailer_type_t       msgh_trailer_type;
    510 	mach_msg_trailer_size_t       msgh_trailer_size;
    511 	mach_port_seqno_t             msgh_seqno;
    512 	security_token_t              msgh_sender;
    513 	audit_token_t                 msgh_audit;
    514 } mach_msg_audit_trailer_t;
    515 
    516 typedef struct {
    517 	mach_msg_trailer_type_t       msgh_trailer_type;
    518 	mach_msg_trailer_size_t       msgh_trailer_size;
    519 	mach_port_seqno_t             msgh_seqno;
    520 	security_token_t              msgh_sender;
    521 	audit_token_t                 msgh_audit;
    522 	mach_port_context_t           msgh_context;
    523 } mach_msg_context_trailer_t;
    524 
    525 
    526 
    527 typedef struct {
    528 	mach_port_name_t sender;
    529 } msg_labels_t;
    530 
    531 typedef int mach_msg_filter_id;
    532 #define MACH_MSG_FILTER_POLICY_ALLOW (mach_msg_filter_id)0
    533 
    534 /*
    535  *  Trailer type to pass MAC policy label info as a mach message trailer.
    536  *
    537  */
    538 
    539 typedef struct {
    540 	mach_msg_trailer_type_t       msgh_trailer_type;
    541 	mach_msg_trailer_size_t       msgh_trailer_size;
    542 	mach_port_seqno_t             msgh_seqno;
    543 	security_token_t              msgh_sender;
    544 	audit_token_t                 msgh_audit;
    545 	mach_port_context_t           msgh_context;
    546 	mach_msg_filter_id            msgh_ad;
    547 	msg_labels_t                  msgh_labels;
    548 } mach_msg_mac_trailer_t;
    549 
    550 
    551 #define MACH_MSG_TRAILER_MINIMUM_SIZE  sizeof(mach_msg_trailer_t)
    552 
    553 /*
    554  * These values can change from release to release - but clearly
    555  * code cannot request additional trailer elements one was not
    556  * compiled to understand.  Therefore, it is safe to use this
    557  * constant when the same module specified the receive options.
    558  * Otherwise, you run the risk that the options requested by
    559  * another module may exceed the local modules notion of
    560  * MAX_TRAILER_SIZE.
    561  */
    562 
    563 typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t;
    564 #define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t))
    565 
    566 /*
    567  * Legacy requirements keep us from ever updating these defines (even
    568  * when the format_0 trailers gain new option data fields in the future).
    569  * Therefore, they shouldn't be used going forward.  Instead, the sizes
    570  * should be compared against the specific element size requested using
    571  * REQUESTED_TRAILER_SIZE.
    572  */
    573 typedef mach_msg_security_trailer_t mach_msg_format_0_trailer_t;
    574 
    575 /*typedef mach_msg_mac_trailer_t mach_msg_format_0_trailer_t;
    576  */
    577 
    578 #define MACH_MSG_TRAILER_FORMAT_0_SIZE sizeof(mach_msg_format_0_trailer_t)
    579 
    580 #define   KERNEL_SECURITY_TOKEN_VALUE  { {0, 1} }
    581 extern const security_token_t KERNEL_SECURITY_TOKEN;
    582 
    583 #define   KERNEL_AUDIT_TOKEN_VALUE  { {0, 0, 0, 0, 0, 0, 0, 0} }
    584 extern const audit_token_t KERNEL_AUDIT_TOKEN;
    585 
    586 typedef integer_t mach_msg_options_t;
    587 
    588 #define MACH_MSG_HEADER_EMPTY (mach_msg_header_t){ }
    589 
    590 typedef struct {
    591 	mach_msg_header_t     header;
    592 } mach_msg_empty_send_t;
    593 
    594 typedef struct {
    595 	mach_msg_header_t     header;
    596 	mach_msg_trailer_t    trailer;
    597 } mach_msg_empty_rcv_t;
    598 
    599 typedef union{
    600 	mach_msg_empty_send_t send;
    601 	mach_msg_empty_rcv_t  rcv;
    602 } mach_msg_empty_t;
    603 
    604 #pragma pack(pop)
    605 
    606 /* utility to round the message size - will become machine dependent */
    607 #define round_msg(x)    (((mach_msg_size_t)(x) + sizeof (natural_t) - 1) & \
    608 	                        ~(sizeof (natural_t) - 1))
    609 
    610 
    611 /*
    612  *  There is no fixed upper bound to the size of Mach messages.
    613  */
    614 #define MACH_MSG_SIZE_MAX       ((mach_msg_size_t) ~0)
    615 
    616 #if defined(__APPLE_API_PRIVATE)
    617 /*
    618  *  But architectural limits of a given implementation, or
    619  *  temporal conditions may cause unpredictable send failures
    620  *  for messages larger than MACH_MSG_SIZE_RELIABLE.
    621  *
    622  *  In either case, waiting for memory is [currently] outside
    623  *  the scope of send timeout values provided to IPC.
    624  */
    625 #define MACH_MSG_SIZE_RELIABLE  ((mach_msg_size_t) 256 * 1024)
    626 #endif
    627 /*
    628  *  Compatibility definitions, for code written
    629  *  when there was a msgh_kind instead of msgh_seqno.
    630  */
    631 #define MACH_MSGH_KIND_NORMAL           0x00000000
    632 #define MACH_MSGH_KIND_NOTIFICATION     0x00000001
    633 #define msgh_kind                       msgh_seqno
    634 #define mach_msg_kind_t                 mach_port_seqno_t
    635 
    636 typedef natural_t mach_msg_type_size_t;
    637 typedef natural_t mach_msg_type_number_t;
    638 
    639 /*
    640  *  Values received/carried in messages.  Tells the receiver what
    641  *  sort of port right he now has.
    642  *
    643  *  MACH_MSG_TYPE_PORT_NAME is used to transfer a port name
    644  *  which should remain uninterpreted by the kernel.  (Port rights
    645  *  are not transferred, just the port name.)
    646  */
    647 
    648 #define MACH_MSG_TYPE_PORT_NONE         0
    649 
    650 #define MACH_MSG_TYPE_PORT_NAME         15
    651 #define MACH_MSG_TYPE_PORT_RECEIVE      MACH_MSG_TYPE_MOVE_RECEIVE
    652 #define MACH_MSG_TYPE_PORT_SEND         MACH_MSG_TYPE_MOVE_SEND
    653 #define MACH_MSG_TYPE_PORT_SEND_ONCE    MACH_MSG_TYPE_MOVE_SEND_ONCE
    654 
    655 #define MACH_MSG_TYPE_LAST              22              /* Last assigned */
    656 
    657 /*
    658  *  A dummy value.  Mostly used to indicate that the actual value
    659  *  will be filled in later, dynamically.
    660  */
    661 
    662 #define MACH_MSG_TYPE_POLYMORPHIC       ((mach_msg_type_name_t) -1)
    663 
    664 /*
    665  *	Is a given item a port type?
    666  */
    667 
    668 #define MACH_MSG_TYPE_PORT_ANY(x)                       \
    669 	(((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) &&         \
    670 	 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))
    671 
    672 #define MACH_MSG_TYPE_PORT_ANY_SEND(x)                  \
    673 	(((x) >= MACH_MSG_TYPE_MOVE_SEND) &&            \
    674 	 ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE))
    675 
    676 #define MACH_MSG_TYPE_PORT_ANY_SEND_ONCE(x)             \
    677 	(((x) == MACH_MSG_TYPE_MOVE_SEND_ONCE) ||       \
    678 	 ((x) == MACH_MSG_TYPE_MAKE_SEND_ONCE))
    679 
    680 #define MACH_MSG_TYPE_PORT_ANY_RIGHT(x)                 \
    681 	(((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) &&         \
    682 	 ((x) <= MACH_MSG_TYPE_MOVE_SEND_ONCE))
    683 
    684 typedef integer_t mach_msg_option_t;
    685 
    686 #define MACH_MSG_OPTION_NONE    0x00000000
    687 
    688 #define MACH_SEND_MSG           0x00000001
    689 #define MACH_RCV_MSG            0x00000002
    690 
    691 #define MACH_RCV_LARGE          0x00000004      /* report large message sizes */
    692 #define MACH_RCV_LARGE_IDENTITY 0x00000008      /* identify source of large messages */
    693 
    694 #define MACH_SEND_TIMEOUT       0x00000010      /* timeout value applies to send */
    695 #define MACH_SEND_OVERRIDE      0x00000020      /* priority override for send */
    696 #define MACH_SEND_INTERRUPT     0x00000040      /* don't restart interrupted sends */
    697 #define MACH_SEND_NOTIFY        0x00000080      /* arm send-possible notify */
    698 #define MACH_SEND_ALWAYS        0x00010000      /* ignore qlimits - kernel only */
    699 #define MACH_SEND_FILTER_NONFATAL        0x00010000      /* rejection by message filter should return failure - user only */
    700 #define MACH_SEND_TRAILER       0x00020000      /* sender-provided trailer */
    701 #define MACH_SEND_NOIMPORTANCE  0x00040000      /* msg won't carry importance */
    702 #define MACH_SEND_NODENAP       MACH_SEND_NOIMPORTANCE
    703 #define MACH_SEND_IMPORTANCE    0x00080000      /* msg carries importance - kernel only */
    704 #define MACH_SEND_SYNC_OVERRIDE 0x00100000      /* msg should do sync IPC override (on legacy kernels) */
    705 #define MACH_SEND_PROPAGATE_QOS 0x00200000      /* IPC should propagate the caller's QoS */
    706 #define MACH_SEND_SYNC_USE_THRPRI       MACH_SEND_PROPAGATE_QOS /* obsolete name */
    707 #define MACH_SEND_KERNEL        0x00400000      /* full send from kernel space - kernel only */
    708 #define MACH_SEND_SYNC_BOOTSTRAP_CHECKIN  0x00800000      /* special reply port should boost thread doing sync bootstrap checkin */
    709 
    710 #define MACH_RCV_TIMEOUT        0x00000100      /* timeout value applies to receive */
    711 #define MACH_RCV_NOTIFY         0x00000000      /* legacy name (value was: 0x00000200) */
    712 #define MACH_RCV_INTERRUPT      0x00000400      /* don't restart interrupted receive */
    713 #define MACH_RCV_VOUCHER        0x00000800      /* willing to receive voucher port */
    714 #define MACH_RCV_OVERWRITE      0x00000000      /* scatter receive (deprecated) */
    715 #define MACH_RCV_GUARDED_DESC   0x00001000      /* Can receive new guarded descriptor */
    716 #define MACH_RCV_SYNC_WAIT      0x00004000      /* sync waiter waiting for rcv */
    717 #define MACH_RCV_SYNC_PEEK      0x00008000      /* sync waiter waiting to peek */
    718 
    719 #define MACH_MSG_STRICT_REPLY   0x00000200      /* Enforce specific properties about the reply port, and
    720 	                                         * the context in which a thread replies to a message.
    721 	                                         * This flag must be passed on both the SEND and RCV */
    722 
    723 
    724 /*
    725  * NOTE: a 0x00------ RCV mask implies to ask for
    726  * a MACH_MSG_TRAILER_FORMAT_0 with 0 Elements,
    727  * which is equivalent to a mach_msg_trailer_t.
    728  *
    729  * XXXMAC: unlike the rest of the MACH_RCV_* flags, MACH_RCV_TRAILER_LABELS
    730  * needs its own private bit since we only calculate its fields when absolutely
    731  * required.
    732  */
    733 #define MACH_RCV_TRAILER_NULL   0
    734 #define MACH_RCV_TRAILER_SEQNO  1
    735 #define MACH_RCV_TRAILER_SENDER 2
    736 #define MACH_RCV_TRAILER_AUDIT  3
    737 #define MACH_RCV_TRAILER_CTX    4
    738 #define MACH_RCV_TRAILER_AV     7
    739 #define MACH_RCV_TRAILER_LABELS 8
    740 
    741 #define MACH_RCV_TRAILER_TYPE(x)     (((x) & 0xf) << 28)
    742 #define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24)
    743 #define MACH_RCV_TRAILER_MASK        ((0xf << 24))
    744 
    745 #define GET_RCV_ELEMENTS(y) (((y) >> 24) & 0xf)
    746 
    747 
    748 /*
    749  * XXXMAC: note that in the case of MACH_RCV_TRAILER_LABELS,
    750  * we just fall through to mach_msg_max_trailer_t.
    751  * This is correct behavior since mach_msg_max_trailer_t is defined as
    752  * mac_msg_mac_trailer_t which is used for the LABELS trailer.
    753  * It also makes things work properly if MACH_RCV_TRAILER_LABELS is ORed
    754  * with one of the other options.
    755  */
    756 
    757 #define REQUESTED_TRAILER_SIZE_NATIVE(y)                        \
    758 	((mach_msg_trailer_size_t)                              \
    759 	 ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ?      \
    760 	  sizeof(mach_msg_trailer_t) :                          \
    761 	  ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ?    \
    762 	   sizeof(mach_msg_seqno_trailer_t) :                   \
    763 	  ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ?   \
    764 	   sizeof(mach_msg_security_trailer_t) :                \
    765 	   ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ?   \
    766 	    sizeof(mach_msg_audit_trailer_t) :                  \
    767 	    ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ?    \
    768 	     sizeof(mach_msg_context_trailer_t) :               \
    769 	     ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ?    \
    770 	      sizeof(mach_msg_mac_trailer_t) :                  \
    771 	     sizeof(mach_msg_max_trailer_t))))))))
    772 
    773 
    774 #define REQUESTED_TRAILER_SIZE(y) REQUESTED_TRAILER_SIZE_NATIVE(y)
    775 
    776 /*
    777  *  Much code assumes that mach_msg_return_t == kern_return_t.
    778  *  This definition is useful for descriptive purposes.
    779  *
    780  *  See <mach/error.h> for the format of error codes.
    781  *  IPC errors are system 4.  Send errors are subsystem 0;
    782  *  receive errors are subsystem 1.  The code field is always non-zero.
    783  *  The high bits of the code field communicate extra information
    784  *  for some error codes.  MACH_MSG_MASK masks off these special bits.
    785  */
    786 
    787 typedef kern_return_t mach_msg_return_t;
    788 
    789 #define MACH_MSG_SUCCESS                0x00000000
    790 
    791 
    792 #define MACH_MSG_MASK                   0x00003e00
    793 /* All special error code bits defined below. */
    794 #define MACH_MSG_IPC_SPACE              0x00002000
    795 /* No room in IPC name space for another capability name. */
    796 #define MACH_MSG_VM_SPACE               0x00001000
    797 /* No room in VM address space for out-of-line memory. */
    798 #define MACH_MSG_IPC_KERNEL             0x00000800
    799 /* Kernel resource shortage handling an IPC capability. */
    800 #define MACH_MSG_VM_KERNEL              0x00000400
    801 /* Kernel resource shortage handling out-of-line memory. */
    802 
    803 #define MACH_SEND_IN_PROGRESS           0x10000001
    804 /* Thread is waiting to send.  (Internal use only.) */
    805 #define MACH_SEND_INVALID_DATA          0x10000002
    806 /* Bogus in-line data. */
    807 #define MACH_SEND_INVALID_DEST          0x10000003
    808 /* Bogus destination port. */
    809 #define MACH_SEND_TIMED_OUT             0x10000004
    810 /* Message not sent before timeout expired. */
    811 #define MACH_SEND_INVALID_VOUCHER       0x10000005
    812 /* Bogus voucher port. */
    813 #define MACH_SEND_INTERRUPTED           0x10000007
    814 /* Software interrupt. */
    815 #define MACH_SEND_MSG_TOO_SMALL         0x10000008
    816 /* Data doesn't contain a complete message. */
    817 #define MACH_SEND_INVALID_REPLY         0x10000009
    818 /* Bogus reply port. */
    819 #define MACH_SEND_INVALID_RIGHT         0x1000000a
    820 /* Bogus port rights in the message body. */
    821 #define MACH_SEND_INVALID_NOTIFY        0x1000000b
    822 /* Bogus notify port argument. */
    823 #define MACH_SEND_INVALID_MEMORY        0x1000000c
    824 /* Invalid out-of-line memory pointer. */
    825 #define MACH_SEND_NO_BUFFER             0x1000000d
    826 /* No message buffer is available. */
    827 #define MACH_SEND_TOO_LARGE             0x1000000e
    828 /* Send is too large for port */
    829 #define MACH_SEND_INVALID_TYPE          0x1000000f
    830 /* Invalid msg-type specification. */
    831 #define MACH_SEND_INVALID_HEADER        0x10000010
    832 /* A field in the header had a bad value. */
    833 #define MACH_SEND_INVALID_TRAILER       0x10000011
    834 /* The trailer to be sent does not match kernel format. */
    835 #define MACH_SEND_INVALID_CONTEXT       0x10000012
    836 /* The sending thread context did not match the context on the dest port */
    837 #define MACH_SEND_INVALID_OPTIONS       0x10000013
    838 /* Send options are invalid. */
    839 #define MACH_SEND_INVALID_RT_OOL_SIZE   0x10000015
    840 /* compatibility: no longer a returned error */
    841 #define MACH_SEND_NO_GRANT_DEST         0x10000016
    842 /* The destination port doesn't accept ports in body */
    843 #define MACH_SEND_MSG_FILTERED          0x10000017
    844 /* Message send was rejected by message filter */
    845 #define MACH_SEND_AUX_TOO_SMALL         0x10000018
    846 /* Message auxiliary data is too small */
    847 #define MACH_SEND_AUX_TOO_LARGE         0x10000019
    848 /* Message auxiliary data is too large */
    849 
    850 #define MACH_RCV_IN_PROGRESS            0x10004001
    851 /* Thread is waiting for receive.  (Internal use only.) */
    852 #define MACH_RCV_INVALID_NAME           0x10004002
    853 /* Bogus name for receive port/port-set. */
    854 #define MACH_RCV_TIMED_OUT              0x10004003
    855 /* Didn't get a message within the timeout value. */
    856 #define MACH_RCV_TOO_LARGE              0x10004004
    857 /* Message buffer is not large enough for inline data. */
    858 #define MACH_RCV_INTERRUPTED            0x10004005
    859 /* Software interrupt. */
    860 #define MACH_RCV_PORT_CHANGED           0x10004006
    861 /* compatibility: no longer a returned error */
    862 #define MACH_RCV_INVALID_NOTIFY         0x10004007
    863 /* Bogus notify port argument. */
    864 #define MACH_RCV_INVALID_DATA           0x10004008
    865 /* Bogus message buffer for inline data. */
    866 #define MACH_RCV_PORT_DIED              0x10004009
    867 /* Port/set was sent away/died during receive. */
    868 #define MACH_RCV_IN_SET                 0x1000400a
    869 /* compatibility: no longer a returned error */
    870 #define MACH_RCV_HEADER_ERROR           0x1000400b
    871 /* Error receiving message header.  See special bits. */
    872 #define MACH_RCV_BODY_ERROR             0x1000400c
    873 /* Error receiving message body.  See special bits. */
    874 #define MACH_RCV_INVALID_TYPE           0x1000400d
    875 /* Invalid msg-type specification in scatter list. */
    876 #define MACH_RCV_SCATTER_SMALL          0x1000400e
    877 /* Out-of-line overwrite region is not large enough */
    878 #define MACH_RCV_INVALID_TRAILER        0x1000400f
    879 /* trailer type or number of trailer elements not supported */
    880 #define MACH_RCV_IN_PROGRESS_TIMED      0x10004011
    881 /* Waiting for receive with timeout. (Internal use only.) */
    882 #define MACH_RCV_INVALID_REPLY          0x10004012
    883 /* invalid reply port used in a STRICT_REPLY message */
    884 #define MACH_RCV_INVALID_ARGUMENTS      0x10004013
    885 /* invalid receive arguments, receive has not started */
    886 
    887 
    888 
    889 __BEGIN_DECLS
    890 
    891 /*
    892  *	Routine:	mach_msg_overwrite
    893  *	Purpose:
    894  *		Send and/or receive a message.  If the message operation
    895  *		is interrupted, and the user did not request an indication
    896  *		of that fact, then restart the appropriate parts of the
    897  *		operation silently (trap version does not restart).
    898  *
    899  *		Distinct send and receive buffers may be specified.  If
    900  *		no separate receive buffer is specified, the msg parameter
    901  *		will be used for both send and receive operations.
    902  *
    903  *		In addition to a distinct receive buffer, that buffer may
    904  *		already contain scatter control information to direct the
    905  *		receiving of the message.
    906  */
    907 __WATCHOS_PROHIBITED __TVOS_PROHIBITED
    908 extern mach_msg_return_t        mach_msg_overwrite(
    909 	mach_msg_header_t *msg,
    910 	mach_msg_option_t option,
    911 	mach_msg_size_t send_size,
    912 	mach_msg_size_t rcv_size,
    913 	mach_port_name_t rcv_name,
    914 	mach_msg_timeout_t timeout,
    915 	mach_port_name_t notify,
    916 	mach_msg_header_t *rcv_msg,
    917 	mach_msg_size_t rcv_limit);
    918 
    919 
    920 /*
    921  *	Routine:	mach_msg
    922  *	Purpose:
    923  *		Send and/or receive a message.  If the message operation
    924  *		is interrupted, and the user did not request an indication
    925  *		of that fact, then restart the appropriate parts of the
    926  *		operation silently (trap version does not restart).
    927  */
    928 __WATCHOS_PROHIBITED __TVOS_PROHIBITED
    929 extern mach_msg_return_t        mach_msg(
    930 	mach_msg_header_t *msg,
    931 	mach_msg_option_t option,
    932 	mach_msg_size_t send_size,
    933 	mach_msg_size_t rcv_size,
    934 	mach_port_name_t rcv_name,
    935 	mach_msg_timeout_t timeout,
    936 	mach_port_name_t notify);
    937 
    938 
    939 /*
    940  *  Routine:    mach_voucher_deallocate
    941  *  Purpose:
    942  *      Deallocate a mach voucher created or received in a message.  Drops
    943  *      one (send right) reference to the voucher.
    944  */
    945 __WATCHOS_PROHIBITED __TVOS_PROHIBITED
    946 extern kern_return_t            mach_voucher_deallocate(
    947 	mach_port_name_t voucher);
    948 
    949 
    950 __END_DECLS
    951 
    952 #endif  /* _MACH_MESSAGE_H_ */