1*bbb1b6f9SApple OSS Distributions #include "ipc_utils.h"
2*bbb1b6f9SApple OSS Distributions #include <darwintest.h>
3*bbb1b6f9SApple OSS Distributions #include <unistd.h>
4*bbb1b6f9SApple OSS Distributions #include <sys/types.h>
5*bbb1b6f9SApple OSS Distributions #include <sys/sysctl.h>
6*bbb1b6f9SApple OSS Distributions
7*bbb1b6f9SApple OSS Distributions /*
8*bbb1b6f9SApple OSS Distributions * Implementation of common IPC utilities for XNU tests
9*bbb1b6f9SApple OSS Distributions *
10*bbb1b6f9SApple OSS Distributions * Note: This implementation is designed specifically for test environments
11*bbb1b6f9SApple OSS Distributions * and uses darwintest T_QUIET macros for internal validations.
12*bbb1b6f9SApple OSS Distributions */
13*bbb1b6f9SApple OSS Distributions
14*bbb1b6f9SApple OSS Distributions /*
15*bbb1b6f9SApple OSS Distributions * Port Management Functions
16*bbb1b6f9SApple OSS Distributions */
17*bbb1b6f9SApple OSS Distributions
18*bbb1b6f9SApple OSS Distributions mach_port_t
ipc_create_receive_port(void)19*bbb1b6f9SApple OSS Distributions ipc_create_receive_port(void)
20*bbb1b6f9SApple OSS Distributions {
21*bbb1b6f9SApple OSS Distributions return ipc_create_receive_port_with_options(0);
22*bbb1b6f9SApple OSS Distributions }
23*bbb1b6f9SApple OSS Distributions
24*bbb1b6f9SApple OSS Distributions mach_port_t
ipc_create_receive_port_with_options(uint32_t mpo_flags)25*bbb1b6f9SApple OSS Distributions ipc_create_receive_port_with_options(uint32_t mpo_flags)
26*bbb1b6f9SApple OSS Distributions {
27*bbb1b6f9SApple OSS Distributions mach_port_options_t opts = {
28*bbb1b6f9SApple OSS Distributions .flags = mpo_flags,
29*bbb1b6f9SApple OSS Distributions };
30*bbb1b6f9SApple OSS Distributions mach_port_name_t port;
31*bbb1b6f9SApple OSS Distributions kern_return_t kr;
32*bbb1b6f9SApple OSS Distributions
33*bbb1b6f9SApple OSS Distributions kr = mach_port_construct(mach_task_self(), &opts, 0, &port);
34*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "ipc_create_receive_port_with_options");
35*bbb1b6f9SApple OSS Distributions
36*bbb1b6f9SApple OSS Distributions return port;
37*bbb1b6f9SApple OSS Distributions }
38*bbb1b6f9SApple OSS Distributions
39*bbb1b6f9SApple OSS Distributions void
ipc_deallocate_port(mach_port_t port)40*bbb1b6f9SApple OSS Distributions ipc_deallocate_port(mach_port_t port)
41*bbb1b6f9SApple OSS Distributions {
42*bbb1b6f9SApple OSS Distributions if (port != MACH_PORT_NULL) {
43*bbb1b6f9SApple OSS Distributions kern_return_t kr = mach_port_deallocate(mach_task_self(), port);
44*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "ipc_deallocate_port");
45*bbb1b6f9SApple OSS Distributions }
46*bbb1b6f9SApple OSS Distributions }
47*bbb1b6f9SApple OSS Distributions
48*bbb1b6f9SApple OSS Distributions kern_return_t
ipc_insert_send_right(mach_port_t receive_port)49*bbb1b6f9SApple OSS Distributions ipc_insert_send_right(mach_port_t receive_port)
50*bbb1b6f9SApple OSS Distributions {
51*bbb1b6f9SApple OSS Distributions kern_return_t kr = mach_port_insert_right(mach_task_self(), receive_port,
52*bbb1b6f9SApple OSS Distributions receive_port, MACH_MSG_TYPE_MAKE_SEND);
53*bbb1b6f9SApple OSS Distributions T_ASSERT_MACH_SUCCESS(kr, "ipc_insert_send_right");
54*bbb1b6f9SApple OSS Distributions return kr;
55*bbb1b6f9SApple OSS Distributions }
56*bbb1b6f9SApple OSS Distributions
57*bbb1b6f9SApple OSS Distributions /*
58*bbb1b6f9SApple OSS Distributions * Single Port Messaging Functions
59*bbb1b6f9SApple OSS Distributions */
60*bbb1b6f9SApple OSS Distributions
61*bbb1b6f9SApple OSS Distributions kern_return_t
ipc_send_port(mach_port_t destination,mach_port_t port,mach_msg_type_name_t disposition)62*bbb1b6f9SApple OSS Distributions ipc_send_port(mach_port_t destination, mach_port_t port, mach_msg_type_name_t disposition)
63*bbb1b6f9SApple OSS Distributions {
64*bbb1b6f9SApple OSS Distributions ipc_single_port_msg_t msg = {
65*bbb1b6f9SApple OSS Distributions .header = {
66*bbb1b6f9SApple OSS Distributions .msgh_remote_port = destination,
67*bbb1b6f9SApple OSS Distributions .msgh_local_port = MACH_PORT_NULL,
68*bbb1b6f9SApple OSS Distributions .msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX,
69*bbb1b6f9SApple OSS Distributions .msgh_size = sizeof(ipc_single_port_msg_t),
70*bbb1b6f9SApple OSS Distributions .msgh_id = 0x1001 /* Single port message ID */
71*bbb1b6f9SApple OSS Distributions },
72*bbb1b6f9SApple OSS Distributions .body = {
73*bbb1b6f9SApple OSS Distributions .msgh_descriptor_count = 1
74*bbb1b6f9SApple OSS Distributions },
75*bbb1b6f9SApple OSS Distributions .port = {
76*bbb1b6f9SApple OSS Distributions .name = port,
77*bbb1b6f9SApple OSS Distributions .disposition = disposition,
78*bbb1b6f9SApple OSS Distributions .type = MACH_MSG_PORT_DESCRIPTOR
79*bbb1b6f9SApple OSS Distributions }
80*bbb1b6f9SApple OSS Distributions };
81*bbb1b6f9SApple OSS Distributions
82*bbb1b6f9SApple OSS Distributions return ipc_send_message(&msg.header);
83*bbb1b6f9SApple OSS Distributions }
84*bbb1b6f9SApple OSS Distributions
85*bbb1b6f9SApple OSS Distributions kern_return_t
ipc_receive_port(mach_port_t destination,mach_port_t * port)86*bbb1b6f9SApple OSS Distributions ipc_receive_port(mach_port_t destination, mach_port_t *port)
87*bbb1b6f9SApple OSS Distributions {
88*bbb1b6f9SApple OSS Distributions ipc_receive_msg_t msg;
89*bbb1b6f9SApple OSS Distributions kern_return_t kr;
90*bbb1b6f9SApple OSS Distributions
91*bbb1b6f9SApple OSS Distributions kr = ipc_receive_message(destination, &msg, sizeof(ipc_receive_msg_t));
92*bbb1b6f9SApple OSS Distributions if (kr == KERN_SUCCESS) {
93*bbb1b6f9SApple OSS Distributions if (msg.header.msgh_id == 0x1001 && msg.body.msgh_descriptor_count == 1) {
94*bbb1b6f9SApple OSS Distributions *port = msg.data.single.port.name;
95*bbb1b6f9SApple OSS Distributions } else {
96*bbb1b6f9SApple OSS Distributions kr = KERN_INVALID_ARGUMENT;
97*bbb1b6f9SApple OSS Distributions }
98*bbb1b6f9SApple OSS Distributions }
99*bbb1b6f9SApple OSS Distributions
100*bbb1b6f9SApple OSS Distributions return kr;
101*bbb1b6f9SApple OSS Distributions }
102*bbb1b6f9SApple OSS Distributions
103*bbb1b6f9SApple OSS Distributions
104*bbb1b6f9SApple OSS Distributions /*
105*bbb1b6f9SApple OSS Distributions * Port Array Messaging Functions
106*bbb1b6f9SApple OSS Distributions */
107*bbb1b6f9SApple OSS Distributions
108*bbb1b6f9SApple OSS Distributions kern_return_t
ipc_send_port_array(mach_port_t destination,mach_port_t * ports,mach_msg_type_number_t count,mach_msg_type_name_t disposition)109*bbb1b6f9SApple OSS Distributions ipc_send_port_array(mach_port_t destination,
110*bbb1b6f9SApple OSS Distributions mach_port_t *ports, mach_msg_type_number_t count,
111*bbb1b6f9SApple OSS Distributions mach_msg_type_name_t disposition)
112*bbb1b6f9SApple OSS Distributions {
113*bbb1b6f9SApple OSS Distributions ipc_port_array_msg_t msg = {
114*bbb1b6f9SApple OSS Distributions .header = {
115*bbb1b6f9SApple OSS Distributions .msgh_remote_port = destination,
116*bbb1b6f9SApple OSS Distributions .msgh_local_port = MACH_PORT_NULL,
117*bbb1b6f9SApple OSS Distributions .msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX,
118*bbb1b6f9SApple OSS Distributions .msgh_size = sizeof(ipc_port_array_msg_t),
119*bbb1b6f9SApple OSS Distributions .msgh_id = 0x1004 /* Port array message ID */
120*bbb1b6f9SApple OSS Distributions },
121*bbb1b6f9SApple OSS Distributions .body = {
122*bbb1b6f9SApple OSS Distributions .msgh_descriptor_count = 1
123*bbb1b6f9SApple OSS Distributions },
124*bbb1b6f9SApple OSS Distributions .ports_descriptor = {
125*bbb1b6f9SApple OSS Distributions .address = (void*)ports,
126*bbb1b6f9SApple OSS Distributions .count = count,
127*bbb1b6f9SApple OSS Distributions .deallocate = FALSE,
128*bbb1b6f9SApple OSS Distributions .disposition = disposition,
129*bbb1b6f9SApple OSS Distributions .type = MACH_MSG_OOL_PORTS_DESCRIPTOR
130*bbb1b6f9SApple OSS Distributions }
131*bbb1b6f9SApple OSS Distributions };
132*bbb1b6f9SApple OSS Distributions
133*bbb1b6f9SApple OSS Distributions return ipc_send_message(&msg.header);
134*bbb1b6f9SApple OSS Distributions }
135*bbb1b6f9SApple OSS Distributions
136*bbb1b6f9SApple OSS Distributions kern_return_t
ipc_receive_port_array(mach_port_t destination,mach_port_t ** ports,mach_msg_type_number_t * count)137*bbb1b6f9SApple OSS Distributions ipc_receive_port_array(mach_port_t destination,
138*bbb1b6f9SApple OSS Distributions mach_port_t **ports, mach_msg_type_number_t *count)
139*bbb1b6f9SApple OSS Distributions {
140*bbb1b6f9SApple OSS Distributions ipc_receive_msg_t msg;
141*bbb1b6f9SApple OSS Distributions kern_return_t kr;
142*bbb1b6f9SApple OSS Distributions
143*bbb1b6f9SApple OSS Distributions kr = ipc_receive_message(destination, &msg, sizeof(ipc_receive_msg_t));
144*bbb1b6f9SApple OSS Distributions if (kr == KERN_SUCCESS) {
145*bbb1b6f9SApple OSS Distributions if (msg.header.msgh_id == 0x1004 && msg.body.msgh_descriptor_count == 1) {
146*bbb1b6f9SApple OSS Distributions *ports = (mach_port_t*)msg.data.array.ports_descriptor.address;
147*bbb1b6f9SApple OSS Distributions *count = msg.data.array.ports_descriptor.count;
148*bbb1b6f9SApple OSS Distributions } else {
149*bbb1b6f9SApple OSS Distributions kr = KERN_INVALID_ARGUMENT;
150*bbb1b6f9SApple OSS Distributions }
151*bbb1b6f9SApple OSS Distributions }
152*bbb1b6f9SApple OSS Distributions
153*bbb1b6f9SApple OSS Distributions return kr;
154*bbb1b6f9SApple OSS Distributions }
155*bbb1b6f9SApple OSS Distributions
156*bbb1b6f9SApple OSS Distributions /*
157*bbb1b6f9SApple OSS Distributions * Generic Messaging Functions
158*bbb1b6f9SApple OSS Distributions */
159*bbb1b6f9SApple OSS Distributions
160*bbb1b6f9SApple OSS Distributions kern_return_t
ipc_send_message(mach_msg_header_t * msg)161*bbb1b6f9SApple OSS Distributions ipc_send_message(mach_msg_header_t *msg)
162*bbb1b6f9SApple OSS Distributions {
163*bbb1b6f9SApple OSS Distributions kern_return_t kr = mach_msg(msg, MACH_SEND_MSG, msg->msgh_size, 0,
164*bbb1b6f9SApple OSS Distributions MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
165*bbb1b6f9SApple OSS Distributions return kr;
166*bbb1b6f9SApple OSS Distributions }
167*bbb1b6f9SApple OSS Distributions
168*bbb1b6f9SApple OSS Distributions kern_return_t
ipc_receive_message(mach_port_t destination,ipc_receive_msg_t * msg,mach_msg_size_t max_size)169*bbb1b6f9SApple OSS Distributions ipc_receive_message(mach_port_t destination, ipc_receive_msg_t *msg, mach_msg_size_t max_size)
170*bbb1b6f9SApple OSS Distributions {
171*bbb1b6f9SApple OSS Distributions kern_return_t kr = mach_msg(&msg->header, MACH_RCV_MSG, 0, max_size,
172*bbb1b6f9SApple OSS Distributions destination, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
173*bbb1b6f9SApple OSS Distributions return kr;
174*bbb1b6f9SApple OSS Distributions }
175*bbb1b6f9SApple OSS Distributions
176*bbb1b6f9SApple OSS Distributions
177*bbb1b6f9SApple OSS Distributions /*
178*bbb1b6f9SApple OSS Distributions * Security and Code Signing Utilities
179*bbb1b6f9SApple OSS Distributions */
180*bbb1b6f9SApple OSS Distributions
181*bbb1b6f9SApple OSS Distributions bool
ipc_hardening_disabled(void)182*bbb1b6f9SApple OSS Distributions ipc_hardening_disabled(void)
183*bbb1b6f9SApple OSS Distributions {
184*bbb1b6f9SApple OSS Distributions #if TARGET_OS_OSX || TARGET_OS_BRIDGE
185*bbb1b6f9SApple OSS Distributions /*
186*bbb1b6f9SApple OSS Distributions * CS_CONFIG_GET_OUT_OF_MY_WAY (enabled via AMFI boot-args)
187*bbb1b6f9SApple OSS Distributions * disables IPC security features. Unfortunately,
188*bbb1b6f9SApple OSS Distributions * BATS runs with this boot-arg enabled very frequently.
189*bbb1b6f9SApple OSS Distributions */
190*bbb1b6f9SApple OSS Distributions code_signing_config_t cur_cs_config = 0;
191*bbb1b6f9SApple OSS Distributions size_t cs_config_size = sizeof(cur_cs_config);
192*bbb1b6f9SApple OSS Distributions int result = sysctlbyname("security.codesigning.config", &cur_cs_config,
193*bbb1b6f9SApple OSS Distributions &cs_config_size, NULL, 0);
194*bbb1b6f9SApple OSS Distributions if (result != 0) {
195*bbb1b6f9SApple OSS Distributions T_QUIET; T_LOG("ipc_hardening_disabled: failed to get codesigning config, assuming not disabled");
196*bbb1b6f9SApple OSS Distributions return false;
197*bbb1b6f9SApple OSS Distributions }
198*bbb1b6f9SApple OSS Distributions return (cur_cs_config & CS_CONFIG_GET_OUT_OF_MY_WAY) != 0;
199*bbb1b6f9SApple OSS Distributions #else /* TARGET_OS_OSX || TARGET_OS_BRIDGE */
200*bbb1b6f9SApple OSS Distributions /* mach hardening is only disabled by boot-args on macOS */
201*bbb1b6f9SApple OSS Distributions return false;
202*bbb1b6f9SApple OSS Distributions #endif
203*bbb1b6f9SApple OSS Distributions }
204