xref: /xnu-11417.121.6/tests/reply_port_defense_client.c (revision a1e26a70f38d1d7daa7b49b258e2f8538ad81650)
1*a1e26a70SApple OSS Distributions #include <stdlib.h>
2*a1e26a70SApple OSS Distributions #include <stdio.h>
3*a1e26a70SApple OSS Distributions #include <pthread.h>
4*a1e26a70SApple OSS Distributions #include <unistd.h>
5*a1e26a70SApple OSS Distributions #include <mach/kern_return.h>
6*a1e26a70SApple OSS Distributions #include <mach/mach.h>
7*a1e26a70SApple OSS Distributions #include <mach/task.h>
8*a1e26a70SApple OSS Distributions #include <mach/thread_status.h>
9*a1e26a70SApple OSS Distributions #include <os/tsd.h>
10*a1e26a70SApple OSS Distributions #include <assert.h>
11*a1e26a70SApple OSS Distributions #include <sys/codesign.h>
12*a1e26a70SApple OSS Distributions #include <stdbool.h>
13*a1e26a70SApple OSS Distributions 
14*a1e26a70SApple OSS Distributions #include "cs_helpers.h"
15*a1e26a70SApple OSS Distributions 
16*a1e26a70SApple OSS Distributions #define MAX_TEST_NUM 11
17*a1e26a70SApple OSS Distributions 
18*a1e26a70SApple OSS Distributions #if __arm64__
19*a1e26a70SApple OSS Distributions #define machine_thread_state_t          arm_thread_state64_t
20*a1e26a70SApple OSS Distributions #define EXCEPTION_THREAD_STATE          ARM_THREAD_STATE64
21*a1e26a70SApple OSS Distributions #define EXCEPTION_THREAD_STATE_COUNT    ARM_THREAD_STATE64_COUNT
22*a1e26a70SApple OSS Distributions #elif __x86_64__
23*a1e26a70SApple OSS Distributions #define machine_thread_state_t          x86_thread_state_t
24*a1e26a70SApple OSS Distributions #define EXCEPTION_THREAD_STATE          x86_THREAD_STATE
25*a1e26a70SApple OSS Distributions #define EXCEPTION_THREAD_STATE_COUNT    x86_THREAD_STATE_COUNT
26*a1e26a70SApple OSS Distributions #else
27*a1e26a70SApple OSS Distributions #error Unsupported architecture
28*a1e26a70SApple OSS Distributions #endif
29*a1e26a70SApple OSS Distributions 
30*a1e26a70SApple OSS Distributions static mach_port_t
alloc_server_port(void)31*a1e26a70SApple OSS Distributions alloc_server_port(void)
32*a1e26a70SApple OSS Distributions {
33*a1e26a70SApple OSS Distributions 	mach_port_t server_port = MACH_PORT_NULL;
34*a1e26a70SApple OSS Distributions 	kern_return_t kr;
35*a1e26a70SApple OSS Distributions 
36*a1e26a70SApple OSS Distributions 	kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &server_port);
37*a1e26a70SApple OSS Distributions 	assert(kr == 0);
38*a1e26a70SApple OSS Distributions 
39*a1e26a70SApple OSS Distributions 	kr = mach_port_insert_right(mach_task_self(), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND);
40*a1e26a70SApple OSS Distributions 	assert(kr == 0);
41*a1e26a70SApple OSS Distributions 
42*a1e26a70SApple OSS Distributions 	return server_port;
43*a1e26a70SApple OSS Distributions }
44*a1e26a70SApple OSS Distributions 
45*a1e26a70SApple OSS Distributions static mach_port_t
alloc_provisional_reply_port()46*a1e26a70SApple OSS Distributions alloc_provisional_reply_port()
47*a1e26a70SApple OSS Distributions {
48*a1e26a70SApple OSS Distributions 	kern_return_t kr;
49*a1e26a70SApple OSS Distributions 	mach_port_t reply_port = MACH_PORT_NULL;
50*a1e26a70SApple OSS Distributions 	mach_port_t task = mach_task_self();
51*a1e26a70SApple OSS Distributions 
52*a1e26a70SApple OSS Distributions 	mach_port_options_t opts = {
53*a1e26a70SApple OSS Distributions 		.flags = MPO_PROVISIONAL_REPLY_PORT | MPO_INSERT_SEND_RIGHT,
54*a1e26a70SApple OSS Distributions 	};
55*a1e26a70SApple OSS Distributions 
56*a1e26a70SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &opts, 0, &reply_port);
57*a1e26a70SApple OSS Distributions 	assert(kr == 0);
58*a1e26a70SApple OSS Distributions 
59*a1e26a70SApple OSS Distributions 	return reply_port;
60*a1e26a70SApple OSS Distributions }
61*a1e26a70SApple OSS Distributions 
62*a1e26a70SApple OSS Distributions static mach_port_t
alloc_reply_port()63*a1e26a70SApple OSS Distributions alloc_reply_port()
64*a1e26a70SApple OSS Distributions {
65*a1e26a70SApple OSS Distributions 	kern_return_t kr;
66*a1e26a70SApple OSS Distributions 	mach_port_t reply_port = MACH_PORT_NULL;
67*a1e26a70SApple OSS Distributions 	mach_port_t task = mach_task_self();
68*a1e26a70SApple OSS Distributions 
69*a1e26a70SApple OSS Distributions 	mach_port_options_t opts = {
70*a1e26a70SApple OSS Distributions 		.flags = MPO_REPLY_PORT | MPO_INSERT_SEND_RIGHT,
71*a1e26a70SApple OSS Distributions 	};
72*a1e26a70SApple OSS Distributions 
73*a1e26a70SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &opts, 0, &reply_port);
74*a1e26a70SApple OSS Distributions 	assert(kr == 0);
75*a1e26a70SApple OSS Distributions 
76*a1e26a70SApple OSS Distributions 	return reply_port;
77*a1e26a70SApple OSS Distributions }
78*a1e26a70SApple OSS Distributions 
79*a1e26a70SApple OSS Distributions /* The rcv right of the port would be marked immovable. */
80*a1e26a70SApple OSS Distributions static void
test_immovable_receive_right(void)81*a1e26a70SApple OSS Distributions test_immovable_receive_right(void)
82*a1e26a70SApple OSS Distributions {
83*a1e26a70SApple OSS Distributions 	kern_return_t kr;
84*a1e26a70SApple OSS Distributions 	mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
85*a1e26a70SApple OSS Distributions 	struct {
86*a1e26a70SApple OSS Distributions 		mach_msg_header_t header;
87*a1e26a70SApple OSS Distributions 		mach_msg_body_t body;
88*a1e26a70SApple OSS Distributions 		mach_msg_port_descriptor_t desc;
89*a1e26a70SApple OSS Distributions 	} msg;
90*a1e26a70SApple OSS Distributions 
91*a1e26a70SApple OSS Distributions 	server_port = alloc_server_port();
92*a1e26a70SApple OSS Distributions 	reply_port = alloc_reply_port();
93*a1e26a70SApple OSS Distributions 
94*a1e26a70SApple OSS Distributions 	msg.header.msgh_remote_port = server_port;
95*a1e26a70SApple OSS Distributions 	msg.header.msgh_local_port = MACH_PORT_NULL;
96*a1e26a70SApple OSS Distributions 	msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
97*a1e26a70SApple OSS Distributions 	msg.header.msgh_size = sizeof msg;
98*a1e26a70SApple OSS Distributions 
99*a1e26a70SApple OSS Distributions 	msg.body.msgh_descriptor_count = 1;
100*a1e26a70SApple OSS Distributions 
101*a1e26a70SApple OSS Distributions 	msg.desc.name = reply_port;
102*a1e26a70SApple OSS Distributions 	msg.desc.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
103*a1e26a70SApple OSS Distributions 	msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
104*a1e26a70SApple OSS Distributions 	kr = mach_msg_send(&msg.header);
105*a1e26a70SApple OSS Distributions 
106*a1e26a70SApple OSS Distributions 	printf("[reply_port_defense_client test_immovable_receive_right]: mach_msg2() returned %d\n", kr);
107*a1e26a70SApple OSS Distributions }
108*a1e26a70SApple OSS Distributions 
109*a1e26a70SApple OSS Distributions /* The only way you could create a send once right is when you send the port in local port of a mach msg with MAKE_SEND_ONCE disposition. */
110*a1e26a70SApple OSS Distributions static void
test_make_send_once_right(void)111*a1e26a70SApple OSS Distributions test_make_send_once_right(void)
112*a1e26a70SApple OSS Distributions {
113*a1e26a70SApple OSS Distributions 	kern_return_t kr;
114*a1e26a70SApple OSS Distributions 	mach_port_t reply_port = alloc_reply_port();
115*a1e26a70SApple OSS Distributions 	kr = mach_port_insert_right(mach_task_self(), reply_port, reply_port, MACH_MSG_TYPE_MAKE_SEND_ONCE);
116*a1e26a70SApple OSS Distributions 	printf("[reply_port_defense_client test_make_send_once_right]: mach_port_insert_right() returned %d\n", kr);
117*a1e26a70SApple OSS Distributions }
118*a1e26a70SApple OSS Distributions 
119*a1e26a70SApple OSS Distributions /* The send right of the port would only used for guarding a name in ipc space, it would not allow to send a message. */
120*a1e26a70SApple OSS Distributions static void
test_using_send_right(void)121*a1e26a70SApple OSS Distributions test_using_send_right(void)
122*a1e26a70SApple OSS Distributions {
123*a1e26a70SApple OSS Distributions 	kern_return_t kr;
124*a1e26a70SApple OSS Distributions 	mach_port_t reply_port = alloc_reply_port();
125*a1e26a70SApple OSS Distributions 	struct {
126*a1e26a70SApple OSS Distributions 		mach_msg_header_t header;
127*a1e26a70SApple OSS Distributions 		mach_msg_body_t body;
128*a1e26a70SApple OSS Distributions 	} msg;
129*a1e26a70SApple OSS Distributions 
130*a1e26a70SApple OSS Distributions 	msg.header.msgh_remote_port = reply_port;
131*a1e26a70SApple OSS Distributions 	msg.header.msgh_local_port = MACH_PORT_NULL;
132*a1e26a70SApple OSS Distributions 	msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
133*a1e26a70SApple OSS Distributions 	msg.header.msgh_size = sizeof msg;
134*a1e26a70SApple OSS Distributions 
135*a1e26a70SApple OSS Distributions 	kr = mach_msg_send(&msg.header);
136*a1e26a70SApple OSS Distributions 	printf("[reply_port_defense_client test_using_send_right]: mach_msg2() returned %d\n", kr);
137*a1e26a70SApple OSS Distributions }
138*a1e26a70SApple OSS Distributions 
139*a1e26a70SApple OSS Distributions /* The send right of the port would only used for guarding a name in ipc space, it would not allowed to get moved. */
140*a1e26a70SApple OSS Distributions static void
test_move_send_right(void)141*a1e26a70SApple OSS Distributions test_move_send_right(void)
142*a1e26a70SApple OSS Distributions {
143*a1e26a70SApple OSS Distributions 	kern_return_t kr;
144*a1e26a70SApple OSS Distributions 	mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
145*a1e26a70SApple OSS Distributions 	struct {
146*a1e26a70SApple OSS Distributions 		mach_msg_header_t header;
147*a1e26a70SApple OSS Distributions 		mach_msg_body_t body;
148*a1e26a70SApple OSS Distributions 		mach_msg_port_descriptor_t desc;
149*a1e26a70SApple OSS Distributions 	} msg;
150*a1e26a70SApple OSS Distributions 
151*a1e26a70SApple OSS Distributions 	server_port = alloc_server_port();
152*a1e26a70SApple OSS Distributions 	reply_port = alloc_reply_port();
153*a1e26a70SApple OSS Distributions 
154*a1e26a70SApple OSS Distributions 	msg.header.msgh_remote_port = server_port;
155*a1e26a70SApple OSS Distributions 	msg.header.msgh_local_port = MACH_PORT_NULL;
156*a1e26a70SApple OSS Distributions 	msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
157*a1e26a70SApple OSS Distributions 	msg.header.msgh_size = sizeof msg;
158*a1e26a70SApple OSS Distributions 
159*a1e26a70SApple OSS Distributions 	msg.body.msgh_descriptor_count = 1;
160*a1e26a70SApple OSS Distributions 
161*a1e26a70SApple OSS Distributions 	msg.desc.name = reply_port;
162*a1e26a70SApple OSS Distributions 	msg.desc.disposition = MACH_MSG_TYPE_MOVE_SEND;
163*a1e26a70SApple OSS Distributions 	msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
164*a1e26a70SApple OSS Distributions 
165*a1e26a70SApple OSS Distributions 	kr = mach_msg_send(&msg.header);
166*a1e26a70SApple OSS Distributions 	printf("[reply_port_defense_client test_move_send_right]: mach_msg2() returned %d\n", kr);
167*a1e26a70SApple OSS Distributions }
168*a1e26a70SApple OSS Distributions 
169*a1e26a70SApple OSS Distributions static void
test_move_provisional_reply_port(void)170*a1e26a70SApple OSS Distributions test_move_provisional_reply_port(void)
171*a1e26a70SApple OSS Distributions {
172*a1e26a70SApple OSS Distributions 	kern_return_t kr;
173*a1e26a70SApple OSS Distributions 	mach_port_t server_port = MACH_PORT_NULL, reply_port = MACH_PORT_NULL;
174*a1e26a70SApple OSS Distributions 	struct {
175*a1e26a70SApple OSS Distributions 		mach_msg_header_t header;
176*a1e26a70SApple OSS Distributions 		mach_msg_body_t body;
177*a1e26a70SApple OSS Distributions 		mach_msg_port_descriptor_t desc;
178*a1e26a70SApple OSS Distributions 	} msg;
179*a1e26a70SApple OSS Distributions 
180*a1e26a70SApple OSS Distributions 	server_port = alloc_server_port();
181*a1e26a70SApple OSS Distributions 	reply_port = alloc_provisional_reply_port();
182*a1e26a70SApple OSS Distributions 
183*a1e26a70SApple OSS Distributions 	msg.header.msgh_remote_port = server_port;
184*a1e26a70SApple OSS Distributions 	msg.header.msgh_local_port = MACH_PORT_NULL;
185*a1e26a70SApple OSS Distributions 	msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
186*a1e26a70SApple OSS Distributions 	msg.header.msgh_size = sizeof msg;
187*a1e26a70SApple OSS Distributions 
188*a1e26a70SApple OSS Distributions 	msg.body.msgh_descriptor_count = 1;
189*a1e26a70SApple OSS Distributions 
190*a1e26a70SApple OSS Distributions 	msg.desc.name = reply_port;
191*a1e26a70SApple OSS Distributions 	msg.desc.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
192*a1e26a70SApple OSS Distributions 	msg.desc.type = MACH_MSG_PORT_DESCRIPTOR;
193*a1e26a70SApple OSS Distributions 
194*a1e26a70SApple OSS Distributions 	kr = mach_msg_send(&msg.header);
195*a1e26a70SApple OSS Distributions 
196*a1e26a70SApple OSS Distributions 	printf("[reply_port_defense_client test_immovable_receive_right]: mach_msg2() returned %d\n", kr);
197*a1e26a70SApple OSS Distributions }
198*a1e26a70SApple OSS Distributions 
199*a1e26a70SApple OSS Distributions static void
test_unentitled_thread_set_state(void)200*a1e26a70SApple OSS Distributions test_unentitled_thread_set_state(void)
201*a1e26a70SApple OSS Distributions {
202*a1e26a70SApple OSS Distributions 	machine_thread_state_t ts;
203*a1e26a70SApple OSS Distributions 	mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
204*a1e26a70SApple OSS Distributions 
205*a1e26a70SApple OSS Distributions 	/* thread_set_state as a hardened binary should fail */
206*a1e26a70SApple OSS Distributions 	kern_return_t kr = thread_get_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, &count);
207*a1e26a70SApple OSS Distributions 
208*a1e26a70SApple OSS Distributions 	kr = thread_set_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, count);
209*a1e26a70SApple OSS Distributions 	assert(kr != KERN_SUCCESS);
210*a1e26a70SApple OSS Distributions 	exit(-1); /* Should have crashed before here! */
211*a1e26a70SApple OSS Distributions }
212*a1e26a70SApple OSS Distributions 
213*a1e26a70SApple OSS Distributions static void
unentitled_set_exception_ports_crash(void)214*a1e26a70SApple OSS Distributions unentitled_set_exception_ports_crash(void)
215*a1e26a70SApple OSS Distributions {
216*a1e26a70SApple OSS Distributions 	mach_port_t exc_port = alloc_server_port();
217*a1e26a70SApple OSS Distributions 
218*a1e26a70SApple OSS Distributions 	/* thread_set_exception_ports as a hardened binary should fail */
219*a1e26a70SApple OSS Distributions 	kern_return_t kr = thread_set_exception_ports(
220*a1e26a70SApple OSS Distributions 		mach_thread_self(),
221*a1e26a70SApple OSS Distributions 		EXC_MASK_ALL,
222*a1e26a70SApple OSS Distributions 		exc_port,
223*a1e26a70SApple OSS Distributions 		(exception_behavior_t)((unsigned int)EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES),
224*a1e26a70SApple OSS Distributions 		EXCEPTION_THREAD_STATE);
225*a1e26a70SApple OSS Distributions 
226*a1e26a70SApple OSS Distributions 	/* thread_set_exception_ports is supposed to crash, unless the policy is turned off.
227*a1e26a70SApple OSS Distributions 	 * Things that disable the policy: AMFI boot-args in use, SIP disabled,
228*a1e26a70SApple OSS Distributions 	 * third party plugins in a process. The caller of this client will check
229*a1e26a70SApple OSS Distributions 	 * whether the test crashed and correctly adhered to these policies.
230*a1e26a70SApple OSS Distributions 	 */
231*a1e26a70SApple OSS Distributions 	printf("thread_set_exception_ports did not crash\n");
232*a1e26a70SApple OSS Distributions }
233*a1e26a70SApple OSS Distributions 
234*a1e26a70SApple OSS Distributions static void
unentitled_set_exception_ports_pass(void)235*a1e26a70SApple OSS Distributions unentitled_set_exception_ports_pass(void)
236*a1e26a70SApple OSS Distributions {
237*a1e26a70SApple OSS Distributions 	mach_port_t exc_port = alloc_server_port();
238*a1e26a70SApple OSS Distributions 
239*a1e26a70SApple OSS Distributions 	/* thread_set_exception_ports with state *IDENTITY_PROTECTED should not fail */
240*a1e26a70SApple OSS Distributions 	kern_return_t kr = thread_set_exception_ports(
241*a1e26a70SApple OSS Distributions 		mach_thread_self(),
242*a1e26a70SApple OSS Distributions 		EXC_MASK_ALL,
243*a1e26a70SApple OSS Distributions 		exc_port,
244*a1e26a70SApple OSS Distributions 		(exception_behavior_t)((unsigned int)EXCEPTION_STATE_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES),
245*a1e26a70SApple OSS Distributions 		EXCEPTION_THREAD_STATE);
246*a1e26a70SApple OSS Distributions 	assert(kr == 0);
247*a1e26a70SApple OSS Distributions 
248*a1e26a70SApple OSS Distributions 	kr = thread_set_exception_ports(
249*a1e26a70SApple OSS Distributions 		mach_thread_self(),
250*a1e26a70SApple OSS Distributions 		EXC_MASK_ALL,
251*a1e26a70SApple OSS Distributions 		exc_port,
252*a1e26a70SApple OSS Distributions 		(exception_behavior_t)((unsigned int)EXCEPTION_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES),
253*a1e26a70SApple OSS Distributions 		EXCEPTION_THREAD_STATE);
254*a1e26a70SApple OSS Distributions 	assert(kr == 0);
255*a1e26a70SApple OSS Distributions 
256*a1e26a70SApple OSS Distributions 	return;
257*a1e26a70SApple OSS Distributions }
258*a1e26a70SApple OSS Distributions 
259*a1e26a70SApple OSS Distributions static void
exception_ports_crash(void)260*a1e26a70SApple OSS Distributions exception_ports_crash(void)
261*a1e26a70SApple OSS Distributions {
262*a1e26a70SApple OSS Distributions 	kern_return_t kr;
263*a1e26a70SApple OSS Distributions 	mach_port_t exc_port;
264*a1e26a70SApple OSS Distributions 	mach_port_options_t opts = {
265*a1e26a70SApple OSS Distributions 		.flags = MPO_INSERT_SEND_RIGHT | MPO_EXCEPTION_PORT,
266*a1e26a70SApple OSS Distributions 	};
267*a1e26a70SApple OSS Distributions 
268*a1e26a70SApple OSS Distributions 	kr = mach_port_construct(mach_task_self(), &opts, 0ull, &exc_port);
269*a1e26a70SApple OSS Distributions 	assert(kr == KERN_SUCCESS);
270*a1e26a70SApple OSS Distributions 
271*a1e26a70SApple OSS Distributions 	kr = task_register_hardened_exception_handler(current_task(),
272*a1e26a70SApple OSS Distributions 	    0, EXC_MASK_BAD_ACCESS,
273*a1e26a70SApple OSS Distributions 	    EXCEPTION_STATE_IDENTITY_PROTECTED, EXCEPTION_THREAD_STATE, exc_port);
274*a1e26a70SApple OSS Distributions 
275*a1e26a70SApple OSS Distributions 	kr = thread_set_exception_ports(
276*a1e26a70SApple OSS Distributions 		mach_thread_self(),
277*a1e26a70SApple OSS Distributions 		EXC_MASK_BAD_ACCESS,
278*a1e26a70SApple OSS Distributions 		exc_port,
279*a1e26a70SApple OSS Distributions 		(exception_behavior_t)((unsigned int)EXCEPTION_STATE_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES),
280*a1e26a70SApple OSS Distributions 		EXCEPTION_THREAD_STATE);
281*a1e26a70SApple OSS Distributions 
282*a1e26a70SApple OSS Distributions 	printf("thread_set_exception_ports did not crash: %d\n", kr);
283*a1e26a70SApple OSS Distributions }
284*a1e26a70SApple OSS Distributions 
285*a1e26a70SApple OSS Distributions static void
kobject_reply_port_defense(void)286*a1e26a70SApple OSS Distributions kobject_reply_port_defense(void)
287*a1e26a70SApple OSS Distributions {
288*a1e26a70SApple OSS Distributions 	machine_thread_state_t ts;
289*a1e26a70SApple OSS Distributions 	mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
290*a1e26a70SApple OSS Distributions 	mach_port_t port = MACH_PORT_NULL;
291*a1e26a70SApple OSS Distributions 
292*a1e26a70SApple OSS Distributions 	kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
293*a1e26a70SApple OSS Distributions 	assert(kr == KERN_SUCCESS);
294*a1e26a70SApple OSS Distributions 
295*a1e26a70SApple OSS Distributions 	// make a kobject call
296*a1e26a70SApple OSS Distributions 	kr = thread_get_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, &count);
297*a1e26a70SApple OSS Distributions 	assert(kr == KERN_SUCCESS);
298*a1e26a70SApple OSS Distributions 
299*a1e26a70SApple OSS Distributions 	// set the MIG reply port to a "normal" port
300*a1e26a70SApple OSS Distributions 	_os_tsd_set_direct(__TSD_MIG_REPLY, (void *)(uintptr_t)port);
301*a1e26a70SApple OSS Distributions 
302*a1e26a70SApple OSS Distributions 	kr = thread_get_state(mach_thread_self(), MACHINE_THREAD_STATE, (thread_state_t)&ts, &count);
303*a1e26a70SApple OSS Distributions 
304*a1e26a70SApple OSS Distributions 	printf("kobject call did not crash: %d\n", kr);
305*a1e26a70SApple OSS Distributions }
306*a1e26a70SApple OSS Distributions 
307*a1e26a70SApple OSS Distributions static void
test_alloc_provisional_reply_port(void)308*a1e26a70SApple OSS Distributions test_alloc_provisional_reply_port(void)
309*a1e26a70SApple OSS Distributions {
310*a1e26a70SApple OSS Distributions 	mach_port_t __unused reply_port = alloc_provisional_reply_port();
311*a1e26a70SApple OSS Distributions }
312*a1e26a70SApple OSS Distributions 
313*a1e26a70SApple OSS Distributions int
main(int argc,char * argv[])314*a1e26a70SApple OSS Distributions main(int argc, char *argv[])
315*a1e26a70SApple OSS Distributions {
316*a1e26a70SApple OSS Distributions 	uint32_t my_csflags = 0;
317*a1e26a70SApple OSS Distributions 	bool thirdparty_hardened = !strcmp(argv[0], "./reply_port_defense_client_3P_hardened");
318*a1e26a70SApple OSS Distributions 
319*a1e26a70SApple OSS Distributions 	/* TODO add some sysctl which disabled platform binary bit here */
320*a1e26a70SApple OSS Distributions 	if (my_csflags & CS_PLATFORM_BINARY == thirdparty_hardened) {
321*a1e26a70SApple OSS Distributions 		printf("platform binary does not match expected\n");
322*a1e26a70SApple OSS Distributions 		return -1;
323*a1e26a70SApple OSS Distributions 	}
324*a1e26a70SApple OSS Distributions 
325*a1e26a70SApple OSS Distributions 
326*a1e26a70SApple OSS Distributions 	void (*tests[MAX_TEST_NUM])(void) = {
327*a1e26a70SApple OSS Distributions 		test_immovable_receive_right, /* 0 */
328*a1e26a70SApple OSS Distributions 		test_make_send_once_right,
329*a1e26a70SApple OSS Distributions 		test_using_send_right, /* 2 */
330*a1e26a70SApple OSS Distributions 		test_move_send_right,
331*a1e26a70SApple OSS Distributions 		test_move_provisional_reply_port, /* 4 */
332*a1e26a70SApple OSS Distributions 		unentitled_set_exception_ports_crash,
333*a1e26a70SApple OSS Distributions 		test_unentitled_thread_set_state, /* 6 */
334*a1e26a70SApple OSS Distributions 		unentitled_set_exception_ports_pass,
335*a1e26a70SApple OSS Distributions 		exception_ports_crash, /* 8 */
336*a1e26a70SApple OSS Distributions 		kobject_reply_port_defense, /* 9 */
337*a1e26a70SApple OSS Distributions 		test_alloc_provisional_reply_port, /* 10 */
338*a1e26a70SApple OSS Distributions 	};
339*a1e26a70SApple OSS Distributions 
340*a1e26a70SApple OSS Distributions 	if (argc < 2) {
341*a1e26a70SApple OSS Distributions 		printf("[reply_port_defense_client]: Specify a test to run.");
342*a1e26a70SApple OSS Distributions 		exit(-1);
343*a1e26a70SApple OSS Distributions 	}
344*a1e26a70SApple OSS Distributions 
345*a1e26a70SApple OSS Distributions 	int test_num = atoi(argv[1]);
346*a1e26a70SApple OSS Distributions 	printf("[reply_port_defense_client]: My Pid: %d Test num: %d third_party_hardened: %s\n",
347*a1e26a70SApple OSS Distributions 	    getpid(), test_num, thirdparty_hardened ? "yes" : "no");
348*a1e26a70SApple OSS Distributions 	fflush(stdout);
349*a1e26a70SApple OSS Distributions 	if (test_num >= 0 && test_num < MAX_TEST_NUM) {
350*a1e26a70SApple OSS Distributions 		(*tests[test_num])();
351*a1e26a70SApple OSS Distributions 	} else {
352*a1e26a70SApple OSS Distributions 		printf("[reply_port_defense_client]: Invalid test num. Exiting...\n");
353*a1e26a70SApple OSS Distributions 		exit(-1);
354*a1e26a70SApple OSS Distributions 	}
355*a1e26a70SApple OSS Distributions 	printf("Child exiting cleanly!!\n");
356*a1e26a70SApple OSS Distributions 	fflush(stdout);
357*a1e26a70SApple OSS Distributions 	// return 0;
358*a1e26a70SApple OSS Distributions 	exit(0);
359*a1e26a70SApple OSS Distributions }
360