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