xref: /xnu-12377.41.6/tests/ipc/ipc_utils.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
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